diff --git a/product/ERP5/Document/AcceptSolver.py b/product/ERP5/Document/AcceptSolver.py
index a00e67f6f5a420c0dfb4515675df1c8f02bdb987..20045baf11d363f0f506d1b4cebb768b48755041 100644
--- a/product/ERP5/Document/AcceptSolver.py
+++ b/product/ERP5/Document/AcceptSolver.py
@@ -27,37 +27,16 @@
 #
 ##############################################################################
 
-import zope.interface
-from AccessControl import ClassSecurityInfo
-from Products.ERP5Type import Permissions, PropertySheet, interfaces
-from Products.ERP5Type.XMLObject import XMLObject
-from Products.ERP5.mixin.solver import SolverMixin
-from Products.ERP5.mixin.configurable import ConfigurableMixin
+from Products.ERP5.mixin.solver import ConfigurablePropertySolverMixin
 
-class AcceptSolver(SolverMixin, ConfigurableMixin, XMLObject):
+class AcceptSolver(ConfigurablePropertySolverMixin):
   """Target solver that accepts the values from the decision on the prevision.
   """
   meta_type = 'ERP5 Accept Solver'
   portal_type = 'Accept Solver'
-  add_permission = Permissions.AddPortalContent
-  isIndexable = 0 # We do not want to fill the catalog with objects on which we need no reporting
-
-  # Declarative security
-  security = ClassSecurityInfo()
-  security.declareObjectProtected(Permissions.AccessContentsInformation)
-
-  # Default Properties
-  property_sheets = ( PropertySheet.Base
-                    , PropertySheet.XMLObject
-                    , PropertySheet.CategoryCore
-                    , PropertySheet.DublinCore
-                    , PropertySheet.TargetSolver
-                    )
-
-  # Declarative interfaces
-  zope.interface.implements(interfaces.ISolver,)
 
   # ISolver Implementation
+  # XXX-Leo: Needs security declaration! It's currently public.
   def solve(self, activate_kw=None):
     """
     Adopt new property to simulation movements, with keeping the
@@ -90,11 +69,18 @@ class AcceptSolver(SolverMixin, ConfigurableMixin, XMLObject):
           if solved_property == 'quantity':
             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)
+        self._updateSimulationMovement(simulation_movement, value_dict,
+                                       activate_kw)
     # Finish solving
     if portal.portal_workflow.isTransitionPossible(self, 'succeed'):
       self.succeed()
+
+  # allow subclasses to override this method and do interesting things
+  # like recording the same values in other simulation movements
+  def _updateSimulationMovement(self, simulation_movement, value_dict,
+                                activate_kw):
+    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)
diff --git a/product/ERP5/Document/AdoptSolver.py b/product/ERP5/Document/AdoptSolver.py
index 704d20e65fa4064f3d1f493f94fe28ac46020697..7d3d6c8a33317a15534d8a491fff09c673c08458 100644
--- a/product/ERP5/Document/AdoptSolver.py
+++ b/product/ERP5/Document/AdoptSolver.py
@@ -27,47 +27,21 @@
 #
 ##############################################################################
 
-import zope.interface
-from AccessControl import ClassSecurityInfo
-from Products.ERP5Type import Permissions, PropertySheet, interfaces
-from Products.ERP5Type.XMLObject import XMLObject
-from Products.ERP5.mixin.solver import SolverMixin
-from Products.ERP5.mixin.configurable import ConfigurableMixin
+from Products.ERP5.mixin.solver import ConfigurablePropertySolverMixin
 
-class AdoptSolver(SolverMixin, ConfigurableMixin, XMLObject):
+class AdoptSolver(ConfigurablePropertySolverMixin):
   """Target solver that adopts the values from the prevision on the decision.
   """
   meta_type = 'ERP5 Adopt Solver'
   portal_type = 'Adopt Solver'
-  add_permission = Permissions.AddPortalContent
-  isIndexable = 0 # We do not want to fill the catalog with objects on which we need no reporting
-
-  # Declarative security
-  security = ClassSecurityInfo()
-  security.declareObjectProtected(Permissions.AccessContentsInformation)
-
-  # Default Properties
-  property_sheets = ( PropertySheet.Base
-                    , PropertySheet.XMLObject
-                    , PropertySheet.CategoryCore
-                    , PropertySheet.DublinCore
-                    , PropertySheet.TargetSolver
-                    )
-
-  # Declarative interfaces
-  zope.interface.implements(interfaces.ISolver,
-                            interfaces.IConfigurable,
-                           )
 
   # ISolver Implementation
+  # XXX-Leo: Needs security declaration! It's currently public.
   def solve(self, activate_kw=None):
     """
     Adopt new property to movements or deliveries.
     """
-    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 = self.getTestedPropertyList()
     delivery_dict = {}
     for simulation_movement in self.getDeliveryValueList():
       delivery_dict.setdefault(simulation_movement.getDeliveryValue(),
diff --git a/product/ERP5/mixin/solver.py b/product/ERP5/mixin/solver.py
index 72d74dffefb8d95fd44a933c3fb9329744829bfd..ad5f52b6f9dd11f09f4e7170b37c5d419fd3c1c1 100644
--- a/product/ERP5/mixin/solver.py
+++ b/product/ERP5/mixin/solver.py
@@ -29,9 +29,11 @@
 
 import zope.interface
 from AccessControl import ClassSecurityInfo
-from Products.ERP5Type import Permissions, interfaces
+from Products.ERP5Type import Permissions, PropertySheet, interfaces
+from Products.ERP5Type.XMLObject import XMLObject
+from Products.ERP5.mixin.configurable import ConfigurableMixin
 
-class SolverMixin:
+class SolverMixin(object):
   """
   Provides generic methods and helper methods to implement ISolver.
   """
@@ -58,3 +60,38 @@ class SolverMixin:
     target_solver_type = self.getPortalTypeValue()
     solver_list = target_solver_type.getDeliverySolverValueList()
     return solver_list
+
+class ConfigurablePropertySolverMixin(SolverMixin,
+                                      ConfigurableMixin,
+                                      XMLObject):
+  """
+  Base class for Target Solvers that can be applied to many
+  solver-decisions of a solver process, and need to accumulate the
+  tested_property_list configuration among all solver-decisions
+  """
+
+  add_permission = Permissions.AddPortalContent
+  isIndexable = 0 # We do not want to fill the catalog with objects on which we need no reporting
+
+  # Declarative security
+  security = ClassSecurityInfo()
+  security.declareObjectProtected(Permissions.AccessContentsInformation)
+
+  zope.interface.implements(interfaces.ISolver,
+                            interfaces.IConfigurable,)
+
+  # Default Properties
+  property_sheets = ( PropertySheet.Base
+                    , PropertySheet.XMLObject
+                    , PropertySheet.CategoryCore
+                    , PropertySheet.DublinCore
+                    , PropertySheet.TargetSolver
+                    )
+
+  def getTestedPropertyList(self):
+    configuration_dict = self.getConfigurationPropertyDict()
+    tested_property_list = configuration_dict.get('tested_property_list')
+    if tested_property_list is None:
+      portal_type = self.getPortalObject().portal_types.getTypeInfo(self)
+      tested_property_list = portal_type.getTestedPropertyList()
+    return tested_property_list