diff --git a/product/ERP5/DeliverySolver/FIFO.py b/product/ERP5/DeliverySolver/FIFO.py
index cdbe08ae55c3e207e2c2a5ba10cb883367fe71e2..d18f961a78e0527a38ec21b70c6a932261986c00 100644
--- a/product/ERP5/DeliverySolver/FIFO.py
+++ b/product/ERP5/DeliverySolver/FIFO.py
@@ -33,3 +33,30 @@ class FIFO(DeliverySolver):
   """
     The FIFO solver reduces deliveted quantity by reducing the quantity of simulation movements from the last order.
   """
+
+  def solve(self, simulation_movement_list, new_quantity):
+    """
+    """
+    result = []
+    def sortByOrderStartDate(a, b);
+      return cmp(a.getExplainationValue().getStartDate() b.getExplainationValue().getStartDate())
+    simulation_movement_list.sort(sortByOrderStartDate)
+    simulation_movement_list.reverse()
+    total_quantity = 0
+    for movement in simulation_movement_list:
+      total_quantity += movement.getQuantity()
+    remaining_quantity = total_quantity - new_quantity
+    for movement in simulation_movement_list:
+      if remaining_quantity:
+        if movement.getQuantity() < remaining_quantity:
+          result.append((movement, movement.getQuantity()))
+          remaining_quantity -= movement.getQuantity()
+          movement.setQuantity(0)
+        else:
+          result.append((movement, remaining_quantity)) 
+          movement.setQuantity(movement.getQuantity() - remaining_quantity)
+          remaining_quantity = 0
+    # Return movement, split_quantity tuples
+    for movement in simulation_movement_list:
+      movement.setDeliveryRatio(movement.getQuantity() / new_quantity)
+    return result
\ No newline at end of file
diff --git a/product/ERP5/Document/AcceptSolver.py b/product/ERP5/Document/AcceptSolver.py
index fc0c22b7c70481958b946eb215d227228012492b..0c0c103092ab79473ebcab885a3524db0756ee36 100644
--- a/product/ERP5/Document/AcceptSolver.py
+++ b/product/ERP5/Document/AcceptSolver.py
@@ -52,4 +52,19 @@ class AcceptSolver(XMLObject):
                     , PropertySheet.XMLObject
                     , PropertySheet.CategoryCore
                     , PropertySheet.DublinCore
-                    )
\ No newline at end of file
+                    )
+
+  # Implementation
+  def solve(self):
+    """
+    """
+    # Adopt new property, keep the original one recorded
+    solved_property = self.getPortalTypeValue().getTestedProperty()
+    for movement in self.getDeliveryValueList():
+      new_value = movement.getProperty(solved_property)
+      for simulation_movement in movement.getDeliveryRelatedValueList():
+        if not simulation_movement.isPropertyRecorded(solved_property):
+          simulation_movement.recordProperty(solved_property)
+        solved_property.setProperty(solved_property, new_value)
+    # Finish solving
+    self.succeed()
\ No newline at end of file
diff --git a/product/ERP5/Document/QuantitySplitSolver.py b/product/ERP5/Document/QuantitySplitSolver.py
index 0f394a51c18e10593d8337a825b5a13edb69b69c..5c30a65abc88f41a1f0f121cf6907b3a84333eb7 100644
--- a/product/ERP5/Document/QuantitySplitSolver.py
+++ b/product/ERP5/Document/QuantitySplitSolver.py
@@ -55,3 +55,19 @@ class QuantitySplitSolver(XMLObject):
                     , PropertySheet.DublinCore
                     , PropertySheet.Arrow
                     )
+  # Implementation
+  def solve(self):
+    """
+    """
+    delivery_solver = self.portal_solvers.buildDeliverySolver(self.getDeliverySolver())
+    for delivery_line in self.getDeliveryValueList(): 
+      decision_quantity = delivery_line.getQuantity()
+      simulation_movement_list = self.getDeliveryRelatedValueList()
+      # Update the quantity using delivery solver algorithm
+      split_list = delivery_solver.solve(simulation_movement_list, decision_quantity)
+      # Create split movements
+      for (simulation_movement, split_quantity) in split_list:
+        new_movement = simulation_movement.copy() # Copy at same level
+        new_movement._setQuantity(split_quantity)
+        new_movement._setStartDate(self.getStartDate())
+        new_movement._setStopDate(self.getStopDate())
\ No newline at end of file
diff --git a/product/ERP5/Document/SolverProcess.py b/product/ERP5/Document/SolverProcess.py
index 5c3bcf73e49ee610a11562dd33181c195b5466f5..1a172b4433a6e6844c523beb260d240ba769a924 100644
--- a/product/ERP5/Document/SolverProcess.py
+++ b/product/ERP5/Document/SolverProcess.py
@@ -71,4 +71,62 @@ class SolverProcess(XMLObject, ActiveProcess):
                     , PropertySheet.XMLObject
                     , PropertySheet.CategoryCore
                     , PropertySheet.DublinCore
-                    )
\ No newline at end of file
+                    )
+
+  def buildTargetSolverList(self):
+    """
+      Builds target solvers from solver decisions
+    """
+    solver_dict = {}
+    movement_dict = {}
+    types_tool = context.portal_types
+
+    # First create a mapping between delivery movements and solvers
+    #   in order to know for each movements which solvers are needed
+    #   and which parameters with
+    for decision in context.contentValues(portal_type="Solver Decision"):
+      solver = decision.getSolverValue()
+      solver_type = solver.getId() # ex. Postpone Production Solver
+      solver_conviguration_dict = decision.getConfigurationPropertyDict()
+      solver_conviguration_key = solver_conviguration_dict.items()
+      for movement in decision.getDeliveryValueList():
+        # Detect incompatibilities
+        movement_solver_dict = movement_dict.setdefault(movement.getRelativeUrl(), {})
+        movement_solver_configuration_dict = movement_solver_dict.setdefault(solver_type, {})
+        movement_solver_configuration_dict[solver_key] = None
+
+    # Second, make sure solvers do not conflict and configuration is valid
+    for movement_url, movement_solver_dict in movement_dict.items():
+      for solver_type, movement_solver_configuration_dict in movement_solver_dict.items():
+        solver = types_tool[solver_type]
+        for other_solver in movement_solver_dict.keys():
+          if solver.conflictsWithSolver(other_solver):
+            raise "Solver %s conflicts with solver %s on movement %s" % (solver_type, other_solver, movement_url)
+        # Make sure multiple configuration are possible
+        try:
+          # Solver key contains only those properties which differentiate
+          # solvers (ex. there should be only Production Reduction Solver)
+          solver_key = solver.reduceConfigurationList(movement_solver_configuration_dict.keys())
+        except:
+          raise
+        solver_key_dict = solver_dict.setdefault(solver_type, {})
+        solver_movement_dict = solver_key_dict.setdefault(solver_key, {})
+        solver_movement_dict[movement_url] = movement_solver_configuration_dict.keys()
+
+    # Third, build target solvers
+    for portal_type, solver_key_dict in solver_dict.items():
+      for solver_key, solver_movement_dict in solver_key_dict.items():
+         solver_instance = self.newContent(portal_type=solver_type)
+         solver_instance._setDeliveryList(solver_movement_dict.keys())
+         for movement_url, configuration_list:
+           for configuration_kw in configuration_list:
+            solver_instance.updateConfiguration(**configuration_kw)
+
+  # Solver Process Workflow Interface 
+  #  NOTE: how can we consider that a workflow defines or provides an interface ?
+  def solve(self):
+    """
+      Start solving
+    """
+    for solver in self.contentValues(portal_type=self.getPortalObject().getPortalTargetSolverTypeList()):
+      solver.activate(active_process=self).solve()
\ No newline at end of file