public void execute(ActivityExecution execution) throws Exception {

    // If there is only one incoming sequence flow, we can directly execute the fork behavior
    int nbrOfExecutionsToJoin = execution.getIncomingTransitions().size();
    if (nbrOfExecutionsToJoin == 1) {
      if (log.isLoggable(Level.FINE)) {
        log.fine(
            "Only one incoming sequence flow found for parallel gateway "
                + execution.getActivity().getId());
      }
      fork(execution);
    } else {

      Activity joinActivity = execution.getActivity();
      List<ActivityExecution> joinedExecutions = new ArrayList<ActivityExecution>();

      List<? extends ActivityExecution> concurrentExecutions =
          execution.getExecutionController().getExecutions();
      for (ActivityExecution concurrentExecution : concurrentExecutions) {
        if (concurrentExecution.getActivity().equals(joinActivity)) {
          joinedExecutions.add(concurrentExecution);
        }
      }

      int nbrOfExecutionsJoined = joinedExecutions.size();
      if (log.isLoggable(Level.FINE)) {
        log.fine(
            nbrOfExecutionsJoined
                + " of "
                + nbrOfExecutionsToJoin
                + " joined in "
                + execution.getActivity().getId());
      }

      if (nbrOfExecutionsJoined == nbrOfExecutionsToJoin) {
        ActivityExecution outgoingExecution = join(execution, joinedExecutions);
        // After all incoming executions are joined, potentially there can be multiple
        // outgoing sequence flow, requiring fork behavior.
        fork(outgoingExecution);
      } else {
        if (log.isLoggable(Level.FINE)) {
          log.fine(
              "Not all executions arrived in parallel gateway '"
                  + execution.getActivity().getId()
                  + "'");
        }
      }
    }
  }
  protected ActivityExecution join(
      ActivityExecution execution, List<ActivityExecution> joinedExecutions) {

    // Child executions must be ended before selecting the ougoing sequence flowm
    // since the children endings have an influence on the reusal of the parent execution
    for (ActivityExecution joinedExecution : joinedExecutions) {
      joinedExecution.getExecutionController().end();
    }

    // HACKHACKHACKHACKHACKHACKHACK
    CommandContext.getCurrent().getPersistenceSession().flush();
    // HACKHACKHACKHACKHACKHACKHACK

    ActivityExecution outgoingExecution = execution.getExecutionController().createExecution();
    outgoingExecution.getExecutionController().setActivity(execution.getActivity());

    return outgoingExecution;
  }