diff --git a/product/ERP5/Document/AcceptSolver.py b/product/ERP5/Document/AcceptSolver.py
index 10bf9d04bfcc964a5e39f3713281db1906f53c13..a00e67f6f5a420c0dfb4515675df1c8f02bdb987 100644
--- a/product/ERP5/Document/AcceptSolver.py
+++ b/product/ERP5/Document/AcceptSolver.py
@@ -63,15 +63,14 @@ class AcceptSolver(SolverMixin, ConfigurableMixin, XMLObject):
     Adopt new property to simulation movements, with keeping the
     original one recorded.
     """
-    configuration_dict = self.getConfigurationPropertyDict()
-    solved_property_list = configuration_dict.get('tested_property_list', None)
+    portal = self.getPortalObject()
+    solved_property_list = self.getConfigurationPropertyDict() \
+                               .get('tested_property_list')
     if solved_property_list is None:
-      portal_type = self.getPortalObject().portal_types.getTypeInfo(self)
-      solved_property_list = portal_type.getTestedPropertyList()
-    if 1:
+      solved_property_list = \
+        portal.portal_types.getTypeInfo(self).getTestedPropertyList()
+    with self.defaultActivateParameterDict(activate_kw, True):
       for simulation_movement in self.getDeliveryValueList():
-        if activate_kw is not None:
-          simulation_movement.setDefaultActivateParameterDict(activate_kw)
         movement = simulation_movement.getDeliveryValue()
         value_dict = {}
         base_category_set = set(movement.getBaseCategoryList())
@@ -89,16 +88,13 @@ class AcceptSolver(SolverMixin, ConfigurableMixin, XMLObject):
             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})
+            new_value *= simulation_movement.getDeliveryRatio()
+          value_dict[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(activate_kw=activate_kw)
     # Finish solving
-    if self.getPortalObject().portal_workflow.isTransitionPossible(
-      self, 'succeed'):
+    if portal.portal_workflow.isTransitionPossible(self, 'succeed'):
       self.succeed()
diff --git a/product/ERP5/Document/QuantitySplitSolver.py b/product/ERP5/Document/QuantitySplitSolver.py
index 48581d7b5e099fb65bac04efbfeaf3282f287c2d..b32e0fb4cf6b6bfcc9c196174da066f3958707ee 100644
--- a/product/ERP5/Document/QuantitySplitSolver.py
+++ b/product/ERP5/Document/QuantitySplitSolver.py
@@ -93,11 +93,10 @@ class QuantitySplitSolver(SolverMixin, ConfigurableMixin, XMLObject):
           new_id = "%s_split_%s" % (simulation_movement.getId(), split_index)
         # Copy at same level
         kw = _getPropertyAndCategoryList(simulation_movement)
-        kw.update({'portal_type':simulation_movement.getPortalType(),
-                   'id':new_id,
-                   'delivery':None,
-                   'quantity':split_quantity})
-        new_movement = applied_rule.newContent(activate_kw=activate_kw, **kw)
+        kw.update(delivery=None, quantity=split_quantity)
+        new_movement = applied_rule.newContent(
+          new_id, simulation_movement.getPortalType(),
+          activate_kw=activate_kw, **kw)
         # Dirty code until IPropertyRecordable is revised.
         # Merge original simulation movement recorded property to new one.
         recorded_property_dict = simulation_movement._getRecordedPropertyDict(None)
@@ -106,8 +105,6 @@ class QuantitySplitSolver(SolverMixin, ConfigurableMixin, XMLObject):
           if new_movement_recorded_property_dict is None:
             new_movement_recorded_property_dict = new_movement._recorded_property_dict = PersistentMapping()
           new_movement_recorded_property_dict.update(recorded_property_dict)
-        if activate_kw is not None:
-          new_movement.setDefaultActivateParameterDict(activate_kw)
         # record zero quantity property, because this was originally zero.
         # without this, splitanddefer after accept decision does not work
         # properly.
@@ -123,6 +120,8 @@ class QuantitySplitSolver(SolverMixin, ConfigurableMixin, XMLObject):
         if stop_date is not None:
           new_movement.recordProperty('stop_date')
           new_movement.setStopDate(stop_date)
+        if activate_kw:
+          new_movement.setDefaultActivateParameterDict({})
         # XXX we need to call expand on both simulation_movement and new_movement here?
         # simulation_movement.expand(activate_kw=activate_kw)
         # new_movement.expand(activate_kw=activate_kw)
diff --git a/product/ERP5/Document/TradeModelSolver.py b/product/ERP5/Document/TradeModelSolver.py
index 0cdb9f92872baf736ed893b71a0635c7e85e74aa..be27a1375ef2e18c5b285741cca0b7c77358881e 100644
--- a/product/ERP5/Document/TradeModelSolver.py
+++ b/product/ERP5/Document/TradeModelSolver.py
@@ -63,52 +63,44 @@ class TradeModelSolver(AcceptSolver):
     Adopt new values to simulation movements, with keeping the original
     one recorded, and then update Trade Model related lines accordingly.
     """
-    configuration_dict = self.getConfigurationPropertyDict()
-    portal_type = self.getPortalObject().portal_types.getTypeInfo(self)
-    solved_property_list = configuration_dict.get('tested_property_list',
-                                                  portal_type.getTestedPropertyList())
-    delivery_dict = {}
+    portal = self.getPortalObject()
+    solved_property_list = self.getConfigurationPropertyDict() \
+                               .get('tested_property_list')
+    if solved_property_list is None:
+      solved_property_list = \
+        portal.portal_types.getTypeInfo(self).getTestedPropertyList()
+    delivery_dict = {} # {movement: simulation_movement_list}
     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.
-    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.
     # XXX is there any better way than using rule's reference?
-    trade_model_related_movement_list = []
-    for movement in all_movement_list:
-      if movement in solved_movement_list:
-        continue
-      applied_rule = movement.getDeliveryRelatedValue().getParentValue()
-      # hard coded reference name
-      if applied_rule.getSpecialiseReference() == 'default_trade_model_rule':
-        trade_model_related_movement_list.append(movement)
+    trade_model_related_movement_dict = {}
+    for delivery in set(movement.getRootDeliveryValue()
+                        for movement in delivery_dict):
+      for movement in delivery.getMovementList():
+        simulation_movement_list = delivery_dict.get(movement) or \
+          movement.getDeliveryRelatedValueList()
+        applied_rule = simulation_movement_list[0].getParentValue()
+        # hard coded reference name
+        if applied_rule.getSpecialiseReference() == 'default_trade_model_rule':
+          trade_model_related_movement_dict[movement] = simulation_movement_list
 
-    if 1:
+    with self.defaultActivateParameterDict(activate_kw, True):
       # Second, apply changes on invoice lines to simulation movements,
       # then expand.
       for movement, simulation_movement_list in delivery_dict.iteritems():
-        if movement in trade_model_related_movement_list:
+        if movement in trade_model_related_movement_dict:
           continue
         for simulation_movement in simulation_movement_list:
-          if activate_kw is not None:
-            simulation_movement.setDefaultActivateParameterDict(activate_kw)
           value_dict = {}
           for solved_property in solved_property_list:
             new_value = movement.getProperty(solved_property)
             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})
+              new_value *= simulation_movement.getDeliveryRatio()
+            value_dict[solved_property] = new_value
           for property_id, value in value_dict.iteritems():
             if not simulation_movement.isPropertyRecorded(property_id):
               simulation_movement.recordProperty(property_id)
@@ -117,33 +109,28 @@ class TradeModelSolver(AcceptSolver):
 
       # Third, adopt changes on trade model related lines.
       # XXX non-linear case is not yet supported.
-      for movement in trade_model_related_movement_list:
-        if activate_kw is not None:
-          movement.setDefaultActivateParameterDict(activate_kw)
+      for movement, simulation_movement_list in \
+          trade_model_related_movement_dict.iteritems():
         for solved_property in solved_property_list:
           if solved_property == 'quantity':
-            simulation_movement_list = movement.getDeliveryRelatedValueList()
-            total_quantity = sum(
-              [x.getQuantity() for x in simulation_movement_list])
+            total_quantity = sum(x.getQuantity()
+              for x in simulation_movement_list)
             movement.setQuantity(total_quantity)
             for simulation_movement in simulation_movement_list:
               quantity = simulation_movement.getQuantity()
-              if total_quantity != 0.0:
+              if total_quantity:
                 delivery_ratio = quantity / total_quantity
               else:
                 delivery_ratio = 1.0 / len(simulation_movement_list)
               delivery_error = total_quantity * delivery_ratio - quantity
               simulation_movement.edit(delivery_ratio=delivery_ratio,
-                                       delivery_error=delivery_error,
-                                       activate_kw=activate_kw)
+                                       delivery_error=delivery_error)
           else:
             # XXX TODO we need to support multiple values for categories or
             # list type property.
-            simulation_movement = movement.getDeliveryRelatedValue()
             movement.setProperty(solved_property,
-                                 simulation_movement.getProperty(solved_property))
+              simulation_movement_list[0].getProperty(solved_property))
 
     # Finish solving
-    if self.getPortalObject().portal_workflow.isTransitionPossible(
-      self, 'succeed'):
+    if portal.portal_workflow.isTransitionPossible(self, 'succeed'):
       self.succeed()
diff --git a/product/ERP5/Document/UnifySolver.py b/product/ERP5/Document/UnifySolver.py
index 55160a15d1b3cf968de74297e56feb7208fcb9d9..b3b786effad492d180214ec69a97aaa96304ab04 100644
--- a/product/ERP5/Document/UnifySolver.py
+++ b/product/ERP5/Document/UnifySolver.py
@@ -95,10 +95,12 @@ class UnifySolver(AcceptSolver):
     Adopt new property value to simulation movements and their deliveries,
     while keeping the original one recorded.
     """
+    portal = self.getPortalObject()
     configuration_dict = self.getConfigurationPropertyDict()
-    portal_type = self.getPortalObject().portal_types.getTypeInfo(self)
-    solved_property_list = configuration_dict.get('tested_property_list',
-                                                  portal_type.getTestedPropertyList())
+    solved_property_list = configuration_dict.get('tested_property_list')
+    if solved_property_list is None:
+      solved_property_list = \
+        portal.portal_types.getTypeInfo(self).getTestedPropertyList()
     # XXX it does not support multiple tested properties.
     solved_property = solved_property_list[0]
     delivery_dict = {}
@@ -115,18 +117,15 @@ class UnifySolver(AcceptSolver):
       ))
       if activate_kw is not None:
         movement.setDefaultActivateParameterDict(activate_kw)
-      new_value = configuration_dict.get('value')
-      movement.setProperty(solved_property, new_value)
+      value = configuration_dict.get('value')
+      movement.setProperty(solved_property, value)
       for simulation_movement in simulation_movement_set:
         if activate_kw is not None:
           simulation_movement.setDefaultActivateParameterDict(activate_kw)
-        value_dict = {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)
+        if not simulation_movement.isPropertyRecorded(solved_property):
+          simulation_movement.recordProperty(solved_property)
+        simulation_movement.setMappedProperty(solved_property, value)
         simulation_movement.expand(activate_kw=activate_kw)
     # Finish solving
-    if self.getPortalObject().portal_workflow.isTransitionPossible(
-      self, 'succeed'):
+    if portal.portal_workflow.isTransitionPossible(self, 'succeed'):
       self.succeed()