/**
   * Evaluates the condition.<br>
   * Called upon by support classes when a qualifier's key and value are known.<br>
   * Needs to be implemented by concrete subclasses.
   *
   * @param key for which a qualifier provided a value
   * @param value the value provided. Null if no value is available. NullValue if key is compared to
   *     a NullValue
   * @param selector the relationship between key and value. A qualifier operator
   * @param context the current context. May be modified by this method
   * @return true if the condition is verified
   */
  public boolean evaluate(String key, Object value, NSSelector selector, BlessingContext context) {
    BinOpStatus binOpStatus = (BinOpStatus) context.status();
    boolean firstVerified = binOpStatus.isFirstVerified();
    boolean secondVerified = binOpStatus.isSecondVerified();

    if (!firstVerified) {
      context.setStatus(binOpStatus.firstStatus());
      firstVerified = firstCondition.evaluate(key, value, selector, context);
      binOpStatus.setFirstVerified(firstVerified);
    }

    if (!secondVerified) {
      context.setStatus(binOpStatus.secondStatus());
      secondVerified = secondCondition.evaluate(key, value, selector, context);
      binOpStatus.setSecondVerified(secondVerified);
    }

    context.setStatus(binOpStatus);

    return computeResult(firstVerified, secondVerified);
  }
  /**
   * Evaluates the condition.<br>
   * Called upon by support classes when a qualifier's key and value are known.<br>
   * Needs to be implemented by concrete subclasses.
   *
   * @param key for which a qualifier provided a value
   * @param value the value provided. Null if no value is available. NullValue if key is compared to
   *     a NullValue
   * @param selector the relationship between key and value. A qualifier operator
   * @param context the current context. May be modified by this method
   * @return true if the condition is verified
   */
  public boolean evaluate(String key, Object value, NSSelector selector, BlessingContext context) {
    if (conditionKey.equals(key)) {
      BlessingStatus status = context.status();
      boolean negate = status.negate();

      if (negate) {
        return (asLessThan && asEquals && asNotEquals && asGreaterThan)
            || (asGreaterThan
                && ((selector == EOQualifier.QualifierOperatorLessThan)
                    || (selector == EOQualifier.QualifierOperatorLessThanOrEqualTo)))
            || (asNotEquals && (selector == EOQualifier.QualifierOperatorEqual)
                || (selector == EOQualifier.QualifierOperatorCaseInsensitiveLike)
                || (selector == EOQualifier.QualifierOperatorLike))
            || (asEquals && (selector == EOQualifier.QualifierOperatorNotEqual))
            || (asLessThan
                && ((selector == EOQualifier.QualifierOperatorGreaterThan)
                    || (selector == EOQualifier.QualifierOperatorGreaterThanOrEqualTo)));
      } else {
        return (asLessThan && asEquals && asNotEquals && asGreaterThan)
            || (asLessThan
                && ((selector == EOQualifier.QualifierOperatorLessThan)
                    || (selector == EOQualifier.QualifierOperatorLessThanOrEqualTo)))
            || (asEquals && (selector == EOQualifier.QualifierOperatorEqual)
                || (selector == EOQualifier.QualifierOperatorCaseInsensitiveLike)
                || (selector == EOQualifier.QualifierOperatorLike))
            || (asNotEquals && (selector == EOQualifier.QualifierOperatorNotEqual))
            || (asGreaterThan
                && ((selector == EOQualifier.QualifierOperatorGreaterThan)
                    || (selector == EOQualifier.QualifierOperatorGreaterThanOrEqualTo)));
      }
    }

    context.setErrorCause(new BlessingErrorCause(this.errorMessage, key, value, selector));

    return false;
  }