private Accumulator[] buildCustomAccumulate(
      final RuleBuildContext context,
      final AccumulateDescr accumDescr,
      MVELDialect dialect,
      Map<String, Declaration> decls,
      Map<String, Declaration> sourceOuterDeclr,
      BoundIdentifiers boundIds,
      boolean readLocalsFromTuple) {

    Accumulator[] accumulators;
    final MVELAnalysisResult initCodeAnalysis =
        (MVELAnalysisResult)
            dialect.analyzeBlock(context, accumDescr, accumDescr.getInitCode(), boundIds);

    // need to copy boundIds, as this as a "this" object.
    final MVELAnalysisResult actionCodeAnalysis =
        (MVELAnalysisResult)
            dialect.analyzeBlock(
                context,
                accumDescr.getActionCode(),
                boundIds,
                initCodeAnalysis.getMvelVariables(),
                "drools",
                KnowledgeHelper.class);

    final MVELAnalysisResult resultCodeAnalysis =
        (MVELAnalysisResult)
            dialect.analyzeExpression(
                context,
                accumDescr,
                accumDescr.getResultCode(),
                boundIds,
                initCodeAnalysis.getMvelVariables());

    context.setTypesafe(initCodeAnalysis.isTypesafe());
    MVELCompilationUnit initUnit =
        dialect.getMVELCompilationUnit(
            accumDescr.getInitCode(),
            initCodeAnalysis,
            getUsedDeclarations(decls, initCodeAnalysis),
            getUsedDeclarations(sourceOuterDeclr, initCodeAnalysis),
            initCodeAnalysis.getMvelVariables(),
            context,
            "drools",
            KnowledgeHelper.class,
            readLocalsFromTuple,
            MVELCompilationUnit.Scope.CONSTRAINT);

    context.setTypesafe(actionCodeAnalysis.isTypesafe());
    MVELCompilationUnit actionUnit =
        dialect.getMVELCompilationUnit(
            accumDescr.getActionCode(),
            actionCodeAnalysis,
            getUsedDeclarations(decls, actionCodeAnalysis),
            getUsedDeclarations(sourceOuterDeclr, actionCodeAnalysis),
            initCodeAnalysis.getMvelVariables(),
            context,
            "drools",
            KnowledgeHelper.class,
            readLocalsFromTuple,
            MVELCompilationUnit.Scope.CONSTRAINT);

    MVELCompilationUnit reverseUnit = null;
    if (accumDescr.getReverseCode() != null) {
      context.setTypesafe(actionCodeAnalysis.isTypesafe());
      reverseUnit =
          dialect.getMVELCompilationUnit(
              accumDescr.getReverseCode(),
              actionCodeAnalysis,
              getUsedDeclarations(decls, actionCodeAnalysis),
              getUsedDeclarations(sourceOuterDeclr, actionCodeAnalysis),
              initCodeAnalysis.getMvelVariables(),
              context,
              "drools",
              KnowledgeHelper.class,
              readLocalsFromTuple,
              MVELCompilationUnit.Scope.CONSTRAINT);
    }

    context.setTypesafe(resultCodeAnalysis.isTypesafe());
    MVELCompilationUnit resultUnit =
        dialect.getMVELCompilationUnit(
            accumDescr.getResultCode(),
            resultCodeAnalysis,
            getUsedDeclarations(decls, resultCodeAnalysis),
            getUsedDeclarations(sourceOuterDeclr, resultCodeAnalysis),
            initCodeAnalysis.getMvelVariables(),
            context,
            "drools",
            KnowledgeHelper.class,
            readLocalsFromTuple,
            MVELCompilationUnit.Scope.CONSTRAINT);

    accumulators =
        new Accumulator[] {new MVELAccumulator(initUnit, actionUnit, reverseUnit, resultUnit)};
    return accumulators;
  }