public ProcessResponse startProcess(String name) throws SSOException {

    String id = idGenerator.generateId();

    PasswordManagementProcess p = getPrototype(name);
    if (p == null) throw new SSOException("No such process : " + name);

    // Create a new process based on the received prototype
    p = p.createNewProcess(id);
    runningProcesses.put(p.getProcessId(), p);
    ProcessResponse r = p.start();
    ((BaseProcessState) p.getState()).setNextStep(r.getNextStep());
    return r;
  }
  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 void checkPendingProcesses() {
    try {

      long now = System.currentTimeMillis();

      for (PasswordManagementProcess process : runningProcesses.values()) {

        try {
          List<PasswordManagementProcess> toRemove = new ArrayList<PasswordManagementProcess>();

          // Ignore valid assertions, they have not expired yet.
          if (!process.isRunning()
              || process.getCreationTime() - now > process.getMaxTimeToLive()) {
            toRemove.add(process);
            /// registry.unregisterToken(securityDomainName, TOKEN_TYPE, process.getId());
            if (log.isDebugEnabled())
              log.debug("[checkPendingProcesses()] Process expired : " + process.getProcessId());
          }

          for (PasswordManagementProcess passwordManagementProcess : toRemove) {
            try {
              passwordManagementProcess.stop();
            } catch (Exception e) {
              log.debug(e.getMessage(), e);
            }
            runningProcesses.remove(passwordManagementProcess.getProcessId());
          }

        } catch (Exception e) {
          log.warn(
              "Can't remove process " + e.getMessage() != null ? e.getMessage() : e.toString(), e);
        }
      }
    } catch (Exception e) {
      log.error("Cannot check pending processes! " + e.getMessage(), e);
    }
  }
  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);
    }
  }
 /**
  * @org.apache.xbean.Property alias="processes"
  *     nestedType="org.josso.selfservices.passwdmanagement.PasswordManagementProcess"
  * @param prototypeProcesses
  */
 public void setPrototypeProcesses(Collection<PasswordManagementProcess> prototypeProcesses) {
   for (PasswordManagementProcess prototype : prototypeProcesses) {
     this.prototypeProcesses.put(prototype.getName(), prototype);
   }
 }
  public ProcessRequest createRequest(String processId) throws PasswordManagementException {
    PasswordManagementProcess p = this.runningProcesses.get(processId);
    if (p == null) throw new PasswordManagementException("Invalid proces ID : " + processId);

    return p.createRequest();
  }