/**
   * Try to execute all waiting processes. A process can be either executed, skipped or left
   * waiting, using the following rules:
   *
   * <ul>
   *   <li>If the waiting process has incoming conditional parameters and one of these parameters is
   *       not set, the process is skipped.
   *   <li>If all of the parameters of the process are ready, execute the process.
   * </ul>
   */
  private void tryToExecuteWaitingInstances() {
    final Set<OPMProcess> followingProcesses = Sets.newHashSet();

    OPMInstanceExecutor instanceExecutor;
    for (final Iterator<OPMProcessInstance> waitingInstanceIt = waitingInstances.iterator();
        waitingInstanceIt.hasNext(); ) {
      OPMProcessInstance waitingInstance = waitingInstanceIt.next();
      instanceExecutor = new OPMInstanceExecutor(waitingInstance, this);

      instanceExecutor.tryToExecuteInstance();

      if (instanceExecutor.wasNotExecuted()) {
        // do nothing
      } else if (instanceExecutor.wasSkipped()) {
        addSkippedProcess(instanceExecutor.getProcess());
        followingProcesses.addAll(calculateFollowingProcesses(instanceExecutor));
        waitingInstanceIt.remove();
      } else {
        executingInstances.add(waitingInstance);
        waitingInstanceIt.remove();
      }
    }

    putProcessesInWaitingList(followingProcesses);
  }
 private Set<OPMProcess> calculateFollowingProcesses(OPMInstanceExecutor instanceExecutor) {
   final Set<OPMProcess> followingProcesses = Sets.newHashSet();
   if (instanceExecutor.wasExecuted()) {
     for (Parameter parameter : instanceExecutor.getOutgoingParameters())
       followingProcesses.addAll(OPDAnalysis.findConnectedEventProcesses(parameter.getObject()));
     followingProcesses.addAll(OPDAnalysis.findInvocationProcesses(instanceExecutor.getProcess()));
   }
   followingProcesses.addAll(findNextProcessesToExecute(instanceExecutor.getProcess()));
   return followingProcesses;
 }
 private void waitForInstanceToFinish() {
   OPMInstanceExecutor executor = null;
   while (true) {
     try {
       executor = getResultQueue().take();
       executingInstances.remove(executor.getInstance());
       break;
     } catch (InterruptedException e) {
       if (isStopped()) {
         return;
       } else {
         logger.finest(
             "Thread interrupted while waiting for result from queue. Will continue waiting.");
       }
     }
   }
   executor.finishExecution();
   addExecutedProcess(executor.getProcess());
   putProcessesInWaitingList(calculateFollowingProcesses(executor));
 }