diff --git a/product/ERP5/Document/BusinessTemplate.py b/product/ERP5/Document/BusinessTemplate.py
index 9014dc7d8986c0ddf8d7bb7c95e08ee81b4fde7b..df0138a32a72fc1d2abfe2c84801d595f6f58d59 100644
--- a/product/ERP5/Document/BusinessTemplate.py
+++ b/product/ERP5/Document/BusinessTemplate.py
@@ -860,6 +860,7 @@ class ObjectTemplateItem(BaseTemplateItem):
               raise
           saved_uid_dict = {}
           subobjects_dict = {}
+          portal_type_dict = {}
           # Object already exists
           old_obj = container._getOb(object_id, None)
           if old_obj is not None:
@@ -872,6 +873,15 @@ class ObjectTemplateItem(BaseTemplateItem):
               old_groups[path] = deepcopy(old_obj.groups)
             subobjects_dict = self._backupObject(action, trashbin,
                                                  container_path, object_id)
+            # in case of portal types, we want to keep some properties
+            if getattr(old_obj, 'meta_type', None) == 'ERP5 Type Information':
+              for attr in ('allowed_content_type_list',
+                           'hidden_content_type_list',
+                           'property_sheet_list',
+                           'base_category_list'):
+                portal_type_dict[attr] = getattr(old_obj, attr, ())
+              portal_type_dict['workflow_chain'] = \
+                getChainByType(context)[1].get('chain_' + object_id, '')
             container.manage_delObjects([object_id])
           else:
             self.onNewObject()
@@ -897,43 +907,17 @@ class ObjectTemplateItem(BaseTemplateItem):
           self.REQUEST.set('is_business_template_installation', 1)
           obj.manage_afterClone(obj)
           obj.wl_clearLocks()
-          # if portal types upgrade, set backup properties
-          if getattr(obj, 'meta_type', None) == 'ERP5 Type Information' and \
-              len(subobjects_dict) > 0:
-            setattr(obj, 'allowed_content_types',
-                    subobjects_dict['allowed_content_type_list'] or [])
-            setattr(obj, 'hidden_content_type_list',
-                    subobjects_dict['hidden_content_type_list'] or [])
-            setattr(obj, 'property_sheet_list',
-                    subobjects_dict['property_sheet_list'] or [])
-            setattr(obj, 'base_category_list',
-                    subobjects_dict['base_category_list'] or [])
-            setattr(obj, '_roles', subobjects_dict['roles_list'] or [])
-            # set actions
-            action_list = subobjects_dict['action_list']
-            for action in action_list:
-              action_text = action.action
-              if isinstance(action_text, Expression):
-                action_text = action_text.text
-              obj.addAction(id = action.id
-                            , name = action.title
-                            , action = action_text
-                            , condition = action.getCondition()
-                            , permission = action.permissions
-                            , category = action.category
-                            , visible = action.visible
-                            , icon = getattr(action, 'icon', None) and action.icon.text or ''
-                            , priority = action.priority
-                            , description = action.description
-                            )
+          if portal_type_dict:
             # set workflow chain
-            wf_chain = subobjects_dict['workflow_chain']
+            wf_chain = portal_type_dict.pop('workflow_chain')
             chain_dict = getChainByType(context)[1]
             default_chain = ''
             chain_dict['chain_%s' % (object_id)] = wf_chain
             context.portal_workflow.manage_changeWorkflows(default_chain, props=chain_dict)
+            # restore some other properties
+            obj.__dict__.update(portal_type_dict)
           # import sub objects if there is
-          elif len(subobjects_dict) > 0:
+          if subobjects_dict:
             # get a jar
             connection = obj._p_jar
             o = obj
@@ -4881,7 +4865,6 @@ Business Template is a set of definitions, such as skins, portal types and categ
         Return the list of modified/new/removed object between a Business Template
         and the one installed if exists
       """
-
       if check_dependencies:
         # required because in multi installation, dependencies has already
         # been checked before and it will failed here as dependencies can be
@@ -5730,7 +5713,7 @@ Business Template is a set of definitions, such as skins, portal types and categ
         portal_type = ttool.getTypeInfo(id)
         if portal_type is None:
           continue
-        if len(getattr(portal_type, '_roles', ())) > 0:
+        if portal_type.getRoleInformationList():
           if id not in bt_portal_type_roles_list:
             bt_portal_type_roles_list.append(id)
 
@@ -5747,8 +5730,8 @@ Business Template is a set of definitions, such as skins, portal types and categ
           property_sheet_list = portal_type.property_sheet_list
         if hasattr(portal_type, 'base_category_list'):
           base_category_list = portal_type.base_category_list
-        if hasattr(portal_type, 'listActions'):
-          action_list = [x.getId() for x in portal_type.listActions()]
+        for action in portal_type.getActionInformationList():
+          action_list.append(action.getReference())
 
         for a_id in allowed_content_type_list:
           allowed_id = id+' | '+a_id
diff --git a/product/ERP5/Tool/TrashTool.py b/product/ERP5/Tool/TrashTool.py
index a62313ff7f7e125db7b2943c4bd34c9fc6d6a68f..0760fbe1c84ae330803391266e3aff7d6b19d92f 100644
--- a/product/ERP5/Tool/TrashTool.py
+++ b/product/ERP5/Tool/TrashTool.py
@@ -120,33 +120,14 @@ class TrashTool(BaseTool):
       else:
         object_path = container_path + [object_id]
         obj = self.unrestrictedTraverse(object_path)
-      if obj is None:
-        pass
-      # in case of portal types, export properties instead of subobjects
-      elif getattr(obj, 'meta_type', None) == 'ERP5 Type Information':
-        subobjects_dict = {}
-        subobjects_dict['allowed_content_type_list'] = getattr(obj, 'allowed_content_types', []) or []
-        subobjects_dict['hidden_content_type_list'] = getattr(obj, 'hidden_content_type_list', []) or []
-        subobjects_dict['property_sheet_list'] = getattr(obj, 'property_sheet_list', []) or []
-        subobjects_dict['base_category_list'] = getattr(obj, 'base_category_list', []) or []
-        subobjects_dict['roles_list'] =  getattr(obj, '_roles', []) or []
-        action_list = obj.listActions() or []
-        subobjects_dict['action_list'] = []
-        for action in action_list:
-          subobjects_dict['action_list'].append(action._getCopy(obj))
-        wf_chain = getChainByType(self.getPortalObject())[1]
-        if wf_chain.has_key('chain_%s' % object_id):
-          subobjects_dict['workflow_chain'] = wf_chain['chain_%s' % object_id]
-        else:
-          subobjects_dict['workflow_chain'] = ''
-      else:
+      if obj is not None:
         for subobject_id in list(obj.objectIds()):
           subobject_path = object_path + [subobject_id]
           subobject = self.unrestrictedTraverse(subobject_path)
           subobject_copy = subobject._p_jar.exportFile(subobject._p_oid)
           subobjects_dict[subobject_id] = subobject_copy
           if save: # remove subobjecs from backup object
-            obj.manage_delObjects([subobject_id])
+            obj._delObject(subobject_id)
     return subobjects_dict
 
   def newTrashBin(self, bt_title='trash', bt=None):
diff --git a/product/ERP5/tests/testBusinessTemplate.py b/product/ERP5/tests/testBusinessTemplate.py
index 2bb5593170d1c6df58cafb9d77a2aff54fe7ab64..022a503184ec8ceb34eded3ea350956c740715db 100644
--- a/product/ERP5/tests/testBusinessTemplate.py
+++ b/product/ERP5/tests/testBusinessTemplate.py
@@ -331,29 +331,25 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor):
     """
     pt = self.getTypeTool()
     # create module object portal type
-    pt.manage_addTypeInformation(ERP5TypeInformation.meta_type,
-                                 id='Geek Object',
-                                 typeinfo_name='ERP5Type: ERP5 Person',)
-    object_type = pt._getOb('Geek Object', None)
+    object_type = pt.newContent('Geek Object', 'Base Type',
+                                type_factory_method_id='addPerson')
     self.failUnless(object_type is not None)
     sequence.edit(object_ptype_id=object_type.getId())
     # create module portal type
-    pt.manage_addTypeInformation(ERP5TypeInformation.meta_type,
-                                 id='Geek Module',
-                                 typeinfo_name='ERP5Type: ERP5 Folder')
-    module_type = pt._getOb('Geek Module', None)
+    module_type = pt.newContent('Geek Module', 'Base Type',
+      type_factory_method_id='addFolder',
+      type_filter_content_type=1,
+      type_allowed_content_type_list=('Geek Object',),
+      type_hidden_content_type_list=('Geek Object',),
+      type_base_category_list=('destination',),
+      type_property_sheet_list=('Version',))
     self.failUnless(module_type is not None)
-    module_type.filter_content_types = 1
-    module_type.allowed_content_types = ('Geek Object',)
-    module_type.hidden_content_type_list = ('Geek Object',)
-    module_type.base_category_list = ('destination',)
-    module_type.property_sheet_list = ('Version',)
     sequence.edit(module_ptype_id=module_type.getId(),
-          module_ptype_filter_content_types=module_type.filter_content_types,
-          module_ptype_allowed_content_types=module_type.allowed_content_types,
-          module_ptype_hidden_content_type_list=module_type.hidden_content_type_list,
-          module_ptype_base_category_list=module_type.base_category_list,
-          module_ptype_property_sheet_list=module_type.property_sheet_list)
+      module_ptype_filter_content_types=module_type.getTypeFilterContentType(),
+      module_ptype_allowed_content_types=module_type.getTypeAllowedContentTypeList(),
+      module_ptype_hidden_content_type_list=module_type.getTypeHiddenContentTypeList(),
+      module_ptype_base_category_list=module_type.getTypeBaseCategoryList(),
+      module_ptype_property_sheet_list=module_type.getTypePropertySheetList())
 
   def stepModifyPortalTypeInBusinessTemplate(self, sequence=None, sequence_list=None, **kw):
     """
@@ -374,10 +370,10 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor):
             template_portal_type_hidden_content_type=(),
             template_portal_type_base_category=('Geek Module | source',),
             template_portal_type_property_sheet=())
-    sequence.edit(module_ptype_allowed_content_types=('Geek Module',),
-                  module_ptype_hidden_content_type_list=(),
-                  module_ptype_base_category_list=('source',),
-                  module_ptype_property_sheet_list=())
+    sequence.edit(module_ptype_allowed_content_types=['Geek Module'],
+                  module_ptype_hidden_content_type_list=[],
+                  module_ptype_base_category_list=['source'],
+                  module_ptype_property_sheet_list=[])
 
   def stepAddPortalTypeToBusinessTemplate(self, sequence=None, sequence_list=None, **kw):
     """
@@ -417,15 +413,17 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor):
     object_type = pt._getOb(object_id, None)
     self.failUnless(object_type is None)
 
-  def stepRemoveViewAction(self, sequence=None, sequence_list=None, **kw):
+  def stepRemoveFirstAction(self, sequence=None, sequence_list=None, **kw):
     """
     Remove PortalType
     """
     pt = self.getTypeTool()
     object_id = sequence.get('object_ptype_id')
-    module_id = sequence.get('module_ptype_id')
-    object_type = pt._getOb(object_id, None)
-    object_type.deleteActions([0])
+    action_id = sequence.get('first_action_id')
+    object_type = pt[object_id]
+    action_id, = [x.getId() for x in object_type.getActionInformationList()
+                            if x.getReference() == action_id]
+    object_type._delObject(action_id)
 
   def stepCheckPortalTypeExists(self, sequence=None, sequence_list=None, **kw):
     """
@@ -436,15 +434,15 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor):
     module_id = sequence.get('module_ptype_id')
     module_type = pt._getOb(module_id, None)
     self.failUnless(module_type is not None)
-    self.assertEquals(module_type.allowed_content_types,
+    self.assertEqual(module_type.getTypeAllowedContentTypeList(),
         sequence.get('module_ptype_allowed_content_types'))
-    self.assertEquals(module_type.hidden_content_type_list,
+    self.assertEqual(module_type.getTypeHiddenContentTypeList(),
         sequence.get('module_ptype_hidden_content_type_list'))
-    self.assertEquals(module_type.filter_content_types,
+    self.assertEqual(module_type.getTypeFilterContentType(),
         sequence.get('module_ptype_filter_content_types'))
-    self.assertEquals(module_type.base_category_list,
+    self.assertEqual(module_type.getTypeBaseCategoryList(),
         sequence.get('module_ptype_base_category_list'))
-    self.assertEquals(module_type.property_sheet_list,
+    self.assertEqual(module_type.getTypePropertySheetList(),
         sequence.get('module_ptype_property_sheet_list'))
     object_type = pt._getOb(object_id, None)
     self.failUnless(object_type is not None)
@@ -1262,19 +1260,6 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor):
       , priority = 1.5 )
     sequence.edit(second_action_id='become_nerd')
 
-  def stepCheckActionsOrder(self, sequence=None, sequence_list=None, **kw):
-    """
-    Check Actions Order
-    """
-    pt = self.getTypeTool()
-    object_id = sequence.get('object_ptype_id')
-    object_pt = pt._getOb(object_id)
-    actions_list = object_pt.listActions()
-    priority = 0
-    for action in actions_list:
-      self.failIf(action.priority < priority)
-      priority = action.priority
-
   def stepCheckFirstActionExists(self, sequence=None, sequence_list=None, **kw):
     """
     Check presence of action
@@ -1283,7 +1268,8 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor):
     object_id = sequence.get('object_ptype_id')
     object_pt = pt._getOb(object_id)
     action_id = sequence.get('first_action_id')
-    self.failUnless(action_id in [x.getId() for x in object_pt.listActions()])
+    self.assertTrue(action_id in [x.getReference()
+      for x in object_pt.getActionInformationList()])
 
   def stepCheckFirstActionNotExists(self, sequence=None, sequence_list=None, **kw):
     """
@@ -1293,7 +1279,8 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor):
     object_id = sequence.get('object_ptype_id')
     object_pt = pt._getOb(object_id)
     action_id = sequence.get('first_action_id')
-    self.failUnless(action_id not in [x.getId() for x in object_pt.listActions()])
+    self.assertTrue(action_id in [x.getReference()
+      for x in object_pt.getActionInformationList()])
 
   def stepCheckSecondActionExists(self, sequence=None, sequence_list=None, **kw):
     """
@@ -1303,7 +1290,8 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor):
     object_id = sequence.get('object_ptype_id')
     object_pt = pt._getOb(object_id)
     action_id = sequence.get('second_action_id')
-    self.failUnless(action_id in [x.getId() for x in object_pt.listActions()])
+    self.assertTrue(action_id in [x.getReference()
+      for x in object_pt.getActionInformationList()])
 
   def stepCheckSecondActionNotExists(self, sequence=None, sequence_list=None, **kw):
     """
@@ -1313,7 +1301,8 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor):
     object_id = sequence.get('object_ptype_id')
     object_pt = pt._getOb(object_id)
     action_id = sequence.get('second_action_id')
-    self.failUnless(action_id not in [x.getId() for x in object_pt.listActions()])
+    self.assertTrue(action_id in [x.getReference()
+      for x in object_pt.getActionInformationList()])
 
   def stepAddSecondActionToBusinessTemplate(self, sequence=None, sequence_list=None, **kw):
     """
@@ -2218,7 +2207,8 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor):
     """
     import_bt = sequence.get('current_bt')
     diff_list = import_bt.BusinessTemplate_getModifiedObject()
-    self.assertTrue('portal_types/Geek Object/view' in [line.object_id for line in diff_list])
+    self.assertTrue('portal_types/Geek Object/become_geek'
+                    in [line.object_id for line in diff_list])
     import_bt.reinstall()
 
   def stepInstallCurrentBusinessTemplate(self, sequence=None, sequence_list=None, **kw):
@@ -3077,7 +3067,6 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor):
                        CheckSkinsLayers \
                        CheckFirstActionExists \
                        CheckSecondActionExists \
-                       CheckActionsOrder \
                        UninstallBusinessTemplate \
                        CheckBuiltBuildingState \
                        CheckNotInstalledInstallationState \
@@ -5054,13 +5043,12 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor):
     pt = self.getTypeTool()
     object_id = sequence.get('object_ptype_id')
     object_pt = pt._getOb(object_id)
-    object_pt.addRole(id='geek_role_definition',
-                       description='A definition with non ascii chars 茅脿猫',
-                       name='Geek Role Definition',
-                       condition='',
-                       category='group/g1\nfunction/f1\n',
-                       base_category_script='Base Category Script',
-                       base_category='group site',)
+    object_pt.newContent(portal_type='Role Information',
+      description='A definition with non ascii chars 茅脿猫',
+      role_name_list=('Geek Role Definition',),
+      role_category_list=('group/g1','function/f1'),
+      role_base_category_script_id='Base Category Script',
+      role_base_category_list=('group','site'))
 
     sequence.edit(portal_type_role='geek_role_definition')
 
@@ -5084,18 +5072,12 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor):
     """
     pt = self.getTypeTool()
     object_id = sequence.get('object_ptype_id')
-    object_pt = pt._getOb(object_id)
-    role_list = object_pt._roles
-    role_list = [x for x in role_list if x.id == 'geek_role_definition']
-    self.assertEquals(1, len(role_list))
-    role = role_list[0]
-    self.assertEquals('Geek Role Definition', role.title)
-    self.assertEquals('A definition with non ascii chars 茅脿猫', role.description)
-    self.assertEquals(('group/g1','function/f1'), role.getCategory())
-    self.assertEquals(('group','site'), role.getBaseCategory())
-    self.assertEquals('Base Category Script', role.getBaseCategoryScript())
-    # role name is a string, not unicode
-    self.assertTrue(isinstance(role.id, str))
+    role, = pt[object_id].getRoleInformationList()
+    self.assertEqual(['Geek Role Definition'], role.getRoleNameList())
+    self.assertEqual('A definition with non ascii chars 茅脿猫', role.getDescription())
+    self.assertEqual(['group/g1','function/f1'], role.getRoleCategoryList())
+    self.assertEqual(['group','site'], role.getRoleBaseCategoryList())
+    self.assertEqual('Base Category Script', role.getRoleBaseCategoryScriptId())
 
   def test_36_CheckPortalTypeRoles(self, quiet=quiet, run=run_all_test):
     if not run: return
@@ -5244,7 +5226,7 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor):
                        SaveBusinessTemplate \
                        InstallCurrentBusinessTemplate Tic \
                        Tic \
-                       RemoveViewAction \
+                       RemoveFirstAction \
                        ReinstallBusinessTemplate Tic \
                        '
     sequence_list.addSequenceString(sequence_string)
diff --git a/product/ERP5/tests/testERP5Core.py b/product/ERP5/tests/testERP5Core.py
index de0f4971018762b1c74a536eb13f36e3283b8da1..6078d257c28e7503919e8cd5b5a3fac8401ae2d1 100644
--- a/product/ERP5/tests/testERP5Core.py
+++ b/product/ERP5/tests/testERP5Core.py
@@ -210,14 +210,12 @@ class TestERP5Core(ERP5TypeTestCase, ZopeTestCase.Functional):
     translation_service = DummyTranslationService()
     setGlobalTranslationService(translation_service)
     # adds a new jump action to Template Tool portal type
-    self.getTypesTool().getTypeInfo('Template Tool').addAction(
-                      id='dummy_jump_action',
-                      name='Dummy Jump Action',
-                      action='',
-                      condition='',
-                      permission='View',
-                      category='object_jump',
-                      visible=1)
+    self.getTypesTool().getTypeInfo('Template Tool').newContent(
+                      portal_type='Action Information',
+                      reference='dummy_jump_action',
+                      title='Dummy Jump Action',
+                      action_permission='View',
+                      action_type='object_jump')
     response = self.publish('%s/portal_templates/view' %
                             self.portal_id, self.auth)
     self.assertEquals(HTTP_OK, response.getStatus())
diff --git a/product/ERP5Type/ERP5Type.py b/product/ERP5Type/ERP5Type.py
index 3eb8dc22d2b8088cf47a9e1a0d06e4704d24d7c7..a479f11deb87ba9a45fa08add746a2f7cf6bd8b4 100644
--- a/product/ERP5Type/ERP5Type.py
+++ b/product/ERP5Type/ERP5Type.py
@@ -593,6 +593,8 @@ class ERP5TypeInformation(XMLObject,
         permissions=tuple(action.getActionPermissionList()))
       for k, v in action.__dict__.iteritems():
         if k in ('action', 'condition', 'icon'):
+          if not v:
+            continue
           v = v.__class__(v.text)
         elif k in ('id', 'float_index', 'action_permission', 'reference'):
           continue