class KiePMMLPredicateFactory {

    static void setCompoundPredicateConstructor(final String generatedClassName,
                                                final String predicateName,
                                                final ConstructorDeclaration constructorDeclaration,
                                                final BOOLEAN_OPERATOR booleanOperator,
                                                final Set<String> predicatesClasses) {
        if (booleanOperator.equals(BOOLEAN_OPERATOR.SURROGATE)) {
            throw new IllegalArgumentException(SURROGATE + " not supported, yet");
        }
        setConstructorSuperNameInvocation(generatedClassName, constructorDeclaration, predicateName);
        final BlockStmt body = constructorDeclaration.getBody();
        final ExplicitConstructorInvocationStmt superStatement = CommonCodegenUtils.getExplicitConstructorInvocationStmt(body)
                .orElseThrow(() -> new KiePMMLException(String.format(MISSING_CONSTRUCTOR_IN_BODY, body)));
        CommonCodegenUtils.setExplicitConstructorInvocationArgument(superStatement, "booleanOperator", booleanOperator.getClass().getCanonicalName() + "." + booleanOperator.name());
        AssignExpr assignExpr = CommonCodegenUtils
                .getAssignExpression(body, "operatorFunction")
                .orElseThrow(() -> new KiePMMLException(String.format(MISSING_VARIABLE_IN_BODY, "operatorFunction", body)));
        CompilationUnit operatorFunctionCU = getFromFileName(KIE_PMML_OPERATOR_FUNCTION_TEMPLATE).clone();
        ClassOrInterfaceDeclaration operatorFunctionClass = operatorFunctionCU.getClassByName(KIE_PMML_OPERATOR_FUNCTION)
                .orElseThrow(() -> new KiePMMLException(MAIN_CLASS_NOT_FOUND));
        String methodName = "getInnerBinaryOperator" + booleanOperator.name();
        final MethodDeclaration methodDeclaration = CommonCodegenUtils.getMethodDeclaration(operatorFunctionClass, methodName)
                .orElseThrow(() -> new KiePMMLException(String.format(MISSING_METHOD_IN_CLASS,methodName, operatorFunctionClass)));
        final BlockStmt methodBody =  methodDeclaration.getBody()
                .orElseThrow(() -> new KiePMMLException(String.format(MISSING_BODY_IN_METHOD, methodDeclaration)));
        final ReturnStmt returnStmt = methodBody.getStatements()
                .stream()
                .filter(statement -> statement instanceof ReturnStmt)
                .map(statement -> (ReturnStmt) statement)
                .findFirst()
                .orElseThrow(() -> new KiePMMLException(String.format(MISSING_RETURN_IN_METHOD, methodDeclaration)));
        final Expression expression = returnStmt.getExpression().orElseThrow(() -> new KiePMMLException(String.format(MISSING_EXPRESSION_IN_RETURN, returnStmt)));
        assignExpr.setValue(expression);
        assignExpr = CommonCodegenUtils
                .getAssignExpression(body, "kiePMMLPredicates")
                .orElseThrow(() -> new KiePMMLException(String.format(MISSING_VARIABLE_IN_BODY, "kiePMMLPredicates", body)));
        ClassOrInterfaceType arrayClass = parseClassOrInterfaceType(ArrayList.class.getName());
        ObjectCreationExpr objectCreationExpr = new ObjectCreationExpr();
        objectCreationExpr.setType(arrayClass);
        assignExpr.setValue(objectCreationExpr);
        for (String predicateClass : predicatesClasses) {
            ClassOrInterfaceType kiePMMLPredicateClass = parseClassOrInterfaceType(predicateClass);
            objectCreationExpr = new ObjectCreationExpr();
            objectCreationExpr.setType(kiePMMLPredicateClass);
            NodeList<Expression> arguments = NodeList.nodeList(objectCreationExpr);
            MethodCallExpr methodCallExpr = new MethodCallExpr();
            methodCallExpr.setScope(assignExpr.getTarget().asNameExpr());
            methodCallExpr.setName("add");
            methodCallExpr.setArguments(arguments);
            ExpressionStmt expressionStmt = new ExpressionStmt();
            expressionStmt.setExpression(methodCallExpr);
            body.addStatement(expressionStmt);
        }
    }

    private  KiePMMLPredicateFactory();

}