class ForEachModelAction extends BaseStatefulAction {

   @Override
   public ActionState execute(ActionContext context) {
      List<Address> stillFiring = new ArrayList<Address>();
      Object original = context.getVariable(targetVariable);
      try {
         for(Model model: context.getModels()) {
            if(selector.apply(model) && condition.apply(model)) {
               try {
                  Address address = model.getAddress();
                  context.logger().debug("[{}] to [{}] because it matched [{}]", delegate, address, selector);
                  ActionContext namespacedContext = context.override(address.getId().toString());
                  namespacedContext.setVariable(targetVariable, address);
                  ActionState exitState = delegate.execute(namespacedContext);
                  if( exitState == ActionState.FIRING) {
                     stillFiring.add(address);
                  }
               }
               catch(Exception e) {
                  context.logger().warn("Error executing action [{}]", delegate.getDescription(), e);
               }
            }
            else {
               context.logger().trace("[{}] did not match [{}]", model, selector);
            }
         }
      }
      finally {
         context.setVariable(targetVariable, original);
         context.setVariable(VAR_STILL_FIRING, stillFiring);
      }
      this.stillFiring = stillFiring;
      return stillFiring.isEmpty() ? ActionState.IDLE : ActionState.FIRING;
   }

   public  ForEachModelAction(
         StatefulAction delegate, 
         Predicate<Model> selector, 
         Predicate<Model> condition, 
         String targetVariable
   );

}