@Override
 public Object resolve(
     MethodAction action,
     RouteType routeType,
     HttpServletRequest req,
     HttpServletResponse resp,
     Map<String, String> pathVars)
     throws ActionException {
   Object controller = getOrCreateController(action);
   Map<Annotation, ActionInterceptor<Annotation>> interceptors = action.interceptors();
   Object result = null;
   Exception exception = null;
   try {
     result = beforeInterceptors(interceptors, req, resp);
     List<?> arguments = bindArguments(action, req, resp, pathVars);
     result = result != null ? result : action.invoke(controller, arguments);
     result = afterInterceptors(result, interceptors, req, resp);
   } catch (InvocationTargetException e) {
     // we need to unwrap InvocationTargetExceptions to get at the real exception
     exception = Cast.as(e.getTargetException(), Exception.class);
     if (exception == null) {
       throw new BaseException(e);
     }
   } catch (Exception e) {
     exception = e;
   }
   if (exception != null) {
     result = exceptionInterceptors(interceptors, req, resp, exception);
     if (result == null) {
       throw new ActionException(exception, "Failed in %s: %s", action, exception.getMessage());
     }
   }
   Logger.debug("%s -> %s resolved", req.getRequestURI(), action);
   return result;
 }
 @Override
 public MethodAction createActionIfPossible(String actionName) {
   // will resolve if both a class and method name can be parsed, and a valid class with that
   // method name can be loaded
   String methodName = MethodAction.methodNameForAction(actionName);
   String className = MethodAction.classNameForAction(actionName);
   if (StringUtils.isEmpty(methodName) || StringUtils.isEmpty(className)) {
     return null;
   }
   try {
     Class<?> clazz = Class.forName(className); // TODO - Restricted in GAE - why is this better?
     // ClassLoaderUtil.loadClass(className);
     Method method = ReflectUtil.findMethod(clazz, methodName);
     if (method == null) {
       return null;
     }
     MethodAction methodAction = new MethodAction(clazz, method, findInterceptors(method));
     // force instantiation of controller - this allows controllers to be injected into eachother
     // and also flushes out instantiation issues at startup
     Object controller = createController(methodAction);
     controllerInstances.put(methodAction.type(), controller);
     return methodAction;
   } catch (BaseException e) {
     throw e;
   } catch (Exception e) {
     return null;
   }
 }
 /**
  * Creates the power on action.
  *
  * @return the method action
  */
 MethodAction createPowerOnAction() {
   MethodAction action = new MethodAction();
   action.setName("PowerOnVM_Task");
   MethodActionArgument argument = new MethodActionArgument();
   argument.setValue(null);
   action.getArgument().addAll(Arrays.asList(new MethodActionArgument[] {argument}));
   return action;
 }
 private Object getOrCreateController(MethodAction methodAction) {
   Object controller = controllerInstances.get(methodAction.type());
   if (controller == null) {
     synchronized (controllerInstances) {
       controller = controllerInstances.get(methodAction.type());
       if (controller == null) {
         controller = createController(methodAction);
         controllerInstances.put(methodAction.type(), controller);
       }
     }
   }
   return controller;
 }
 <T> T createController(MethodAction actionMethod) {
   Class<T> type = actionMethod.type();
   if (!injectionContext.contains(type)) {
     injectionContext.inject(type).as(type);
   }
   try {
     return injectionContext.get(type);
   } catch (Exception e) {
     throw new ActionException(
         e, "Failed to create controller %s: %s", type.toString(), e.getMessage());
   }
 }
 List<Object> bindArguments(
     MethodAction action,
     HttpServletRequest req,
     HttpServletResponse resp,
     Map<String, String> pathVars) {
   Map<ParameterDescription, Object> boundParameters =
       new LinkedHashMap<ParameterDescription, Object>();
   for (ParameterDescription parameterDescription : action.parameters()) {
     boundParameters.put(parameterDescription, null);
   }
   if (!boundParameters.isEmpty()) {
     for (ActionMethodBinder binder : methodBinderRegistry.getRegisteredActionMethodBinders()) {
       binder.bindAll(boundParameters, req, resp, pathVars);
     }
   }
   return new ArrayList<Object>(boundParameters.values());
 }