public static ProcessDefinition createMilestoneProcessDefinition() {
    ProcessDefinition pd =
        new ProcessDefinition(
            new String[] {
              "start-state start",
              "fork fork",
              "state b",
              "milestone-node m",
              "state c",
              "state d",
              "join join",
              "end-state end"
            },
            new String[] {
              "start --> fork",
              "fork --m--> b",
              "fork --d--> d",
              "b --> m",
              "m --> c",
              "c --> join",
              "d --> join",
              "join --> end"
            });

    Node d = pd.getNode("d");

    Delegation instantiatableDelegate = new Delegation(new MilestoneEvent("m", "../m"));
    Event event = new Event(Event.EVENTTYPE_NODE_LEAVE);
    d.addEvent(event);
    event.addAction(new Action(instantiatableDelegate));

    pd.addDefinition(new ContextDefinition());

    return pd;
  }
  /**
   * marks this task as done and specifies the name of a transition leaving the task-node for the
   * case that the completion of this task instances triggers a signal on the token. If this task
   * leads to a signal on the token, the given transition name will be used in the signal. If this
   * task completion does not trigger execution to move on, the transitionName is ignored.
   */
  public void end(String transitionName) {
    Transition leavingTransition = null;

    if (task != null) {
      Node node = task.getTaskNode();
      if (node == null) {
        node = (Node) task.getParent();
      }

      if (node != null) {
        leavingTransition = node.getLeavingTransition(transitionName);
      }
    }
    if (leavingTransition == null) {
      throw new JbpmException(
          "task node does not have leaving transition '" + transitionName + "'");
    }
    end(leavingTransition);
  }
  public void readNode(Element nodeElement, Node node, NodeCollection nodeCollection) {
    super.readNode(nodeElement, node, nodeCollection);

    // only instrument states
    if (State.class.isAssignableFrom(node.getClass())) {
      String distributionName = nodeElement.attributeValue("time-distribution");
      getSimulationDefinition().addStateDistribution(node, distributionName);

      readResourceUsages(nodeElement, node);
    }
    // TODO: Later implement a resource requirement for whole TaskNode
    //       valid for all Tasks in it (but consumed only one for all Tasks
    //    else if (TaskNode.class.isAssignableFrom(node.getClass())) {
    //       readResourceUsages(nodeElement, node);
    //     }
  }