[jboss-svn-commits] JBL Code SVN: r19599 - in labs/jbossrules/trunk/drools-solver: drools-solver-core/src/main/java/org/drools/solver/core and 20 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Wed Apr 16 15:18:08 EDT 2008


Author: ge0ffrey
Date: 2008-04-16 15:18:08 -0400 (Wed, 16 Apr 2008)
New Revision: 19599

Added:
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/LocalSearchSolverScope.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/StepScope.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/MoveScope.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/AcceptedListBasedForager.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/AcceptedMoveScopeComparator.java
Removed:
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/SolverLifecycleListener.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/bestsolution/event/
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/TimeGradientBasedAccepter.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/Acception.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/AcceptionComparator.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/AcceptionListBasedForager.java
Modified:
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/config/localsearch/LocalSearchSolverConfig.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/Solver.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/DefaultLocalSearchSolver.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/LocalSearchSolver.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/LocalSearchSolverLifecycleListener.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/bestsolution/BestSolutionRecaller.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/Decider.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/DefaultDecider.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/AbstractAccepter.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/Accepter.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/CompositeAccepter.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/simulatedannealing/SimulatedAnnealingAccepter.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/tabu/AbstractTabuAccepter.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/tabu/MoveTabuAccepter.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/tabu/PropertyTabuAccepter.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/tabu/SolutionTabuAccepter.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/AbstractForager.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/FirstRandomlyAcceptedForager.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/Forager.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/MaxScoreOfAllForager.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/selector/AbstractSelector.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/selector/CompositeSelector.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/selector/MoveFactorySelector.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/selector/Selector.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/selector/TopListSelector.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/AbstractCompositeFinish.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/AbstractFinish.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/AndCompositeFinish.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/FeasableScoreFinish.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/Finish.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/OrCompositeFinish.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/StepCountFinish.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/TimeMillisSpendFinish.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/UnimprovedStepCountFinish.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/stepstatistic/StepStatistic.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/move/factory/AbstractMoveFactory.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/move/factory/CachedMoveFactory.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/solution/initializer/AbstractStartingSolutionInitializer.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/solution/initializer/StartingSolutionInitializer.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/test/java/org/drools/solver/core/localsearch/decider/forager/FirstRandomlyAcceptedForagerTest.java
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/test/java/org/drools/solver/core/localsearch/decider/forager/MaxScoreOfAllForagerTest.java
   labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/common/business/SolutionBusiness.java
   labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/itc2007/curriculumcourse/solver/move/factory/LectureSwitchMoveFactory.java
   labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/itc2007/curriculumcourse/solver/solution/initializer/CurriculumCourseStartingSolutionInitializer.java
   labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/itc2007/examination/solver/move/factory/ExamSwitchMoveFactory.java
   labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/itc2007/examination/solver/solution/initializer/ExaminationStartingSolutionInitializer.java
   labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/travelingtournament/solver/smart/move/factory/SmartTravelingTournamentMoveFactory.java
   labs/jbossrules/trunk/drools-solver/src/uml/design.jude
Log:
the big scope refactor

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/config/localsearch/LocalSearchSolverConfig.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/config/localsearch/LocalSearchSolverConfig.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/config/localsearch/LocalSearchSolverConfig.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -18,7 +18,6 @@
 import org.drools.solver.config.localsearch.decider.selector.SelectorConfig;
 import org.drools.solver.config.localsearch.evaluation.scorecalculator.ScoreCalculatorConfig;
 import org.drools.solver.config.localsearch.finish.FinishConfig;
-import org.drools.solver.core.evaluation.EvaluationHandler;
 import org.drools.solver.core.localsearch.DefaultLocalSearchSolver;
 import org.drools.solver.core.localsearch.LocalSearchSolver;
 import org.drools.solver.core.localsearch.bestsolution.BestSolutionRecaller;
@@ -135,7 +134,8 @@
         } else {
             localSearchSolver.setRandomSeed(0L);
         }
-        localSearchSolver.setEvaluationHandler(buildEvaluationHandler());
+        localSearchSolver.setRuleBase(buildRuleBase());
+        localSearchSolver.setScoreCalculator(scoreCalculatorConfig.buildScoreCalculator());
         localSearchSolver.setStartingSolutionInitializer(buildStartingSolutionInitializer());
         localSearchSolver.setBestSolutionRecaller(new BestSolutionRecaller());
         localSearchSolver.setFinish(finishConfig.buildFinish());
@@ -143,14 +143,6 @@
         return localSearchSolver;
     }
 
-    protected EvaluationHandler buildEvaluationHandler() {
-        EvaluationHandler evaluationHandler = new EvaluationHandler();
-        RuleBase ruleBase = buildRuleBase();
-        evaluationHandler.setRuleBase(ruleBase);
-        evaluationHandler.setScoreCalculator(scoreCalculatorConfig.buildScoreCalculator());
-        return evaluationHandler;
-    }
-
     private RuleBase buildRuleBase() {
         PackageBuilder packageBuilder = new PackageBuilder();
         for (String scoreDrl : scoreDrlList) {

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/Solver.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/Solver.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/Solver.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -1,8 +1,5 @@
 package org.drools.solver.core;
 
-import java.util.Random;
-
-import org.drools.solver.core.evaluation.EvaluationHandler;
 import org.drools.solver.core.solution.Solution;
 
 /**
@@ -10,12 +7,8 @@
  */
 public interface Solver {
 
-    void setStartingSolution(Solution solution);
+    void setStartingSolution(Solution startingSolution);
 
-    Random getRandom();
-    @Deprecated
-    EvaluationHandler getEvaluationHandler();
-
     double getBestScore();
     Solution getBestSolution();
 

Deleted: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/SolverLifecycleListener.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/SolverLifecycleListener.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/SolverLifecycleListener.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -1,12 +0,0 @@
-package org.drools.solver.core;
-
-/**
- * @author Geoffrey De Smet
- */
-public interface SolverLifecycleListener {
-
-    void solvingStarted();
-
-    void solvingEnded();
-
-}

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/DefaultLocalSearchSolver.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/DefaultLocalSearchSolver.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/DefaultLocalSearchSolver.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -2,11 +2,12 @@
 
 import java.util.Random;
 
-import org.drools.solver.core.evaluation.EvaluationHandler;
+import org.drools.RuleBase;
 import org.drools.solver.core.localsearch.bestsolution.BestSolutionRecaller;
 import org.drools.solver.core.localsearch.decider.Decider;
 import org.drools.solver.core.localsearch.finish.Finish;
 import org.drools.solver.core.move.Move;
+import org.drools.solver.core.score.calculator.ScoreCalculator;
 import org.drools.solver.core.solution.Solution;
 import org.drools.solver.core.solution.initializer.StartingSolutionInitializer;
 import org.slf4j.Logger;
@@ -21,27 +22,23 @@
 
     protected long randomSeed; // TODO refactor to AbstractSolver
 
-    protected EvaluationHandler evaluationHandler; // TODO refactor to AbstractSolver
     protected StartingSolutionInitializer startingSolutionInitializer = null; // TODO refactor to AbstractSolver
     protected BestSolutionRecaller bestSolutionRecaller;
     protected Finish finish;
     protected Decider decider;
 
-    protected long startingSystemTimeMillis;
-    protected Random random;
-    protected int stepIndex;
-    protected double stepScore;
+    protected LocalSearchSolverScope localSearchSolverScope = new LocalSearchSolverScope(); // TODO remove me
 
     public void setRandomSeed(long randomSeed) {
         this.randomSeed = randomSeed;
     }
 
-    public EvaluationHandler getEvaluationHandler() {
-        return evaluationHandler;
+    public void setRuleBase(RuleBase ruleBase) {
+        localSearchSolverScope.setRuleBase(ruleBase);
     }
 
-    public void setEvaluationHandler(EvaluationHandler evaluationHandler) {
-        this.evaluationHandler = evaluationHandler;
+    public void setScoreCalculator(ScoreCalculator scoreCalculator) {
+        localSearchSolverScope.setWorkingScoreCalculator(scoreCalculator);
     }
 
     public StartingSolutionInitializer getStartingSolutionInitializer() {
@@ -50,9 +47,6 @@
 
     public void setStartingSolutionInitializer(StartingSolutionInitializer startingSolutionInitializer) {
         this.startingSolutionInitializer = startingSolutionInitializer;
-        if (startingSolutionInitializer != null) {
-            this.startingSolutionInitializer.setSolver(this);
-        }
     }
 
     public void setBestSolutionRecaller(BestSolutionRecaller bestSolutionRecaller) {
@@ -74,46 +68,28 @@
         this.finish.setLocalSearchSolver(this);
     }
 
-
-    public long getTimeMillisSpend() {
-        long now = System.currentTimeMillis();
-        return now - startingSystemTimeMillis;
+    public void setStartingSolution(Solution startingSolution) {
+        localSearchSolverScope.setWorkingSolution(startingSolution);
     }
 
-    public Random getRandom() {
-        return random;
+    // TODO define a better API
+    public double getBestScore() {
+        return this.localSearchSolverScope.getBestScore();
     }
 
-    public int getStepIndex() {
-        return stepIndex;
-    }
-
-    public double getStepScore() {
-        return stepScore;
-    }
-
-    public void setStartingSolution(Solution solution) {
-        evaluationHandler.setSolution(solution);
-    }
-
-    public Solution getCurrentSolution() {
-        return evaluationHandler.getSolution();
-    }
-
-    public int getBestSolutionStepIndex() {
-        return bestSolutionRecaller.getBestSolutionStepIndex();
-    }
-
+    // TODO define a better API
     public Solution getBestSolution() {
-        return bestSolutionRecaller.getBestSolution();
+        return this.localSearchSolverScope.getBestSolution();
     }
 
-    public double getBestScore() {
-        return bestSolutionRecaller.getBestScore();
+    // TODO define a better API
+    public long getTimeMillisSpend() {
+        return this.localSearchSolverScope.calculateTimeMillisSpend();
     }
 
-    public double calculateTimeGradient() {
-        return finish.calculateTimeGradient();
+    // TODO define a better API
+    public LocalSearchSolverScope getLocalSearchSolverScope() {
+        return localSearchSolverScope;
     }
 
     // ************************************************************************
@@ -121,70 +97,93 @@
     // ************************************************************************
 
     public void solve() {
-        solvingStarted();
-        while (!finish.isFinished()) {
-            beforeDeciding();
-            Move nextStep = decider.decideNextStep();
+        LocalSearchSolverScope localSearchSolverScope = this.localSearchSolverScope;
+        solvingStarted(localSearchSolverScope);
+
+        StepScope stepScope = createNextStepScope(localSearchSolverScope, null);
+        while (!finish.isFinished(stepScope)) {
+            stepScope.setTimeGradient(finish.calculateTimeGradient(stepScope));
+            beforeDeciding(stepScope);
+            decider.decideNextStep(stepScope);
+            Move nextStep = stepScope.getStep();
             if (nextStep == null) {
-                logger.warn("No move accepted for step ({}) out of {} accepted moves. Finishing early.",
-                        getStepIndex(), decider.getForager().getAcceptedMovesSize());
+                logger.warn("No move accepted for step index ({}) out of {} accepted moves. Finishing early.",
+                        stepScope.getStepIndex(), decider.getForager().getAcceptedMovesSize());
                 break;
             }
             logger.info("Step index ({}), time spend ({}) taking step ({}) out of {} accepted moves.",
-                    new Object[]{getStepIndex(), getTimeMillisSpend(), nextStep,
-                            decider.getForager().getAcceptedMovesSize()});
-            stepDecided(nextStep);
-            nextStep.doMove(evaluationHandler.getStatefulSession());
-            stepScore = evaluationHandler.fireAllRulesAndCalculateStepScore();
-            stepIndex++;
-            stepTaken();
+                    new Object[]{stepScope.getStepIndex(), localSearchSolverScope.calculateTimeMillisSpend(),
+                            nextStep, decider.getForager().getAcceptedMovesSize()});
+            stepDecided(stepScope);
+            nextStep.doMove(stepScope.getWorkingMemory());
+//            stepIndex++; // TODO influences
+            stepTaken(stepScope);
+            stepScope = createNextStepScope(localSearchSolverScope, stepScope);
         }
-        solvingEnded();
+        solvingEnded(localSearchSolverScope);
     }
 
-    public void solvingStarted() {
-        startingSystemTimeMillis = System.currentTimeMillis();
+    private StepScope createNextStepScope(LocalSearchSolverScope localSearchSolverScope, StepScope completedStepScope) {
+        if (completedStepScope == null) {
+            completedStepScope = new StepScope(localSearchSolverScope);
+            completedStepScope.setScore(localSearchSolverScope.getStartingScore());
+            completedStepScope.setStepIndex(-1);
+            completedStepScope.setTimeGradient(0.0);
+        }
+        localSearchSolverScope.setLastCompletedStepScope(completedStepScope);
+        StepScope stepScope = new StepScope(localSearchSolverScope);
+        stepScope.setStepIndex(completedStepScope.getStepIndex() + 1);
+        return stepScope;
+    }
+
+    @Override
+    public void solvingStarted(LocalSearchSolverScope localSearchSolverScope) {
+        localSearchSolverScope.resetTimeMillisSpend();
         logger.info("Solving with random seed ({}).", randomSeed);
-        random = new Random(randomSeed);
+        localSearchSolverScope.setWorkingRandom(new Random(randomSeed));
         if (startingSolutionInitializer != null) {
-            Solution solution = evaluationHandler.getSolution();
-            if (!startingSolutionInitializer.isSolutionInitialized(solution)) {
+            if (!startingSolutionInitializer.isSolutionInitialized(localSearchSolverScope)) {
                 logger.info("Initializing solution.");
-                startingSolutionInitializer.initializeSolution(solution);
+                startingSolutionInitializer.initializeSolution(localSearchSolverScope);
             } else {
                 logger.debug("Solution is already initialized.");
             }
         }
-        stepIndex = 0;
-        stepScore = evaluationHandler.fireAllRulesAndCalculateStepScore();
-        bestSolutionRecaller.solvingStarted();
-        finish.solvingStarted();
-        decider.solvingStarted();
+        localSearchSolverScope.setStartingScore(localSearchSolverScope.calculateScoreFromWorkingMemory());
+        bestSolutionRecaller.solvingStarted(localSearchSolverScope);
+        finish.solvingStarted(localSearchSolverScope);
+        decider.solvingStarted(localSearchSolverScope);
     }
 
-    public void beforeDeciding() {
-        bestSolutionRecaller.beforeDeciding();
-        finish.beforeDeciding();
-        decider.beforeDeciding();
+    @Override
+    public void beforeDeciding(StepScope stepScope) {
+        bestSolutionRecaller.beforeDeciding(stepScope);
+        finish.beforeDeciding(stepScope);
+        decider.beforeDeciding(stepScope);
     }
 
-    public void stepDecided(Move step) {
-        bestSolutionRecaller.stepDecided(step);
-        finish.stepDecided(step);
-        decider.stepDecided(step);
+    @Override
+    public void stepDecided(StepScope stepScope) {
+        bestSolutionRecaller.stepDecided(stepScope);
+        finish.stepDecided(stepScope);
+        decider.stepDecided(stepScope);
     }
 
-    public void stepTaken() {
-        bestSolutionRecaller.stepTaken();
-        finish.stepTaken();
-        decider.stepTaken();
+    @Override
+    public void stepTaken(StepScope stepScope) {
+        bestSolutionRecaller.stepTaken(stepScope);
+        finish.stepTaken(stepScope);
+        decider.stepTaken(stepScope);
     }
 
-    public void solvingEnded() {
-        bestSolutionRecaller.solvingEnded();
-        finish.solvingEnded();
-        decider.solvingEnded();
-        logger.info("Solved in {} steps and {} time millis spend.", stepIndex, getTimeMillisSpend());
+    @Override
+    public void solvingEnded(LocalSearchSolverScope localSearchSolverScope) {
+        bestSolutionRecaller.solvingEnded(localSearchSolverScope);
+        finish.solvingEnded(localSearchSolverScope);
+        decider.solvingEnded(localSearchSolverScope);
+        logger.info("Solved in {} steps and {} time millis spend.",
+                localSearchSolverScope.getLastCompletedStepScope().getStepIndex(),
+                localSearchSolverScope.calculateTimeMillisSpend());
     }
 
 }

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/LocalSearchSolver.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/LocalSearchSolver.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/LocalSearchSolver.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -1,34 +1,10 @@
 package org.drools.solver.core.localsearch;
 
 import org.drools.solver.core.Solver;
-import org.drools.solver.core.localsearch.decider.Decider;
-import org.drools.solver.core.solution.Solution;
 
 /**
  * @author Geoffrey De Smet
  */
 public interface LocalSearchSolver extends Solver {
 
-    /**
-     * @return the number of steps already taken.
-     */
-    int getStepIndex();
-
-    /**
-     * @return the score of the last taken step.
-     */
-    double getStepScore();
-
-    /**
-     * @return the solution as it currently is - which might be temperarly modified
-     * by a selected move which is being decided upon.
-     */
-    Solution getCurrentSolution();
-
-    int getBestSolutionStepIndex();
-
-    double calculateTimeGradient();
-
-    Decider getDecider();
-
 }

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/LocalSearchSolverLifecycleListener.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/LocalSearchSolverLifecycleListener.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/LocalSearchSolverLifecycleListener.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -1,17 +1,18 @@
 package org.drools.solver.core.localsearch;
 
-import org.drools.solver.core.SolverLifecycleListener;
-import org.drools.solver.core.move.Move;
-
 /**
  * @author Geoffrey De Smet
  */
-public interface LocalSearchSolverLifecycleListener extends SolverLifecycleListener {
+public interface LocalSearchSolverLifecycleListener {
 
-    void beforeDeciding();
+    void solvingStarted(LocalSearchSolverScope localSearchSolverScope);
 
-    void stepDecided(Move step);
+    void beforeDeciding(StepScope stepScope);
 
-    void stepTaken();
+    void stepDecided(StepScope stepScope);
 
+    void stepTaken(StepScope stepScope);
+
+    void solvingEnded(LocalSearchSolverScope localSearchSolverScope);
+
 }

Added: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/LocalSearchSolverScope.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/LocalSearchSolverScope.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/LocalSearchSolverScope.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -0,0 +1,148 @@
+package org.drools.solver.core.localsearch;
+
+import java.util.Random;
+
+import org.drools.RuleBase;
+import org.drools.StatefulSession;
+import org.drools.WorkingMemory;
+import org.drools.solver.core.score.calculator.ScoreCalculator;
+import org.drools.solver.core.solution.Solution;
+
+/**
+ * @author Geoffrey De Smet
+ */
+public class LocalSearchSolverScope {
+
+    public static final String GLOBAL_SCORE_CALCULATOR_KEY = "scoreCalculator";
+
+    protected RuleBase ruleBase;
+
+    private long startingSystemTimeMillis;
+
+    private Solution workingSolution;
+    private StatefulSession workingMemory;
+    private ScoreCalculator workingScoreCalculator;
+    private Random workingRandom;
+
+    private double startingScore;
+
+    private int bestSolutionStepIndex;
+    private Solution bestSolution;
+    private double bestScore;
+
+    private StepScope lastCompletedStepScope;
+
+    public void setRuleBase(RuleBase ruleBase) {
+        this.ruleBase = ruleBase;
+    }
+
+    public long getStartingSystemTimeMillis() {
+        return startingSystemTimeMillis;
+    }
+
+    public void setStartingSystemTimeMillis(long startingSystemTimeMillis) {
+        this.startingSystemTimeMillis = startingSystemTimeMillis;
+    }
+
+    public Solution getWorkingSolution() {
+        return workingSolution;
+    }
+
+    public void setWorkingSolution(Solution workingSolution) {
+        this.workingSolution = workingSolution;
+        resetWorkingMemory();
+    }
+
+    public WorkingMemory getWorkingMemory() {
+        return workingMemory;
+    }
+
+    public ScoreCalculator getWorkingScoreCalculator() {
+        return workingScoreCalculator;
+    }
+
+    public void setWorkingScoreCalculator(ScoreCalculator workingScoreCalculator) {
+        this.workingScoreCalculator = workingScoreCalculator;
+    }
+
+    public Random getWorkingRandom() {
+        return workingRandom;
+    }
+
+    public void setWorkingRandom(Random workingRandom) {
+        this.workingRandom = workingRandom;
+    }
+
+    public double getStartingScore() {
+        return startingScore;
+    }
+
+    public void setStartingScore(double startingScore) {
+        this.startingScore = startingScore;
+    }
+
+    public int getBestSolutionStepIndex() {
+        return bestSolutionStepIndex;
+    }
+
+    public void setBestSolutionStepIndex(int bestSolutionStepIndex) {
+        this.bestSolutionStepIndex = bestSolutionStepIndex;
+    }
+
+    public Solution getBestSolution() {
+        return bestSolution;
+    }
+
+    public void setBestSolution(Solution bestSolution) {
+        this.bestSolution = bestSolution;
+    }
+
+    public double getBestScore() {
+        return bestScore;
+    }
+
+    public void setBestScore(double bestScore) {
+        this.bestScore = bestScore;
+    }
+
+    public StepScope getLastCompletedStepScope() {
+        return lastCompletedStepScope;
+    }
+
+    public void setLastCompletedStepScope(StepScope lastCompletedStepScope) {
+        this.lastCompletedStepScope = lastCompletedStepScope;
+    }
+
+    // ************************************************************************
+    // Calculated methods
+    // ************************************************************************
+
+    public double calculateScoreFromWorkingMemory() {
+        workingMemory.fireAllRules();
+        return workingScoreCalculator.calculateStepScore();
+    }
+
+    public void resetTimeMillisSpend() {
+        startingSystemTimeMillis = System.currentTimeMillis();
+    }
+
+    public long calculateTimeMillisSpend() {
+        long now = System.currentTimeMillis();
+        return now - startingSystemTimeMillis;
+    }
+
+    private void resetWorkingMemory() {
+        if (workingMemory != null) {
+            workingMemory.dispose();
+        }
+        workingMemory = ruleBase.newStatefulSession();
+        workingMemory.setGlobal(GLOBAL_SCORE_CALCULATOR_KEY, workingScoreCalculator);
+//        if (logger.isTraceEnabled()) {
+//            statefulSession.addEventListener(new DebugWorkingMemoryEventListener());
+//        }
+        for (Object fact : workingSolution.getFacts()) {
+            workingMemory.insert(fact);
+        }
+    }
+
+}

Added: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/StepScope.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/StepScope.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/StepScope.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -0,0 +1,92 @@
+package org.drools.solver.core.localsearch;
+
+import java.util.Random;
+
+import org.drools.WorkingMemory;
+import org.drools.solver.core.move.Move;
+import org.drools.solver.core.solution.Solution;
+
+/**
+ * @author Geoffrey De Smet
+ */
+public class StepScope {
+
+    private final LocalSearchSolverScope localSearchSolverScope;
+
+    private int stepIndex = -1;
+    private double timeGradient = Double.NaN;
+    private Move step = null;
+    private double score = Double.NaN;
+    private Solution clonedSolution = null;
+
+    public StepScope(LocalSearchSolverScope localSearchSolverScope) {
+        this.localSearchSolverScope = localSearchSolverScope;
+    }
+
+    public LocalSearchSolverScope getLocalSearchSolverScope() {
+        return localSearchSolverScope;
+    }
+
+    public int getStepIndex() {
+        return stepIndex;
+    }
+
+    public void setStepIndex(int stepIndex) {
+        this.stepIndex = stepIndex;
+    }
+
+    public double getTimeGradient() {
+        return timeGradient;
+    }
+
+    public void setTimeGradient(double timeGradient) {
+        this.timeGradient = timeGradient;
+    }
+
+    public Move getStep() {
+        return step;
+    }
+
+    public void setStep(Move step) {
+        this.step = step;
+    }
+
+    public double getScore() {
+        return score;
+    }
+
+    public void setScore(double score) {
+        this.score = score;
+    }
+
+    public Solution getClonedSolution() {
+        return clonedSolution;
+    }
+
+    public void setClonedSolution(Solution clonedSolution) {
+        this.clonedSolution = clonedSolution;
+    }
+    // ************************************************************************
+    // Calculated methods
+    // ************************************************************************
+
+    public Solution getWorkingSolution() {
+        return localSearchSolverScope.getWorkingSolution();
+    }
+
+    public WorkingMemory getWorkingMemory() {
+        return localSearchSolverScope.getWorkingMemory();
+    }
+
+    public Random getWorkingRandom() {
+        return localSearchSolverScope.getWorkingRandom();
+    }
+
+    public Solution createOrGetClonedSolution() {
+        if (clonedSolution == null) {
+            clonedSolution = getWorkingSolution().cloneSolution();
+        }
+        return clonedSolution;
+    }
+
+}

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/bestsolution/BestSolutionRecaller.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/bestsolution/BestSolutionRecaller.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/bestsolution/BestSolutionRecaller.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -3,8 +3,8 @@
 import org.drools.solver.core.localsearch.LocalSearchSolver;
 import org.drools.solver.core.localsearch.LocalSearchSolverAware;
 import org.drools.solver.core.localsearch.LocalSearchSolverLifecycleListener;
-import org.drools.solver.core.move.Move;
-import org.drools.solver.core.solution.Solution;
+import org.drools.solver.core.localsearch.LocalSearchSolverScope;
+import org.drools.solver.core.localsearch.StepScope;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -17,59 +17,49 @@
 
     protected LocalSearchSolver localSearchSolver;
 
-    private int bestSolutionStepIndex;
-    private Solution bestSolution;
-    private double bestScore;
-
     public void setLocalSearchSolver(LocalSearchSolver localSearchSolver) {
         this.localSearchSolver = localSearchSolver;
     }
 
-    public int getBestSolutionStepIndex() {
-        return bestSolutionStepIndex;
-    }
-
-    public Solution getBestSolution() {
-        return bestSolution;
-    }
-
-    public double getBestScore() {
-        return bestScore;
-    }
-
     // ************************************************************************
     // Worker methods
     // ************************************************************************
 
-    public void solvingStarted() {
-        double initialScore = localSearchSolver.getStepScore();
+    @Override
+    public void solvingStarted(LocalSearchSolverScope localSearchSolverScope) {
+        double initialScore = localSearchSolverScope.getStartingScore();
         logger.info("Initial score ({}) is starting best score. Updating best solution and best score.", initialScore);
-        bestSolutionStepIndex = localSearchSolver.getStepIndex();
-        bestSolution = localSearchSolver.getCurrentSolution().cloneSolution();
-        bestScore = initialScore;
+        localSearchSolverScope.setBestSolutionStepIndex(-1);
+        localSearchSolverScope.setBestSolution(localSearchSolverScope.getWorkingSolution().cloneSolution());
+        localSearchSolverScope.setBestScore(initialScore);
     }
 
-    public void beforeDeciding() {
+    @Override
+    public void beforeDeciding(StepScope stepScope) {
     }
 
-    public void stepDecided(Move step) {
+    @Override
+    public void stepDecided(StepScope stepScope) {
     }
 
-    public void stepTaken() {
-        double newScore = localSearchSolver.getStepScore();
+    @Override
+    public void stepTaken(StepScope stepScope) {
+        LocalSearchSolverScope localSearchSolverScope = stepScope.getLocalSearchSolverScope();
+        double newScore = stepScope.getScore();
+        double bestScore = localSearchSolverScope.getBestScore();
         if (newScore > bestScore) {
             logger.info("New score ({}) is better then last best score ({}). Updating best solution and best score.",
                     newScore, bestScore);
-            bestSolutionStepIndex = localSearchSolver.getStepIndex();
-            bestSolution = localSearchSolver.getCurrentSolution().cloneSolution();
-            bestScore = newScore;
-            // TODO BestSolutionChangedEvent
+            localSearchSolverScope.setBestSolutionStepIndex(stepScope.getStepIndex());
+            localSearchSolverScope.setBestSolution(stepScope.createOrGetClonedSolution());
+            localSearchSolverScope.setBestScore(stepScope.getScore());
         } else {
             logger.info("New score ({}) is not better then last best score ({}).", newScore, bestScore);
         }
     }
 
-    public void solvingEnded() {
+    @Override
+    public void solvingEnded(LocalSearchSolverScope localSearchSolverScope) {
     }
 
 }

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/Decider.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/Decider.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/Decider.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -2,15 +2,15 @@
 
 import org.drools.solver.core.localsearch.LocalSearchSolverAware;
 import org.drools.solver.core.localsearch.LocalSearchSolverLifecycleListener;
+import org.drools.solver.core.localsearch.StepScope;
 import org.drools.solver.core.localsearch.decider.forager.Forager;
-import org.drools.solver.core.move.Move;
 
 /**
  * @author Geoffrey De Smet
  */
 public interface Decider extends LocalSearchSolverAware, LocalSearchSolverLifecycleListener {
 
-    Move decideNextStep();
+    void decideNextStep(StepScope stepScope);
 
     Forager getForager();
 

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/DefaultDecider.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/DefaultDecider.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/DefaultDecider.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -3,8 +3,9 @@
 import java.util.List;
 
 import org.drools.WorkingMemory;
-import org.drools.solver.core.evaluation.EvaluationHandler;
 import org.drools.solver.core.localsearch.LocalSearchSolver;
+import org.drools.solver.core.localsearch.LocalSearchSolverScope;
+import org.drools.solver.core.localsearch.StepScope;
 import org.drools.solver.core.localsearch.decider.accepter.Accepter;
 import org.drools.solver.core.localsearch.decider.forager.Forager;
 import org.drools.solver.core.localsearch.decider.selector.Selector;
@@ -58,79 +59,90 @@
     // Worker methods
     // ************************************************************************
 
-    public void solvingStarted() {
-        selector.solvingStarted();
-        accepter.solvingStarted();
-        forager.solvingStarted();
+    @Override
+    public void solvingStarted(LocalSearchSolverScope localSearchSolverScope) {
+        selector.solvingStarted(localSearchSolverScope);
+        accepter.solvingStarted(localSearchSolverScope);
+        forager.solvingStarted(localSearchSolverScope);
     }
 
-    public void beforeDeciding() {
-        selector.beforeDeciding();
-        accepter.beforeDeciding();
-        forager.beforeDeciding();
+    @Override
+    public void beforeDeciding(StepScope stepScope) {
+        selector.beforeDeciding(stepScope);
+        accepter.beforeDeciding(stepScope);
+        forager.beforeDeciding(stepScope);
     }
 
-    public Move decideNextStep() {
-        WorkingMemory workingMemory = localSearchSolver.getEvaluationHandler().getStatefulSession();
-        List<Move> moveList = selector.selectMoveList();
+    public void decideNextStep(StepScope stepScope) {
+        WorkingMemory workingMemory = stepScope.getWorkingMemory();
+        List<Move> moveList = selector.selectMoveList(stepScope);
         for (Move move : moveList) {
+            MoveScope moveScope = new MoveScope(stepScope);
+            moveScope.setMove(move);
             // Filter out not doable moves
             if (move.isMoveDoable(workingMemory)) {
-                doMove(move);
+                doMove(moveScope);
+                if (forager.isQuitEarly()) {
+                    break;
+                }
             } else {
-                logger.debug("    Move ({}) ignored because not doable.", move);
+                logger.debug("    Move ({}) ignored because it is not doable.", move);
             }
-            if (forager.isQuitEarly()) {
-                break;
-            }
         }
-        return forager.pickMove();
+        MoveScope pickedMoveScope = forager.pickMove(stepScope);
+        if (pickedMoveScope != null) {
+            stepScope.setStep(pickedMoveScope.getMove());
+            stepScope.setScore(pickedMoveScope.getScore());
+        }
     }
 
-    private void doMove(Move move) {
-        WorkingMemory workingMemory = localSearchSolver.getEvaluationHandler().getStatefulSession();
+    private void doMove(MoveScope moveScope) {
+        WorkingMemory workingMemory = moveScope.getWorkingMemory();
+        Move move = moveScope.getMove();
         Move undoMove = move.createUndoMove(workingMemory);
+        moveScope.setUndoMove(undoMove);
         move.doMove(workingMemory);
-        processMove(move);
+        processMove(moveScope);
         undoMove.doMove(workingMemory);
         if (verifyUndoMoveIsUncorrupted) {
-            double undoScore = localSearchSolver.getEvaluationHandler().fireAllRulesAndCalculateDecisionScore();
-            if (undoScore != localSearchSolver.getStepScore()) {
+            double undoScore = moveScope.getStepScope().getLocalSearchSolverScope().calculateScoreFromWorkingMemory();
+            if (undoScore != moveScope.getStepScope().getLocalSearchSolverScope()
+                    .getLastCompletedStepScope().getScore()) {
                 throw new IllegalStateException(
                         "Corrupted undo move (" + undoMove + ") received from move (" + move + ").");
             }
         }
+        logger.debug("    Move ({}) with score ({}) and acceptChance ({}).",
+                new Object[]{moveScope.getMove(), moveScope.getScore(), moveScope.getAcceptChance()});
     }
 
-    private void processMove(Move move) {
-        EvaluationHandler evaluationHandler = localSearchSolver.getEvaluationHandler();
-        double score = evaluationHandler.fireAllRulesAndCalculateDecisionScore();
-        double acceptChance = accepter.calculateAcceptChance(move, score);
-        // TODO the move's toString() is ussually wrong because doMove has already been called
-        logger.debug("    Move ({}) with score ({}) and acceptChance ({}).", new Object[]{move, score, acceptChance});
-        forager.addMove(move, score, acceptChance);
+    private void processMove(MoveScope moveScope) {
+        double score = moveScope.getStepScope().getLocalSearchSolverScope().calculateScoreFromWorkingMemory();
+        moveScope.setScore(score);
+        double acceptChance = accepter.calculateAcceptChance(moveScope);
+        moveScope.setAcceptChance(acceptChance);
+        forager.addMove(moveScope);
     }
 
-    public int getAcceptedMovesSize() {
-        return forager.getAcceptedMovesSize();
+    @Override
+    public void stepDecided(StepScope stepScope) {
+        selector.stepDecided(stepScope);
+        accepter.stepDecided(stepScope);
+        forager.stepDecided(stepScope);
     }
 
-    public void stepDecided(Move step) {
-        selector.stepDecided(step);
-        accepter.stepDecided(step);
-        forager.stepDecided(step);
+    @Override
+    public void stepTaken(StepScope stepScope) {
+        selector.stepTaken(stepScope);
+        accepter.stepTaken(stepScope);
+        forager.stepTaken(stepScope);
     }
 
-    public void stepTaken() {
-        selector.stepTaken();
-        accepter.stepTaken();
-        forager.stepTaken();
+    @Override
+    public void solvingEnded(LocalSearchSolverScope localSearchSolverScope) {
+        selector.solvingEnded(localSearchSolverScope);
+        accepter.solvingEnded(localSearchSolverScope);
+        forager.solvingEnded(localSearchSolverScope);
     }
 
-    public void solvingEnded() {
-        selector.solvingEnded();
-        accepter.solvingEnded();
-        forager.solvingEnded();
-    }
-
 }

Added: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/MoveScope.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/MoveScope.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/MoveScope.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -0,0 +1,86 @@
+package org.drools.solver.core.localsearch.decider;
+
+import java.util.Random;
+
+import org.drools.WorkingMemory;
+import org.drools.solver.core.localsearch.StepScope;
+import org.drools.solver.core.move.Move;
+import org.drools.solver.core.solution.Solution;
+
+/**
+ * @author Geoffrey De Smet
+ */
+public class MoveScope {
+
+    private final StepScope stepScope;
+    private Move move = null;
+    private Move undoMove = null;
+    private double acceptChance = Double.NaN;
+    private double score = Double.NEGATIVE_INFINITY;
+    private double decisionScore = Double.NaN;
+
+    public MoveScope(StepScope stepScope) {
+        this.stepScope = stepScope;
+    }
+
+    public StepScope getStepScope() {
+        return stepScope;
+    }
+
+    public Move getMove() {
+        return move;
+    }
+
+    public void setMove(Move move) {
+        this.move = move;
+    }
+
+    public Move getUndoMove() {
+        return undoMove;
+    }
+
+    public void setUndoMove(Move undoMove) {
+        this.undoMove = undoMove;
+    }
+
+    public double getAcceptChance() {
+        return acceptChance;
+    }
+
+    public void setAcceptChance(double acceptChance) {
+        this.acceptChance = acceptChance;
+    }
+
+    public double getScore() {
+        return score;
+    }
+
+    public void setScore(double score) {
+        this.score = score;
+    }
+
+    public double getDecisionScore() {
+        return decisionScore;
+    }
+
+    public void setDecisionScore(double decisionScore) {
+        this.decisionScore = decisionScore;
+    }
+
+    // ************************************************************************
+    // Calculated methods
+    // ************************************************************************
+
+    public Solution getWorkingSolution() {
+        return stepScope.getWorkingSolution();
+    }
+
+    public WorkingMemory getWorkingMemory() {
+        return stepScope.getWorkingMemory();
+    }
+
+    public Random getWorkingRandom() {
+        return stepScope.getWorkingRandom();
+    }
+
+}

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/AbstractAccepter.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/AbstractAccepter.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/AbstractAccepter.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -1,7 +1,8 @@
 package org.drools.solver.core.localsearch.decider.accepter;
 
 import org.drools.solver.core.localsearch.LocalSearchSolver;
-import org.drools.solver.core.move.Move;
+import org.drools.solver.core.localsearch.LocalSearchSolverScope;
+import org.drools.solver.core.localsearch.StepScope;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -14,6 +15,7 @@
 
     protected LocalSearchSolver localSearchSolver;
 
+    @Override
     public void setLocalSearchSolver(LocalSearchSolver localSearchSolver) {
         this.localSearchSolver = localSearchSolver;
     }
@@ -22,23 +24,28 @@
     // Worker methods
     // ************************************************************************
 
-    public void solvingStarted() {
+    @Override
+    public void solvingStarted(LocalSearchSolverScope localSearchSolverScope) {
         // Hook which can be optionally overwritten by subclasses.
     }
 
-    public void beforeDeciding() {
+    @Override
+    public void beforeDeciding(StepScope stepScope) {
         // Hook which can be optionally overwritten by subclasses.
     }
 
-    public void stepDecided(Move step) {
+    @Override
+    public void stepDecided(StepScope stepScope) {
         // Hook which can be optionally overwritten by subclasses.
     }
 
-    public void stepTaken() {
+    @Override
+    public void stepTaken(StepScope stepScope) {
         // Hook which can be optionally overwritten by subclasses.
     }
 
-    public void solvingEnded() {
+    @Override
+    public void solvingEnded(LocalSearchSolverScope localSearchSolverScope) {
         // Hook which can be optionally overwritten by subclasses.
     }
 

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/Accepter.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/Accepter.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/Accepter.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -2,13 +2,20 @@
 
 import org.drools.solver.core.localsearch.LocalSearchSolverAware;
 import org.drools.solver.core.localsearch.LocalSearchSolverLifecycleListener;
-import org.drools.solver.core.move.Move;
+import org.drools.solver.core.localsearch.decider.MoveScope;
 
 /**
+ * Accepts or rejects a selected move that could be the next step.
+ * Notice that it's the forager which makes the actual decision.
+ * Always extend {@link AbstractAccepter} to avoid future backwards imcompatiblity issues.
  * @author Geoffrey De Smet
  */
 public interface Accepter extends LocalSearchSolverAware, LocalSearchSolverLifecycleListener {
 
-    double calculateAcceptChance(Move move, double score);
+    /**
+     * @param moveScope not null
+     * @return never negative; if rejected 0.0; if accepted higher than 0.0 (ussually 1.0)
+     */
+    double calculateAcceptChance(MoveScope moveScope);
 
 }

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/CompositeAccepter.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/CompositeAccepter.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/CompositeAccepter.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -3,9 +3,14 @@
 import java.util.List;
 
 import org.drools.solver.core.localsearch.LocalSearchSolver;
-import org.drools.solver.core.move.Move;
+import org.drools.solver.core.localsearch.LocalSearchSolverScope;
+import org.drools.solver.core.localsearch.StepScope;
+import org.drools.solver.core.localsearch.decider.MoveScope;
 
 /**
+ * Combines several accepters into one.
+ * Multiplies the accept chance of its accepters.
+ * For example: combine solution and property tabu to do tabu on both.
  * @author Geoffrey De Smet
  */
 public class CompositeAccepter extends AbstractAccepter {
@@ -16,6 +21,7 @@
         this.accepterList = accepterList;
     }
 
+    @Override
     public void setLocalSearchSolver(LocalSearchSolver localSearchSolver) {
         super.setLocalSearchSolver(localSearchSolver);
         for (Accepter accepter : accepterList) {
@@ -27,41 +33,47 @@
     // Worker methods
     // ************************************************************************
 
-    public void solvingStarted() {
+    @Override
+    public void solvingStarted(LocalSearchSolverScope localSearchSolverScope) {
         for (Accepter accepter : accepterList) {
-            accepter.solvingStarted();
+            accepter.solvingStarted(localSearchSolverScope);
         }
     }
 
-    public void beforeDeciding() {
+    @Override
+    public void beforeDeciding(StepScope stepScope) {
         for (Accepter accepter : accepterList) {
-            accepter.beforeDeciding();
+            accepter.beforeDeciding(stepScope);
         }
     }
 
-    public double calculateAcceptChance(Move move, double score) {
+    @Override
+    public double calculateAcceptChance(MoveScope moveScope) {
         double acceptChance = 1.0;
         for (Accepter accepter : accepterList) {
-            acceptChance *= accepter.calculateAcceptChance(move, score);
+            acceptChance *= accepter.calculateAcceptChance(moveScope);
         }
         return acceptChance;
     }
 
-    public void stepDecided(Move step) {
+    @Override
+    public void stepDecided(StepScope stepScope) {
         for (Accepter accepter : accepterList) {
-            accepter.stepDecided(step);
+            accepter.stepDecided(stepScope);
         }
     }
 
-    public void stepTaken() {
+    @Override
+    public void stepTaken(StepScope stepScope) {
         for (Accepter accepter : accepterList) {
-            accepter.stepTaken();
+            accepter.stepTaken(stepScope);
         }
     }
 
-    public void solvingEnded() {
+    @Override
+    public void solvingEnded(LocalSearchSolverScope localSearchSolverScope) {
         for (Accepter accepter : accepterList) {
-            accepter.solvingEnded();
+            accepter.solvingEnded(localSearchSolverScope);
         }
     }
 

Deleted: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/TimeGradientBasedAccepter.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/TimeGradientBasedAccepter.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/TimeGradientBasedAccepter.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -1,19 +0,0 @@
-package org.drools.solver.core.localsearch.decider.accepter;
-
-/**
- * @author Geoffrey De Smet
- */
-public abstract class TimeGradientBasedAccepter extends AbstractAccepter {
-
-    protected double timeGradient;
-
-    // ************************************************************************
-    // Worker methods
-    // ************************************************************************
-    
-    @Override
-    public void beforeDeciding() {
-        timeGradient = localSearchSolver.calculateTimeGradient();
-    }
-
-}

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/simulatedannealing/SimulatedAnnealingAccepter.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/simulatedannealing/SimulatedAnnealingAccepter.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/simulatedannealing/SimulatedAnnealingAccepter.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -1,18 +1,17 @@
 package org.drools.solver.core.localsearch.decider.accepter.simulatedannealing;
 
-import org.drools.solver.core.localsearch.decider.accepter.TimeGradientBasedAccepter;
-import org.drools.solver.core.move.Move;
+import org.drools.solver.core.localsearch.decider.MoveScope;
+import org.drools.solver.core.localsearch.decider.accepter.AbstractAccepter;
 
 /**
+ * TODO Under construction
  * @author Geoffrey De Smet
  */
-public class SimulatedAnnealingAccepter extends TimeGradientBasedAccepter {
+public class SimulatedAnnealingAccepter extends AbstractAccepter {
 
     protected double scoreDeltaNormalizer = 10000.0;
     protected boolean compareToBestScore = false;
 
-    protected double cachedAcceptChancePart;
-
     public void setScoreDeltaNormalizer(double scoreDeltaNormalizer) {
         this.scoreDeltaNormalizer = scoreDeltaNormalizer;
     }
@@ -25,20 +24,18 @@
     // Worker methods
     // ************************************************************************
 
-    public void beforeDeciding() {
-        super.beforeDeciding();
-        cachedAcceptChancePart = timeGradient / scoreDeltaNormalizer;
-    }
-
-    public double calculateAcceptChance(Move move, double score) {
+    @Override
+    public double calculateAcceptChance(MoveScope moveScope) {
         double compareScore = compareToBestScore
-                ? localSearchSolver.getBestScore()
-                : localSearchSolver.getStepScore();
-        double scoreDelta = score - compareScore;
+                ? moveScope.getStepScope().getLocalSearchSolverScope().getBestScore()
+                : moveScope.getStepScope().getLocalSearchSolverScope().getLastCompletedStepScope().getScore();
+        // TODO Support for decision score
+        double scoreDelta = moveScope.getScore() - compareScore;
         if (scoreDelta > 0.0) { // TODO if scoreDelta 0 then it will end up 1.0 anyway?
             return 1.0;
         } else {
-            double acceptChance = Math.exp(scoreDelta * cachedAcceptChancePart);
+            double timeGradient = moveScope.getStepScope().getTimeGradient();
+            double acceptChance = Math.exp(scoreDelta * timeGradient / scoreDeltaNormalizer);
 //            double acceptChance = Math.min(Math.exp(scoreDelta / scoreDeltaNormalizer), 1.0) * (1.0 - timeGradient);
             // Math.min(acceptChance, 1.0) is oboselete because scoreDelta <= 0.0
             return acceptChance;

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/tabu/AbstractTabuAccepter.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/tabu/AbstractTabuAccepter.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/tabu/AbstractTabuAccepter.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -7,8 +7,10 @@
 import java.util.List;
 import java.util.Map;
 
+import org.drools.solver.core.localsearch.LocalSearchSolverScope;
+import org.drools.solver.core.localsearch.StepScope;
+import org.drools.solver.core.localsearch.decider.MoveScope;
 import org.drools.solver.core.localsearch.decider.accepter.AbstractAccepter;
-import org.drools.solver.core.move.Move;
 
 /**
  * @author Geoffrey De Smet
@@ -38,7 +40,7 @@
     // ************************************************************************
 
     @Override
-    public void solvingStarted() {
+    public void solvingStarted(LocalSearchSolverScope localSearchSolverScope) {
         if (completeTabuSize < 0) {
             throw new IllegalArgumentException("Property completeTabuSize (" + completeTabuSize
                     + ") is negative.");
@@ -54,8 +56,11 @@
         tabuSequenceList = new LinkedList<Object>();
     }
 
-    public double calculateAcceptChance(Move move, double score) {
-        Collection<? extends Object> tabus = findTabu(move);
+    @Override
+    public double calculateAcceptChance(MoveScope moveScope) {
+        // TODO aspiration
+
+        Collection<? extends Object> tabus = findTabu(moveScope);
         int maximumTabuStepIndex = -1;
         for (Object tabu : tabus) {
             Integer tabuStepIndexInteger = tabuToStepIndexMap.get(tabu);
@@ -64,15 +69,17 @@
             }
         }
         if (maximumTabuStepIndex < 0) {
+            // The move isn't tabu at all
             return 1.0;
         }
-        int tabuStepCount = localSearchSolver.getStepIndex() - maximumTabuStepIndex - 1;
+        int tabuStepCount = moveScope.getStepScope().getStepIndex() - maximumTabuStepIndex - 1;
         if (tabuStepCount < completeTabuSize) {
-            logger.debug("    Proposed move ({}) is complete tabu.", move);
+            logger.debug("    Proposed move ({}) is complete tabu.", moveScope.getMove());
             return 0.0;
         }
         double acceptChance = calculatePartialTabuAcceptChance(tabuStepCount - completeTabuSize);
-        logger.debug("    Proposed move ({}) is partially tabu with accept chance ({}).", move, acceptChance);
+        logger.debug("    Proposed move ({}) is partially tabu with accept chance ({}).",
+                moveScope.getMove(), acceptChance);
         return acceptChance;
     }
 
@@ -83,9 +90,9 @@
     }
 
     @Override
-    public void stepDecided(Move step) {
-        if (step != null) { // TODO fixme by better use of lifecycle method
-            Collection<? extends Object> tabus = findNewTabu(step);
+    public void stepDecided(StepScope stepScope) {
+        if (stepScope.getStep() != null) { // TODO fixme by better use of lifecycle method
+            Collection<? extends Object> tabus = findNewTabu(stepScope);
             for (Object tabu : tabus) {
                 // required to push tabu to the end of the line
                 if (tabuToStepIndexMap.containsKey(tabu)) {
@@ -99,16 +106,14 @@
                     it.remove();
                     tabuToStepIndexMap.remove(removeTabu);
                 }
-                tabuToStepIndexMap.put(tabu, localSearchSolver.getStepIndex());
+                tabuToStepIndexMap.put(tabu, stepScope.getStepIndex());
                 tabuSequenceList.add(tabu);
             }
         }
     }
 
-    protected abstract Collection<? extends Object> findTabu(Move move);
+    protected abstract Collection<? extends Object> findTabu(MoveScope moveScope);
 
-    protected Collection<? extends Object> findNewTabu(Move step) {
-        return findTabu(step);
-    }
+    protected abstract Collection<? extends Object> findNewTabu(StepScope stepScope);
 
 }

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/tabu/MoveTabuAccepter.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/tabu/MoveTabuAccepter.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/tabu/MoveTabuAccepter.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -3,6 +3,8 @@
 import java.util.Collection;
 import java.util.Collections;
 
+import org.drools.solver.core.localsearch.StepScope;
+import org.drools.solver.core.localsearch.decider.MoveScope;
 import org.drools.solver.core.move.Move;
 
 /**
@@ -21,16 +23,17 @@
     // ************************************************************************
 
     @Override
-    protected Collection<? extends Object> findTabu(Move move) {
-        return Collections.singletonList(move);
+    protected Collection<? extends Object> findTabu(MoveScope moveScope) {
+        return Collections.singletonList(moveScope.getMove());
     }
 
     @Override
-    protected Collection<? extends Object> findNewTabu(Move step) {
+    protected Collection<? extends Object> findNewTabu(StepScope stepScope) {
         Move tabuMove;
+        Move step = stepScope.getStep();
         if (useUndoMoveAsTabuMove) {
-            tabuMove = step.createUndoMove(
-                    localSearchSolver.getEvaluationHandler().getStatefulSession());
+            // In stepTaken this the undoMove would be corrupted
+            tabuMove = step.createUndoMove(stepScope.getWorkingMemory());
         } else {
             tabuMove = step;
         }

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/tabu/PropertyTabuAccepter.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/tabu/PropertyTabuAccepter.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/tabu/PropertyTabuAccepter.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -2,7 +2,8 @@
 
 import java.util.Collection;
 
-import org.drools.solver.core.move.Move;
+import org.drools.solver.core.localsearch.StepScope;
+import org.drools.solver.core.localsearch.decider.MoveScope;
 
 /**
  * @author Geoffrey De Smet
@@ -14,9 +15,15 @@
     // ************************************************************************
 
     @Override
-    protected Collection<? extends Object> findTabu(Move move) {
-        TabuPropertyEnabled tabuPropertyEnabled = (TabuPropertyEnabled) move;
+    protected Collection<? extends Object> findTabu(MoveScope moveScope) {
+        TabuPropertyEnabled tabuPropertyEnabled = (TabuPropertyEnabled) moveScope.getMove();
         return tabuPropertyEnabled.getTabuProperties();
     }
 
+    @Override
+    protected Collection<? extends Object> findNewTabu(StepScope stepScope) {
+        TabuPropertyEnabled tabuPropertyEnabled = (TabuPropertyEnabled) stepScope.getStep();
+        return tabuPropertyEnabled.getTabuProperties();
+    }
+
 }

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/tabu/SolutionTabuAccepter.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/tabu/SolutionTabuAccepter.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/accepter/tabu/SolutionTabuAccepter.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -3,7 +3,8 @@
 import java.util.Collection;
 import java.util.Collections;
 
-import org.drools.solver.core.move.Move;
+import org.drools.solver.core.localsearch.StepScope;
+import org.drools.solver.core.localsearch.decider.MoveScope;
 
 /**
  * @author Geoffrey De Smet
@@ -15,13 +16,14 @@
     // ************************************************************************
 
     @Override
-    protected Collection<? extends Object> findTabu(Move move) {
-        return Collections.singletonList(localSearchSolver.getCurrentSolution());
+    protected Collection<? extends Object> findTabu(MoveScope moveScope) {
+        return Collections.singletonList(moveScope.getWorkingSolution());
     }
 
     @Override
-    protected Collection<? extends Object> findNewTabu(Move step) {
-        return Collections.singletonList(localSearchSolver.getCurrentSolution().cloneSolution());
+    protected Collection<? extends Object> findNewTabu(StepScope stepScope) {
+        // TODO this should be better done in stepTaken
+        return Collections.singletonList(stepScope.createOrGetClonedSolution());
     }
     
 }

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/AbstractForager.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/AbstractForager.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/AbstractForager.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -1,7 +1,8 @@
 package org.drools.solver.core.localsearch.decider.forager;
 
 import org.drools.solver.core.localsearch.LocalSearchSolver;
-import org.drools.solver.core.move.Move;
+import org.drools.solver.core.localsearch.LocalSearchSolverScope;
+import org.drools.solver.core.localsearch.StepScope;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -22,23 +23,28 @@
     // Worker methods
     // ************************************************************************
 
-    public void solvingStarted() {
+    @Override
+    public void solvingStarted(LocalSearchSolverScope localSearchSolverScope) {
         // Hook which can be optionally overwritten by subclasses.
     }
 
-    public void beforeDeciding() {
+    @Override
+    public void beforeDeciding(StepScope stepScope) {
         // Hook which can be optionally overwritten by subclasses.
     }
 
-    public void stepDecided(Move step) {
+    @Override
+    public void stepDecided(StepScope stepScope) {
         // Hook which can be optionally overwritten by subclasses.
     }
 
-    public void stepTaken() {
+    @Override
+    public void stepTaken(StepScope stepScope) {
         // Hook which can be optionally overwritten by subclasses.
     }
 
-    public void solvingEnded() {
+    @Override
+    public void solvingEnded(LocalSearchSolverScope localSearchSolverScope) {
         // Hook which can be optionally overwritten by subclasses.
     }
 

Copied: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/AcceptedListBasedForager.java (from rev 19218, labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/AcceptionListBasedForager.java)
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/AcceptedListBasedForager.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/AcceptedListBasedForager.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -0,0 +1,102 @@
+package org.drools.solver.core.localsearch.decider.forager;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.drools.solver.core.localsearch.StepScope;
+import org.drools.solver.core.localsearch.decider.MoveScope;
+import org.drools.solver.core.move.Move;
+
+/**
+ * @author Geoffrey De Smet
+ */
+public abstract class AcceptedListBasedForager extends AbstractForager {
+
+    protected AcceptedMoveScopeComparator acceptionComparator = new AcceptedMoveScopeComparator();
+    protected List<MoveScope> acceptedList;
+    protected boolean listSorted;
+    protected double maxScore;
+    protected double acceptChanceMaxScoreTotal;
+
+    public void setAcceptionComparator(AcceptedMoveScopeComparator acceptionComparator) {
+        this.acceptionComparator = acceptionComparator;
+    }
+
+    @Override
+    public void beforeDeciding(StepScope stepScope) {
+        acceptedList = new ArrayList<MoveScope>(); // TODO use size of moveList in decider
+        listSorted = false;
+        maxScore = Double.NEGATIVE_INFINITY;
+        acceptChanceMaxScoreTotal = 0.0;
+    }
+
+    protected void addMoveScopeToAcceptedList(MoveScope moveScope) {
+        acceptedList.add(moveScope);
+        listSorted = false;
+        if (moveScope.getScore() > maxScore) {
+            acceptChanceMaxScoreTotal = moveScope.getAcceptChance();
+            maxScore = moveScope.getScore();
+        } else if (moveScope.getScore() == maxScore) {
+            acceptChanceMaxScoreTotal += moveScope.getAcceptChance();
+        }
+    }
+
+    @Override
+    public boolean isQuitEarly() {
+        return false;
+    }
+
+    protected MoveScope pickMaxScoreMoveScopeFromAcceptedList(StepScope stepScope) {
+        if (acceptedList.isEmpty())
+        {
+            return null;
+        }
+        sortAcceptedList();
+        MoveScope pickedMoveScope = null;
+        double randomChance = stepScope.getWorkingRandom().nextDouble();
+        double acceptMark = acceptChanceMaxScoreTotal * randomChance;
+        for (ListIterator<MoveScope> it = acceptedList.listIterator(acceptedList.size()); it.hasPrevious();) {
+            MoveScope moveScope = it.previous();
+            acceptMark -= moveScope.getAcceptChance();
+            // TODO That underflow warn is nonsence. randomChance can be 0.0 and the last acceptMark can end up 0.0
+            // TODO so < is nonsence
+            if (acceptMark < 0.0) {
+                pickedMoveScope = moveScope;
+                break;
+            }
+        }
+        if (pickedMoveScope == null) {
+            // TODO This isn't really underflow when an forager accepts only moves with acceptChance 0.0
+            logger.warn("Underflow occured with acceptChanceMaxScoreTotal ({}) " +
+                    "and randomChance ({}).", acceptChanceMaxScoreTotal, randomChance);
+            // Deal with it anyway (no fail-fast here)
+            pickedMoveScope = acceptedList.get(acceptedList.size() - 1);
+        }
+        return pickedMoveScope;
+    }
+
+    public int getAcceptedMovesSize() {
+        return acceptedList.size();
+    }
+
+    public List<Move> getTopList(int topSize) {
+        sortAcceptedList();
+        int size = acceptedList.size();
+        List<Move> topList = new ArrayList<Move>(Math.min(topSize, size));
+        List<MoveScope> subAcceptedList = acceptedList.subList(Math.max(0, size - topSize), size);
+        for (MoveScope moveScope : subAcceptedList) {
+            topList.add(moveScope.getMove());
+        }
+        return topList;
+    }
+
+    protected void sortAcceptedList() {
+        if (!listSorted) {
+            Collections.sort(acceptedList, acceptionComparator);
+            listSorted = true;
+        }
+    }
+
+}

Copied: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/AcceptedMoveScopeComparator.java (from rev 19218, labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/AcceptionComparator.java)
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/AcceptedMoveScopeComparator.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/AcceptedMoveScopeComparator.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -0,0 +1,21 @@
+package org.drools.solver.core.localsearch.decider.forager;
+
+import java.util.Comparator;
+
+import org.apache.commons.lang.builder.CompareToBuilder;
+import org.drools.solver.core.localsearch.decider.MoveScope;
+
+/**
+ * @author Geoffrey De Smet
+ */
+public class AcceptedMoveScopeComparator implements Comparator<MoveScope> {
+
+    public int compare(MoveScope a, MoveScope b) {
+        CompareToBuilder compareToBuilder = new CompareToBuilder();
+        compareToBuilder.append(a.getScore(), b.getScore());
+        compareToBuilder.append(a.getAcceptChance(), b.getAcceptChance());
+        // moves are not compared
+        return compareToBuilder.toComparison();
+    }
+
+}

Deleted: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/Acception.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/Acception.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/Acception.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -1,58 +0,0 @@
-package org.drools.solver.core.localsearch.decider.forager;
-
-import org.apache.commons.lang.builder.EqualsBuilder;
-import org.apache.commons.lang.builder.HashCodeBuilder;
-import org.drools.solver.core.move.Move;
-
-/**
- * @author Geoffrey De Smet
- */
-public class Acception {
-
-    private Move move;
-    private double score;
-    private double acceptChance;
-
-    public Acception(Move move, double score, double acceptChance) {
-        this.move = move;
-        this.score = score;
-        this.acceptChance = acceptChance;
-    }
-
-    public Move getMove() {
-        return move;
-    }
-
-    public double getScore() {
-        return score;
-    }
-
-    public double getAcceptChance() {
-        return acceptChance;
-    }
-
-
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        } else if (o instanceof Acception) {
-            Acception other = (Acception) o;
-            return new EqualsBuilder()
-                    .append(score, other.score)
-                    .append(acceptChance, other.acceptChance)
-                    .append(move, other.move)
-                    .isEquals();
-        } else {
-            return false;
-        }
-    }
-
-    public int hashCode() {
-        return new HashCodeBuilder()
-                .append(score)
-                .append(acceptChance)
-                .append(move)
-                .toHashCode();
-    }
-
-}

Deleted: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/AcceptionComparator.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/AcceptionComparator.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/AcceptionComparator.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -1,20 +0,0 @@
-package org.drools.solver.core.localsearch.decider.forager;
-
-import java.util.Comparator;
-
-import org.apache.commons.lang.builder.CompareToBuilder;
-
-/**
- * @author Geoffrey De Smet
- */
-public class AcceptionComparator implements Comparator<Acception> {
-
-    public int compare(Acception a, Acception b) {
-        CompareToBuilder compareToBuilder = new CompareToBuilder();
-        compareToBuilder.append(a.getScore(), b.getScore());
-        compareToBuilder.append(a.getAcceptChance(), b.getAcceptChance());
-        // moves are not compared
-        return compareToBuilder.toComparison();
-    }
-
-}

Deleted: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/AcceptionListBasedForager.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/AcceptionListBasedForager.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/AcceptionListBasedForager.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -1,91 +0,0 @@
-package org.drools.solver.core.localsearch.decider.forager;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.ListIterator;
-
-import org.drools.solver.core.move.Move;
-
-/**
- * @author Geoffrey De Smet
- */
-public abstract class AcceptionListBasedForager extends AbstractForager {
-
-    protected AcceptionComparator acceptionComparator = new AcceptionComparator();
-    protected List<Acception> acceptionList;
-    protected boolean listSorted;
-    protected double maxScore;
-    protected double acceptChanceMaxScoreTotal;
-
-    public void setAcceptionComparator(AcceptionComparator acceptionComparator) {
-        this.acceptionComparator = acceptionComparator;
-    }
-
-    @Override
-    public void beforeDeciding() {
-        acceptionList = new ArrayList<Acception>(); // TODO use size of moveList in decider
-        listSorted = false;
-        maxScore = Double.NEGATIVE_INFINITY;
-        acceptChanceMaxScoreTotal = 0.0;
-    }
-
-    protected void addMoveToAcceptionList(Move move, double score, double acceptChance) {
-        acceptionList.add(new Acception(move, score, acceptChance));
-        listSorted = false;
-        if (score > maxScore) {
-            acceptChanceMaxScoreTotal = acceptChance;
-            maxScore = score;
-        } else if (score == maxScore) {
-            acceptChanceMaxScoreTotal += acceptChance;
-        }
-    }
-
-    protected Move pickMaxScoreMove() {
-        if (acceptionList.isEmpty())
-        {
-            return null;
-        }
-        sortAcceptionList();
-        Move pickedMove = null;
-        double random = localSearchSolver.getRandom().nextDouble();
-        double acceptMark = acceptChanceMaxScoreTotal * random;
-        for (ListIterator<Acception> it = acceptionList.listIterator(acceptionList.size()); it.hasPrevious();) {
-            Acception acception = it.previous();
-            acceptMark -= acception.getAcceptChance();
-            if (acceptMark < 0.0) {
-                pickedMove = acception.getMove();
-                break;
-            }
-        }
-        if (pickedMove == null) {
-            logger.warn("Underflow occured with acceptChanceMaxScoreTotal ({}) " +
-                    "and random ({}).", acceptChanceMaxScoreTotal, random);
-            // Deal with it anyway (no fail-fast here)
-            pickedMove = acceptionList.get(acceptionList.size() - 1).getMove();
-        }
-        return pickedMove;
-    }
-
-    public int getAcceptedMovesSize() {
-        return acceptionList.size();
-    }
-
-    public List<Move> getTopList(int topSize) {
-        sortAcceptionList();
-        int size = acceptionList.size();
-        List<Move> topList = new ArrayList<Move>(Math.min(topSize, size));
-        List<Acception> subAcceptionList = acceptionList.subList(Math.max(0, size - topSize), size);
-        for (Acception acception : subAcceptionList) {
-            topList.add(acception.getMove());
-        }
-        return topList;
-    }
-
-    protected void sortAcceptionList() {
-        if (!listSorted) {
-            Collections.sort(acceptionList, acceptionComparator);
-            listSorted = true;
-        }
-    }
-}

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/FirstRandomlyAcceptedForager.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/FirstRandomlyAcceptedForager.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/FirstRandomlyAcceptedForager.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -1,42 +1,47 @@
 package org.drools.solver.core.localsearch.decider.forager;
 
-import org.drools.solver.core.move.Move;
+import org.drools.solver.core.localsearch.StepScope;
+import org.drools.solver.core.localsearch.decider.MoveScope;
 
 /**
  * @author Geoffrey De Smet
  */
-public class FirstRandomlyAcceptedForager extends AcceptionListBasedForager {
+public class FirstRandomlyAcceptedForager extends AcceptedListBasedForager {
 
-    protected Move earlyPickedMove = null;
+    protected MoveScope earlyPickedMoveScope = null;
 
     // ************************************************************************
     // Worker methods
     // ************************************************************************
 
     @Override
-    public void beforeDeciding() {
-        super.beforeDeciding();
-        earlyPickedMove = null;
+    public void beforeDeciding(StepScope stepScope) {
+        super.beforeDeciding(stepScope);
+        earlyPickedMoveScope = null;
     }
 
-    public void addMove(Move move, double score, double acceptChance) {
-        if (acceptChance > 0.0) {
-            if (localSearchSolver.getRandom().nextDouble() <= acceptChance) {
-                earlyPickedMove = move;
+    @Override
+    public void addMove(MoveScope moveScope) {
+        if (moveScope.getAcceptChance() > 0.0) {
+            double randomChance = moveScope.getWorkingRandom().nextDouble();
+            if (randomChance <= moveScope.getAcceptChance()) {
+                earlyPickedMoveScope = moveScope;
             }
-            addMoveToAcceptionList(move, score, acceptChance);
+            addMoveScopeToAcceptedList(moveScope);
         }
     }
 
+    @Override
     public boolean isQuitEarly() {
-        return earlyPickedMove != null;
+        return earlyPickedMoveScope != null;
     }
 
-    public Move pickMove() {
-        if (earlyPickedMove != null) {
-            return earlyPickedMove;
+    @Override
+    public MoveScope pickMove(StepScope stepScope) {
+        if (earlyPickedMoveScope != null) {
+            return earlyPickedMoveScope;
         } else {
-            return pickMaxScoreMove();
+            return pickMaxScoreMoveScopeFromAcceptedList(stepScope);
         }
     }
 

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/Forager.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/Forager.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/Forager.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -4,6 +4,8 @@
 
 import org.drools.solver.core.localsearch.LocalSearchSolverAware;
 import org.drools.solver.core.localsearch.LocalSearchSolverLifecycleListener;
+import org.drools.solver.core.localsearch.StepScope;
+import org.drools.solver.core.localsearch.decider.MoveScope;
 import org.drools.solver.core.move.Move;
 
 /**
@@ -11,11 +13,11 @@
  */
 public interface Forager extends LocalSearchSolverAware, LocalSearchSolverLifecycleListener {
 
-    void addMove(Move move, double score, double acceptChance);
+    void addMove(MoveScope moveScope);
 
     boolean isQuitEarly();
 
-    Move pickMove();
+    MoveScope pickMove(StepScope stepScope);
 
     int getAcceptedMovesSize();
 

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/MaxScoreOfAllForager.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/MaxScoreOfAllForager.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/forager/MaxScoreOfAllForager.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -1,28 +1,27 @@
 package org.drools.solver.core.localsearch.decider.forager;
 
-import org.drools.solver.core.move.Move;
+import org.drools.solver.core.localsearch.StepScope;
+import org.drools.solver.core.localsearch.decider.MoveScope;
 
 /**
  * @author Geoffrey De Smet
  */
-public class MaxScoreOfAllForager extends AcceptionListBasedForager {
+public class MaxScoreOfAllForager extends AcceptedListBasedForager {
 
     // ************************************************************************
     // Worker methods
     // ************************************************************************
 
-    public void addMove(Move move, double score, double acceptChance) {
-        if (acceptChance > 0.0) {
-            addMoveToAcceptionList(move, score, acceptChance);
+    @Override
+    public void addMove(MoveScope moveScope) {
+        if (moveScope.getAcceptChance() > 0.0) {
+            addMoveScopeToAcceptedList(moveScope);
         }
     }
 
-    public boolean isQuitEarly() {
-        return false;
+    @Override
+    public MoveScope pickMove(StepScope stepScope) {
+        return pickMaxScoreMoveScopeFromAcceptedList(stepScope);
     }
 
-    public Move pickMove() {
-        return pickMaxScoreMove();
-    }
-
 }

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/selector/AbstractSelector.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/selector/AbstractSelector.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/selector/AbstractSelector.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -1,7 +1,8 @@
 package org.drools.solver.core.localsearch.decider.selector;
 
 import org.drools.solver.core.localsearch.LocalSearchSolver;
-import org.drools.solver.core.move.Move;
+import org.drools.solver.core.localsearch.LocalSearchSolverScope;
+import org.drools.solver.core.localsearch.StepScope;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -22,23 +23,28 @@
     // Worker methods
     // ************************************************************************
 
-    public void solvingStarted() {
+    @Override
+    public void solvingStarted(LocalSearchSolverScope localSearchSolverScope) {
         // Hook which can be optionally overwritten by subclasses.
     }
 
-    public void beforeDeciding() {
+    @Override
+    public void beforeDeciding(StepScope stepScope) {
         // Hook which can be optionally overwritten by subclasses.
     }
 
-    public void stepDecided(Move step) {
+    @Override
+    public void stepDecided(StepScope stepScope) {
         // Hook which can be optionally overwritten by subclasses.
     }
 
-    public void stepTaken() {
+    @Override
+    public void stepTaken(StepScope stepScope) {
         // Hook which can be optionally overwritten by subclasses.
     }
 
-    public void solvingEnded() {
+    @Override
+    public void solvingEnded(LocalSearchSolverScope localSearchSolverScope) {
         // Hook which can be optionally overwritten by subclasses.
     }
 

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/selector/CompositeSelector.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/selector/CompositeSelector.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/selector/CompositeSelector.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -4,6 +4,8 @@
 import java.util.List;
 
 import org.drools.solver.core.localsearch.LocalSearchSolver;
+import org.drools.solver.core.localsearch.LocalSearchSolverScope;
+import org.drools.solver.core.localsearch.StepScope;
 import org.drools.solver.core.move.Move;
 
 /**
@@ -17,6 +19,7 @@
         this.selectorList = selectorList;
     }
 
+    @Override
     public void setLocalSearchSolver(LocalSearchSolver localSearchSolver) {
         super.setLocalSearchSolver(localSearchSolver);
         for (Selector selector : selectorList) {
@@ -28,23 +31,26 @@
     // Worker methods
     // ************************************************************************
 
-    public void solvingStarted() {
+    @Override
+    public void solvingStarted(LocalSearchSolverScope localSearchSolverScope) {
         for (Selector selector : selectorList) {
-            selector.solvingStarted();
+            selector.solvingStarted(localSearchSolverScope);
         }
     }
 
-    public void beforeDeciding() {
+    @Override
+    public void beforeDeciding(StepScope stepScope) {
         for (Selector selector : selectorList) {
-            selector.beforeDeciding();
+            selector.beforeDeciding(stepScope);
         }
     }
 
-    public List<Move> selectMoveList() {
+    @Override
+    public List<Move> selectMoveList(StepScope stepScope) {
         int totalSize = 0;
         List<List<Move>> subMoveLists = new ArrayList<List<Move>>(selectorList.size());
         for (Selector selector : selectorList) {
-            List<Move> subMoveList = selector.selectMoveList();
+            List<Move> subMoveList = selector.selectMoveList(stepScope);
             totalSize += subMoveList.size();
             subMoveLists.add(subMoveList);
         }
@@ -52,24 +58,28 @@
         for (List<Move> subMoveList : subMoveLists) {
             moveList.addAll(subMoveList);
         }
+        // TODO support overal shuffling
         return moveList;
     }
 
-    public void stepDecided(Move step) {
+    @Override
+    public void stepDecided(StepScope stepScope) {
         for (Selector selector : selectorList) {
-            selector.stepDecided(step);
+            selector.stepDecided(stepScope);
         }
     }
 
-    public void stepTaken() {
+    @Override
+    public void stepTaken(StepScope stepScope) {
         for (Selector selector : selectorList) {
-            selector.stepTaken();
+            selector.stepTaken(stepScope);
         }
     }
 
-    public void solvingEnded() {
+    @Override
+    public void solvingEnded(LocalSearchSolverScope localSearchSolverScope) {
         for (Selector selector : selectorList) {
-            selector.solvingEnded();
+            selector.solvingEnded(localSearchSolverScope);
         }
     }
 

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/selector/MoveFactorySelector.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/selector/MoveFactorySelector.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/selector/MoveFactorySelector.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -4,6 +4,8 @@
 import java.util.List;
 
 import org.drools.solver.core.localsearch.LocalSearchSolver;
+import org.drools.solver.core.localsearch.LocalSearchSolverScope;
+import org.drools.solver.core.localsearch.StepScope;
 import org.drools.solver.core.move.Move;
 import org.drools.solver.core.move.factory.MoveFactory;
 
@@ -38,18 +40,21 @@
     // Worker methods
     // ************************************************************************
 
-    public void solvingStarted() {
-        moveFactory.solvingStarted();
+    @Override
+    public void solvingStarted(LocalSearchSolverScope localSearchSolverScope) {
+        moveFactory.solvingStarted(localSearchSolverScope);
     }
 
-    public void beforeDeciding() {
-        moveFactory.beforeDeciding();
+    @Override
+    public void beforeDeciding(StepScope stepScope) {
+        moveFactory.beforeDeciding(stepScope);
     }
 
-    public final List<Move> selectMoveList() {
-        List<Move> moveList = moveFactory.createMoveList(localSearchSolver.getCurrentSolution());
+    @Override
+    public final List<Move> selectMoveList(StepScope stepScope) {
+        List<Move> moveList = moveFactory.createMoveList(stepScope.getWorkingSolution());
         if (shuffle) {
-            Collections.shuffle(moveList, localSearchSolver.getRandom());
+            Collections.shuffle(moveList, stepScope.getWorkingRandom());
         }
         if (relativeSelection != null) {
             int selectionSize = (int) Math.ceil(relativeSelection * moveList.size());
@@ -61,16 +66,19 @@
         return moveList;
     }
 
-    public void stepDecided(Move step) {
-        moveFactory.stepDecided(step);
+    @Override
+    public void stepDecided(StepScope stepScope) {
+        moveFactory.stepDecided(stepScope);
     }
 
-    public void stepTaken() {
-        moveFactory.stepTaken();
+    @Override
+    public void stepTaken(StepScope stepScope) {
+        moveFactory.stepTaken(stepScope);
     }
 
-    public void solvingEnded() {
-        moveFactory.solvingEnded();
+    @Override
+    public void solvingEnded(LocalSearchSolverScope localSearchSolverScope) {
+        moveFactory.solvingEnded(localSearchSolverScope);
     }
 
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/selector/Selector.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/selector/Selector.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/selector/Selector.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -4,6 +4,7 @@
 
 import org.drools.solver.core.localsearch.LocalSearchSolverAware;
 import org.drools.solver.core.localsearch.LocalSearchSolverLifecycleListener;
+import org.drools.solver.core.localsearch.StepScope;
 import org.drools.solver.core.move.Move;
 
 /**
@@ -11,6 +12,6 @@
  */
 public interface Selector extends LocalSearchSolverAware, LocalSearchSolverLifecycleListener {
 
-    List<Move> selectMoveList();
+    List<Move> selectMoveList(StepScope stepScope);
 
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/selector/TopListSelector.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/selector/TopListSelector.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/decider/selector/TopListSelector.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -3,6 +3,9 @@
 import java.util.Collections;
 import java.util.List;
 
+import org.drools.solver.core.localsearch.DefaultLocalSearchSolver;
+import org.drools.solver.core.localsearch.LocalSearchSolverScope;
+import org.drools.solver.core.localsearch.StepScope;
 import org.drools.solver.core.move.Move;
 
 /**
@@ -22,16 +25,20 @@
     // Worker methods
     // ************************************************************************
 
-    public void solvingStarted() {
+    @Override
+    public void solvingStarted(LocalSearchSolverScope localSearchSolverScope) {
         topList = Collections.emptyList();
     }
 
-    public final List<Move> selectMoveList() {
+    @Override
+    public final List<Move> selectMoveList(StepScope stepScope) {
         return topList;
     }
 
-    public void stepTaken() {
-        topList = localSearchSolver.getDecider().getForager().getTopList(topSize);
+    @Override
+    public void stepTaken(StepScope stepScope) {
+        // TODO fixme
+        topList = ((DefaultLocalSearchSolver) localSearchSolver).getDecider().getForager().getTopList(topSize);
     }
 
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/AbstractCompositeFinish.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/AbstractCompositeFinish.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/AbstractCompositeFinish.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -3,7 +3,8 @@
 import java.util.List;
 
 import org.drools.solver.core.localsearch.LocalSearchSolver;
-import org.drools.solver.core.move.Move;
+import org.drools.solver.core.localsearch.LocalSearchSolverScope;
+import org.drools.solver.core.localsearch.StepScope;
 
 /**
  * Superclass for CompositeFinish classes that combine multiple Finishes.
@@ -30,37 +31,37 @@
     // ************************************************************************
 
     @Override
-    public void solvingStarted() {
+    public void solvingStarted(LocalSearchSolverScope localSearchSolverScope) {
         for (Finish finish : finishList) {
-            finish.solvingStarted();
+            finish.solvingStarted(localSearchSolverScope);
         }
     }
 
     @Override
-    public void beforeDeciding() {
+    public void beforeDeciding(StepScope stepScope) {
         for (Finish finish : finishList) {
-            finish.beforeDeciding();
+            finish.beforeDeciding(stepScope);
         }
     }
 
     @Override
-    public void stepDecided(Move step) {
+    public void stepDecided(StepScope stepScope) {
         for (Finish finish : finishList) {
-            finish.stepDecided(step);
+            finish.stepDecided(stepScope);
         }
     }
 
     @Override
-    public void stepTaken() {
+    public void stepTaken(StepScope stepScope) {
         for (Finish finish : finishList) {
-            finish.stepTaken();
+            finish.stepTaken(stepScope);
         }
     }
 
     @Override
-    public void solvingEnded() {
+    public void solvingEnded(LocalSearchSolverScope localSearchSolverScope) {
         for (Finish finish : finishList) {
-            finish.solvingEnded();
+            finish.solvingEnded(localSearchSolverScope);
         }
     }
 

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/AbstractFinish.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/AbstractFinish.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/AbstractFinish.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -1,7 +1,8 @@
 package org.drools.solver.core.localsearch.finish;
 
 import org.drools.solver.core.localsearch.LocalSearchSolver;
-import org.drools.solver.core.move.Move;
+import org.drools.solver.core.localsearch.LocalSearchSolverScope;
+import org.drools.solver.core.localsearch.StepScope;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -22,23 +23,28 @@
     // Worker methods
     // ************************************************************************
 
-    public void solvingStarted() {
+    @Override
+    public void solvingStarted(LocalSearchSolverScope localSearchSolverScope) {
         // Hook which can be optionally overwritten by subclasses.
     }
 
-    public void beforeDeciding() {
+    @Override
+    public void beforeDeciding(StepScope stepScope) {
         // Hook which can be optionally overwritten by subclasses.
     }
 
-    public void stepDecided(Move step) {
+    @Override
+    public void stepDecided(StepScope stepScope) {
         // Hook which can be optionally overwritten by subclasses.
     }
 
-    public void stepTaken() {
+    @Override
+    public void stepTaken(StepScope stepScope) {
         // Hook which can be optionally overwritten by subclasses.
     }
 
-    public void solvingEnded() {
+    @Override
+    public void solvingEnded(LocalSearchSolverScope localSearchSolverScope) {
         // Hook which can be optionally overwritten by subclasses.
     }
 

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/AndCompositeFinish.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/AndCompositeFinish.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/AndCompositeFinish.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -1,5 +1,7 @@
 package org.drools.solver.core.localsearch.finish;
 
+import org.drools.solver.core.localsearch.StepScope;
+
 /**
  * @author Geoffrey De Smet
  */
@@ -11,10 +13,11 @@
 
     /**
      * @return true if all the Finishes are finished.
+     * @param stepScope
      */
-    public boolean isFinished() {
+    public boolean isFinished(StepScope stepScope) {
         for (Finish finish : finishList) {
-            if (!finish.isFinished()) {
+            if (!finish.isFinished(stepScope)) {
                 return false;
             }
         }
@@ -25,11 +28,12 @@
      * Calculates the minimum timeGradient of all finishes.
      * Not supported timeGradients (-1.0) are ignored. 
      * @return the minimum timeGradient of the finishes.
+     * @param stepScope
      */
-    public double calculateTimeGradient() {
+    public double calculateTimeGradient(StepScope stepScope) {
         double timeGradient = 1.0;
         for (Finish finish : finishList) {
-            double nextTimeGradient = finish.calculateTimeGradient();
+            double nextTimeGradient = finish.calculateTimeGradient(stepScope);
             if (nextTimeGradient >= 0.0) {
                 timeGradient = Math.min(timeGradient, nextTimeGradient);
             }

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/FeasableScoreFinish.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/FeasableScoreFinish.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/FeasableScoreFinish.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -1,5 +1,8 @@
 package org.drools.solver.core.localsearch.finish;
 
+import org.drools.solver.core.localsearch.LocalSearchSolverScope;
+import org.drools.solver.core.localsearch.StepScope;
+
 /**
  * @author Geoffrey De Smet
  */
@@ -8,7 +11,7 @@
     private double feasableScore;
 
     private double startingScore;
-    private double totalDelta;
+    private double feasableDelta;
     
     public void setFeasableScore(double feasableScore) {
         this.feasableScore = feasableScore;
@@ -19,20 +22,20 @@
     // ************************************************************************
 
     @Override
-    public void solvingStarted() {
-        startingScore = localSearchSolver.getStepScore();
-        totalDelta = startingScore - feasableScore;
+    public void solvingStarted(LocalSearchSolverScope localSearchSolverScope) {
+        startingScore = localSearchSolverScope.getStartingScore();
+        feasableDelta = startingScore - feasableScore;
     }
 
-    public boolean isFinished() {
-        double bestScore = localSearchSolver.getBestScore();
+    public boolean isFinished(StepScope stepScope) {
+        double bestScore = stepScope.getLocalSearchSolverScope().getBestScore();
         return bestScore >= feasableScore;
     }
 
-    public double calculateTimeGradient() {
-        double stepScore = localSearchSolver.getStepScore();
+    public double calculateTimeGradient(StepScope stepScope) {
+        double stepScore = stepScope.getLocalSearchSolverScope().getLastCompletedStepScope().getScore();
         double stepDelta = startingScore - stepScore;
-        double timeGradient = stepDelta / totalDelta;
+        double timeGradient = stepDelta / feasableDelta;
         return Math.min(timeGradient, 1.0);
     }
     

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/Finish.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/Finish.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/Finish.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -2,6 +2,7 @@
 
 import org.drools.solver.core.localsearch.LocalSearchSolverAware;
 import org.drools.solver.core.localsearch.LocalSearchSolverLifecycleListener;
+import org.drools.solver.core.localsearch.StepScope;
 
 /**
  * Determines when the LocalSearchSolver should stop.
@@ -11,9 +12,10 @@
 
     /**
      * Called by the LocalSearchSolver after every step to determine if the search should stop.
+     * @param stepScope never null
      * @return true if the search should finish.
      */
-    boolean isFinished();
+    boolean isFinished(StepScope stepScope);
 
     /**
      * A timeGradient is a relative estimate of how long the search will continue.
@@ -26,9 +28,10 @@
      * <p/>
      * A Finish's timeGradient can be requested after they are finished, so implementations
      * should be carefull not to return a tempature above 1.0.
+     * @param stepScope never null
      * @return timeGradient t for which 0.0 &lt;= t &lt;= 1.0 or -1.0 when it is not supported.
      * At the start of a search t is 0.0 and at the end of a search t would be 1.0.
      */
-    double calculateTimeGradient();
+    double calculateTimeGradient(StepScope stepScope);
 
 }

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/OrCompositeFinish.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/OrCompositeFinish.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/OrCompositeFinish.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -1,5 +1,7 @@
 package org.drools.solver.core.localsearch.finish;
 
+import org.drools.solver.core.localsearch.StepScope;
+
 /**
  * @author Geoffrey De Smet
  */
@@ -11,10 +13,11 @@
 
     /**
      * @return true if any of the Finishes is finished.
+     * @param stepScope
      */
-    public boolean isFinished() {
+    public boolean isFinished(StepScope stepScope) {
         for (Finish finish : finishList) {
-            if (finish.isFinished()) {
+            if (finish.isFinished(stepScope)) {
                 return true;
             }
         }
@@ -25,11 +28,12 @@
      * Calculates the minimum timeGradient of all finishes.
      * Not supported timeGradients (-1.0) are ignored.
      * @return the maximum timeGradient of the finishes.
+     * @param stepScope
      */
-    public double calculateTimeGradient() {
+    public double calculateTimeGradient(StepScope stepScope) {
         double timeGradient = 0.0;
         for (Finish finish : finishList) {
-            double nextTimeGradient = finish.calculateTimeGradient();
+            double nextTimeGradient = finish.calculateTimeGradient(stepScope);
             if (nextTimeGradient >= 0.0) {
                 timeGradient = Math.max(timeGradient, nextTimeGradient);
             }

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/StepCountFinish.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/StepCountFinish.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/StepCountFinish.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -1,5 +1,7 @@
 package org.drools.solver.core.localsearch.finish;
 
+import org.drools.solver.core.localsearch.StepScope;
+
 /**
  * @author Geoffrey De Smet
  */
@@ -15,13 +17,13 @@
     // Worker methods
     // ************************************************************************
 
-    public boolean isFinished() {
-        int stepIndex = localSearchSolver.getStepIndex();
+    public boolean isFinished(StepScope stepScope) {
+        int stepIndex = stepScope.getStepIndex();
         return stepIndex >= maximumStepCount;
     }
 
-    public double calculateTimeGradient() {
-        int stepIndex = localSearchSolver.getStepIndex();
+    public double calculateTimeGradient(StepScope stepScope) {
+        int stepIndex = stepScope.getStepIndex();
         double timeGradient = ((double) stepIndex) / ((double) maximumStepCount);
         return Math.min(timeGradient, 1.0);
     }

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/TimeMillisSpendFinish.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/TimeMillisSpendFinish.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/TimeMillisSpendFinish.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -1,5 +1,7 @@
 package org.drools.solver.core.localsearch.finish;
 
+import org.drools.solver.core.localsearch.StepScope;
+
 /**
  * @author Geoffrey De Smet
  */
@@ -19,13 +21,13 @@
     // Worker methods
     // ************************************************************************
 
-    public boolean isFinished() {
-        long timeMillisSpend = localSearchSolver.getTimeMillisSpend();
+    public boolean isFinished(StepScope stepScope) {
+        long timeMillisSpend = stepScope.getLocalSearchSolverScope().calculateTimeMillisSpend();
         return timeMillisSpend >= maximumTimeMillisSpend;
     }
 
-    public double calculateTimeGradient() {
-        long timeMillisSpend = localSearchSolver.getTimeMillisSpend();
+    public double calculateTimeGradient(StepScope stepScope) {
+        long timeMillisSpend = stepScope.getLocalSearchSolverScope().calculateTimeMillisSpend();
         double timeGradient = ((double) timeMillisSpend) / ((double) maximumTimeMillisSpend);
         return Math.min(timeGradient, 1.0);
     }

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/UnimprovedStepCountFinish.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/UnimprovedStepCountFinish.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/finish/UnimprovedStepCountFinish.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -1,5 +1,7 @@
 package org.drools.solver.core.localsearch.finish;
 
+import org.drools.solver.core.localsearch.StepScope;
+
 /**
  * @author Geoffrey De Smet
  */
@@ -15,19 +17,19 @@
     // Worker methods
     // ************************************************************************
     
-    private int getUnimprovedStepCount() {
-        int improvedStepIndex = localSearchSolver.getBestSolutionStepIndex();
-        int stepIndex = localSearchSolver.getStepIndex();
-        return stepIndex - improvedStepIndex;
+    private int calculateUnimprovedStepCount(StepScope stepScope) {
+        int bestStepIndex = stepScope.getLocalSearchSolverScope().getBestSolutionStepIndex();
+        int stepIndex = stepScope.getStepIndex();
+        return stepIndex - bestStepIndex;
     }
 
-    public boolean isFinished() {
-        int unimprovedStepCount = getUnimprovedStepCount();
+    public boolean isFinished(StepScope stepScope) {
+        int unimprovedStepCount = calculateUnimprovedStepCount(stepScope);
         return unimprovedStepCount >= maximumUnimprovedStepCount;
     }
 
-    public double calculateTimeGradient() {
-        int unimprovedStepCount = getUnimprovedStepCount();
+    public double calculateTimeGradient(StepScope stepScope) {
+        int unimprovedStepCount = calculateUnimprovedStepCount(stepScope);
         double timeGradient = ((double) unimprovedStepCount) / ((double) maximumUnimprovedStepCount);
         return Math.min(timeGradient, 1.0);
     }

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/stepstatistic/StepStatistic.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/stepstatistic/StepStatistic.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/localsearch/stepstatistic/StepStatistic.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -1,20 +1,14 @@
 package org.drools.solver.core.localsearch.stepstatistic;
 
-import org.drools.solver.core.solution.Solution;
-
 /**
  * @author Geoffrey De Smet
  */
-public interface StepStatistic {
+public interface StepStatistic { // TODO This isn't used anywhere
 
-    int getBestSolutionStepIndex();
-    Solution getBestSolution();
-    double getBestScore();
-
     /**
      * How much of all the selectable moves should be evaluated for the current step.
      * @return a number > 0 and <= 1.0
      */
-    double getSelectorThoroughness();
+    double getSelectorThoroughness(); // TODO this is a new feature to implement somewhere 
 
 }

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/move/factory/AbstractMoveFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/move/factory/AbstractMoveFactory.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/move/factory/AbstractMoveFactory.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -1,7 +1,8 @@
 package org.drools.solver.core.move.factory;
 
 import org.drools.solver.core.localsearch.LocalSearchSolver;
-import org.drools.solver.core.move.Move;
+import org.drools.solver.core.localsearch.LocalSearchSolverScope;
+import org.drools.solver.core.localsearch.StepScope;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -22,23 +23,28 @@
     // Worker methods
     // ************************************************************************
 
-    public void solvingStarted() {
+    @Override
+    public void solvingStarted(LocalSearchSolverScope localSearchSolverScope) {
         // Hook which can be optionally overwritten by subclasses.
     }
 
-    public void beforeDeciding() {
+    @Override
+    public void beforeDeciding(StepScope stepScope) {
         // Hook which can be optionally overwritten by subclasses.
     }
 
-    public void stepDecided(Move step) {
+    @Override
+    public void stepDecided(StepScope stepScope) {
         // Hook which can be optionally overwritten by subclasses.
     }
 
-    public void stepTaken() {
+    @Override
+    public void stepTaken(StepScope stepScope) {
         // Hook which can be optionally overwritten by subclasses.
     }
 
-    public void solvingEnded() {
+    @Override
+    public void solvingEnded(LocalSearchSolverScope localSearchSolverScope) {
         // Hook which can be optionally overwritten by subclasses.
     }
 

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/move/factory/CachedMoveFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/move/factory/CachedMoveFactory.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/move/factory/CachedMoveFactory.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -3,6 +3,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.drools.solver.core.localsearch.LocalSearchSolverScope;
 import org.drools.solver.core.move.Move;
 import org.drools.solver.core.solution.Solution;
 
@@ -14,12 +15,13 @@
     protected List<Move> cachedMoveList;
 
     @Override
-    public void solvingStarted() {
-        cachedMoveList = createCachedMoveList(localSearchSolver.getCurrentSolution());
+    public void solvingStarted(LocalSearchSolverScope localSearchSolverScope) {
+        cachedMoveList = createCachedMoveList(localSearchSolverScope.getWorkingSolution());
     }
 
-    public abstract List<Move> createCachedMoveList(Solution startingSolution);
+    public abstract List<Move> createCachedMoveList(Solution solution);
 
+    @Override
     public List<Move> createMoveList(Solution solution) {
         // Shallow copy so it can be shuffled and filtered etc
         return new ArrayList<Move>(cachedMoveList);

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/solution/initializer/AbstractStartingSolutionInitializer.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/solution/initializer/AbstractStartingSolutionInitializer.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/solution/initializer/AbstractStartingSolutionInitializer.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -1,7 +1,6 @@
 package org.drools.solver.core.solution.initializer;
 
-import org.drools.solver.core.Solver;
-import org.drools.solver.core.solution.Solution;
+import org.drools.solver.core.localsearch.LocalSearchSolverScope;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -12,17 +11,12 @@
 
     protected final transient Logger logger = LoggerFactory.getLogger(getClass());
 
-    protected Solver solver;
-
-    public void setSolver(Solver solver) {
-        this.solver = solver;
-    }
-
     // ************************************************************************
     // Worker methods
     // ************************************************************************
 
-    public boolean isSolutionInitialized(Solution solution) {
+    @Override
+    public boolean isSolutionInitialized(LocalSearchSolverScope localSearchSolverScope) {
         return false;
     }
 

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/solution/initializer/StartingSolutionInitializer.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/solution/initializer/StartingSolutionInitializer.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/solution/initializer/StartingSolutionInitializer.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -1,15 +1,14 @@
 package org.drools.solver.core.solution.initializer;
 
-import org.drools.solver.core.SolverAware;
-import org.drools.solver.core.solution.Solution;
+import org.drools.solver.core.localsearch.LocalSearchSolverScope;
 
 /**
  * @author Geoffrey De Smet
  */
-public interface StartingSolutionInitializer extends SolverAware {
+public interface StartingSolutionInitializer {
 
-    boolean isSolutionInitialized(Solution solution);
+    boolean isSolutionInitialized(LocalSearchSolverScope localSearchSolverScope);
 
-    void initializeSolution(Solution solution);
+    void initializeSolution(LocalSearchSolverScope localSearchSolverScope);
 
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/test/java/org/drools/solver/core/localsearch/decider/forager/FirstRandomlyAcceptedForagerTest.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/test/java/org/drools/solver/core/localsearch/decider/forager/FirstRandomlyAcceptedForagerTest.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/test/java/org/drools/solver/core/localsearch/decider/forager/FirstRandomlyAcceptedForagerTest.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -4,7 +4,9 @@
 import java.util.Random;
 
 import junit.framework.TestCase;
-import org.drools.solver.core.localsearch.DefaultLocalSearchSolver;
+import org.drools.solver.core.localsearch.LocalSearchSolverScope;
+import org.drools.solver.core.localsearch.StepScope;
+import org.drools.solver.core.localsearch.decider.MoveScope;
 import org.drools.solver.core.move.DummyMove;
 import org.drools.solver.core.move.Move;
 
@@ -15,35 +17,43 @@
 
     public void testPicking() {
         Forager forager = new FirstRandomlyAcceptedForager();
-        forager.setLocalSearchSolver(new DefaultLocalSearchSolver() {
-            public Random getRandom() {
-                return new Random() {
+        LocalSearchSolverScope localSearchSolverScope = new LocalSearchSolverScope();
+        localSearchSolverScope.setWorkingRandom(new Random() {
                     public double nextDouble() {
                         return 0.99;
                     }
-                };
-            }
-        });
-        forager.solvingStarted();
-        forager.beforeDeciding();
+                });
+        forager.solvingStarted(localSearchSolverScope);
+        StepScope stepScope = new StepScope(localSearchSolverScope);
+        forager.beforeDeciding(stepScope);
         Move a = new DummyMove();
         Move b = new DummyMove();
         Move c = new DummyMove();
         Move d = new DummyMove();
-        forager.addMove(a, -100.0, 0.0);
+        forager.addMove(createMoveScope(stepScope, a, -100.0, 0.0));
         assertFalse(forager.isQuitEarly());
-        forager.addMove(b, -10.0, 0.8);
+        forager.addMove(createMoveScope(stepScope, b, -10.0, 0.8));
         assertFalse(forager.isQuitEarly());
-        forager.addMove(c, -10.0, 0.0);
+        forager.addMove(createMoveScope(stepScope, c, -10.0, 0.0));
         assertFalse(forager.isQuitEarly());
-        forager.addMove(d, -100.0, 1.0);
+        forager.addMove(createMoveScope(stepScope, d, -100.0, 1.0));
         assertTrue(forager.isQuitEarly());
-        Move picked = forager.pickMove();
+        MoveScope pickedScope = forager.pickMove(stepScope);
+        Move picked = pickedScope.getMove();
         assertTrue(picked == d);
         List<Move> topList = forager.getTopList(2);
         assertTrue(topList.contains(b));
         assertTrue(topList.contains(d));
-        forager.solvingEnded();
+        forager.solvingEnded(localSearchSolverScope);
     }
 
+    public MoveScope createMoveScope(StepScope stepScope, Move move, double score, double acceptChance) {
+        // TODO duplicate code from MaxScoreOfAllForagerTest
+        MoveScope moveScope = new MoveScope(stepScope);
+        moveScope.setMove(move);
+        moveScope.setScore(score);
+        moveScope.setAcceptChance(acceptChance);
+        return moveScope;
+    }
+
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/test/java/org/drools/solver/core/localsearch/decider/forager/MaxScoreOfAllForagerTest.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/test/java/org/drools/solver/core/localsearch/decider/forager/MaxScoreOfAllForagerTest.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/test/java/org/drools/solver/core/localsearch/decider/forager/MaxScoreOfAllForagerTest.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -4,7 +4,9 @@
 import java.util.Random;
 
 import junit.framework.TestCase;
-import org.drools.solver.core.localsearch.DefaultLocalSearchSolver;
+import org.drools.solver.core.localsearch.LocalSearchSolverScope;
+import org.drools.solver.core.localsearch.StepScope;
+import org.drools.solver.core.localsearch.decider.MoveScope;
 import org.drools.solver.core.move.DummyMove;
 import org.drools.solver.core.move.Move;
 
@@ -15,24 +17,23 @@
 
     public void testPicking() {
         Forager forager = new MaxScoreOfAllForager();
-        forager.setLocalSearchSolver(new DefaultLocalSearchSolver() {
-            public Random getRandom() {
-                return new Random();
-            }
-        });
-        forager.solvingStarted();
-        forager.beforeDeciding();
+        LocalSearchSolverScope localSearchSolverScope = new LocalSearchSolverScope();
+        localSearchSolverScope.setWorkingRandom(new Random());
+        forager.solvingStarted(localSearchSolverScope);
+        StepScope stepScope = new StepScope(localSearchSolverScope);
+        forager.beforeDeciding(stepScope);
         Move a = new DummyMove();
         Move b = new DummyMove();
         Move c = new DummyMove();
         Move d = new DummyMove();
         Move e = new DummyMove();
-        forager.addMove(a, -100.0, 10000.0);
-        forager.addMove(b, -90.0, 2000.0);
-        forager.addMove(c, -100.0, 300.0);
-        forager.addMove(d, -190.0, 40.0);
-        forager.addMove(e, -90.0, 5.0);
-        Move picked = forager.pickMove();
+        forager.addMove(createMoveScope(stepScope, a, -100.0, 10000.0));
+        forager.addMove(createMoveScope(stepScope, b, -90.0, 2000.0));
+        forager.addMove(createMoveScope(stepScope, c, -100.0, 300.0));
+        forager.addMove(createMoveScope(stepScope, d, -190.0, 40.0));
+        forager.addMove(createMoveScope(stepScope, e, -90.0, 5.0));
+        MoveScope pickedScope = forager.pickMove(stepScope);
+        Move picked = pickedScope.getMove();
         assertTrue(picked == b || picked == e);
         List<Move> topList = forager.getTopList(3);
         assertTrue(topList.contains(a));
@@ -40,7 +41,15 @@
         assertFalse(topList.contains(c));
         assertFalse(topList.contains(d));
         assertTrue(topList.contains(e));
-        forager.solvingEnded();
+        forager.solvingEnded(localSearchSolverScope);
     }
 
+    public MoveScope createMoveScope(StepScope stepScope, Move move, double score, double acceptChance) {
+        MoveScope moveScope = new MoveScope(stepScope);
+        moveScope.setMove(move);
+        moveScope.setScore(score);
+        moveScope.setAcceptChance(acceptChance);
+        return moveScope;
+    }
+
 }

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/common/business/SolutionBusiness.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/common/business/SolutionBusiness.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/common/business/SolutionBusiness.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -10,10 +10,11 @@
 import java.util.List;
 import java.util.Map;
 
-import org.drools.StatefulSession;
+import org.drools.WorkingMemory;
 import org.drools.base.ClassObjectFilter;
 import org.drools.solver.core.Solver;
-import org.drools.solver.core.evaluation.EvaluationHandler;
+import org.drools.solver.core.localsearch.DefaultLocalSearchSolver;
+import org.drools.solver.core.localsearch.LocalSearchSolverScope;
 import org.drools.solver.core.move.Move;
 import org.drools.solver.core.score.constraint.ConstraintOccurrence;
 import org.drools.solver.core.score.constraint.DoubleConstraintOccurrence;
@@ -37,7 +38,7 @@
     private File solvedDataDir;
 
     private Solver solver;
-    private EvaluationHandler evaluationHandler;
+    private LocalSearchSolverScope localSearchSolverScope;
 
     public void setSolutionDao(SolutionDao solutionDao) {
         this.solutionDao = solutionDao;
@@ -66,7 +67,7 @@
 
     public void setSolver(Solver solver) {
         this.solver = solver;
-        this.evaluationHandler = solver.getEvaluationHandler();
+        this.localSearchSolverScope = ((DefaultLocalSearchSolver) solver).getLocalSearchSolverScope();
     }
 
 
@@ -83,20 +84,20 @@
     }
 
     public Solution getSolution() {
-        return evaluationHandler.getSolution();
+        return localSearchSolverScope.getWorkingSolution();
     }
 
     public double getScore() {
-        return evaluationHandler.fireAllRulesAndCalculateStepScore();
+        return localSearchSolverScope.calculateScoreFromWorkingMemory();
     }
 
     public List<ScoreDetail> getScoreDetailList() {
         Map<String, ScoreDetail> scoreDetailMap = new HashMap<String, ScoreDetail>();
-        StatefulSession statefulSession = evaluationHandler.getStatefulSession();
-        if (statefulSession == null) {
+        WorkingMemory workingMemory = localSearchSolverScope.getWorkingMemory();
+        if (workingMemory == null) {
             return Collections.emptyList();
         }
-        Iterator<ConstraintOccurrence> it = statefulSession.iterateObjects(
+        Iterator<ConstraintOccurrence> it = workingMemory.iterateObjects(
                 new ClassObjectFilter(ConstraintOccurrence.class));
         while (it.hasNext()) {
             ConstraintOccurrence occurrence = it.next();
@@ -129,17 +130,17 @@
     }
 
     public void save(File file) {
-        Solution solution = evaluationHandler.getSolution();
+        Solution solution = localSearchSolverScope.getWorkingSolution();
         solutionDao.writeSolution(solution, file);
     }
 
     public void doMove(Move move) {
-        if (!move.isMoveDoable(evaluationHandler.getStatefulSession())) {
+        if (!move.isMoveDoable(localSearchSolverScope.getWorkingMemory())) {
             logger.info("Not doing user move ({}) because it is not doable.", move);
             return;
         }
         logger.info("Doing user move ({}).", move);
-        move.doMove(evaluationHandler.getStatefulSession());
+        move.doMove(localSearchSolverScope.getWorkingMemory());
     }
 
     public void solve() {

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/itc2007/curriculumcourse/solver/move/factory/LectureSwitchMoveFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/itc2007/curriculumcourse/solver/move/factory/LectureSwitchMoveFactory.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/itc2007/curriculumcourse/solver/move/factory/LectureSwitchMoveFactory.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -17,7 +17,7 @@
 public class LectureSwitchMoveFactory extends CachedMoveFactory {
 
     public List<Move> createCachedMoveList(Solution solution) {
-        CurriculumCourseSchedule schedule = (CurriculumCourseSchedule) localSearchSolver.getCurrentSolution();
+        CurriculumCourseSchedule schedule = (CurriculumCourseSchedule) solution;
         List<Lecture> lectureList = schedule.getLectureList();
         List<Move> moveList = new ArrayList<Move>();
         for (ListIterator<Lecture> leftIt = lectureList.listIterator(); leftIt.hasNext();) {

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/itc2007/curriculumcourse/solver/solution/initializer/CurriculumCourseStartingSolutionInitializer.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/itc2007/curriculumcourse/solver/solution/initializer/CurriculumCourseStartingSolutionInitializer.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/itc2007/curriculumcourse/solver/solution/initializer/CurriculumCourseStartingSolutionInitializer.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -7,8 +7,7 @@
 import org.apache.commons.lang.builder.CompareToBuilder;
 import org.drools.FactHandle;
 import org.drools.WorkingMemory;
-import org.drools.solver.core.evaluation.EvaluationHandler;
-import org.drools.solver.core.solution.Solution;
+import org.drools.solver.core.localsearch.LocalSearchSolverScope;
 import org.drools.solver.core.solution.initializer.AbstractStartingSolutionInitializer;
 import org.drools.solver.examples.common.domain.PersistableIdComparator;
 import org.drools.solver.examples.itc2007.curriculumcourse.domain.Course;
@@ -24,26 +23,25 @@
 public class CurriculumCourseStartingSolutionInitializer extends AbstractStartingSolutionInitializer {
 
     @Override
-    public boolean isSolutionInitialized(Solution solution) {
-        CurriculumCourseSchedule schedule = (CurriculumCourseSchedule) solution;
+    public boolean isSolutionInitialized(LocalSearchSolverScope localSearchSolverScope) {
+        CurriculumCourseSchedule schedule = (CurriculumCourseSchedule) localSearchSolverScope.getWorkingSolution();
         return schedule.isInitialized();
     }
 
-    public void initializeSolution(Solution solution) {
-        CurriculumCourseSchedule schedule = (CurriculumCourseSchedule) solution;
-        initializeLectureList(schedule);
+    public void initializeSolution(LocalSearchSolverScope localSearchSolverScope) {
+        CurriculumCourseSchedule schedule = (CurriculumCourseSchedule) localSearchSolverScope.getWorkingSolution();
+        initializeLectureList(localSearchSolverScope, schedule);
     }
 
-    private void initializeLectureList(CurriculumCourseSchedule schedule) {
-        EvaluationHandler evaluationHandler = solver.getEvaluationHandler();
+    private void initializeLectureList(LocalSearchSolverScope localSearchSolverScope,
+            CurriculumCourseSchedule schedule) {
         List<Period> periodList = schedule.getPeriodList();
         List<Room> roomList = schedule.getRoomList();
-        evaluationHandler.setSolution(schedule);
-        WorkingMemory workingMemory = evaluationHandler.getStatefulSession();
+        WorkingMemory workingMemory = localSearchSolverScope.getWorkingMemory();
 
         List<Lecture> lectureList = createLectureList(schedule);
         for (Lecture lecture : lectureList) {
-            double unscheduledScore = evaluationHandler.fireAllRulesAndCalculateStepScore();
+            double unscheduledScore = localSearchSolverScope.calculateScoreFromWorkingMemory();
             FactHandle lectureHandle = null;
 
             List<PeriodScoring> periodScoringList = new ArrayList<PeriodScoring>(periodList.size());
@@ -56,7 +54,7 @@
                     lecture.setPeriod(period);
                     workingMemory.modifyInsert(lectureHandle, lecture);
                 }
-                double score = evaluationHandler.fireAllRulesAndCalculateStepScore();
+                double score = localSearchSolverScope.calculateScoreFromWorkingMemory();
                 periodScoringList.add(new PeriodScoring(period, score));
             }
             Collections.sort(periodScoringList);
@@ -78,7 +76,7 @@
                     workingMemory.modifyRetract(lectureHandle);
                     lecture.setRoom(room);
                     workingMemory.modifyInsert(lectureHandle, lecture);
-                    double score = evaluationHandler.fireAllRulesAndCalculateStepScore();
+                    double score = localSearchSolverScope.calculateScoreFromWorkingMemory();
                     if (score < unscheduledScore) {
                         if (score > bestScore) {
                             bestScore = score;

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/itc2007/examination/solver/move/factory/ExamSwitchMoveFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/itc2007/examination/solver/move/factory/ExamSwitchMoveFactory.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/itc2007/examination/solver/move/factory/ExamSwitchMoveFactory.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -17,7 +17,7 @@
 public class ExamSwitchMoveFactory extends CachedMoveFactory {
 
     public List<Move> createCachedMoveList(Solution solution) {
-        Examination examination = (Examination) localSearchSolver.getCurrentSolution();
+        Examination examination = (Examination) solution;
         List<Exam> examList = examination.getExamList();
         List<Move> moveList = new ArrayList<Move>();
         for (ListIterator<Exam> leftIt = examList.listIterator(); leftIt.hasNext();) {

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/itc2007/examination/solver/solution/initializer/ExaminationStartingSolutionInitializer.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/itc2007/examination/solver/solution/initializer/ExaminationStartingSolutionInitializer.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/itc2007/examination/solver/solution/initializer/ExaminationStartingSolutionInitializer.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -11,8 +11,7 @@
 import org.apache.commons.lang.builder.CompareToBuilder;
 import org.drools.FactHandle;
 import org.drools.WorkingMemory;
-import org.drools.solver.core.evaluation.EvaluationHandler;
-import org.drools.solver.core.solution.Solution;
+import org.drools.solver.core.localsearch.LocalSearchSolverScope;
 import org.drools.solver.core.solution.initializer.AbstractStartingSolutionInitializer;
 import org.drools.solver.examples.common.domain.PersistableIdComparator;
 import org.drools.solver.examples.itc2007.examination.domain.Exam;
@@ -31,28 +30,26 @@
 public class ExaminationStartingSolutionInitializer extends AbstractStartingSolutionInitializer {
 
     @Override
-    public boolean isSolutionInitialized(Solution solution) {
-        Examination examination = (Examination) solution;
+    public boolean isSolutionInitialized(LocalSearchSolverScope localSearchSolverScope) {
+        Examination examination = (Examination) localSearchSolverScope.getWorkingSolution();
         return examination.isInitialized();
     }
 
-    public void initializeSolution(Solution solution) {
-        Examination examination = (Examination) solution;
-        initializeExamList(examination);
+    public void initializeSolution(LocalSearchSolverScope localSearchSolverScope) {
+        Examination examination = (Examination) localSearchSolverScope.getWorkingSolution();
+        initializeExamList(localSearchSolverScope, examination);
     }
 
-    private void initializeExamList(Examination examination) {
-        EvaluationHandler evaluationHandler = solver.getEvaluationHandler();
+    private void initializeExamList(LocalSearchSolverScope localSearchSolverScope, Examination examination) {
         List<Period> periodList = examination.getPeriodList();
         List<Room> roomList = examination.getRoomList();
         List<Exam> examList = new ArrayList<Exam>(examination.getTopicList().size()); // TODO this can be returned from createExamAssigningScoreList
-        evaluationHandler.setSolution(examination);
-        WorkingMemory workingMemory = evaluationHandler.getStatefulSession();
+        WorkingMemory workingMemory = localSearchSolverScope.getWorkingMemory();
 
         List<ExamInitializationWeight> examInitialWeightList = createExamAssigningScoreList(examination);
 
         for (ExamInitializationWeight examInitialWeight : examInitialWeightList) {
-            double unscheduledScore = evaluationHandler.fireAllRulesAndCalculateStepScore();
+            double unscheduledScore = localSearchSolverScope.calculateScoreFromWorkingMemory();
             Exam leader = examInitialWeight.getExam();
             FactHandle leaderHandle = null;
 
@@ -80,12 +77,12 @@
                         workingMemory.modifyInsert(examToHandle.getExamHandle(), examToHandle.getExam());
                     }
                 }
-                double score = evaluationHandler.fireAllRulesAndCalculateStepScore();
+                double score = localSearchSolverScope.calculateScoreFromWorkingMemory();
                 periodScoringList.add(new PeriodScoring(period, score));
             }
             Collections.sort(periodScoringList);
 
-            scheduleLeader(periodScoringList, roomList, evaluationHandler, workingMemory, unscheduledScore,
+            scheduleLeader(periodScoringList, roomList, localSearchSolverScope, workingMemory, unscheduledScore,
                     examToHandleList, leader, leaderHandle);
             examList.add(leader);
 
@@ -94,7 +91,7 @@
                 Exam exam = examToHandle.getExam();
                 // Leader already has a room
                 if (!exam.isCoincidenceLeader()) {
-                    scheduleNonLeader(roomList, evaluationHandler, workingMemory, exam, examToHandle.getExamHandle());
+                    scheduleNonLeader(roomList, localSearchSolverScope, workingMemory, exam, examToHandle.getExamHandle());
                     examList.add(exam);
                 }
             }
@@ -104,7 +101,7 @@
     }
 
     private void scheduleLeader(List<PeriodScoring> periodScoringList, List<Room> roomList,
-            EvaluationHandler evaluationHandler, WorkingMemory workingMemory, double unscheduledScore,
+            LocalSearchSolverScope localSearchSolverScope, WorkingMemory workingMemory, double unscheduledScore,
             List<ExamToHandle> examToHandleList, Exam leader, FactHandle leaderHandle) {
         boolean perfectMatch = false;
         double bestScore = Double.NEGATIVE_INFINITY;
@@ -124,7 +121,7 @@
                 workingMemory.modifyRetract(leaderHandle);
                 leader.setRoom(room);
                 workingMemory.modifyInsert(leaderHandle, leader);
-                double score = evaluationHandler.fireAllRulesAndCalculateStepScore();
+                double score = localSearchSolverScope.calculateScoreFromWorkingMemory();
                 if (score < unscheduledScore) {
                     if (score > bestScore) {
                         bestScore = score;
@@ -161,12 +158,12 @@
     }
 
     private void scheduleNonLeader(List<Room> roomList,
-            EvaluationHandler evaluationHandler, WorkingMemory workingMemory,
+            LocalSearchSolverScope localSearchSolverScope, WorkingMemory workingMemory,
             Exam exam, FactHandle examHandle) {
         if (exam.getRoom() != null) {
             throw new IllegalStateException("Exam (" + exam + ") already has a room.");
         }
-        double unscheduledScore = evaluationHandler.fireAllRulesAndCalculateStepScore();
+        double unscheduledScore = localSearchSolverScope.calculateScoreFromWorkingMemory();
         boolean perfectMatch = false;
         double bestScore = Double.NEGATIVE_INFINITY;
         Room bestRoom = null;
@@ -174,7 +171,7 @@
             workingMemory.modifyRetract(examHandle);
             exam.setRoom(room);
             workingMemory.modifyInsert(examHandle, exam);
-            double score = evaluationHandler.fireAllRulesAndCalculateStepScore();
+            double score = localSearchSolverScope.calculateScoreFromWorkingMemory();
             if (score < unscheduledScore) {
                 if (score > bestScore) {
                     bestScore = score;

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/travelingtournament/solver/smart/move/factory/SmartTravelingTournamentMoveFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/travelingtournament/solver/smart/move/factory/SmartTravelingTournamentMoveFactory.java	2008-04-16 18:21:26 UTC (rev 19598)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/travelingtournament/solver/smart/move/factory/SmartTravelingTournamentMoveFactory.java	2008-04-16 19:18:08 UTC (rev 19599)
@@ -8,6 +8,7 @@
 import java.util.ListIterator;
 import java.util.Map;
 
+import org.drools.solver.core.localsearch.LocalSearchSolverScope;
 import org.drools.solver.core.move.Move;
 import org.drools.solver.core.move.factory.AbstractMoveFactory;
 import org.drools.solver.core.solution.Solution;
@@ -26,8 +27,8 @@
     private List<Move> cachedMoveList;
 
     @Override
-    public void solvingStarted() {
-        TravelingTournament travelingTournament = (TravelingTournament) localSearchSolver.getCurrentSolution();
+    public void solvingStarted(LocalSearchSolverScope localSearchSolverScope) {
+        TravelingTournament travelingTournament = (TravelingTournament) localSearchSolverScope.getWorkingSolution();
         cachedMoveList = new ArrayList<Move>(travelingTournament.getMatchList().size() / 2);
         addCachedHomeAwaySwapMoves(travelingTournament);
     }

Modified: labs/jbossrules/trunk/drools-solver/src/uml/design.jude
===================================================================
(Binary files differ)




More information about the jboss-svn-commits mailing list