private static Object binaryCall(Call call, Object left, Object right) {
      Preconditions.checkArgument(call.operator().arity() == Operator.Arity.BINARY, "Expected binary call got %s", call);
      final Operator op = call.operator();

      if (op == Operators.EQUAL || op == Operators.NOT_EQUAL) {
        final boolean equals = Objects.equals(left, right);
        return (op == Operators.EQUAL) == equals;
      }

      if (op == Operators.IN || op == Operators.NOT_IN) {
        Preconditions.checkArgument(right instanceof Iterable, "%s is not iterable", left.getClass());
        @SuppressWarnings("unchecked")
        final Iterable<Object> rightValue = (Iterable<Object>) right;
        final Stream<Object> stream = StreamSupport.stream(rightValue.spliterator(), false);
        return op == Operators.IN ? stream.anyMatch(r -> Objects.equals(left, r)) : stream.noneMatch(r -> Objects.equals(left, r));
      }

      if (op == IterableOperators.HAS_SIZE) {
        Preconditions.checkArgument(left instanceof Iterable, "%s is not iterable", left);
        Preconditions.checkArgument(right instanceof Number, "%s is not a number", left);
        final Iterable<?> iter = (Iterable<?>) left;
        final int size = ((Number) right).intValue();
        return Iterables.size(iter) == size;
      }

      if (op == IterableOperators.CONTAINS) {
        Preconditions.checkArgument(left instanceof Iterable, "%s is not iterable", left);
        return Iterables.contains((Iterable<?>) left, right);
      }

      // comparables
      if (ComparableOperators.isComparable(call.operator())) {
        Preconditions.checkArgument(left instanceof Comparable, "%s is not comparable", left);
        @SuppressWarnings("unchecked")
        final Comparable<Object> leftComparable = (Comparable<Object>) left;

        Preconditions.checkArgument(right instanceof Comparable, "%s is not comparable", right);
        @SuppressWarnings("unchecked")
        final Comparable<Object> rightComparable = (Comparable<Object>) right;

        final int compare = leftComparable.compareTo(rightComparable);

        if (op == ComparableOperators.GREATER_THAN) {
          return compare > 0;
        } else if (op == ComparableOperators.GREATER_THAN_OR_EQUAL) {
          return compare >= 0;
        } else if (op == ComparableOperators.LESS_THAN) {
          return compare < 0;
        } else if (op == ComparableOperators.LESS_THAN_OR_EQUAL) {
          return compare <= 0;
        }
      }

      if (op == StringOperators.HAS_LENGTH) {
        Preconditions.checkArgument(left instanceof CharSequence, "%s is not CharSequence", left);
        Preconditions.checkArgument(right instanceof Number, "%s is not Number", right);
        int length = ((Number) right).intValue();
        return left.toString().length() == length;
      }

      if (op == StringOperators.MATCHES) {
        Preconditions.checkArgument(left instanceof CharSequence, "%s is not string (or CharSequence)", left);
        Preconditions.checkArgument(right instanceof Pattern, "%s is not regex pattern", right);
        return ((Pattern) right).asPredicate().test(left.toString());
      }

      if (op == StringOperators.STARTS_WITH || op == StringOperators.ENDS_WITH || op == StringOperators.CONTAINS) {
        Preconditions.checkArgument(left instanceof CharSequence, "%s is not string (or CharSequence)", left);
        Preconditions.checkArgument(right instanceof CharSequence, "%s is not string (or CharSequence)", right);

        if (op == StringOperators.CONTAINS) {
          return left.toString().contains(right.toString());
        }

        return op == StringOperators.STARTS_WITH ? left.toString().startsWith(right.toString()) : left.toString().endsWith(right.toString());
      }

      throw new UnsupportedOperationException("Unsupported binary call " + call);
    }
Predicate to check that current expression with given parameter evaluates to {@code true}
criteria/inmemory/src/org/immutables/criteria/inmemory/ExpressionInterpreter.java