@Override
 @SuppressWarnings("ConstantConditions")
 protected void adjustMvcArguments(@Nonnull MVCGroup group, @Nonnull Map<String, Object> args) {
   super.adjustMvcArguments(group, args);
   FactoryBuilderSupport builder = (FactoryBuilderSupport) group.getMember(BUILDER);
   args.put(BUILDER, builder);
   for (Map.Entry<String, Object> variable : args.entrySet()) {
     builder.setVariable(variable.getKey(), variable.getValue());
   }
 }
  @Override
  protected void destroyMembers(@Nonnull MVCGroup group, boolean fireDestructionEvents) {
    super.destroyMembers(group, fireDestructionEvents);

    try {
      FactoryBuilderSupport builder = (FactoryBuilderSupport) group.getMember(BUILDER);
      if (builder != null) {
        builder.dispose();
        builder.getVariables().clear();
      }
    } catch (Exception e) {
      // TODO find out why this call breaks applet mode on shutdown
      LOG.error(
          "Application encountered an error while destroying group '" + group.getMvcId() + "'",
          sanitize(e));
    }
  }
  @Nonnull
  @Override
  @SuppressWarnings("unchecked")
  protected Map<String, Object> instantiateMembers(
      @Nonnull Map<String, ClassHolder> classMap, @Nonnull Map<String, Object> args) {
    Map<String, Object> map = super.instantiateMembers(classMap, args);
    FactoryBuilderSupport builder = createBuilder(getApplication());
    map.put(BUILDER, builder);

    for (Object member : map.values()) {
      // all scripts get the builder as their binding
      if (member instanceof Script) {
        builder.getVariables().putAll(((Script) member).getBinding().getVariables());
        ((Script) member).setBinding(builder);
      }
    }

    return map;
  }
 public Object invokeMethod(Object object, String methodName, Object[] arguments) {
   try {
     return delegate.invokeMethod(object, methodName, arguments);
   } catch (MissingMethodException mme) {
     // attempt builder resolution
     try {
       if (builder.getMetaClass().respondsTo(builder, methodName).isEmpty()) {
         // dispatch to factories if it is not a literal method
         return builder.invokeMethod(methodName, arguments);
       } else {
         return InvokerHelper.invokeMethod(builder, methodName, arguments);
       }
     } catch (MissingMethodException mme2) {
       // chain secondary exception
       Throwable root = mme;
       while (root.getCause() != null) {
         root = root.getCause();
       }
       root.initCause(mme2);
       // throw original
       throw mme;
     }
   }
 }