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