@Override
  public Oql visit(Call call) {
    final Operator op = call.operator();
    final List<Expression> args = call.arguments();

    if (op == Operators.NOT_IN || op == IterableOperators.NOT_EMPTY) {
      // geode doesn't understand syntax foo not in [1, 2, 3]
      // convert "foo not in [1, 2, 3]" into "not (foo in [1, 2, 3])"
      return visit(Expressions.not(Expressions.call(inverseOp(op), call.arguments())));
    }

    if (op == Operators.AND || op == Operators.OR) {
      Preconditions.checkArgument(!args.isEmpty(), "Size should be >=1 for %s but was %s", op, args.size());
      final String join = ") " + op.name() + " (";
      final String newOql = "(" + args.stream().map(a -> a.accept(this)).map(Oql::oql).collect(Collectors.joining(join)) + ")";
      return new Oql(variables, newOql);
    }

    if (op.arity() == Operator.Arity.BINARY) {
      return binaryOperator(call);
    }

    if (op.arity() == Operator.Arity.UNARY) {
      return unaryOperator(call);
    }

    throw new UnsupportedOperationException("Don't know how to handle " + call);
  }
@param useBindVariables wherever query should be generated with bind variables or not
criteria/geode/src/org/immutables/criteria/geode/GeodeQueryVisitor.java