diff --git a/product/ERP5/Document/SimulationMovement.py b/product/ERP5/Document/SimulationMovement.py
index 41538adcee366ca995a53b4b0f7dd46da39fc9a7..ed65084cb860fe0aab62f0085df14d75ffbd3e3f 100644
--- a/product/ERP5/Document/SimulationMovement.py
+++ b/product/ERP5/Document/SimulationMovement.py
@@ -331,22 +331,6 @@ class SimulationMovement(PropertyRecordableMixin, Movement, ExplainableMixin):
       if explanation_value != portal:
         return explanation_value
 
-  def asComposedDocument(self, *args, **kw):
-    # XXX: What delivery should be used to find amount generator lines ?
-    #      With the currently enabled code, entire branches in the simulation
-    #      tree get (temporary) deleted when new delivery lines are being built
-    #      (and don't have yet a specialise value).
-    #      With the commented code, changing the STC on a SIT generated from a
-    #      SPL/SO would have no impact (and would never make the SIT divergent).
-    #return self.getRootSimulationMovement() \
-    #           .getDeliveryValue() \
-    #           .asComposedDocument(*args, **kw)
-    while 1:
-      delivery_value = self.getDeliveryValue()
-      if delivery_value is not None:
-        return delivery_value.asComposedDocument(*args, **kw)
-      self = self.getParentValue().getParentValue()
-
   # Deliverability / orderability
   security.declareProtected( Permissions.AccessContentsInformation,
                              'isOrderable')
diff --git a/product/ERP5/Document/TradeModelSimulationRule.py b/product/ERP5/Document/TradeModelSimulationRule.py
index d904c1f23951f9c64ae88f80952d85f097df4394..e9160e0a281bb85ab2328536a875194f971bfdc5 100644
--- a/product/ERP5/Document/TradeModelSimulationRule.py
+++ b/product/ERP5/Document/TradeModelSimulationRule.py
@@ -96,17 +96,15 @@ class TradeModelRuleMovementGenerator(MovementGeneratorMixin):
 
   def _getInputMovementList(self, movement_list=None, rounding=False):
     simulation_movement = self._applied_rule.getParentValue()
-    trade_model = simulation_movement.asComposedDocument()
-
-    if trade_model is None:
-      return
-
+    specialise_list = simulation_movement.getSpecialiseList()
     rule = self._applied_rule.getSpecialiseValue()
     for amount in simulation_movement.getAggregatedAmountList(
         # XXX add a 'trade_amount_generator' group type
         amount_generator_type_list=('Purchase Trade Condition',
                                     'Sale Trade Condition',
                                     'Trade Model Line')):
-      yield self._applied_rule.newContent(
+      movement = self._applied_rule.newContent(
         portal_type=RuleMixin.movement_type, temp_object=True,
         **dict((k, v) for k, v in amount.__dict__.iteritems() if k[0] != '_'))
+      movement._setSpecialiseList(specialise_list)
+      yield movement
diff --git a/product/ERP5/mixin/composition.py b/product/ERP5/mixin/composition.py
index 20fbc2f0f4add01f858791201e579c366196f4c3..51cea7ecf90747f3ba9462b9f6dfedfe1a09bbd5 100644
--- a/product/ERP5/mixin/composition.py
+++ b/product/ERP5/mixin/composition.py
@@ -80,15 +80,10 @@ def _getEffectiveModel(self, start_date=None, stop_date=None):
 
 
 # We do have clever caching here, since container_list does not contain objects
-# with no subobject. Example:
-#  If a SO (-> TC1, TC2) has 1 SOL (without specialise) and 1 TML,
-#  "SOL.asComposedDocument()" gives:
-#  1. _effective_model_list equals to
-#     [SOL] + [SO, TC1, TC2] = [SOL, SO, TC1, TC2]
-#  2. first call to objectValues passes container_list = [SO, TC1, TC2]
-#     to  _findPredicateList (SOL being filtered out)
-#  After evaluation of "SOL.asComposedDocument()" and "SO.asComposedDocument()",
-#  _findPredicateList has only 1 entry in its cache.
+# with no subobject.
+# After evaluation of asComposedDocument() on a SO and all its SOL,
+# _findPredicateList's cache has at most 1 entry per specialise value found
+# on SO/SOL.
 @transactional_cached()
 def _findPredicateList(container_list, portal_type=None):
   predicate_list = []
@@ -203,12 +198,10 @@ class CompositionMixin:
           model_set.add(model)
           if 1: #model.test(self): # XXX
             model_list.append(model)
-    try:
-      parent_asComposedDocument = self.getParentValue().asComposedDocument
-    except AttributeError:
-      pass
-    else:
-      model_list += [model for model in parent_asComposedDocument(
+    del model_list[0]
+    parent = self.getParentValue()
+    if hasattr(aq_base(parent), 'asComposedDocument'):
+      model_list += [model for model in parent.asComposedDocument(
                              specialise_type_list)._effective_model_list
                            if model not in model_set]
     return model_list