diff --git a/bt5/erp5_accounting/SkinTemplateItem/portal_skins/erp5_accounting/AccountingTransaction_getAccountingTransactionLineList.py b/bt5/erp5_accounting/SkinTemplateItem/portal_skins/erp5_accounting/AccountingTransaction_getAccountingTransactionLineList.py
index 4a1055014fcb8a0a906bb3659c61450c8ae9836e..1bc4259db3f9579e7116fe1218548cb7f086471f 100644
--- a/bt5/erp5_accounting/SkinTemplateItem/portal_skins/erp5_accounting/AccountingTransaction_getAccountingTransactionLineList.py
+++ b/bt5/erp5_accounting/SkinTemplateItem/portal_skins/erp5_accounting/AccountingTransaction_getAccountingTransactionLineList.py
@@ -1,12 +1,15 @@
 if not portal_type:
   portal_type = context.getPortalObject().getPortalAccountingMovementTypeList()
 
-sort_dict = { 'income': 0,
-              'expense': -2,
-              'receivable': -2,
-              'payable': 0,
-              'collected_vat': -1,
-              'refundable_vat': -1 }
+sort_dict = {
+  'bank': -3,
+  'income': 0,
+  'expense': -2,
+  'receivable': -2,
+  'payable': 0,
+  'collected_vat': -1,
+  'refundable_vat': -1,
+}
 
 def getAccountingTransactionLineSortKey(line):
   return sort_dict.get(line.getId(), (line.getIntIndex() or line.getIntId() or 0))
diff --git a/bt5/erp5_calendar/SkinTemplateItem/portal_skins/erp5_calendar/PersonModule_getLeaveRequestReportLineList.py b/bt5/erp5_calendar/SkinTemplateItem/portal_skins/erp5_calendar/PersonModule_getLeaveRequestReportLineList.py
index 7503fe13d7a3406a653891c13d934dcfb4a2592e..0283a96b21d009c914d8ca3e47f9edae0f23fca4 100644
--- a/bt5/erp5_calendar/SkinTemplateItem/portal_skins/erp5_calendar/PersonModule_getLeaveRequestReportLineList.py
+++ b/bt5/erp5_calendar/SkinTemplateItem/portal_skins/erp5_calendar/PersonModule_getLeaveRequestReportLineList.py
@@ -68,10 +68,7 @@ for person in person_value_list:
         total=person_total,
         **result_dict))
 
-result_list.sort(lambda a,b: cmp(
-        a.person_career_reference or a.person_title,
-        b.person_career_reference or b.person_title))
-
+result_list.sort(key=lambda r: (r.person_career_reference or '', r.person_title or ''))
 request.set('total_time', total_time)
 request.set('total_time_per_resource', total_time_per_resource)
 
diff --git a/bt5/erp5_configurator/DocumentTemplateItem/portal_components/document.erp5.BusinessConfiguration.py b/bt5/erp5_configurator/DocumentTemplateItem/portal_components/document.erp5.BusinessConfiguration.py
index 1a051004f6e8c0d0e0567670e0986d8beac9d7a4..764a8ca8b89055252da2e44f243643ac3d802a85 100644
--- a/bt5/erp5_configurator/DocumentTemplateItem/portal_components/document.erp5.BusinessConfiguration.py
+++ b/bt5/erp5_configurator/DocumentTemplateItem/portal_components/document.erp5.BusinessConfiguration.py
@@ -553,12 +553,12 @@ class BusinessConfiguration(Item):
                                "immediateReindexObject"])
     # build
     configuration_save_list = self.contentValues(portal_type='Configuration Save')
-    configuration_save_list.sort(lambda x, y: cmp(x.getIntIndex(x.getIntId()),
-                                                  y.getIntIndex(y.getIntId())))
+    configuration_save_list.sort(key=lambda x: (x.getIntIndex(x.getIntId()) or 0))
     for configuration_save in configuration_save_list:
       # XXX: check which items are configure-able
       configuration_item_list = configuration_save.contentValues()
-      configuration_item_list.sort(lambda x, y: cmp(x.getIntId(), y.getIntId()))
+      configuration_item_list.sort(key=lambda x: (x.getIntId() or 0))
+
       for configurator_item in configuration_item_list:
         configurator_item.activate(**kw).fixConsistency(
             filter={"constraint_type":"configuration"})
diff --git a/bt5/erp5_ooo_import/SkinTemplateItem/portal_skins/erp5_ooo_import/Base_getActiveProcessFromSelectionList.py b/bt5/erp5_ooo_import/SkinTemplateItem/portal_skins/erp5_ooo_import/Base_getActiveProcessFromSelectionList.py
index 9bcbd191d5dc3f0796560263bdcd268bf2718a66..ed4a93d524df48135c4ab6168c5a15c9044429b9 100644
--- a/bt5/erp5_ooo_import/SkinTemplateItem/portal_skins/erp5_ooo_import/Base_getActiveProcessFromSelectionList.py
+++ b/bt5/erp5_ooo_import/SkinTemplateItem/portal_skins/erp5_ooo_import/Base_getActiveProcessFromSelectionList.py
@@ -16,6 +16,4 @@ for (x,y) in selection_param_list:
 
 active_process_list = [(y,x) for (x,y) in active_process_dict.items()]
 
-active_process_list.sort(lambda x, y: cmp(x[1],y[1]), reverse=True )
-
-return active_process_list
+return sorted(active_process_list, key=lambda item: item[1], reverse=True)
diff --git a/bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/AccountingTransactionModule_getNetSalaryReportSectionLineList.py b/bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/AccountingTransactionModule_getNetSalaryReportSectionLineList.py
index ba1ebf0e03e26baad3467033db434ff75a516fef..3d2624d3e5cc73d24edc2c480a1a701c09abd9d0 100644
--- a/bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/AccountingTransactionModule_getNetSalaryReportSectionLineList.py
+++ b/bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/AccountingTransactionModule_getNetSalaryReportSectionLineList.py
@@ -58,13 +58,7 @@ for inventory in portal.portal_simulation.getInventoryList(
 
 request.set('total_price', total_price)
 
-def sort_method(a, b):
-  employee_career_reference_diff = cmp(a.employee_career_reference,
-                                       b.employee_career_reference)
-  if employee_career_reference_diff:
-    return employee_career_reference_diff
-  return cmp(a.employee_title, b.employee_title)
-
-object_list.sort(sort_method)
-
-return object_list
+return sorted(
+  object_list,
+  key=lambda o: (o.employee_career_reference or '', o.employee_title)
+)
diff --git a/bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/AccountingTransactionModule_getPaySheetLineReportSectionLineList.py b/bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/AccountingTransactionModule_getPaySheetLineReportSectionLineList.py
index 2c2093d89d72cde47be583888cab5473af0fbf31..65644776fbfd10906ca47e8fedcc8109cfab75b6 100644
--- a/bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/AccountingTransactionModule_getPaySheetLineReportSectionLineList.py
+++ b/bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/AccountingTransactionModule_getPaySheetLineReportSectionLineList.py
@@ -38,10 +38,10 @@ inventory_param_dict = {
 }
 
 employee_param_dict = inventory_param_dict.copy()
-employee_param_dict['contribution_share_uid'] = context.portal_categories.contribution_share.employee.getUid()
+employee_param_dict['contribution_share_uid'] = portal.portal_categories.contribution_share.employee.getUid()
 
 employer_param_dict = inventory_param_dict.copy()
-employer_param_dict['contribution_share_uid'] = context.portal_categories.contribution_share.employer.getUid()
+employer_param_dict['contribution_share_uid'] = portal.portal_categories.contribution_share.employer.getUid()
 
 if request.get('mirror_section'):
   mirror_section = request['mirror_section']
@@ -112,21 +112,14 @@ request.set('base_total', base_total)
 request.set('total', total)
 
 
-sorted_inventory_list = []
-sorted_inventory_list = inventory_list.values()
-
 # sort by salary range, and add intermediate sums if needed
-def sort_method(a, b):
-  salary_range_diff = cmp(a.salary_range, b.salary_range)
-  if salary_range_diff:
-    return salary_range_diff
-  employee_career_reference_diff = cmp(a.employee_career_reference,
-                                       b.employee_career_reference)
-  if employee_career_reference_diff:
-    return employee_career_reference_diff
-  return cmp(a.employee_title, b.employee_title)
-
-sorted_inventory_list.sort(sort_method)
+sorted_inventory_list = sorted(
+  inventory_list.values(),
+  key=lambda i: (
+    i.salary_range or '',
+    i.employee_career_reference or '',
+    i.employee_title or '',
+  ))
 
 i = 0
 intermediate_base_total = 0
diff --git a/bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_getMovementList.py b/bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_getMovementList.py
index 22f02017281f997c342e11ffa2d6694bbab41057..63b5b439ccffd4951c96e661784f3041846fe963 100644
--- a/bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_getMovementList.py
+++ b/bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_getMovementList.py
@@ -120,38 +120,12 @@ for paysheet_line in paysheet_line_list:
   if 'no_slice' in object_dict:
     line_list.append(paysheet_line.asContext(**object_dict['no_slice']))
 
-
-
-# sort results
-def sortByTitleAscending(x, y):
-  return cmp(x.getTitle(), y.getTitle())
-
-def sortByTitleDescending(x, y):
-  return cmp(y.getTitle(), x.getTitle())
-
-def sortByIntIndexAscending(x, y):
-  return cmp(x.getIntIndex(), y.getIntIndex())
-
-def sortByIntIndexDescending(x, y):
-  return cmp(y.getIntIndex(), x.getIntIndex())
-
-sortByDefaultSortMethod = sortByIntIndexAscending
-
+reverse = False
+sort_key = lambda l: (l.getIntIndex() or 0)
 if 'sort_on' in kw:
   sort_on = kw['sort_on']
-  if sort_on[0][0] == 'title' and sort_on[0][1]=='ascending':
-    line_list.sort(sortByTitleAscending)
-  elif sort_on[0][0] == 'title' and sort_on[0][1]=='descending':
-    line_list.sort(sortByTitleDescending)
-  elif sort_on[0][0] == 'int_index' and sort_on[0][1]=='ascending':
-    line_list.sort(sortByIntIndexAscending)
-  elif sort_on[0][0] == 'int_index' and sort_on[0][1]=='descending':
-    line_list.sort(sortByIntIndexDescending)
-  else:
-    line_list.sort(sortByDefaultSortMethod)
-else:
-  line_list.sort(sortByDefaultSortMethod)
-
-
+  reverse = sort_on[0][1]=='descending'
+  if sort_on[0][0] == 'title':
+    sort_key = lambda l: (l.getTitle() or '')
 
-return line_list
+return sorted(line_list, key=sort_key, reverse=reverse)
diff --git a/bt5/erp5_project/SkinTemplateItem/portal_skins/erp5_project/Project_getSourceProjectRelatedTaskList.py b/bt5/erp5_project/SkinTemplateItem/portal_skins/erp5_project/Project_getSourceProjectRelatedTaskList.py
index 4c7696b78ae29d5e1e6f2516b481282bcf9f07d8..278c6f68cea573400234ec46df3ba97113f0a276 100644
--- a/bt5/erp5_project/SkinTemplateItem/portal_skins/erp5_project/Project_getSourceProjectRelatedTaskList.py
+++ b/bt5/erp5_project/SkinTemplateItem/portal_skins/erp5_project/Project_getSourceProjectRelatedTaskList.py
@@ -24,12 +24,6 @@ task_line_list = []
 for task in task_list:
   task_line_list.extend(task.contentValues(portal_type='Task Line'))
 
-def sortTaskLine(a, b):
-  result = cmp(a.getStartDate(), b.getStartDate())
-  if result == 0:
-    result = cmp(a.getTitle(), b.getTitle())
-  return result
-
-task_line_list.sort(sortTaskLine)
-
-return task_line_list
+return sorted(
+  task_line_list,
+  key=lambda tl: (tl.hasStartDate(), tl.getStartDate(), tl.getTitle()))
diff --git a/bt5/erp5_project/SkinTemplateItem/portal_skins/erp5_project/Project_getSourceProjectRelatedTaskReportList.py b/bt5/erp5_project/SkinTemplateItem/portal_skins/erp5_project/Project_getSourceProjectRelatedTaskReportList.py
index fdaf5ff3480ee5e5765751a1ff93344f50ea2fb0..524ffe03be23d1ae0a85bb2a92d3b35b1d2c6757 100644
--- a/bt5/erp5_project/SkinTemplateItem/portal_skins/erp5_project/Project_getSourceProjectRelatedTaskReportList.py
+++ b/bt5/erp5_project/SkinTemplateItem/portal_skins/erp5_project/Project_getSourceProjectRelatedTaskReportList.py
@@ -40,12 +40,6 @@ for task in task_list:
   task_line_list.extend(task.objectValues(portal_type=('Task Line', 'Task Report Line')))
 
 
-def sortTaskLine(a, b):
-  result = cmp(a.getStartDate(), b.getStartDate())
-  if result == 0:
-    result = cmp(a.getTitle(), b.getTitle())
-  return result
-
-task_line_list.sort(sortTaskLine)
-
-return task_line_list
+return sorted(
+  task_line_list,
+  key=lambda tl: (tl.getStartDate() is not None, tl.getStartDate(), tl.getTitle()))
diff --git a/bt5/erp5_trade/SkinTemplateItem/portal_skins/erp5_trade/OrderModule_getOrderStatList.py b/bt5/erp5_trade/SkinTemplateItem/portal_skins/erp5_trade/OrderModule_getOrderStatList.py
index 4ad5f0f12c5e198c35930228d93138799ea6c259..583efb9ae500c23af6cae4fb66c243c04ed4f425 100644
--- a/bt5/erp5_trade/SkinTemplateItem/portal_skins/erp5_trade/OrderModule_getOrderStatList.py
+++ b/bt5/erp5_trade/SkinTemplateItem/portal_skins/erp5_trade/OrderModule_getOrderStatList.py
@@ -57,8 +57,6 @@ if active_process_path:
 else:
   raise ValueError("No active process found to process report")
 
-def sortProduct(a, b):
-  return cmp(a['product'], b['product'])
 
 period_counter_dict = {}
 line_list = []
@@ -132,7 +130,7 @@ if len(client_dict):
 
           product_lines_list.append(obj)
       # sort product list
-      product_lines_list.sort(sortProduct)
+      product_lines_list.sort(key=lambda p: p['product'])
       extend(product_lines_list)
 else:
   # products
@@ -169,7 +167,8 @@ else:
         period_counter_dict['total amount'] = line_total_amount
       append(obj)
 
-    line_list.sort(sortProduct)
+    line_list.sort(key=lambda p: p['product'])
+
 
 obj = Object(uid="new_")
 obj["client"] = 'Total'
diff --git a/product/CMFCategory/Category.py b/product/CMFCategory/Category.py
index 5ea4ac556b0377db67560942c63e2fb86b3c8a67..a83ea2ee27e46a54db3b547a45c3201f74a3bc57 100644
--- a/product/CMFCategory/Category.py
+++ b/product/CMFCategory/Category.py
@@ -335,7 +335,11 @@ class Category(Folder):
         if not isinstance(local_sort_id, (tuple, list)):
           local_sort_id = (local_sort_id, )
         def sort_key(c):
-          return [c.getProperty(sort_id, 0) for sort_id in local_sort_id]
+          k = []
+          for sort_id in local_sort_id:
+            v = c.getProperty(sort_id)
+            k.extend([v is not None, v])
+          return k
         local_sort_key = sort_key
       if local_sort_method:
         warnings.warn(
@@ -894,7 +898,11 @@ class BaseCategory(Category):
         if not isinstance(local_sort_id, (tuple, list)):
           local_sort_id = (local_sort_id, )
         def sort_key(c):
-          return [c.getProperty(sort_id, 0) for sort_id in local_sort_id]
+          k = []
+          for sort_id in local_sort_id:
+            v = c.getProperty(sort_id)
+            k.extend([v is not None, v])
+          return k
         local_sort_key = sort_key
       if local_sort_method:
         warnings.warn(
diff --git a/product/CMFCategory/Renderer.py b/product/CMFCategory/Renderer.py
index f990de8f2af6404703fe6f6803e6fce1d6d1bbb4..b2a76117d2d84913c2aebe648a63a163d813c593 100644
--- a/product/CMFCategory/Renderer.py
+++ b/product/CMFCategory/Renderer.py
@@ -149,7 +149,10 @@ class Renderer(Filter):
     elif self.sort_key is not None:
       value_list.sort(key=self.sort_key)
     elif self.sort_id is not None:
-      value_list.sort(key=lambda x: x.getProperty(self.sort_id))
+      def sort_key(x):
+        k = x.getProperty(self.sort_id)
+        return (k is not None, k)
+      value_list.sort(key=sort_key)
 
     # If base=1 but base_category is None, it is necessary to guess the base category
     # by heuristic.
diff --git a/product/ERP5/bootstrap/erp5_core/ExtensionTemplateItem/portal_components/extension.erp5.FolderWorkflowActionUtils.py b/product/ERP5/bootstrap/erp5_core/ExtensionTemplateItem/portal_components/extension.erp5.FolderWorkflowActionUtils.py
index d0e9c56deb33f697be04d4b5b6489f27ccb9fbd3..fa3881551745821a7cae995ebcc9bc9fca1fd22e 100644
--- a/product/ERP5/bootstrap/erp5_core/ExtensionTemplateItem/portal_components/extension.erp5.FolderWorkflowActionUtils.py
+++ b/product/ERP5/bootstrap/erp5_core/ExtensionTemplateItem/portal_components/extension.erp5.FolderWorkflowActionUtils.py
@@ -148,14 +148,7 @@ def getDocumentGroupByWorkflowStateList(self, form_id='', **kw):
                 workflow_state=current_workflow_state,
                 ))
 
-  # Let us sort this list by translated title of workflow state and workflow
-  def compareState(a, b):
-    return cmp((a.workflow_title, a.translated_workflow_state_title),
-               (b.workflow_title, b.translated_workflow_state_title))
-  document_list.sort(compareState)
-
-  # Return result
-  return document_list
+  return sorted(document_list, key=lambda b: (b.workflow_title, b.translated_workflow_state_title))
 
 
 
diff --git a/product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/Category_getSortedCategoryChildValueList.py b/product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/Category_getSortedCategoryChildValueList.py
deleted file mode 100644
index e3f0a4e106963a0f7d23effc20db2d281de14e0e..0000000000000000000000000000000000000000
--- a/product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/Category_getSortedCategoryChildValueList.py
+++ /dev/null
@@ -1,8 +0,0 @@
-from erp5.component.module.Log import log
-# this script is no longer needed.
-log('Category_getSortedCategoryChildValueList', 'use getCategoryChildValueList method')
-
-value_list = [o for o in context.getCategoryChildValueList() if o.getRelativeUrl() != context.getRelativeUrl()]
-sort_id='int_index'
-value_list.sort(key=lambda x: x.getProperty(sort_id))
-return value_list
diff --git a/product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/Category_getSortedCategoryChildValueList.xml b/product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/Category_getSortedCategoryChildValueList.xml
deleted file mode 100644
index b9dc79ffc032de9001f7266d8944450b523c06d7..0000000000000000000000000000000000000000
--- a/product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/Category_getSortedCategoryChildValueList.xml
+++ /dev/null
@@ -1,62 +0,0 @@
-<?xml version="1.0"?>
-<ZopeData>
-  <record id="1" aka="AAAAAAAAAAE=">
-    <pickle>
-      <global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
-    </pickle>
-    <pickle>
-      <dictionary>
-        <item>
-            <key> <string>_bind_names</string> </key>
-            <value>
-              <object>
-                <klass>
-                  <global name="_reconstructor" module="copy_reg"/>
-                </klass>
-                <tuple>
-                  <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
-                  <global name="object" module="__builtin__"/>
-                  <none/>
-                </tuple>
-                <state>
-                  <dictionary>
-                    <item>
-                        <key> <string>_asgns</string> </key>
-                        <value>
-                          <dictionary>
-                            <item>
-                                <key> <string>name_container</string> </key>
-                                <value> <string>container</string> </value>
-                            </item>
-                            <item>
-                                <key> <string>name_context</string> </key>
-                                <value> <string>context</string> </value>
-                            </item>
-                            <item>
-                                <key> <string>name_m_self</string> </key>
-                                <value> <string>script</string> </value>
-                            </item>
-                            <item>
-                                <key> <string>name_subpath</string> </key>
-                                <value> <string>traverse_subpath</string> </value>
-                            </item>
-                          </dictionary>
-                        </value>
-                    </item>
-                  </dictionary>
-                </state>
-              </object>
-            </value>
-        </item>
-        <item>
-            <key> <string>_params</string> </key>
-            <value> <string>**kw</string> </value>
-        </item>
-        <item>
-            <key> <string>id</string> </key>
-            <value> <string>Category_getSortedCategoryChildValueList</string> </value>
-        </item>
-      </dictionary>
-    </pickle>
-  </record>
-</ZopeData>
diff --git a/product/ERP5/bootstrap/erp5_core/ToolComponentTemplateItem/portal_components/tool.erp5.DomainTool.py b/product/ERP5/bootstrap/erp5_core/ToolComponentTemplateItem/portal_components/tool.erp5.DomainTool.py
index 6280d5ee3fad4163f5944d1fab9eddc2267e24ec..c5fec5de31f4c1bf3d4d3d1c86b4e5aff8e0e153 100644
--- a/product/ERP5/bootstrap/erp5_core/ToolComponentTemplateItem/portal_components/tool.erp5.DomainTool.py
+++ b/product/ERP5/bootstrap/erp5_core/ToolComponentTemplateItem/portal_components/tool.erp5.DomainTool.py
@@ -27,6 +27,7 @@
 #
 ##############################################################################
 
+import functools
 from collections import defaultdict
 from AccessControl import ClassSecurityInfo
 from Products.ERP5Type.Globals import InitializeClass
@@ -243,7 +244,10 @@ class DomainTool(BaseTool):
       if sort_key_method is not None:
         result_list.sort(key=sort_key_method)
       elif sort_method is not None:
-        result_list.sort(cmp=sort_method)
+        if six.PY3:
+          result_list.sort(key=functools.cmp_to_key(sort_method))
+        else:
+          result_list.sort(cmp=sort_method)
     return result_list
 
   # XXX FIXME method should not be public