private String toBinaryTermExpression(Field field, TypeReference resultType, BinaryTerm binaryTerm, Function<VariableLiteral, String> variableExpressionGenerator, Tracer tracer) {
        tracer = tracer.dive("binary term instanceOf");
        Term a = binaryTerm.getA();
        Term b = binaryTerm.getB();
        String operation = binaryTerm.getOperation();
        switch (operation) {
            case "^": {
                tracer = tracer.dive(operation);
                if ((resultType != getAnyTypeReference()) && !resultType.isIntegerTypeReference() && !resultType.isFloatTypeReference()) {
                    throw new IllegalArgumentException("'A^B' expression requires numeric result type");
                }
                return tracer + "Math.pow((" + toExpression(field, resultType, a, variableExpressionGenerator) + "), (" + toExpression(field, resultType, b, variableExpressionGenerator) + "))";
            }
            case "*":
            case "/":
            case "%":
            case "+":
            case "-": {
                tracer = tracer.dive(operation);
                if ((resultType != getAnyTypeReference()) && !resultType.isIntegerTypeReference() && !resultType.isFloatTypeReference()) {
                    throw new IllegalArgumentException("'A" + operation + "B' expression requires numeric result type");
                }
                return tracer + "(" + toExpression(field, resultType, a, variableExpressionGenerator) + ") " + operation + " (" + toExpression(field, resultType, b, variableExpressionGenerator) + ")";
            }
            case ">>":
            case "<<": {
                tracer = tracer.dive(operation);
                return tracer + "(" + toExpression(field, resultType, a, variableExpressionGenerator) + ") " + operation + " (" + toExpression(field, INT_TYPE_REFERENCE, b, variableExpressionGenerator) + ")";
            }
            case ">=":
            case "<=":
            case ">":
            case "<":
            case "==":
            case "!=": {
                if ((resultType != getAnyTypeReference()) && !resultType.isBooleanTypeReference()) {
                    throw new IllegalArgumentException("'A" + operation + "B' expression requires boolean result type");
                }
                // TODO: Try to infer the types of the arguments in this case
                return tracer + "(" + toExpression(field, ANY_TYPE_REFERENCE, a, variableExpressionGenerator) + ") " + operation + " (" + toExpression(field, ANY_TYPE_REFERENCE, b, variableExpressionGenerator) + ")";
            }
            case "&&":
            case "||": {
                if ((resultType != getAnyTypeReference()) && !resultType.isBooleanTypeReference()) {
                    throw new IllegalArgumentException("'A" + operation + "B' expression requires boolean result type");
                }
                return tracer + "(" + toExpression(field, resultType, a, variableExpressionGenerator) + ") " + operation + " (" + toExpression(field, resultType, b, variableExpressionGenerator) + ")";
            }
            case "&":
            case "|": {
                throw new IllegalArgumentException("Implement this some day ...");
            }
            default: {
                throw new IllegalArgumentException("Unsupported ternary operation type " + operation);
            }
        }
    }
@param field               this generally only is needed in order to access field attributes such as encoding etc.
@param resultType          the type the resulting expression should have
@param term                the term representing the expression
@param serializerArguments any serializer arguments, which could be referenced in expressions (Needed for getting the type)
@return Java code which does the things defined in 'term'
code-generation/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageTemplateHelper.java