diff --git a/product/ERP5/Document/Delivery.py b/product/ERP5/Document/Delivery.py
index c4966d4778af02eaf9e86a0093a786cb562d33b5..4d5f68751f90107da0dc01ab5cd62cc9085cae8e 100644
--- a/product/ERP5/Document/Delivery.py
+++ b/product/ERP5/Document/Delivery.py
@@ -284,7 +284,7 @@ class Delivery(XMLObject, ImmobilisationDelivery):
       return 1
     
     security.declareProtected(Permissions.View, 'isDivergent')
-    def isDivergent(self,fast=0,**kw):
+    def isDivergent(self, fast=0, **kw):
       """
         Returns 1 if the target is not met according to the current information
         After and edit, the isOutOfTarget will be checked. If it is 1,
@@ -304,6 +304,16 @@ class Delivery(XMLObject, ImmobilisationDelivery):
           return 1
       return 0
 
+    security.declareProtected(Permissions.View, 'getDivergenceList')
+    def getDivergenceList(self):
+      """
+      Return a list of messages that contains the divergences
+      """
+      divergence_list = []
+      for movement in self.getMovementList():
+         divergence_list.extend(movement.getDivergenceList())
+      return divergence_list
+
     def updateCausalityState(self,**kw):
       """
       This is often called as an activity, it will check if the
@@ -554,8 +564,8 @@ class Delivery(XMLObject, ImmobilisationDelivery):
     # Applied Rule stuff
     def updateAppliedRule(self, rule_id,force=0,**kw):
       """
-        Create a new Applied Rule is none is related, or call expand
-        on the existing one.
+      Create a new Applied Rule is none is related, or call expand
+      on the existing one.
       """
       if (rule_id is not None) and\
          (self.getSimulationState() not in \
diff --git a/product/ERP5/Document/DeliveryLine.py b/product/ERP5/Document/DeliveryLine.py
index f9bb89fa3f62f33c8fc070de35f4760fb0ee142f..d9db3ad5f69b463fe06490f9130f32f3d2af596d 100644
--- a/product/ERP5/Document/DeliveryLine.py
+++ b/product/ERP5/Document/DeliveryLine.py
@@ -69,6 +69,7 @@ class DeliveryLine(Movement, XMLObject, XMLMatrix, Variated,
                       , PropertySheet.Price
                       , PropertySheet.VariationRange
                       , PropertySheet.ItemAggregation
+                      , PropertySheet.SortIndex
                       )
 
     # Multiple inheritance definition
@@ -217,13 +218,25 @@ class DeliveryLine(Movement, XMLObject, XMLMatrix, Variated,
 
         emit targetUnreachable !
       """
+      if self.getDivergenceList() == []:
+        return 0
+      else:
+        return 1
+  
+    security.declareProtected(Permissions.View, 'getDivergentList')
+    def getDivergenceList(self):
+      """
+      Return a list of messages that contains the divergences
+      """
+      divergence_list = []
       if self.hasCellContent():
-        for cell in self.contentValues(filter={'portal_type': self.getPortalDeliveryMovementTypeList()}):
-          if cell.isDivergent():
-            return 1
+        for cell in self.contentValues(filter={
+                'portal_type': self.getPortalDeliveryMovementTypeList()}):
+          divergence_list.extend(cell.getDivergenceList())
+        return divergence_list
       else:
-         return Movement.isDivergent(self)
-
+        return Movement.getDivergenceList(self)
+     
     def applyToDeliveryLineRelatedMovement(self, portal_type='Simulation Movement', method_id = 'expand'):
       # Find related in simulation
       for my_simulation_movement in self.getDeliveryRelatedValueList(
diff --git a/product/ERP5/Document/DeliveryRule.py b/product/ERP5/Document/DeliveryRule.py
index e50147d625d3f2962584cb7b5d601a2e1ecfbd0f..ab1ffe855bb1edd85cf987e4adb3261763fcdfec 100644
--- a/product/ERP5/Document/DeliveryRule.py
+++ b/product/ERP5/Document/DeliveryRule.py
@@ -89,9 +89,8 @@ class DeliveryRule(Rule):
       delivery_movement_list = delivery.getMovementList()
       # Check existing movements
       for movement in applied_rule.contentValues(portal_type=movement_type):
-        if movement.getLastExpandSimulationState() not in \
-            delivery.getPortalCurrentInventoryStateList():
-
+        if movement.getLastExpandSimulationState() in \
+            delivery.getPortalDraftOrderStateList():
           movement_delivery = movement.getDeliveryValue()
           if not self._isTreeDelivered([movement], ignore_first=1) and \
               movement_delivery not in delivery_movement_list:
@@ -184,7 +183,7 @@ class DeliveryRule(Rule):
 
   # Solvers
   security.declareProtected(Permissions.AccessContentsInformation, 'isStable')
-  def isStable(self, movement):
+  def isStable(self, applied_rule):
     """
     Checks that the applied_rule is stable
     """
diff --git a/product/ERP5/Document/InvoiceTransactionRule.py b/product/ERP5/Document/InvoiceTransactionRule.py
index 75e2f6b44a961f19cb81fa3a6a3d5a43243d90eb..1c2f8337a7a3ac5116e57ee35ed3c1eafc9a0c74 100644
--- a/product/ERP5/Document/InvoiceTransactionRule.py
+++ b/product/ERP5/Document/InvoiceTransactionRule.py
@@ -185,7 +185,6 @@ class InvoiceTransactionRule(Rule, PredicateMatrix):
 
     # Pass to base class
     Rule.expand(self, applied_rule, force=force, **kw)
-
   
   # Matrix related
   security.declareProtected( Permissions.ModifyPortalContent,
@@ -221,24 +220,24 @@ class InvoiceTransactionRule(Rule, PredicateMatrix):
       and blocks expansion process
     """
 
-  # Solvers
-  security.declareProtected(Permissions.View, 'isDivergent')
-  def isDivergent(self, applied_rule):
-    """
-      Returns 1 if divergent rule
-    """
-
-  security.declareProtected(Permissions.View, 'getDivergenceList')
-  def getDivergenceList(self, applied_rule):
-    """
-      Returns a list Divergence descriptors
-    """
-
-  security.declareProtected(Permissions.View, 'getSolverList')
-  def getSolverList(self, applied_rule):
-    """
-      Returns a list Divergence solvers
-    """
+#   # Solvers
+#   security.declareProtected(Permissions.View, 'isDivergent')
+#   def isDivergent(self, applied_rule):
+#     """
+#       Returns 1 if divergent rule
+#     """
+# 
+#   security.declareProtected(Permissions.View, 'getDivergenceList')
+#   def getDivergenceList(self, applied_rule):
+#     """
+#       Returns a list Divergence descriptors
+#     """
+# 
+#   security.declareProtected(Permissions.View, 'getSolverList')
+#   def getSolverList(self, applied_rule):
+#     """
+#       Returns a list Divergence solvers
+#     """
 
   # Deliverability / orderability
   def isOrderable(self, m):
diff --git a/product/ERP5/Document/Movement.py b/product/ERP5/Document/Movement.py
index ba05ca7bd52fabac50e183232ac44561d4ed96c1..1e98a83957d436bf3b65116e8b80dce84cf97aa1 100644
--- a/product/ERP5/Document/Movement.py
+++ b/product/ERP5/Document/Movement.py
@@ -38,7 +38,7 @@ from Products.ERP5Type.XMLObject import XMLObject
 
 from Products.ERP5.Document.Amount import Amount
 
-from zLOG import LOG, WARNING
+from zLOG import LOG, WARNING, DEBUG
 
 class Movement(XMLObject, Amount):
   """
@@ -423,6 +423,16 @@ class Movement(XMLObject, Amount):
         return 1
     return 0
 
+  def getDivergenceList(self):
+    """
+    Return a list of messages that contains the divergences 
+    """
+    divergence_list = [] 
+    for simulation_movement in self.getDeliveryRelatedValueList():
+      divergence_list.extend(simulation_movement.getDivergenceList())
+
+    return divergence_list
+
   security.declareProtected(Permissions.AccessContentsInformation,
                             'isFrozen')
   def isFrozen(self):
@@ -435,7 +445,7 @@ class Movement(XMLObject, Amount):
     # XXX Hardcoded
     # Maybe, we should use getPortalCurrentInventoryStateList
     # and another portal method for cancelled (and deleted)
-    #LOG("Movement, isFrozen", WARNING, "Hardcoded state list")
+#     LOG("Movement, isFrozen", DEBUG, "Hardcoded state list")
     if self.getSimulationState() in ('stopped', 'delivered', 'cancelled'):
       return 1
     if self._baseIsFrozen() == 0:
diff --git a/product/ERP5/Document/Rule.py b/product/ERP5/Document/Rule.py
index 00d5603835a1c5816b332f7ada2406d07cafa1bd..c98143923ae99385f29271f426bb46966967176f 100644
--- a/product/ERP5/Document/Rule.py
+++ b/product/ERP5/Document/Rule.py
@@ -175,53 +175,36 @@ class Rule(XMLObject, Predicate):
   # Solvers
   security.declareProtected( Permissions.AccessContentsInformation,
                             'isDivergent')
-  def isDivergent(self, movement, ignore_list=[]):
+  def isDivergent(self, sim_mvt, ignore_list=[]):
     """
     Returns true if the Simulation Movement is divergent comparing to
     the delivery value
     """
-    delivery = movement.getDeliveryValue()
+    delivery = sim_mvt.getDeliveryValue()
     if delivery is None:
       return 0
-    
-    default_match_list = (
-      'source_section', 'destination_section', 'source',
-      'destination', 'resource', 'variation_category_list', 
-      'aggregate_list', 'start_date', 'stop_date')
-    match_list = [x for x in default_match_list if x not in ignore_list]
-    for prop in match_list:
-      if movement.getProperty(prop) != delivery.getProperty(prop):
-        return 1
-    
-    d_quantity = delivery.getQuantity()
-    quantity = movement.getCorrectedQuantity()
-    d_error = movement.getDeliveryError()
-    if quantity is None:
-      if d_quantity is None:
-        return 0
-      return 1
-    if d_quantity is None:
-      d_quantity = 0
-    if d_error is None:
-      d_error = 0
-    delivery_ratio = movement.getDeliveryRatio()
-    # if the delivery_ratio is None, make sure that we are
-    # divergent even if the delivery quantity is 0
-    if delivery_ratio is not None:
-      d_quantity *= delivery_ratio
-      if delivery_ratio == 0 and quantity > 0:
-        return 1
-    if d_quantity != quantity + d_error:
+      
+    if self.getDivergenceList(sim_mvt) == []:
+      return 0
+    else:
       return 1
-    return 0
-
-#    security.declareProtected(Permissions.View, 'getDivergenceList')
-#    def getDivergenceList(self, applied_rule):
-#      """
-#        Returns a list Divergence descriptors
-#      """
-#
+    
+  security.declareProtected(Permissions.View, 'getDivergenceList')
+  def getDivergenceList(self, sim_mvt):
+    """
+    Return a list of messages that contains the divergences.
+    """
+    result_list = []
+    for divergence_tester in self.contentValues(
+               portal_type=self.getPortalDivergenceTesterTypeList()):
+      result = divergence_tester.explain(sim_mvt)
+      result_list.extend(result)
+    return result_list
+
+  # XXX getSolverList is not part of the API and should be removed.
+  # Use getDivergenceList instead.
 #    security.declareProtected(Permissions.View, 'getSolverList')
+
 #    def getSolverList(self, applied_rule):
 #      """
 #        Returns a list Divergence solvers
@@ -330,8 +313,8 @@ class Rule(XMLObject, Predicate):
           p_matched_list.append(movement)
 
       # XXX hardcoded ...
-      LOG("Rule, _getCompensatedMovementList", WARNING, 
-          "Hardcoded properties check")
+#       LOG("Rule, _getCompensatedMovementList", WARNING, 
+#           "Hardcoded properties check")
       # Movements exist, we'll try to make them match the prevision
       if p_matched_list != []:
         # Check the quantity