/**
   * Check if the triggering conditions have been fulfilled, meaning the state should be flushed.
   * Contract: for an encoding of: 1&2|3&4|5&6 the conditions are evaluated left-to-right, with no
   * precedence rule of AND over OR (so it's different from Java precedence rules).
   *
   * @return <code>true</code> if the triggering conditions have been fulfilled; <code>false</code>
   *     if not.
   */
  private boolean triggeringConditionsFulfilled(Collection events) {
    boolean result = true;

    Set fulfilled = new HashSet();
    for (Iterator it = events.iterator(); it.hasNext(); ) {
      AbstractEvent event = (AbstractEvent) it.next();
      fulfilled.add(event.getInstanceId());
    }

    // Now let's see how well we did
    int orInd = 0;

    for (Iterator i = orTriggerIds.keySet().iterator(); i.hasNext(); ) {
      Object orId = i.next();
      if (fulfilled.contains(orId)) {
        Integer index = (Integer) orTriggerIds.get(orId);
        if (orInd < index.intValue()) {
          orInd = index.intValue();
        }
      }
    }

    // Go through the subIds
    for (int i = orInd; (result == true) && (i < andTriggerIds.length); i++) {
      // Did not fulfill yet
      if (!fulfilled.contains(andTriggerIds[i])) {
        result = false;
      }
    }

    return result;
  }
 protected Collection evaluate(AbstractEvent event) {
   if (log.isDebugEnabled()) {
     log.debug("evaluate event: " + event);
   }
   Integer triggerId = event.getInstanceId();
   AbstractEvent previous = events.get(triggerId);
   if ((previous != null) && (previous.getTimestamp() > event.getTimestamp())) {
     // The event we are processing is older than our current state
     return null;
   }
   events.put(triggerId, event);
   return getFulfillingConditions();
 }