diff --git a/product/ERP5/Document/AcceptSolver.py b/product/ERP5/Document/AcceptSolver.py
index 9db36a26c9aba5bd7770a5fe6d06e68d38a50bb7..1be4bc4fe5d68bffeb49b766a73f31c47bdaebfa 100644
--- a/product/ERP5/Document/AcceptSolver.py
+++ b/product/ERP5/Document/AcceptSolver.py
@@ -64,31 +64,25 @@ class AcceptSolver(SolverMixin, ConfigurableMixin, XMLObject):
     original one recorded.
     """
     configuration_dict = self.getConfigurationPropertyDict()
-    portal_type = self.getPortalObject().portal_types.getTypeInfo(self)
-    solved_property_list = configuration_dict.get('tested_property_list',
-                                                  portal_type.getTestedPropertyList())
-    for movement in self.getDeliveryValueList():
-      simulation_movement_list = movement.getDeliveryRelatedValueList()
-      # if movement here is a delivery, we need to find simulation
-      # movements by its movements.
-      if len(simulation_movement_list) == 0:
-        simulation_movement_list = sum(
-          [x.getDeliveryRelatedValueList() \
-           for x in self.getDeliveryValue().getMovementList()], [])
-      for simulation_movement in simulation_movement_list:
-        value_dict = {}
-        for solved_property in solved_property_list:
-          new_value = movement.getProperty(solved_property)
-          # XXX hard coded
-          if solved_property == 'quantity':
-            new_quantity = new_value * simulation_movement.getDeliveryRatio()
-            value_dict.update({'quantity':new_quantity})
-          else:
-            value_dict.update({solved_property:new_value})
-        for property_id, value in value_dict.iteritems():
-          if not simulation_movement.isPropertyRecorded(property_id):
-            simulation_movement.recordProperty(property_id)
-          simulation_movement.setMappedProperty(property_id, value)
-        simulation_movement.expand()
+    solved_property_list = configuration_dict.get('tested_property_list', None)
+    if solved_property_list is None:
+      portal_type = self.getPortalObject().portal_types.getTypeInfo(self)
+      solved_property_list = portal_type.getTestedPropertyList()
+    for simulation_movement in self.getDeliveryValueList():
+      movement = simulation_movement.getDeliveryValue()
+      value_dict = {}
+      for solved_property in solved_property_list:
+        new_value = movement.getProperty(solved_property)
+        # XXX hard coded
+        if solved_property == 'quantity':
+          new_quantity = new_value * simulation_movement.getDeliveryRatio()
+          value_dict.update({'quantity':new_quantity})
+        else:
+          value_dict.update({solved_property:new_value})
+      for property_id, value in value_dict.iteritems():
+        if not simulation_movement.isPropertyRecorded(property_id):
+          simulation_movement.recordProperty(property_id)
+        simulation_movement.setMappedProperty(property_id, value)
+      simulation_movement.expand()
     # Finish solving
     self.succeed()
diff --git a/product/ERP5/Document/AdoptSolver.py b/product/ERP5/Document/AdoptSolver.py
index 0f551768aaba44fccdcfd37b6b7287151e204279..30adc6b1023800e415d5b7a4b256b5086e70fd91 100644
--- a/product/ERP5/Document/AdoptSolver.py
+++ b/product/ERP5/Document/AdoptSolver.py
@@ -68,14 +68,18 @@ class AdoptSolver(SolverMixin, ConfigurableMixin, XMLObject):
     portal_type = self.getPortalObject().portal_types.getTypeInfo(self)
     solved_property_list = configuration_dict.get('tested_property_list',
                                                   portal_type.getTestedPropertyList())
-    for movement in self.getDeliveryValueList():
+    delivery_dict = {}
+    for simulation_movement in self.getDeliveryValueList():
+      delivery_dict.setdefault(simulation_movement.getDeliveryValue(),
+                               []).append(simulation_movement)
+    for movement, simulation_movement_list in delivery_dict.iteritems():
       for solved_property in solved_property_list:
         # XXX hardcoded
         if solved_property == 'quantity':
           total_quantity = sum(
             [x.getQuantity() for x in movement.getDeliveryRelatedValueList()])
           movement.setQuantity(total_quantity)
-          for simulation_movement in movement.getDeliveryRelatedValueList():
+          for simulation_movement in simulation_movement_list:
             quantity = simulation_movement.getQuantity()
             delivery_ratio = quantity / total_quantity
             delivery_error = total_quantity * delivery_ratio - quantity
diff --git a/product/ERP5/Document/QuantitySplitSolver.py b/product/ERP5/Document/QuantitySplitSolver.py
index 2723579a4cf7cb6e4e754398df3fcee2199bd7b7..832be411fb2ce9e507e6519780f04cb5a93fe56c 100644
--- a/product/ERP5/Document/QuantitySplitSolver.py
+++ b/product/ERP5/Document/QuantitySplitSolver.py
@@ -65,11 +65,14 @@ class QuantitySplitSolver(SolverMixin, ConfigurableMixin, XMLObject):
   # ISolver Implementation
   def solve(self):
     """
-    """    
-    for delivery_line in self.getDeliveryValueList(): 
-      decision_quantity = delivery_line.getQuantity()
-      simulation_movement_list = delivery_line.getDeliveryRelatedValueList()
-      configuration_dict = self.getConfigurationPropertyDict()
+    """
+    configuration_dict = self.getConfigurationPropertyDict()
+    delivery_dict = {}
+    for simulation_movement in self.getDeliveryValueList():
+      delivery_dict.setdefault(simulation_movement.getDeliveryValue(),
+                               []).append(simulation_movement)
+    for movement, simulation_movement_list in delivery_dict.iteritems():
+      decision_quantity = movement.getQuantity()
       delivery_solver = self.portal_solvers.newDeliverySolver(
         configuration_dict['delivery_solver'], simulation_movement_list)
       # Update the quantity using delivery solver algorithm
diff --git a/product/ERP5/Document/SolverProcess.py b/product/ERP5/Document/SolverProcess.py
index 6ab870f1dc2d09d79bc51c91ddda585a9fc300b9..b51e2b3266c812e539f089d375b9c7723415eab1 100644
--- a/product/ERP5/Document/SolverProcess.py
+++ b/product/ERP5/Document/SolverProcess.py
@@ -83,7 +83,7 @@ class SolverProcess(XMLObject, ActiveProcess):
     movement_dict = {}
     message_list = []
 
-    # First create a mapping between delivery movements and solvers
+    # First create a mapping between simulation movements and solvers
     #   in order to know for each movements which solvers are needed
     #   and which parameters with
     #
@@ -230,7 +230,7 @@ class SolverProcess(XMLObject, ActiveProcess):
           application_list.sort()
           solver_decision_key = (divergence_tester.getRelativeUrl(), tuple(application_list))
           movement_dict = solver_decision_dict.setdefault(solver_decision_key, {})
-          movement_dict[movement] = None
+          movement_dict[simulation_movement] = None
 
     # Now build the solver decision instances based on the previous
     # grouping
@@ -259,12 +259,11 @@ class SolverProcess(XMLObject, ActiveProcess):
         # Process, but ideally, the relation should be created when a
         # Target Solver processes, not when a Solver Decision is
         # created.
-        # for movement in movement_dict.keys():
-        #   for simulation_movement in movement.getDeliveryRelatedValueList():
-        #     solver_list = simulation_movement.getSolverValueList()
-        #     if self not in solver_list:
-        #       simulation_movement.setSolverValueList(
-        #         solver_list + [self])
+        # for simulation_movement in movement_dict.keys():
+        #   solver_list = simulation_movement.getSolverValueList()
+        #   if self not in solver_list:
+        #     simulation_movement.setSolverValueList(
+        #       solver_list + [self])
     # XXX what should we do for non-matched existing solver decisions?
     # do we need to cancel them by using an appropriate workflow?
 
diff --git a/product/ERP5/Document/TradeModelSolver.py b/product/ERP5/Document/TradeModelSolver.py
index 9681465d3296d1e3a234e0e432c32a550044bdb2..d8dfd40744e6016e0e70018f7a7aebc4f5174d2e 100644
--- a/product/ERP5/Document/TradeModelSolver.py
+++ b/product/ERP5/Document/TradeModelSolver.py
@@ -64,15 +64,18 @@ class TradeModelSolver(AcceptSolver):
     portal_type = self.getPortalObject().portal_types.getTypeInfo(self)
     solved_property_list = configuration_dict.get('tested_property_list',
                                                   portal_type.getTestedPropertyList())
+    delivery_dict = {}
+    for simulation_movement in self.getDeliveryValueList():
+      delivery_dict.setdefault(simulation_movement.getDeliveryValue(),
+                               []).append(simulation_movement)
 
     # Here, items of delivery_list should be movements, not deliveries.
-    solved_movement_list = self.getDeliveryValueList()
-    delivery_list = []
-    for solved_movement in solved_movement_list:
-      delivery = solved_movement.getDeliveryValue()
-      if delivery not in delivery_list:
-        delivery_list.append(delivery)
-    all_movement_list = sum([x.getMovementList() for x in delivery_list], [])
+    delivery_set = set()
+    solved_movement_list = delivery_dict.iterkeys()
+    for movement in solved_movement_list:
+      delivery = movement.getRootDeliveryValue()
+      delivery_set.add(delivery)
+    all_movement_list = sum([x.getMovementList() for x in delivery_set], [])
 
     # First, separate movements into invoice lines and trade model
     # related lines.
@@ -88,8 +91,8 @@ class TradeModelSolver(AcceptSolver):
 
     # Second, apply changes on invoice lines to simulation movements,
     # then expand.
-    for movement in solved_movement_list:
-      for simulation_movement in movement.getDeliveryRelatedValueList():
+    for movement, simulation_movement_list in delivery_dict.iteritems():
+      for simulation_movement in simulation_movement_list:
         value_dict = {}
         for solved_property in solved_property_list:
           new_value = movement.getProperty(solved_property)
diff --git a/product/ERP5/Document/UnifySolver.py b/product/ERP5/Document/UnifySolver.py
index 7d9687b06c0dbcdebb4fecc7a5829f9dbdbc4e12..3b1ed941d76333b731104668d4583e5127c0459a 100644
--- a/product/ERP5/Document/UnifySolver.py
+++ b/product/ERP5/Document/UnifySolver.py
@@ -67,17 +67,14 @@ class UnifySolver(AcceptSolver):
                                                   portal_type.getTestedPropertyList())
     # XXX it does not support multiple tested properties.
     solved_property = solved_property_list[0]
-    for movement in self.getDeliveryValueList():
+    delivery_dict = {}
+    for simulation_movement in self.getDeliveryValueList():
+      delivery_dict.setdefault(simulation_movement.getDeliveryValue(),
+                               []).append(simulation_movement)
+    for movement, simulation_movement_list in delivery_dict.iteritems():
       configuration_dict = self.getConfigurationPropertyDict()
       new_value = configuration_dict.get('value')
       movement.setProperty(solved_property, new_value)
-      simulation_movement_list = movement.getDeliveryRelatedValueList()
-      # if movement here is a delivery, we need to find simulation
-      # movements by its movements.
-      if len(simulation_movement_list) == 0:
-        simulation_movement_list = sum(
-          [x.getDeliveryRelatedValueList() \
-           for x in self.getDeliveryValue().getMovementList()], [])
       for simulation_movement in simulation_movement_list:
         value_dict = {solved_property:new_value}
         for property_id, value in value_dict.iteritems():