public static FEEL_1_1Parser parse(FEELEventListenersManager eventsManager, String source, Map<String, Type> inputVariableTypes, Map<String, Object> inputVariables, Collection<FEELFunction> additionalFunctions, List<FEELProfile> profiles, FEELTypeRegistry typeRegistry) {
        CharStream input = CharStreams.fromString(source);
        FEEL_1_1Lexer lexer = new FEEL_1_1Lexer( input );
        CommonTokenStream tokens = new CommonTokenStream( lexer );
        FEEL_1_1Parser parser = new FEEL_1_1Parser( tokens );

        ParserHelper parserHelper = new ParserHelper(eventsManager);
        additionalFunctions.forEach(f -> parserHelper.getSymbolTable().getBuiltInScope().define(f.getSymbol()));
        parser.setHelper(parserHelper);
        parser.setErrorHandler( new FEELErrorHandler() );
        parser.removeErrorListeners(); // removes the error listener that prints to the console
        parser.addErrorListener( new FEELParserErrorListener( eventsManager ) );

        // pre-loads the parser with symbols
        defineVariables( inputVariableTypes, inputVariables, parser );
        
        if (typeRegistry != null) {
            parserHelper.setTypeRegistry(typeRegistry);
        }

        return parser;
    }
@Test
    void instanceOfExpressionAnd() {
        String inputExpression = "\"foo\" instance of string and 10 instance of number";
        BaseNode andExpr = parse( inputExpression );

        assertThat( andExpr).isInstanceOf(InfixOpNode.class);
        assertThat( andExpr.getText()).isEqualTo(inputExpression);
        assertThat( andExpr.getResultType()).isEqualTo(BuiltInType.BOOLEAN);

        InfixOpNode and = (InfixOpNode) andExpr;
        assertThat( and.getOperator()).isEqualTo(InfixOperator.AND);
        assertThat( and.getLeft()).isInstanceOf(InstanceOfNode.class);
        assertThat( and.getRight()).isInstanceOf(InstanceOfNode.class);
        assertThat( and.getLeft().getText()).isEqualTo( "\"foo\" instance of string");
        assertThat( and.getRight().getText()).isEqualTo( "10 instance of number");
        assertThat( and.getLeft().getResultType()).isEqualTo(BuiltInType.BOOLEAN);
        assertThat( and.getRight().getResultType()).isEqualTo(BuiltInType.BOOLEAN);

        InstanceOfNode ioExpr = (InstanceOfNode) and.getLeft();
        assertThat( ioExpr.getExpression()).isInstanceOf(StringNode.class);
        assertThat( ioExpr.getExpression().getText()).isEqualTo( "\"foo\"");
        assertThat( ioExpr.getType()).isInstanceOf(TypeNode.class);
        assertThat( ioExpr.getType().getText()).isEqualTo("string");

        ioExpr = (InstanceOfNode) and.getRight();
        assertThat( ioExpr.getExpression()).isInstanceOf(NumberNode.class);
        assertThat( ioExpr.getExpression().getText()).isEqualTo("10");
        assertThat( ioExpr.getType()).isInstanceOf(TypeNode.class);
        assertThat( ioExpr.getType().getText()).isEqualTo("number");
    }