private Set<Status> getAllAvailableWorkflowStatuses(Issue issue) {
   log.debug("getting available workflow statuses");
   JiraWorkflow workflow = workflowManager.getWorkflow(issue);
   Set<Status> result = new HashSet<Status>();
   for (ActionDescriptor actionDescriptor : getAvailableActions(issue)) {
     log.debug("available action : " + actionDescriptor.getName());
     Set<ResultDescriptor> results = getAllResults(actionDescriptor);
     if (results.size() > 1)
       log.warn(
           "for some reason issue action : "
               + actionDescriptor.getName()
               + " for issue : "
               + issue.getKey()
               + " has more than one results");
     for (ResultDescriptor resultDescriptor : results) {
       Status status =
           workflow.getLinkedStatusObject(
               workflow.getDescriptor().getStep(resultDescriptor.getStep()));
       result.add(status);
       log.debug("linked status object : " + status.getName());
     }
   }
   log.debug("available statuses size : " + result.size());
   return result;
 }
 private Set<Integer> getNextStatusActionIds(Issue issue, Status to) {
   JiraWorkflow workflow = workflowManager.getWorkflow(issue);
   Set<Integer> result = new HashSet<Integer>();
   for (ActionDescriptor actionDescriptor : getAvailableActions(issue)) {
     Set<ResultDescriptor> results = getAllResults(actionDescriptor); // supposed to be size of 1
     for (ResultDescriptor resultDescriptor : results) {
       Status status =
           workflow.getLinkedStatusObject(
               workflow.getDescriptor().getStep(resultDescriptor.getStep()));
       if (status != null && status.equals(to)) {
         result.add(actionDescriptor.getId());
       }
     }
   }
   return result;
 }
  /**
   * Constructs and adds a {@link FunctionDescriptor} in its correct position in the list of
   * post-functions.
   *
   * @throws WorkflowException
   */
  protected void addWorkflowDescriptor() throws WorkflowException {
    FunctionDescriptor functionDescriptor =
        DescriptorFactory.getFactory().createFunctionDescriptor();
    functionDescriptor.setType("class");
    final Map functionArgs = functionDescriptor.getArgs();
    functionArgs.put("class.name", getDescriptor().getImplementationClass().getName());

    // Add parameters to the workflow function descriptor
    // Make the factory process it
    WorkflowFunctionModuleDescriptor functionModuleDescriptor =
        (WorkflowFunctionModuleDescriptor) getDescriptor();
    WorkflowPluginFunctionFactory workflowFunctionFactory =
        (WorkflowPluginFunctionFactory) functionModuleDescriptor.getModule();
    functionArgs.putAll(workflowFunctionFactory.getDescriptorParams(getDescriptorParams()));

    ResultDescriptor unconditionalResult = getTransition().getUnconditionalResult();

    if (unconditionalResult == null) {
      unconditionalResult = DescriptorFactory.getFactory().createResultDescriptor();
      getTransition().setUnconditionalResult(unconditionalResult);
    }

    final List postFunctions = unconditionalResult.getPostFunctions();

    int position = -1;

    // If the function has a weight, determine position to add the function to
    if (functionModuleDescriptor.getWeight() != null) {
      // NOTE: this code is slow - however it should not be executed too often as
      // the only functions that should have weight are the 'system' ones - and all of them should
      // be
      // added during AddWorkflowTransition stage by default. So the oly time this code should be
      // executed
      // is if a system function is not in the post functions list (e.g. workflow imported via XML)
      // and is being added.
      for (int i = 0; i < postFunctions.size(); i++) {
        // Look for the first existing post fuction with weight greater than the weight of the
        // one we already have
        FunctionDescriptor descriptor = (FunctionDescriptor) postFunctions.get(i);
        if (descriptor.getType().equals("class")
            && descriptor.getArgs().containsKey("class.name")) {
          WorkflowFunctionModuleDescriptor workflowModuleDescriptor = null;
          try {
            workflowModuleDescriptor =
                getWorkflowModuleDescriptor((String) descriptor.getArgs().get("class.name"));
            if (workflowModuleDescriptor != null) {
              final Integer weight = workflowModuleDescriptor.getWeight();
              if (weight != null) {
                if (weight.compareTo(functionModuleDescriptor.getWeight()) > 0) {
                  position = i;
                  break;
                }
              }
            }
          } catch (PluginParseException e) {
            throw new InfrastructureException(e);
          }
        }
      }

      if (position == -1) {
        // If the function has a weight but we did not find any functions with a weight larger than
        // this one
        // add the function at the end
        position = postFunctions.size();
      }
    } else {
      // Default to adding the function in the first position
      // So the user does not have to move it up before all the system (default) post-fucntions
      position = 0;
    }

    postFunctions.add(position, functionDescriptor);

    currentPostFunctionCount = "" + (position + 1);

    workflowService.updateWorkflow(getJiraServiceContext(), getWorkflow());
  }