class Filter {

  public boolean matches(Row row) {
    Object leftValue = extractValue(_leftOperand, row);
    Object rightValue = extractValue(_rightOperand, row);

    if (leftValue == null && rightValue == null) {
      return (_operator == Operator.IS);
    } else if (leftValue == null || rightValue == null) {
      return (_operator == Operator.ISNOT);
    }

    // at this point both values are non-null. IS is same as EQ, and ISNOT as NE
    switch (_operator) {
      case EQ:
      case IS:
        return compareValues(leftValue, rightValue) == 0;
      case GE:
        return compareValues(leftValue, rightValue) >= 0;
      case GT:
        return compareValues(leftValue, rightValue) > 0;
      case LE:
        return compareValues(leftValue, rightValue) <= 0;
      case LT:
        return compareValues(leftValue, rightValue) < 0;
      case NE:
      case ISNOT:
        return compareValues(leftValue, rightValue) != 0;
      default:
        throw new BatfishException("Unhandled operator: " + _operator);
    }
  }

  @JsonCreator public  Filter(String filterStr);

}