// TODO remove this method and use the SingletonInverseVariableSupply directly
 public Object getTrailingEntity(
     GenuineVariableDescriptor chainedVariableDescriptor, Object planningValue) {
   SingletonInverseVariableSupply supply =
       variableListenerSupport.demand(
           new SingletonInverseVariableDemand(chainedVariableDescriptor));
   return supply.getInverseSingleton(planningValue);
 }
 protected AbstractScoreDirector(
     F scoreDirectorFactory, boolean constraintMatchEnabledPreference) {
   this.scoreDirectorFactory = scoreDirectorFactory;
   this.constraintMatchEnabledPreference = constraintMatchEnabledPreference;
   variableListenerSupport = new VariableListenerSupport(this);
   variableListenerSupport.linkVariableListeners();
 }
 public void assertVariableListenersDoNotAffectWorkingScore(Score expectedWorkingScore) {
   variableListenerSupport.triggerAllVariableListeners();
   Score workingScore = calculateScore();
   if (!expectedWorkingScore.equals(workingScore)) {
     throw new IllegalStateException(
         "VariableListener corruption: the expectedWorkingScore ("
             + expectedWorkingScore
             + ") is not the workingScore  ("
             + workingScore
             + ") after all VariableListeners were triggered without changes to the genuine variables.\n"
             + "A VariableListener probably changed a shadow variable,"
             + " despite that the genuine variable didn't change,"
             + " which means the shadow variable's original value is probably wrong.");
   }
 }
 public void afterProblemFactRemoved(Object problemFact) {
   variableListenerSupport.resetWorkingSolution(); // TODO do not nuke it
 }
 public void afterEntityRemoved(EntityDescriptor entityDescriptor, Object entity) {
   variableListenerSupport.afterEntityRemoved(entityDescriptor, entity);
   if (!allChangesWillBeUndoneBeforeStepEnds) {
     setWorkingEntityListDirty();
   }
 }
 public void beforeEntityRemoved(EntityDescriptor entityDescriptor, Object entity) {
   variableListenerSupport.beforeEntityRemoved(entityDescriptor, entity);
 }
 public void afterVariableChanged(VariableDescriptor variableDescriptor, Object entity) {
   variableListenerSupport.afterVariableChanged(variableDescriptor, entity);
 }
 public void beforeVariableChanged(VariableDescriptor variableDescriptor, Object entity) {
   variableListenerSupport.beforeVariableChanged(variableDescriptor, entity);
 }
 public void dispose() {
   variableListenerSupport.clearWorkingSolution();
 }
 @Override
 public void commitMove() {
   variableListenerSupport.triggerVariableListenersInNotificationQueues();
 }
 public void setWorkingSolution(Solution workingSolution) {
   this.workingSolution = workingSolution;
   variableListenerSupport.resetWorkingSolution();
   setWorkingEntityListDirty();
 }