code: private void cancelProcessInstanceTree(ProcessInstance pi)
      throws Exception {
          if (pi.getStatusCode().equals(WorkStatus.STATUS_COMPLETED) ||
                  pi.getStatusCode().equals(WorkStatus.STATUS_CANCELLED)) {
              throw new ProcessException("ProcessInstance is not in a cancellable state");
          }
          List<ProcessInstance> childInstances = edao.getChildProcessInstances(pi.getId());
          for (ProcessInstance child : childInstances) {
              if (!child.getStatusCode().equals(WorkStatus.STATUS_COMPLETED)
                      && !child.getStatusCode().equals(WorkStatus.STATUS_CANCELLED)) {
                  this.cancelProcessInstanceTree(child);
              } else {
                  logger.info("Descendent ProcessInstance in not in a cancellable state. ProcessInstanceId="
                      + child.getId());
              }
          }
          this.cancelProcessInstance(pi);
      }
docs: Cancels the process instance as well as all descendant process instances.
  Deregisters associated event wait instances.