class ForEachModelAction implements Action {

   @Override
   public void execute(ActionContext context) {
      Object original = context.getVariable(targetVariable);
      try {
         for(Model model: context.getModels()) {
            if(selector.apply(model)) {
               try {
                  Address address = model.getAddress();
                  context.logger().debug("[{}] to [{}] because it matched [{}]", delegate, address, selector);
                  context.setVariable(targetVariable, address);
                  delegate.execute(context);
               }
               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);
      }
   }

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

}