protected WorkflowFunctionModuleDescriptor getWorkflowModuleDescriptor(String className)
      throws PluginParseException {
    final Collection moduleDescriptors =
        getPluginAccessor()
            .getEnabledModuleDescriptorsByType(
                JiraWorkflowPluginConstants.MODULE_NAME_WORKFLOW_FUNCTION);

    for (Iterator iterator = moduleDescriptors.iterator(); iterator.hasNext(); ) {
      WorkflowFunctionModuleDescriptor workflowFunctionModuleDescriptor =
          (WorkflowFunctionModuleDescriptor) iterator.next();
      if (workflowFunctionModuleDescriptor.getImplementationClass().getName().equals(className)) {
        return workflowFunctionModuleDescriptor;
      }
    }

    return null;
  }
  /**
   * 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());
  }