docs: public void parseEndEvents(Element parentElement, ScopeImpl scope) {
      for (Element endEventElement : parentElement.elements("endEvent")) {
        ActivityImpl activity = createActivityOnScope(endEventElement, scope);
  
        Element errorEventDefinition = endEventElement.element(ERROR_EVENT_DEFINITION);
        Element cancelEventDefinition = endEventElement.element(CANCEL_EVENT_DEFINITION);
        Element terminateEventDefinition = endEventElement.element("terminateEventDefinition");
        Element messageEventDefinitionElement = endEventElement.element(MESSAGE_EVENT_DEFINITION);
        Element signalEventDefinition = endEventElement.element(SIGNAL_EVENT_DEFINITION);
        Element compensateEventDefinitionElement = endEventElement.element(COMPENSATE_EVENT_DEFINITION);
        Element escalationEventDefinition = endEventElement.element(ESCALATION_EVENT_DEFINITION);
  
        if (errorEventDefinition != null) { // error end event
          String errorRef = errorEventDefinition.attribute("errorRef");
  
          if (errorRef == null || "".equals(errorRef)) {
            addError("'errorRef' attribute is mandatory on error end event", errorEventDefinition);
          } else {
            Error error = errors.get(errorRef);
            if (error != null && (error.getErrorCode() == null || "".equals(error.getErrorCode()))) {
              addError(
                  "'errorCode' is mandatory on errors referenced by throwing error event definitions, but the error '" + error.getId() + "' does not define one.",
                  errorEventDefinition);
            }
            activity.getProperties().set(BpmnProperties.TYPE, ActivityTypes.END_EVENT_ERROR);
            if(error != null) {
              activity.setActivityBehavior(new ErrorEndEventActivityBehavior(error.getErrorCode()));
            } else {
              activity.setActivityBehavior(new ErrorEndEventActivityBehavior(errorRef));
            }
          }
        } else if (cancelEventDefinition != null) {
          if (scope.getProperty(BpmnProperties.TYPE.getName()) == null || !scope.getProperty(BpmnProperties.TYPE.getName()).equals("transaction")) {
            addError("end event with cancelEventDefinition only supported inside transaction subprocess", cancelEventDefinition);
          } else {
            activity.getProperties().set(BpmnProperties.TYPE, ActivityTypes.END_EVENT_CANCEL);
            activity.setActivityBehavior(new CancelEndEventActivityBehavior());
            activity.setActivityStartBehavior(ActivityStartBehavior.INTERRUPT_FLOW_SCOPE);
            activity.setProperty(PROPERTYNAME_THROWS_COMPENSATION, true);
            activity.setScope(true);
          }
        } else if (terminateEventDefinition != null) {
          activity.getProperties().set(BpmnProperties.TYPE, ActivityTypes.END_EVENT_TERMINATE);
          activity.setActivityBehavior(new TerminateEndEventActivityBehavior());
          activity.setActivityStartBehavior(ActivityStartBehavior.INTERRUPT_FLOW_SCOPE);
        } else if (messageEventDefinitionElement != null) {
          if (isServiceTaskLike(messageEventDefinitionElement)) {
  
            // CAM-436 same behaviour as service task
            ActivityImpl act = parseServiceTaskLike(ActivityTypes.END_EVENT_MESSAGE, messageEventDefinitionElement, scope);
            activity.getProperties().set(BpmnProperties.TYPE, ActivityTypes.END_EVENT_MESSAGE);
            activity.setActivityBehavior(act.getActivityBehavior());
            scope.getActivities().remove(act);
          } else {
            // default to non behavior if no service task
            // properties have been specified
            activity.setActivityBehavior(new IntermediateThrowNoneEventActivityBehavior());
          }
        } else if (signalEventDefinition != null) {
          activity.getProperties().set(BpmnProperties.TYPE, ActivityTypes.END_EVENT_SIGNAL);
          EventSubscriptionDeclaration signalDefinition = parseSignalEventDefinition(signalEventDefinition, true);
          activity.setActivityBehavior(new ThrowSignalEventActivityBehavior(signalDefinition));
  
        } else if (compensateEventDefinitionElement != null) {
          activity.getProperties().set(BpmnProperties.TYPE, ActivityTypes.END_EVENT_COMPENSATION);
          CompensateEventDefinition compensateEventDefinition = parseThrowCompensateEventDefinition(compensateEventDefinitionElement, scope);
          activity.setActivityBehavior(new CompensationEventActivityBehavior(compensateEventDefinition));
          activity.setProperty(PROPERTYNAME_THROWS_COMPENSATION, true);
          activity.setScope(true);
  
        } else if(escalationEventDefinition != null) {
          activity.getProperties().set(BpmnProperties.TYPE, ActivityTypes.END_EVENT_ESCALATION);
  
          Escalation escalation = findEscalationForEscalationEventDefinition(escalationEventDefinition);
          if (escalation != null && escalation.getEscalationCode() == null) {
            addError("escalation end event must have an 'escalationCode'", escalationEventDefinition);
          }
          activity.setActivityBehavior(new ThrowEscalationEventActivityBehavior(escalation));
  
        } else { // default: none end event
          activity.getProperties().set(BpmnProperties.TYPE, ActivityTypes.END_EVENT_NONE);
          activity.setActivityBehavior(new NoneEndEventActivityBehavior());
        }
  
        if (activity != null) {
          parseActivityInputOutput(endEventElement, activity);
        }
  
        parseAsynchronousContinuationForActivity(endEventElement, activity);
  
        parseExecutionListenersOnScope(endEventElement, activity);
  
        for (BpmnParseListener parseListener : parseListeners) {
          parseListener.parseEndEvent(endEventElement, scope, activity);
        }
  
      }
    }