// -----------------------------------------------------
 //                                          Reset Method
 //                                          ------------
 protected void doSetupResetMethod(
     S2ExecuteConfig executeConfig, S2ActionMapping actionMapping, Execute execute) {
   final String reset = execute.reset();
   if (!StringUtil.isEmpty(reset)) {
     Method resetMethod = null;
     if ("reset".equals(reset)) {
       resetMethod = actionMapping.getActionFormBeanDesc().getMethodNoException(reset);
     } else {
       resetMethod = actionMapping.getActionFormBeanDesc().getMethod(reset);
     }
     if (resetMethod != null) {
       executeConfig.setResetMethod(resetMethod);
     }
   }
 }
 // ===================================================================================
 //                                                                       Set up Method
 //                                                                       =============
 @Override
 protected void setupMethod(S2ActionMapping actionMapping, Class<?> actionClass) {
   // copied from super and adjust a little bit
   S2ExecuteConfig allSelectedExecuteConfig = null;
   for (Class<?> clazz = actionClass; clazz != Object.class; clazz = clazz.getSuperclass()) {
     for (Method method : clazz.getDeclaredMethods()) {
       if (isOutOfTargetMethod(actionMapping, actionClass, method)) {
         continue;
       }
       checkActionMethod(actionClass, method);
       checkDuplicateExecute(actionMapping, actionClass, method);
       final S2ExecuteConfig executeConfig = createExecuteConfig();
       setupExecuteConfig(executeConfig, actionMapping, actionClass, method);
       if (executeConfig.isUrlPatternAllSelected()) {
         if (allSelectedExecuteConfig != null) {
           throw new MultipleAllSelectedUrlPatternRuntimeException(
               allSelectedExecuteConfig.getUrlPattern(), executeConfig.getUrlPattern());
         }
         allSelectedExecuteConfig = executeConfig;
       } else {
         actionMapping.addExecuteConfig(executeConfig);
       }
     }
   }
   registerAllSelectedExecuteConfig(actionMapping, allSelectedExecuteConfig);
   checkExecuteConfigSize(actionMapping, actionClass);
 }
 // -----------------------------------------------------
 //                                            Validation
 //                                            ----------
 protected void doSetupValidationConfig(
     S2ExecuteConfig executeConfig,
     S2ActionMapping actionMapping,
     Class<?> actionClass,
     Method method,
     Execute execute,
     String input) {
   final List<S2ValidationConfig> validationConfigs = new ArrayList<S2ValidationConfig>();
   final String validate = execute.validate();
   boolean validator = false;
   if (!StringUtil.isEmpty(validate)) {
     final BeanDesc actionBeanDesc = actionMapping.getActionBeanDesc();
     final BeanDesc actionFormBeanDesc = actionMapping.getActionFormBeanDesc();
     for (String name : StringUtil.split(validate, ", ")) {
       if (VALIDATOR.equals(name)) {
         if (!execute.validator()) {
           throw new UnmatchValidatorAndValidateRuntimeException(actionClass, method.getName());
         }
         validationConfigs.add(createValidationConfig());
         validator = true;
       } else if (actionFormBeanDesc.hasMethod(name)) {
         final Method validateMethod = actionFormBeanDesc.getMethod(name);
         checkValidateMethod(actionClass, validateMethod);
         validationConfigs.add(createValidationConfig(validateMethod));
       } else {
         final Method validateMethod = actionBeanDesc.getMethod(name);
         checkValidateMethod(actionClass, validateMethod);
         validationConfigs.add(createValidationConfig(validateMethod));
       }
     }
   }
   if (!validator && execute.validator()) {
     validationConfigs.add(0, createValidationConfig());
   }
   if (!validationConfigs.isEmpty() && input == null) {
     throw new IllegalValidatorOfExecuteMethodRuntimeException(actionClass, method.getName());
   }
   executeConfig.setValidationConfigs(validationConfigs);
 }
 protected boolean isOutOfTargetMethod(
     S2ActionMapping actionMapping, Class<?> actionClass, Method method) {
   if (!ModifierUtil.isPublic(method)) {
     return true;
   }
   final Execute execute = method.getAnnotation(Execute.class);
   if (execute == null) {
     return true;
   }
   if (actionMapping.getExecuteConfig(method.getName()) != null) {
     return true;
   }
   return false;
 }
 protected void checkExecuteConfigSize(S2ActionMapping actionMapping, Class<?> actionClass) {
   if (actionMapping.getExecuteConfigSize() == 0) {
     throw new ExecuteMethodNotFoundRuntimeException(actionClass);
   }
 }
 // ===================================================================================
 //                                                                        Registration
 //                                                                        ============
 protected void registerAllSelectedExecuteConfig(
     S2ActionMapping actionMapping, S2ExecuteConfig allSelectedExecuteConfig) {
   if (allSelectedExecuteConfig != null) {
     actionMapping.addExecuteConfig(allSelectedExecuteConfig);
   }
 }
 protected void checkDuplicateExecute(
     S2ActionMapping actionMapping, Class<?> actionClass, Method m) {
   if (actionMapping.getActionFormBeanDesc().hasPropertyDesc(m.getName())) {
     throw new DuplicateExecuteMethodAndPropertyRuntimeException(actionClass, m.getName());
   }
 }