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;
 }
  public static void main(String args[]) {
    try {
      DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

      // Define a bean and register it
      beanFactory.registerSingleton("args", Arrays.asList(args));
      GenericApplicationContext cmdArgCxt = new GenericApplicationContext(beanFactory);
      // Must call refresh to initialize context
      cmdArgCxt.refresh();

      String configs[] = {"/META-INF/spring/app-config.xml"};
      AbstractApplicationContext context = new ClassPathXmlApplicationContext(configs, cmdArgCxt);
      context.registerShutdownHook();
      Workflow workflow = (Workflow) context.getBean("workflow");
      System.out.println("Workflow names:");
      int i = 1;
      for (String name : workflow.getWorkflowNames()) {
        System.out.format("%02d) %s%n", i++, name);
      }

      BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

      System.out.print("User: "******"caller", username);

      String command;
      do {
        try {
          System.out.print("Enter command: ");
          command = in.readLine();

          if (command == null || "q".equals(command) || "quit".equals(command)) break;

          if ("log".equals(command)) {
            System.out.print("User: "******"caller", username);
          }
          if ("init".equals(command)) {
            System.out.print("Workflow name: ");
            String workflowName = in.readLine();

            long id = workflow.initialize(workflowName, 1, inputs);
            System.out.println("Workflow initialized with id: " + id);
          } else if ("desc".equals(command)) {
            System.out.print("Workflow ID: ");
            long id = Long.parseLong(in.readLine());

            String workflowName = workflow.getWorkflowName(id);
            WorkflowDescriptor descriptor = workflow.getWorkflowDescriptor(workflowName);

            System.out.print("Workflow state: ");
            switch (workflow.getEntryState(id)) {
              case WorkflowEntry.CREATED:
                System.out.println("CREATED");
                break;
              case WorkflowEntry.ACTIVATED:
                System.out.println("ACTIVATED");
                break;
              case WorkflowEntry.SUSPENDED:
                System.out.println("SUSPENDED");
                break;
              case WorkflowEntry.KILLED:
                System.out.println("KILLED");
                break;
              case WorkflowEntry.COMPLETED:
                System.out.println("COMPLETED");
                break;
              default:
                System.out.println("UNKNOWN");
            }

            List<Step> currentSteps = workflow.getCurrentSteps(id);
            System.out.println("Current steps:");
            int j = 0;
            for (Step step : currentSteps) {
              ++j;
              StepDescriptor stepDesc = descriptor.getStep(step.getStepId());
              System.out.println("Meta attributes:");
              System.out.format("\t%s%n", stepDesc.getMetaAttributes().toString());
              System.out.format(
                  "%02d) %s (%s - %s)%n",
                  step.getStepId(), stepDesc.getName(), step.getStatus(), step.getOwner());
            }

            int[] availableActions = workflow.getAvailableActions(id, inputs);
            System.out.println("Available actions:");
            for (j = 0; j < availableActions.length; j++) {
              ActionDescriptor action = descriptor.getAction(availableActions[j]);
              System.out.println(String.format("%02d) %s", availableActions[j], action.getName()));
            }
          } else if ("exec".equals(command)) {
            System.out.print("Workflow ID: ");
            long id = Long.parseLong(in.readLine());
            System.out.print("Action ID: ");
            int actionId = Integer.parseInt(in.readLine());

            workflow.doAction(id, actionId, inputs);
          } else if ("query".equals(command)) {
            Set<WorkflowNameAndStep> stepInfos = new LinkedHashSet<WorkflowNameAndStep>();
            stepInfos.add(new WorkflowNameAndStep(1, "example"));
            stepInfos.add(new WorkflowNameAndStep(2, "sp3-moderation"));
            List ids = workflow.getWorkflowsByNamesAndSteps(stepInfos);
            System.out.println("Found ids are: " + ids);
          }
        } catch (Exception e) {
          e.printStackTrace();
        }

        System.out.println("-------------------------------------");
      } while (true);

      System.out.println("Exiting");
    } catch (Exception e) {
      e.printStackTrace();
    }
  }