diff --git a/product/ERP5Catalog/CatalogTool.py b/product/ERP5Catalog/CatalogTool.py
index b3a9b5b80e84779315e7d2f882ed3d40fe913d45..4b12222e5e5e3439da3d5e5905ec7e2d8914a4ca 100644
--- a/product/ERP5Catalog/CatalogTool.py
+++ b/product/ERP5Catalog/CatalogTool.py
@@ -769,6 +769,13 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject):
         else:
           super(CatalogTool, self).catalogObjectList(object_list, *args, **kw)
 
+    security.declarePrivate('uncatalogObjectList')
+    def uncatalogObjectList(self, message_list):
+      """Uncatalog a list of objects"""
+      for obj, args, kw in message_list:
+        self.unindexObject(*args, **kw)
+      del message_list[:]
+
     security.declarePrivate('unindexObject')
     def unindexObject(self, object=None, path=None, uid=None,sql_catalog_id=None):
         """
diff --git a/product/ERP5Type/CopySupport.py b/product/ERP5Type/CopySupport.py
index f3404f6daac7d664317f2028dea9448de8869db2..b8f6058aa1448bee424c33a171010ddbd2675868 100644
--- a/product/ERP5Type/CopySupport.py
+++ b/product/ERP5Type/CopySupport.py
@@ -375,14 +375,12 @@ class CopyContainer:
           catalog.beforeUnindexObject(None,path=path,uid=uid)
           # Then start activity in order to remove lines in catalog,
           # sql wich generate locks
-          if path is None:
-            path = self.getPath()
           # - serialization_tag is used in order to prevent unindexation to 
           # happen before/in parallel with reindexations of the same object.
           catalog.activate(activity='SQLQueue',
                            tag='%s' % uid,
-                           serialization_tag=self.getRootDocumentPath()).unindexObject(None, 
-                                           path=path,uid=uid)
+                           group_method_id='portal_catalog/uncatalogObjectList',
+                           serialization_tag=self.getRootDocumentPath()).unindexObject(uid=uid)
 
   security.declareProtected(Permissions.ModifyPortalContent, 'moveObject')
   def moveObject(self, idxs=None):
diff --git a/product/ERP5Type/tests/testCopySupport.py b/product/ERP5Type/tests/testCopySupport.py
index 3d1ba1d63d734179d8fd98349b661cce9ab92f64..3b5e57b060c1cc3bd58a0f7ebe4a982cdba4eba6 100644
--- a/product/ERP5Type/tests/testCopySupport.py
+++ b/product/ERP5Type/tests/testCopySupport.py
@@ -31,6 +31,7 @@ import transaction
 
 from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
 #from AccessControl.SecurityManagement import newSecurityManager
+from Products.CMFActivity.ActivityTool import ActivityTool
 from Products.CMFActivity.Errors import ActivityPendingError
 
 class TestCopySupport(ERP5TypeTestCase):
@@ -100,13 +101,49 @@ class TestCopySupport(ERP5TypeTestCase):
     # Currently, the test passes only because ActivityTool.distribute always
     # iterates on queues in the same order: SQLQueue before SQLDict.
     # If Python returned dictionary values in a different order,
-    # reindex activities fail with the following error:
+    # reindex activities would fail with the following error:
     #   uid of <Products.ERP5Catalog.CatalogTool.IndexableObjectWrapper for
     #   /erp5/person_module/1/old_address> is 599L and is already assigned
     #   to deleted in catalog !!! This can be fatal.
     # This test would also fail if SQLDict was used for 'unindexObject'.
     self.tic()
 
+  def test_03_unindexObjectGrouping(self):
+    person = self.portal.person_module.newContent(portal_type='Person',
+                                                  address_city='Lille',
+                                                  email_text='foo@bar.com')
+    transaction.commit()
+    self.tic()
+    search_catalog = self.portal.portal_catalog.unrestrictedSearchResults
+    uid_list = [person.getUid(),
+                person.default_address.getUid(),
+                person.default_email.getUid()]
+    uid_list.sort()
+    self.assertEqual(len(search_catalog(uid=uid_list)), len(uid_list))
+    self.portal.person_module._delObject(person.getId())
+    del person
+    transaction.commit()
+    self.assertEqual(len(search_catalog(uid=uid_list)), len(uid_list))
+    activity_tool = self.portal.portal_activities
+    self.assertEqual(len(activity_tool.getMessageList()), len(uid_list))
+
+    ActivityTool_invokeGroup = ActivityTool.invokeGroup
+    invokeGroup_list = []
+    def invokeGroup(self, method_id, message_list, activity):
+      invokeGroup_list.extend((method_id,
+                               sorted(m.kw.get('uid') for m in message_list),
+                               activity))
+      return ActivityTool_invokeGroup(self, method_id, message_list, activity)
+    try:
+      ActivityTool.invokeGroup = invokeGroup
+      self.tic()
+    finally:
+      ActivityTool.invokeGroup = ActivityTool_invokeGroup
+    self.assertEqual(invokeGroup_list,
+      ['portal_catalog/uncatalogObjectList', uid_list, 'SQLQueue'])
+    self.assertEqual(len(search_catalog(uid=uid_list)), 0)
+
+
 def test_suite():
   suite = unittest.TestSuite()
   suite.addTest(unittest.makeSuite(TestCopySupport))