private static MatchedEventMap consolidate(
      MatchedEventMap beginState, ArrayList<EventBean>[] matchedEventList, int[] tagsArrayed) {
    if (tagsArrayed == null) {
      return beginState;
    }

    for (int i = 0; i < tagsArrayed.length; i++) {
      if (matchedEventList[i] == null) {
        continue;
      }
      EventBean[] eventsForTag =
          matchedEventList[i].toArray(new EventBean[matchedEventList[i].size()]);
      beginState.add(tagsArrayed[i], eventsForTag);
    }

    return beginState;
  }
  public final void evaluateTrue(
      MatchedEventMap matchEvent, EvalStateNode fromNode, boolean isQuitted) {
    if (InstrumentationHelper.ENABLED) {
      InstrumentationHelper.get()
          .qPatternMatchUntilEvaluateTrue(evalMatchUntilNode, matchEvent, fromNode == stateUntil);
    }
    boolean isMatcher = false;
    if (fromNode == stateMatcher) {
      // Add the additional tagged events to the list for later posting
      isMatcher = true;
      numMatches++;
      int[] tags = evalMatchUntilNode.getFactoryNode().getTagsArrayed();
      for (int i = 0; i < tags.length; i++) {
        Object theEvent = matchEvent.getMatchingEventAsObject(tags[i]);
        if (theEvent != null) {
          if (matchedEventArrays[i] == null) {
            matchedEventArrays[i] = new ArrayList<EventBean>();
          }
          if (theEvent instanceof EventBean) {
            matchedEventArrays[i].add((EventBean) theEvent);
          } else {
            EventBean[] arrayEvents = (EventBean[]) theEvent;
            matchedEventArrays[i].addAll(Arrays.asList(arrayEvents));
          }
        }
      }
    }

    if (isQuitted) {
      if (isMatcher) {
        stateMatcher = null;
      } else {
        stateUntil = null;
      }
    }

    // handle matcher evaluating true
    if (isMatcher) {
      if ((isTightlyBound()) && (numMatches == lowerbounds)) {
        quitInternal();
        MatchedEventMap consolidated =
            consolidate(
                matchEvent,
                matchedEventArrays,
                evalMatchUntilNode.getFactoryNode().getTagsArrayed());
        this.getParentEvaluator().evaluateTrue(consolidated, this, true);
      } else {
        // restart or keep started if not bounded, or not upper bounds, or upper bounds not reached
        boolean restart = (!isBounded()) || (upperbounds == null) || (upperbounds > numMatches);
        if (stateMatcher == null) {
          if (restart) {
            EvalNode childMatcher = evalMatchUntilNode.getChildNodeSub();
            stateMatcher = childMatcher.newState(this, null, 0L);
            stateMatcher.start(beginState);
          }
        } else {
          if (!restart) {
            stateMatcher.quit();
            stateMatcher = null;
          }
        }
      }
    } else
    // handle until-node
    {
      quitInternal();

      // consolidate multiple matched events into a single event
      MatchedEventMap consolidated =
          consolidate(
              matchEvent, matchedEventArrays, evalMatchUntilNode.getFactoryNode().getTagsArrayed());

      if ((lowerbounds != null) && (numMatches < lowerbounds)) {
        this.getParentEvaluator().evaluateFalse(this, true);
      } else {
        this.getParentEvaluator().evaluateTrue(consolidated, this, true);
      }
    }
    if (InstrumentationHelper.ENABLED) {
      InstrumentationHelper.get()
          .aPatternMatchUntilEvaluateTrue(stateMatcher == null && stateUntil == null);
    }
  }