class OrOperator extends Operator<Boolean> {

    public static final String NAME = "op_or";

    public static final Signature SIGNATURE = Signature.scalar(
        NAME,
        DataTypes.BOOLEAN.getTypeSignature(),
        DataTypes.BOOLEAN.getTypeSignature(),
        DataTypes.BOOLEAN.getTypeSignature()
    );


    public static void register(Functions.Builder builder) {
        builder.add(SIGNATURE, OrOperator::new);
    }

    public OrOperator(Signature signature, BoundSignature boundSignature) {
        super(signature, boundSignature);
    }

    @Override
    public Symbol normalizeSymbol(Function function, TransactionContext txnCtx, NodeContext nodeCtx) {<FILL_FUNCTION_BODY>}

    @Override
    public Boolean evaluate(TransactionContext txnCtx, NodeContext nodeCtx, Input<Boolean>... args) {
        assert args != null : "args must not be null";
        assert args.length == 2 : "number of args must be 2";
        assert args[0] != null && args[1] != null : "1st and 2nd argument must not be null";

        // implement three valued logic.
        // don't touch anything unless you have a good reason for it! :)
        // http://en.wikipedia.org/wiki/Three-valued_logic
        Boolean left = args[0].value();
        Boolean right = args[1].value();

        if (left == null && right == null) {
            return null;
        }

        if (left == null) {
            return (right) ? true : null;
        }

        if (right == null) {
            return (left) ? true : null;
        }

        return left || right;
    }

    @Override
    public Query toQuery(Function function, Context context) {
        BooleanQuery.Builder query = new BooleanQuery.Builder();
        query.setMinimumNumberShouldMatch(1);
        for (Symbol symbol : function.arguments()) {
            query.add(symbol.accept(context.visitor(), context), BooleanClause.Occur.SHOULD);
        }
        return query.build();
    }
}

        assert function != null : "function must not be null";
        assert function.arguments().size() == 2 : "number of args must be 2";

        Symbol left = function.arguments().get(0);
        Symbol right = function.arguments().get(1);

        if (left.symbolType().isValueSymbol() && right.symbolType().isValueSymbol()) {
            return Literal.of(evaluate(txnCtx, nodeCtx, (Input) left, (Input) right));
        }

        /*
         * true  or x    -> true
         * false or x    -> x
         * null  or x    -> null or true -> return function as is
         */
        if (left instanceof Input) {
            Object value = ((Input) left).value();
            if (value == null) {
                return function;
            }
            assert value instanceof Boolean : "value must be Boolean";
            if ((Boolean) value) {
                return Literal.of(true);
            } else {
                return right;
            }
        }

        if (right instanceof Input) {
            Object value = ((Input) right).value();
            if (value == null) {
                return function;
            }
            assert value instanceof Boolean : "value must be Boolean";
            if ((Boolean) value) {
                return Literal.of(true);
            } else {
                return left;
            }
        }

        return function;
    
<methods>public io.crate.expression.symbol.Symbol normalizeSymbol(io.crate.expression.symbol.Function, io.crate.metadata.TransactionContext, io.crate.metadata.NodeContext) <variables>public static final java.lang.String PREFIX,public static final io.crate.types.BooleanType RETURN_TYPE