protected void invokeVariableListeners(boolean includeCustomerListeners) {
    Queue<VariableEvent> variableEventsQueue = getVariableEventQueue();

    while (!variableEventsQueue.isEmpty()) {
      // do not remove the event yet, as otherwise new events will immediately be dispatched
      VariableEvent nextEvent = variableEventsQueue.peek();

      CmmnExecution sourceExecution = (CmmnExecution) nextEvent.getSourceScope();

      DelegateCaseVariableInstanceImpl delegateVariable =
          DelegateCaseVariableInstanceImpl.fromVariableInstance(nextEvent.getVariableInstance());
      delegateVariable.setEventName(nextEvent.getEventName());
      delegateVariable.setSourceExecution(sourceExecution);

      Map<String, List<VariableListener<?>>> listenersByActivity =
          sourceExecution
              .getActivity()
              .getVariableListeners(delegateVariable.getEventName(), includeCustomerListeners);

      CmmnExecution currentExecution = sourceExecution;
      while (currentExecution != null) {

        if (currentExecution.getActivityId() != null) {
          List<VariableListener<?>> listeners =
              listenersByActivity.get(currentExecution.getActivityId());

          if (listeners != null) {
            delegateVariable.setScopeExecution(currentExecution);

            for (VariableListener<?> listener : listeners) {
              try {
                CaseVariableListener caseVariableListener = (CaseVariableListener) listener;
                CaseVariableListenerInvocation invocation =
                    new CaseVariableListenerInvocation(
                        caseVariableListener, delegateVariable, currentExecution);
                Context.getProcessEngineConfiguration()
                    .getDelegateInterceptor()
                    .handleInvocation(invocation);
              } catch (Exception e) {
                throw LOG.invokeVariableListenerException(e);
              }
            }
          }
        }

        currentExecution = currentExecution.getParent();
      }

      // finally remove the event from the queue
      variableEventsQueue.remove();
    }
  }
 protected boolean hasVariableWithSameNameInParent(CmmnExecution execution, String variableName) {
   while (execution != null) {
     if (execution.getId().equals(getId())) {
       return false;
     }
     TypedValue variableTypedValue = execution.getVariableLocalTyped(variableName);
     if (variableTypedValue != null) {
       return true;
     }
     execution = execution.getParent();
   }
   return false;
 }