public void register(String processId, String name, Object extension) {

    if (log.isDebugEnabled()) log.debug("Registering " + name);

    PasswordManagementProcess p = this.runningProcesses.get(processId);

    Class clazz = p.getClass();

    while (clazz != null) {
      Field[] fields = clazz.getDeclaredFields();
      for (Field field : fields) {

        if (log.isDebugEnabled()) log.debug("Checking field : " + field.getName());

        if (field.isAnnotationPresent(Extension.class)) {

          Extension ex = field.getAnnotation(Extension.class);

          if (ex.value().equals(name)) {
            log.debug("Injecting extension : " + name);
            try {

              // Make field accessible ...
              if (!field.isAccessible()) {
                field.setAccessible(true);
              }
              field.set(p, extension);
              return;
            } catch (IllegalAccessException e) {
              log.error(e.getMessage(), e);
            }
          }
        }
      }
      clazz = clazz.getSuperclass();
    }
  }
  public ProcessResponse handleRequest(ProcessRequest request) throws PasswordManagementException {

    String processId = request.getProcessId();
    String actionName = null;

    if (log.isDebugEnabled()) log.debug("Handling request for process [" + processId + "]");

    try {

      PasswordManagementProcess p = runningProcesses.get(processId);
      if (p == null) throw new PasswordManagementException("No such process " + processId);

      String nextStep = p.getState().getNextStep();

      if (log.isDebugEnabled()) log.debug("Handling request for process [" + processId + "]");

      Method[] methods = p.getClass().getMethods();
      for (Method method : methods) {

        if (log.isDebugEnabled()) log.debug("Processing method : " + method.getName());

        if (!method.isAnnotationPresent(Action.class)) continue;

        Action action = method.getAnnotation(Action.class);

        if (log.isDebugEnabled()) log.debug("Processing method annotation : " + action);

        for (String actionStep : action.fromSteps()) {

          if (log.isDebugEnabled()) log.debug("Processing annotation step : " + actionStep);

          if (actionStep.equals(nextStep)) {
            actionName = method.getName();

            if (log.isDebugEnabled())
              log.debug(
                  "Dispatching request from step "
                      + nextStep
                      + " to process ["
                      + processId
                      + "] action "
                      + actionName);

            // Store response next step in process state :
            ProcessResponse r = (ProcessResponse) method.invoke(p, request);
            ((BaseProcessState) p.getState()).setNextStep(r.getNextStep());
            return r;
          }
        }
      }

      throw new PasswordManagementException("Step [" + nextStep + "] not supported by process");

    } catch (InvocationTargetException e) {
      throw new PasswordManagementException(
          "Cannot invoke process action [" + actionName + "] : " + e.getMessage(), e);
    } catch (IllegalAccessException e) {
      throw new PasswordManagementException(
          "Cannot invoke process action [" + actionName + "] : " + e.getMessage(), e);
    }
  }