class DroolsConstraintStreamScoreDirectorFactory<Solution_, Score_ extends Score<Score_>>
        extends AbstractConstraintStreamScoreDirectorFactory<Solution_, Score_> {

    private final KieBaseDescriptor<Solution_> kieBaseDescriptor;
    private final boolean droolsAlphaNetworkCompilationEnabled;

    public DroolsConstraintStreamScoreDirectorFactory(SolutionDescriptor<Solution_> solutionDescriptor,
            ConstraintProvider constraintProvider, boolean droolsAlphaNetworkCompilationEnabled) {
        this(solutionDescriptor,
                buildKieBase(solutionDescriptor, constraintProvider, droolsAlphaNetworkCompilationEnabled),
                droolsAlphaNetworkCompilationEnabled);
    }

    @SuppressWarnings("unchecked")
    public DroolsConstraintStreamScoreDirectorFactory(SolutionDescriptor<Solution_> solutionDescriptor,
            KieBaseDescriptor<Solution_> kieBaseDescriptor, boolean droolsAlphaNetworkCompilationEnabled) {
        super(solutionDescriptor);
        this.kieBaseDescriptor = Objects.requireNonNull(kieBaseDescriptor);
        this.droolsAlphaNetworkCompilationEnabled = droolsAlphaNetworkCompilationEnabled;
    }

    @Override
    public DroolsConstraintStreamScoreDirector<Solution_, Score_> buildScoreDirector(boolean lookUpEnabled,
            boolean constraintMatchEnabledPreference) {
        return new DroolsConstraintStreamScoreDirector<>(this, lookUpEnabled, constraintMatchEnabledPreference);
    }

    public static <Solution_> KieBaseDescriptor<Solution_> buildKieBase(SolutionDescriptor<Solution_> solutionDescriptor,
            ConstraintProvider constraintProvider, boolean droolsAlphaNetworkCompilationEnabled) {
        List<DroolsConstraint<Solution_>> constraints = new DroolsConstraintFactory<>(solutionDescriptor)
                .buildConstraints(constraintProvider);
        // Each constraint gets its own global, in which it will keep its impacter.
        // Impacters carry constraint weights, and therefore the instances are solution-specific.
        AtomicInteger idCounter = new AtomicInteger(0);
        Map<DroolsConstraint<Solution_>, Global<WeightedScoreImpacter>> constraintToGlobalMap = constraints.stream()
                .collect(toMap(Function.identity(),
                        c -> globalOf(WeightedScoreImpacter.class, c.getConstraintPackage(),
                                "scoreImpacter" + idCounter.getAndIncrement())));
        ModelImpl model = constraints.stream()
                .map(constraint -> constraint.buildRule(constraintToGlobalMap.get(constraint)))
                .reduce(new ModelImpl(), ModelImpl::addRule, (m, key) -> m);
        constraintToGlobalMap.forEach((constraint, global) -> model.addGlobal(global));
        KieBase kieBase = buildKieBaseFromModel(model, droolsAlphaNetworkCompilationEnabled);
        return new KieBaseDescriptor<>(constraintToGlobalMap, kieBase);
    }

    private static KieBase buildKieBaseFromModel(Model model, boolean droolsAlphaNetworkCompilationEnabled) {<FILL_FUNCTION_BODY>}

    public SessionDescriptor<Score_> newSession(boolean constraintMatchEnabled, Solution_ workingSolution) {
        // Extract constraint weights.
        Map<DroolsConstraint<Solution_>, Score_> constraintToWeightMap = kieBaseDescriptor.getConstraintToGlobalMap()
                .keySet()
                .stream()
                .collect(toMap(Function.identity(), constraint -> constraint.extractConstraintWeight(workingSolution)));
        // Create the session itself.
        KieSession kieSession = buildKieSessionFromKieBase(kieBaseDescriptor.get());
        ((RuleEventManager) kieSession).addEventListener(new OptaPlannerRuleEventListener()); // Enables undo in rules.
        // Build and set the impacters for each constraint; this locks in the constraint weights.
        ScoreDefinition<Score_> scoreDefinition = solutionDescriptor.getScoreDefinition();
        AbstractScoreInliner<Score_> scoreInliner = AbstractScoreInliner.buildScoreInliner(scoreDefinition,
                constraintMatchEnabled);
        Set<String> disabledConstraints = new HashSet<>();
        for (Map.Entry<DroolsConstraint<Solution_>, Score_> entry : constraintToWeightMap.entrySet()) {
            DroolsConstraint<Solution_> constraint = entry.getKey();
            Score_ constraintWeight = entry.getValue();
            if (constraintWeight.isZero()) {
                disabledConstraints.add(constraint.getConstraintId());
            } else {
                String globalName = kieBaseDescriptor.getConstraintToGlobalMap().get(constraint).getName();
                kieSession.setGlobal(globalName, scoreInliner.buildWeightedScoreImpacter(constraint, constraintWeight));
            }
        }
        // Return only the inliner as that holds the work product of the individual impacters.
        AgendaFilter agendaFilter =
                disabledConstraints.isEmpty() ? null : new ConstraintDisablingAgendaFilter(Set.copyOf(disabledConstraints));
        return new SessionDescriptor<>(kieSession, scoreInliner, agendaFilter);
    }

    @Override
    public SolutionDescriptor<Solution_> getSolutionDescriptor() {
        return solutionDescriptor;
    }

    private static KieSession buildKieSessionFromKieBase(KieBase kieBase) {
        KieSessionConfiguration config = KieServices.get().newKieSessionConfiguration();
        config.setOption(DirectFiringOption.YES); // For performance; not applicable to DRL due to insertLogical etc.
        return kieBase.newKieSession(config, null);
    }

    @Override
    public AbstractScoreInliner<Score_> fireAndForget(Object... facts) {
        SessionDescriptor<Score_> sessionDescriptor = newSession(true, null);
        KieSession session = sessionDescriptor.getSession();
        try {
            Arrays.stream(facts).forEach(session::insert);
            session.fireAllRules();
        } finally {
            session.dispose();
        }
        return sessionDescriptor.getScoreInliner();
    }

    @Override
    public Constraint[] getConstraints() {
        return kieBaseDescriptor.getConstraintToGlobalMap()
                .keySet()
                .toArray(Constraint[]::new);
    }

    public boolean isDroolsAlphaNetworkCompilationEnabled() {
        return droolsAlphaNetworkCompilationEnabled;
    }

    private static final class ConstraintDisablingAgendaFilter implements AgendaFilter {

        private final Set<String> disabledConstraintIdSet;
        private final Map<Rule, Boolean> ruleEnabledCache = new HashMap<>();

        public ConstraintDisablingAgendaFilter(Set<String> disabledConstraintIdSet) {
            this.disabledConstraintIdSet = Objects.requireNonNull(disabledConstraintIdSet);
        }

        @Override
        public boolean accept(Match match) {
            Rule rule = match.getRule();
            return ruleEnabledCache.computeIfAbsent(rule, r -> {
                String constraintId = ConstraintMatchTotal.composeConstraintId(r.getPackageName(), r.getName());
                return !disabledConstraintIdSet.contains(constraintId);
            });
        }
    }

}

        KieBaseConfiguration kieBaseConfiguration = KieServices.get().newKieBaseConfiguration();
        kieBaseConfiguration.setOption(KieBaseMutabilityOption.DISABLED); // For performance; applicable to DRL too.
        kieBaseConfiguration.setProperty(PropertySpecificOption.PROPERTY_NAME,
                PropertySpecificOption.DISABLED.name()); // Users of CS must not rely on underlying Drools gimmicks.
        KieBase kieBase = KieBaseBuilder.createKieBaseFromModel(model, kieBaseConfiguration);
        if (droolsAlphaNetworkCompilationEnabled) {
            KieBaseUpdaterANC.generateAndSetInMemoryANC(kieBase); // Enable Alpha Network Compiler for performance.
        }
        return kieBase;
    
<methods>public transient abstract AbstractScoreInliner<Score_> fireAndForget(java.lang.Object[]) ,public abstract org.optaplanner.core.api.score.stream.Constraint[] getConstraints() <variables>