diff --git a/product/ERP5Type/XMLMatrix.py b/product/ERP5Type/XMLMatrix.py
index cc09dcbe7b72017560dd530664db7fe3f7abd0a7..8d7c2c42be8254ddbd2060e106742f4a9ab018ef 100755
--- a/product/ERP5Type/XMLMatrix.py
+++ b/product/ERP5Type/XMLMatrix.py
@@ -320,6 +320,113 @@ class XMLMatrix(Folder):
       self._setCellRange(*kw, **kwd)
       self.reindexObject()
 
+    security.declareProtected( Permissions.ModifyPortalContent, '_renameCellRange' )
+    def _renameCellRange(self, *kw, **kwd):
+      """
+          Rename a range for a matrix, this method can
+          also handle a changement of the size of a matrix
+      """
+      base_id = kwd.get('base_id', 'cell')
+
+      movement = {}  # We will put in this dictionnary the previous and new
+                     # id of a given cell
+      new_index = PersistentMapping() # new_index defines the relation between keys
+                                      # and ids of cells
+
+      if not hasattr(self, 'index'):
+        self.index = PersistentMapping()
+
+      # Return if previous range is the same
+      current_range = self.getCellRange(base_id=base_id) or []
+      if current_range == list(kw): # kw is a tuple
+        LOG('XMLMatrix',0,'return form _setCellRange - no need to change range')
+        return
+
+      # We must make sure the base_id exists
+      # in the event of a matrix creation for example
+      if not self.index.has_key(base_id):
+        # Create an index for this base_id
+        self.index[base_id] = PersistentMapping()
+
+      # First, delete all cells which are out of range.
+      size_list = []
+      for place_list in kw:
+        size_list.append(len(place_list))
+      if len(kw) < len(current_range):
+        size_list.extend([1] * (len(current_range) - len(kw)))
+      removed_cell_id_list = []
+      cell_id_list = []
+      for cell_id in self.getCellIdList(base_id = base_id):
+        if self.get(cell_id) is not None:
+          cell_id_list.append(cell_id)
+      for cell_id in cell_id_list:
+        index_list = []
+        for index in cell_id[len(base_id)+1:].split('_'):
+          index_list.append(int(index))
+        for i in range(len(index_list)):
+          if index_list[i] >= size_list[i]:
+            removed_cell_id_list.append(cell_id)
+            break
+      for cell_id in removed_cell_id_list:
+        self._delObject(cell_id)
+        cell_id_list.remove(cell_id)
+
+      # Secondly, rename coordinates. This does not change cell ids.
+      for i in range(max(len(kw), len(current_range))):
+        if i >= len(kw):
+          del self.index[base_id][i]
+        else:
+          if i >= len(current_range):
+            self.index[base_id][i] = PersistentMapping()
+          for place in self.index[base_id][i].keys():
+            if place not in kw[i]:
+              del self.index[base_id][i][place]
+          j = 0
+          for place in kw[i]:
+            self.index[base_id][i][place] = j
+            j += 1
+
+      # Lastly, rename ids and catalog/uncatalog everything.
+      if len(current_range) < len(kw):
+        # Need to move, say, base_1_2 -> base_1_2_0
+        appended_id = '_0' * (len(kw) - len(current_range))
+        for old_id in cell_id_list:
+          cell = self.get(old_id)
+          if cell is not None:
+            new_id = old_id + appended_id
+            cell.isIndexable = 0
+            cell.id = new_id
+            self._setObject(new_id, cell)
+            self._delObject(old_id)
+            cell.isIndexable = 1
+            cell.reindexObject()
+            cell.unindexObject(path='%s/%s' % (self.getUrl(), old_id))
+      elif len(current_range) > len(kw):
+        # Need to move, say, base_1_2_0 -> base_1_2
+        removed_id_len = 2 * (len(current_range) - len(kw))
+        for old_id in cell_id_list:
+          cell = self.get(old_id)
+          if cell is not None:
+            new_id = old_id[:-removed_id_len]
+            cell.isIndexable = 0
+            cell.id = new_id
+            self._setObject(new_id, cell)
+            self._delObject(old_id)
+            cell.isIndexable = 1
+            cell.reindexObject()
+            cell.unindexObject(path='%s/%s' % (self.getUrl(), old_id))
+
+    security.declareProtected( Permissions.ModifyPortalContent, 'renameCellRange' )
+    def renameCellRange(self, *kw, **kwd):
+      """
+          Rename the indices provided
+          one list per index (kw)
+
+          Any number of list can be provided
+      """
+      self._renameCellRange(*kw, **kwd)
+      self.reindexObject()
+
     security.declareProtected( Permissions.AccessContentsInformation, 'getCellRange' )
     def getCellRange(self, base_id='cell'):
       """
@@ -390,6 +497,8 @@ class XMLMatrix(Folder):
       for i in range(0, len(self.index[base_id].keys())):
         t = self.index[base_id][i]
         id_tuple += [t.keys()]
+      if len(id_tuple) == 0:
+        return ()
       return cartesianProduct(id_tuple)
 
     security.declareProtected( Permissions.AccessContentsInformation, 'getCellKeys' )