public void execute(ExecutionImpl execution) { Activity activity = execution.getActivity(); // evaluate the conditions and select the forking transitions List<Transition> forkingTransitions = new ArrayList<Transition>(); for (Transition transition : activity.getOutgoingTransitions()) { Condition condition = ((TransitionImpl) transition).getCondition(); if (condition == null || condition.evaluate(execution)) { forkingTransitions.add(transition); } } switch (forkingTransitions.size()) { case 0: // if no outgoing transitions should be forked, end this execution execution.end(); break; case 1: // if there is exactly one transition to be taken, just use the incoming execution execution.take(forkingTransitions.get(0)); break; default: // if there are more transitions, perform full fork ExecutionImpl concurrentRoot; if (Execution.STATE_ACTIVE_ROOT.equals(execution.getState())) { concurrentRoot = execution; execution.setState(Execution.STATE_INACTIVE_CONCURRENT_ROOT); execution.setActivity(null); } else if (Execution.STATE_ACTIVE_CONCURRENT.equals(execution.getState())) { concurrentRoot = execution.getParent(); execution.end(); } else { throw new AssertionError(execution.getState()); } Map<Transition, ExecutionImpl> concurrentExecutions = new HashMap<Transition, ExecutionImpl>(); for (Transition transition : forkingTransitions) { ExecutionImpl concurrentExecution = concurrentRoot.createExecution(transition.getName()); concurrentExecution.setActivity(activity); concurrentExecution.setState(Execution.STATE_ACTIVE_CONCURRENT); concurrentExecutions.put(transition, concurrentExecution); } for (Entry<Transition, ExecutionImpl> entry : concurrentExecutions.entrySet()) { entry.getValue().take(entry.getKey()); if (concurrentRoot.isEnded()) break; } } }