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();
    }
  }
  // variable listeners
  public void dispatchEvent(VariableEvent variableEvent) {
    boolean invokeCustomListeners =
        Context.getProcessEngineConfiguration().isInvokeCustomVariableListeners();

    Map<String, List<VariableListener<?>>> listeners =
        getActivity().getVariableListeners(variableEvent.getEventName(), invokeCustomListeners);

    // only attempt to invoke listeners if there are any (as this involves resolving the upwards
    // execution hierarchy)
    if (!listeners.isEmpty()) {
      getCaseInstance().queueVariableEvent(variableEvent, invokeCustomListeners);
    }
  }
 public boolean shouldEvaluateForVariableEvent(VariableEvent event) {
   return ((variableName == null || event.getVariableInstance().getName().equals(variableName))
       && ((variableEvents == null || variableEvents.isEmpty())
           || variableEvents.contains(event.getEventName())));
 }