[jboss-svn-commits] JBL Code SVN: r22931 - in labs/jbossrules/trunk: drools-compiler/src/test/java/org/drools/integrationtests and 9 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Fri Sep 19 18:46:08 EDT 2008


Author: tirelli
Date: 2008-09-19 18:46:08 -0400 (Fri, 19 Sep 2008)
New Revision: 22931

Added:
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/Neighbor.java
   labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_LockOnActiveWithModify.drl
   labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_ModifyWithLockOnActive.drl
Modified:
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/Cell.java
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/ExecutionFlowControlTest.java
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/ClassFieldAccessorCache.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultAgenda.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalAgenda.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java
   labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/java/org/drools/examples/conway/AgendaGroupDelegate.java
   labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/java/org/drools/examples/conway/RuleFlowDelegate.java
   labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/rules/org/drools/examples/PetStore.drl
   labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/rules/org/drools/examples/Shopping.drl
   labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/rules/org/drools/examples/conway/conway-agendagroup.drl
   labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/rules/org/drools/examples/process/order/validation.drl
   labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/rules/org/drools/tutorials/banking/Example2.drl
   labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/rules/org/drools/tutorials/banking/Example3.drl
Log:
JBRULES-1774: fixing examples for 5.0M2 release. Adding tests to integration tests

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/Cell.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/Cell.java	2008-09-19 18:29:01 UTC (rev 22930)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/Cell.java	2008-09-19 22:46:08 UTC (rev 22931)
@@ -19,8 +19,13 @@
  */
 
 public class Cell implements Serializable {
+    public static final int LIVE = 1;
+    public static final int DEAD = 2;
 
     int value = 0;
+    int row;
+    int col;
+    int state;
 
     public Cell() {
 
@@ -29,6 +34,22 @@
     public Cell(final int value) {
         this.value = value;
     }
+    
+    public Cell(int state,
+                int row,
+                int col) {
+        super();
+        this.state = state;
+        this.row = row;
+        this.col = col;
+//        if( row == 1 && col == 1 ) {
+//            value = 8;
+//        } else if( row+col == 2 ) {
+//            value = 3;
+//        } else {
+//            value = 5;
+//        }
+    }
 
     public int getValue() {
         return this.value;
@@ -38,11 +59,41 @@
         this.value = value;
     }
 
+    public int getX() {
+        return row;
+    }
+
+    public void setX(int x) {
+        this.row = x;
+    }
+
+    public int getY() {
+        return col;
+    }
+
+    public void setY(int y) {
+        this.col = y;
+    }
+
+    public int getState() {
+        return state;
+    }
+
+    public void setState(int state) {
+        this.state = state;
+    }
+    
     @Override
+    public String toString() {
+        return "Cell( ["+row+","+col+"] "+( (state==DEAD)?"DEAD":"LIVE") +" = "+value+" )";
+    }
+
+    @Override
     public int hashCode() {
         final int prime = 31;
         int result = 1;
-        result = prime * result + value;
+        result = prime * result + row;
+        result = prime * result + col;
         return result;
     }
 
@@ -51,8 +102,11 @@
         if ( this == obj ) return true;
         if ( obj == null ) return false;
         if ( getClass() != obj.getClass() ) return false;
-        final Cell other = (Cell) obj;
-        if ( value != other.value ) return false;
+        Cell other = (Cell) obj;
+        if ( row != other.row ) return false;
+        if ( col != other.col ) return false;
         return true;
     }
+    
+    
 }
\ No newline at end of file

Added: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/Neighbor.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/Neighbor.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/Neighbor.java	2008-09-19 22:46:08 UTC (rev 22931)
@@ -0,0 +1,31 @@
+package org.drools;
+
+public class Neighbor {
+    
+    private Cell cell;
+    private Cell neighbor;
+    public Neighbor(Cell cell,
+                    Cell neighbor) {
+        super();
+        this.cell = cell;
+        this.neighbor = neighbor;
+    }
+    public Cell getCell() {
+        return cell;
+    }
+    public void setCell(Cell cell) {
+        this.cell = cell;
+    }
+    public Cell getNeighbor() {
+        return neighbor;
+    }
+    public void setNeighbor(Cell neighbor) {
+        this.neighbor = neighbor;
+    }
+    
+    @Override
+    public String toString() {
+        return "[" + cell + " <=> " + neighbor +"]";
+    }
+    
+}

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/ExecutionFlowControlTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/ExecutionFlowControlTest.java	2008-09-19 18:29:01 UTC (rev 22930)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/ExecutionFlowControlTest.java	2008-09-19 22:46:08 UTC (rev 22931)
@@ -4,9 +4,11 @@
 import junit.framework.TestCase;
 
 import org.drools.Alarm;
+import org.drools.Cell;
 import org.drools.Cheese;
 import org.drools.FactHandle;
 import org.drools.Message;
+import org.drools.Neighbor;
 import org.drools.Person;
 import org.drools.PersonInterface;
 import org.drools.RuleBase;
@@ -14,6 +16,7 @@
 import org.drools.RuleBaseFactory;
 import org.drools.StatefulSession;
 import org.drools.WorkingMemory;
+import org.drools.audit.WorkingMemoryFileLogger;
 import org.drools.common.DefaultAgenda;
 import org.drools.common.InternalWorkingMemoryActions;
 import org.drools.common.RuleFlowGroupImpl;
@@ -319,6 +322,148 @@
                       group2.size() );
     }
 
+    public void testLockOnActiveWithModify2() throws Exception {
+        final PackageBuilder builder = new PackageBuilder();
+        builder.addPackageFromDrl( new InputStreamReader( getClass().getResourceAsStream( "test_LockOnActiveWithModify.drl" ) ) );
+        final Package pkg = builder.getPackage();
+
+        RuleBase ruleBase = getRuleBase();
+        ruleBase.addPackage( pkg );
+        ruleBase    = SerializationHelper.serializeObject(ruleBase);
+        final StatefulSession session = ruleBase.newStatefulSession();
+//        WorkingMemoryFileLogger logger = new WorkingMemoryFileLogger( session );
+//        logger.setFileName( "conway" );
+
+        // populating working memory
+        final int size = 3;
+        
+        Cell[][] cells = new Cell[size][];
+        FactHandle[][] handles = new FactHandle[size][];
+        for( int row = 0; row < size; row++ ) {
+            cells[row] = new Cell[size];
+            handles[row] = new FactHandle[size];
+            for( int col = 0; col < size; col++ ) {
+                cells[row][col] = new Cell(Cell.DEAD, row, col);
+                handles[row][col] = session.insert( cells[row][col] );
+                if( row >= 1 && col >=1 ) {
+                    // northwest
+                    session.insert( new Neighbor( cells[row-1][col-1], cells[row][col] ) );
+                    session.insert( new Neighbor( cells[row][col], cells[row-1][col-1] ) );
+                }
+                if( row >= 1 ) {
+                    // north
+                    session.insert( new Neighbor( cells[row-1][col], cells[row][col] ) );
+                    session.insert( new Neighbor( cells[row][col], cells[row-1][col] ) );
+                }
+                if( row >= 1 && col < (size-1) ) {
+                    // northeast
+                    session.insert( new Neighbor( cells[row-1][col+1], cells[row][col] ) );
+                    session.insert( new Neighbor( cells[row][col], cells[row-1][col+1] ) );
+                }
+                if( col >= 1 ) {
+                    // west
+                    session.insert( new Neighbor( cells[row][col-1], cells[row][col] ) );
+                    session.insert( new Neighbor( cells[row][col], cells[row][col-1] ) );
+                }
+            }
+        }
+
+        session.clearAgendaGroup( "calculate" );
+        
+        // now, start playing
+        int fired = session.fireAllRules(100);
+        assertEquals( 0, fired );
+
+        session.setFocus( "calculate" );
+        fired = session.fireAllRules(100);
+//        logger.writeToDisk();
+        assertEquals( 0, fired );
+        assertEquals( "MAIN", session.getAgenda().getFocusName() );
+        
+        // on the fifth day God created the birds and sea creatures
+        session.modifyRetract( handles[0][0] );
+        cells[0][0].setState( Cell.LIVE );
+        session.modifyInsert( handles[0][0], cells[0][0] );
+        session.setFocus( "birth" );
+        session.setFocus( "calculate" );
+        fired = session.fireAllRules(100);
+        
+//        logger.writeToDisk();
+        int[][] expected = new int[][]{{0,1,0},{1,1,0},{0,0,0}};
+        assertEqualsMatrix( size,
+                            cells,
+                            expected );
+        assertEquals( "MAIN", session.getAgenda().getFocusName() );
+        
+        // on the sixth day God created the animals that walk over the land and the Man
+        session.modifyRetract( handles[1][1] );
+        cells[1][1].setState( Cell.LIVE );
+        session.modifyInsert( handles[1][1], cells[1][1] );
+        session.setFocus( "calculate" );
+        session.fireAllRules(100);
+//        logger.writeToDisk();
+        
+        expected = new int[][]{{1,2,1},{2,1,1},{1,1,1}};
+        assertEqualsMatrix( size,
+                            cells,
+                            expected );
+        assertEquals( "MAIN", session.getAgenda().getFocusName() );
+        
+        session.setFocus( "birth" );
+        session.fireAllRules(100);
+        expected = new int[][]{{1,2,1},{2,1,1},{1,1,1}};
+        assertEqualsMatrix( size,
+                            cells,
+                            expected );
+        assertEquals( "MAIN", session.getAgenda().getFocusName() );
+
+        session.setFocus( "calculate" );
+        session.fireAllRules(100);
+//        logger.writeToDisk();
+//        printMatrix( cells );
+        
+        expected = new int[][]{{3,3,2},{3,3,2},{2,2,1}};
+        assertEqualsMatrix( size,
+                            cells,
+                            expected );
+        assertEquals( "MAIN", session.getAgenda().getFocusName() );
+
+        // on the seventh day, while God rested, man start killing them all
+        session.modifyRetract( handles[0][0] );
+        cells[0][0].setState( Cell.DEAD );
+        session.modifyInsert( handles[0][0], cells[0][0] );
+        session.setFocus( "calculate" );
+        session.fireAllRules(100);
+        
+        expected = new int[][]{{3,2,2},{2,2,2},{2,2,1}};
+        assertEqualsMatrix( size,
+                            cells,
+                            expected );
+        assertEquals( "MAIN", session.getAgenda().getFocusName() );
+        
+    }
+
+//    private void printMatrix(Cell[][] cells) {
+//        System.out.println("----------");
+//        for( int row = 0; row < cells.length; row++) {
+//            for( int col = 0; col < cells[row].length; col++ ) {
+//                System.out.print( cells[row][col].getValue() + ((cells[row][col].getState()==Cell.LIVE)?"L  ":".  ") );
+//            }
+//            System.out.println();
+//        }
+//        System.out.println("----------");
+//    }
+
+    private void assertEqualsMatrix(final int size,
+                                    Cell[][] cells,
+                                    int[][] expected) {
+        for( int row = 0; row < size; row++) {
+            for( int col = 0; col < size; col++ ) {
+                assertEquals( "Wrong value at "+row+","+col+": ", expected[row][col], cells[row][col].getValue() );
+            }
+        }
+    }
+
     public void testAgendaGroups() throws Exception {
         final PackageBuilder builder = new PackageBuilder();
         builder.addPackageFromDrl( new InputStreamReader( getClass().getResourceAsStream( "test_AgendaGroups.drl" ) ) );

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java	2008-09-19 18:29:01 UTC (rev 22930)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java	2008-09-19 22:46:08 UTC (rev 22931)
@@ -5486,5 +5486,33 @@
 
     }
 
+    public void testModifyWithLockOnActive() throws Exception {
+        final PackageBuilder builder = new PackageBuilder();
+        builder.addPackageFromDrl( new InputStreamReader( getClass().getResourceAsStream( "test_ModifyWithLockOnActive.drl" ) ) );
+        final Package pkg = builder.getPackage();
 
+        RuleBase ruleBase = getRuleBase();
+        ruleBase.addPackage( pkg );
+        ruleBase = SerializationHelper.serializeObject( ruleBase );
+        StatefulSession session = ruleBase.newStatefulSession();
+
+        final List results = new ArrayList();
+        session.setGlobal( "results",
+                           results );
+
+        final Person bob = new Person( "Bob", 15 );
+        final Person mark = new Person( "Mark", 16 );
+        final Person michael = new Person( "Michael", 14);
+        session.insert( bob );
+        session.insert( mark );
+        session.insert( michael );
+        session.setFocus( "feeding" );
+        session.fireAllRules( 5 );
+
+        assertEquals( 2,
+                      ((List) session.getGlobal( "results" )).size() );
+
+    }
+
+
 }

Added: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_LockOnActiveWithModify.drl
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_LockOnActiveWithModify.drl	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_LockOnActiveWithModify.drl	2008-09-19 22:46:08 UTC (rev 22931)
@@ -0,0 +1,33 @@
+package org.drools;
+
+rule "calculate live"
+	agenda-group "calculate"
+	lock-on-active true
+    when
+    	$c : Cell( state == Cell.LIVE )
+    	     Neighbor( cell == $c, $n : neighbor )
+    then
+		modify( $n ) {
+		    setValue( $n.getValue() + 1 )
+		}
+end  
+
+rule "calculate dead"
+	agenda-group "calculate"
+	lock-on-active true
+    when
+    	$c : Cell( state == Cell.DEAD )
+    	     Neighbor( cell == $c, $n : neighbor )
+    then
+		modify( $n ) {
+		    setValue( $n.getValue() - 1 )
+		}
+end  
+
+rule "and there was life"
+   agenda-group "birth"
+   when
+       $c : Cell( state == Cell.DEAD, value == 2 )
+   then
+       modify( $c ) { setState( Cell.LIVE ) }
+end

Added: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_ModifyWithLockOnActive.drl
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_ModifyWithLockOnActive.drl	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_ModifyWithLockOnActive.drl	2008-09-19 22:46:08 UTC (rev 22931)
@@ -0,0 +1,22 @@
+package org.drools;
+
+global java.util.List results;
+
+rule "eat food"
+   agenda-group "feeding"
+   lock-on-active
+when
+    $p: Person( age >= 15 )
+then
+    modify( $p ) { setStatus("not hungry") }
+    results.add( $p );
+end
+
+rule "happy birthday"
+   agenda-group "feeding"
+   lock-on-active
+when
+    $p: Person( name == "Michael" )
+then
+    modify( $p ) { setAge(15) }
+end

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/ClassFieldAccessorCache.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/ClassFieldAccessorCache.java	2008-09-19 18:29:01 UTC (rev 22930)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/ClassFieldAccessorCache.java	2008-09-19 22:46:08 UTC (rev 22931)
@@ -285,7 +285,10 @@
         
     public CacheEntry getCacheEntry(Class cls) {
         // System classloader classes return null on some JVMs
-        ClassLoader cl = cls.getClassLoader() != null ? cls.getClassLoader() : ClassLoader.getSystemClassLoader();
+        ClassLoader cl = cls.getClassLoader() != null ? 
+        		         cls.getClassLoader() : ( this.classLoader != null ) ? 
+        		        		                  this.classLoader : 
+        		        		                  ClassLoader.getSystemClassLoader();
 
         CacheEntry cache = this.cacheByClassLoader.get( cl );
         if ( cache == null ) {

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java	2008-09-19 18:29:01 UTC (rev 22930)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java	2008-09-19 22:46:08 UTC (rev 22931)
@@ -97,1580 +97,1617 @@
  * @author <a href="mailto:mark.proctor at jboss.com">Mark Proctor</a>
  * @author <a href="mailto:simon at redhillconsulting.com.au">Simon Harris </a>
  */
-public abstract class AbstractWorkingMemory implements
-		InternalWorkingMemoryActions, EventSupport, PropertyChangeListener {
-	// ------------------------------------------------------------
-	// Constants
-	// ------------------------------------------------------------
-	protected static final Class[] ADD_REMOVE_PROPERTY_CHANGE_LISTENER_ARG_TYPES = new Class[] { PropertyChangeListener.class };
-	private static final int NODE_MEMORIES_ARRAY_GROWTH = 32;
+public abstract class AbstractWorkingMemory
+    implements
+    InternalWorkingMemoryActions,
+    EventSupport,
+    PropertyChangeListener {
+    // ------------------------------------------------------------
+    // Constants
+    // ------------------------------------------------------------
+    protected static final Class[]                           ADD_REMOVE_PROPERTY_CHANGE_LISTENER_ARG_TYPES = new Class[]{PropertyChangeListener.class};
+    private static final int                                 NODE_MEMORIES_ARRAY_GROWTH                    = 32;
 
-	// ------------------------------------------------------------
-	// Instance members
-	// ------------------------------------------------------------
-	protected long id;
+    // ------------------------------------------------------------
+    // Instance members
+    // ------------------------------------------------------------
+    protected long                                           id;
 
-	/** The arguments used when adding/removing a property change listener. */
-	protected Object[] addRemovePropertyChangeListenerArgs;
+    /** The arguments used when adding/removing a property change listener. */
+    protected Object[]                                       addRemovePropertyChangeListenerArgs;
 
-	/** The actual memory for the <code>JoinNode</code>s. */
-	protected NodeMemories nodeMemories;
+    /** The actual memory for the <code>JoinNode</code>s. */
+    protected NodeMemories                                   nodeMemories;
 
-	protected ObjectStore objectStore;
+    protected ObjectStore                                    objectStore;
 
-	protected Map queryResults;
+    protected Map                                            queryResults;
 
-	/** Global values which are associated with this memory. */
-	protected GlobalResolver globalResolver;
+    /** Global values which are associated with this memory. */
+    protected GlobalResolver                                 globalResolver;
 
-	/** The eventSupport */
-	protected WorkingMemoryEventSupport workingMemoryEventSupport;
+    /** The eventSupport */
+    protected WorkingMemoryEventSupport                      workingMemoryEventSupport;
 
-	protected AgendaEventSupport agendaEventSupport;
+    protected AgendaEventSupport                             agendaEventSupport;
 
-	protected RuleFlowEventSupport workflowEventSupport;
+    protected RuleFlowEventSupport                           workflowEventSupport;
 
-	protected List __ruleBaseEventListeners;
+    protected List                                           __ruleBaseEventListeners;
 
-	/** The <code>RuleBase</code> with which this memory is associated. */
-	protected transient InternalRuleBase ruleBase;
+    /** The <code>RuleBase</code> with which this memory is associated. */
+    protected transient InternalRuleBase                     ruleBase;
 
-	protected FactHandleFactory handleFactory;
+    protected FactHandleFactory                              handleFactory;
 
-	protected TruthMaintenanceSystem tms;
+    protected TruthMaintenanceSystem                         tms;
 
-	/** Rule-firing agenda. */
-	protected InternalAgenda agenda;
+    /** Rule-firing agenda. */
+    protected InternalAgenda                                 agenda;
 
-	protected Queue<WorkingMemoryAction> actionQueue;
+    protected Queue<WorkingMemoryAction>                     actionQueue;
 
-	protected volatile boolean evaluatingActionQueue;
+    protected volatile boolean                               evaluatingActionQueue;
 
-	protected ReentrantLock lock;
+    protected ReentrantLock                                  lock;
 
-	protected boolean discardOnLogicalOverride;
+    protected boolean                                        discardOnLogicalOverride;
 
-	/**
-	 * This must be thread safe as it is incremented and read via different
-	 * EntryPoints
-	 */
-	protected AtomicLong propagationIdCounter;
+    /**
+     * This must be thread safe as it is incremented and read via different
+     * EntryPoints
+     */
+    protected AtomicLong                                     propagationIdCounter;
 
-	private boolean maintainTms;
-	private boolean sequential;
+    private boolean                                          maintainTms;
+    private boolean                                          sequential;
 
-	private List liaPropagations;
+    private List                                             liaPropagations;
 
-	/** Flag to determine if a rule is currently being fired. */
-	protected volatile AtomicBoolean firing;
+    /** Flag to determine if a rule is currently being fired. */
+    protected volatile AtomicBoolean                         firing;
 
-	private ProcessInstanceManager processInstanceManager;
+    private ProcessInstanceManager                           processInstanceManager;
 
-	private WorkItemManager workItemManager;
+    private WorkItemManager                                  workItemManager;
 
-	private TimerManager timerManager;
+    private TimerManager                                     timerManager;
 
-	private TimeMachine timeMachine;
+    private TimeMachine                                      timeMachine;
 
-	protected transient ObjectTypeConfigurationRegistry typeConfReg;
+    protected transient ObjectTypeConfigurationRegistry      typeConfReg;
 
-	protected EntryPoint entryPoint;
-	protected transient EntryPointNode entryPointNode;
+    protected EntryPoint                                     entryPoint;
+    protected transient EntryPointNode                       entryPointNode;
 
-	protected Map<String, WorkingMemoryEntryPoint> entryPoints;
+    protected Map<String, WorkingMemoryEntryPoint>           entryPoints;
 
-	protected InternalFactHandle initialFactHandle;
+    protected InternalFactHandle                             initialFactHandle;
 
-	protected SessionConfiguration config;
+    protected SessionConfiguration                           config;
 
-	protected Map<RuleBasePartitionId, PartitionTaskManager> partitionManagers;
+    protected Map<RuleBasePartitionId, PartitionTaskManager> partitionManagers;
 
-	// ------------------------------------------------------------
-	// Constructors
-	// ------------------------------------------------------------
-	public AbstractWorkingMemory() {
+    private Map<InternalFactHandle, PropagationContext>      modifyContexts;
 
-	}
+    // ------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------
+    public AbstractWorkingMemory() {
 
-	/**
-	 * Construct.
-	 * 
-	 * @param ruleBase
-	 *            The backing rule-base.
-	 */
-	public AbstractWorkingMemory(final int id, final InternalRuleBase ruleBase,
-			final FactHandleFactory handleFactory,
-			final SessionConfiguration config) {
-		this(id, ruleBase, handleFactory, null, 0, config);
-	}
+    }
 
-	public AbstractWorkingMemory(final int id, final InternalRuleBase ruleBase,
-			final FactHandleFactory handleFactory,
-			final InitialFactHandle initialFactHandle,
-			final long propagationContext, final SessionConfiguration config) {
-		this.id = id;
-		this.config = config;
-		this.ruleBase = ruleBase;
-		this.handleFactory = handleFactory;
-		this.globalResolver = new MapGlobalResolver();
+    /**
+     * Construct.
+     * 
+     * @param ruleBase
+     *            The backing rule-base.
+     */
+    public AbstractWorkingMemory(final int id,
+                                 final InternalRuleBase ruleBase,
+                                 final FactHandleFactory handleFactory,
+                                 final SessionConfiguration config) {
+        this( id,
+              ruleBase,
+              handleFactory,
+              null,
+              0,
+              config );
+    }
 
-		final RuleBaseConfiguration conf = this.ruleBase.getConfiguration();
+    public AbstractWorkingMemory(final int id,
+                                 final InternalRuleBase ruleBase,
+                                 final FactHandleFactory handleFactory,
+                                 final InitialFactHandle initialFactHandle,
+                                 final long propagationContext,
+                                 final SessionConfiguration config) {
+        this.id = id;
+        this.config = config;
+        this.ruleBase = ruleBase;
+        this.handleFactory = handleFactory;
+        this.globalResolver = new MapGlobalResolver();
 
-		this.maintainTms = conf.isMaintainTms();
-		this.sequential = conf.isSequential();
+        final RuleBaseConfiguration conf = this.ruleBase.getConfiguration();
 
-		if (initialFactHandle == null) {
-			this.initialFactHandle = new InitialFactHandle(handleFactory
-					.newFactHandle(new InitialFactHandleDummyObject(), null,
-							this));
-		} else {
-			this.initialFactHandle = initialFactHandle;
-		}
+        this.maintainTms = conf.isMaintainTms();
+        this.sequential = conf.isSequential();
 
-		this.actionQueue = new LinkedList<WorkingMemoryAction>();
+        if ( initialFactHandle == null ) {
+            this.initialFactHandle = new InitialFactHandle( handleFactory.newFactHandle( new InitialFactHandleDummyObject(),
+                                                                                         null,
+                                                                                         this ) );
+        } else {
+            this.initialFactHandle = initialFactHandle;
+        }
 
-		this.addRemovePropertyChangeListenerArgs = new Object[] { this };
-		this.queryResults = Collections.EMPTY_MAP;
-		this.workingMemoryEventSupport = new WorkingMemoryEventSupport();
-		this.agendaEventSupport = new AgendaEventSupport();
-		this.workflowEventSupport = new RuleFlowEventSupport();
-		this.__ruleBaseEventListeners = new LinkedList();
-		this.lock = new ReentrantLock();
-		this.liaPropagations = Collections.EMPTY_LIST;
-		this.processInstanceManager = conf.getProcessInstanceManagerFactory()
-				.createProcessInstanceManager(this);
-		this.timeMachine = new TimeMachine();
+        this.actionQueue = new LinkedList<WorkingMemoryAction>();
 
-		TimerService timerService = TimerServiceFactory
-				.getTimerService(this.config.getClockType());
-		this.timerManager = new TimerManager(this, timerService);
+        this.addRemovePropertyChangeListenerArgs = new Object[]{this};
+        this.queryResults = Collections.EMPTY_MAP;
+        this.workingMemoryEventSupport = new WorkingMemoryEventSupport();
+        this.agendaEventSupport = new AgendaEventSupport();
+        this.workflowEventSupport = new RuleFlowEventSupport();
+        this.__ruleBaseEventListeners = new LinkedList();
+        this.lock = new ReentrantLock();
+        this.liaPropagations = Collections.EMPTY_LIST;
+        this.processInstanceManager = conf.getProcessInstanceManagerFactory().createProcessInstanceManager( this );
+        this.timeMachine = new TimeMachine();
 
-		this.nodeMemories = new ConcurrentNodeMemories(this.ruleBase);
+        TimerService timerService = TimerServiceFactory.getTimerService( this.config.getClockType() );
+        this.timerManager = new TimerManager( this,
+                                              timerService );
 
-		if (this.maintainTms) {
-			this.tms = new TruthMaintenanceSystem(this);
-		} else {
-			this.tms = null;
-		}
+        this.nodeMemories = new ConcurrentNodeMemories( this.ruleBase );
 
-		this.propagationIdCounter = new AtomicLong(propagationContext);
+        if ( this.maintainTms ) {
+            this.tms = new TruthMaintenanceSystem( this );
+        } else {
+            this.tms = null;
+        }
 
-		this.objectStore = new SingleThreadedObjectStore(conf, this.lock);
+        this.propagationIdCounter = new AtomicLong( propagationContext );
 
-		// Only takes effect if are using idententity behaviour for assert
-		if (LogicalOverride.DISCARD.equals(conf.getLogicalOverride())) {
-			this.discardOnLogicalOverride = true;
-		} else {
-			this.discardOnLogicalOverride = false;
-		}
+        this.objectStore = new SingleThreadedObjectStore( conf,
+                                                          this.lock );
 
-		this.entryPoints = new ConcurrentHashMap();
-		this.entryPoints.put("DEFAULT", this);
+        // Only takes effect if are using idententity behaviour for assert
+        if ( LogicalOverride.DISCARD.equals( conf.getLogicalOverride() ) ) {
+            this.discardOnLogicalOverride = true;
+        } else {
+            this.discardOnLogicalOverride = false;
+        }
 
-		this.entryPoint = EntryPoint.DEFAULT;
-		this.firing = new AtomicBoolean(false);
+        this.entryPoints = new ConcurrentHashMap();
+        this.entryPoints.put( "DEFAULT",
+                              this );
 
-		initPartitionManagers();
-		initTransient();
-	}
+        this.entryPoint = EntryPoint.DEFAULT;
+        this.firing = new AtomicBoolean( false );
+        this.modifyContexts = new HashMap<InternalFactHandle, PropagationContext>();
 
-	// ------------------------------------------------------------
-	// Instance methods
-	// ------------------------------------------------------------
+        initPartitionManagers();
+        initTransient();
+    }
 
-	public void setRuleBase(final InternalRuleBase ruleBase) {
-		this.ruleBase = ruleBase;
-		this.nodeMemories.setRuleBaseReference(this.ruleBase);
-		initTransient();
-	}
+    // ------------------------------------------------------------
+    // Instance methods
+    // ------------------------------------------------------------
 
-	/**
-	 * Creates the actual partition managers and their tasks for multi-thread
-	 * processing
-	 */
-	private void initPartitionManagers() {
-		if (this.ruleBase.getConfiguration().isPartitionsEnabled()) {
+    public void setRuleBase(final InternalRuleBase ruleBase) {
+        this.ruleBase = ruleBase;
+        this.nodeMemories.setRuleBaseReference( this.ruleBase );
+        initTransient();
+    }
 
-			// the Map MUST be thread safe
-			this.partitionManagers = new ConcurrentHashMap<RuleBasePartitionId, PartitionTaskManager>();
+    /**
+     * Creates the actual partition managers and their tasks for multi-thread
+     * processing
+     */
+    private void initPartitionManagers() {
+        if ( this.ruleBase.getConfiguration().isPartitionsEnabled() ) {
 
-			for (RuleBasePartitionId partitionId : this.ruleBase
-					.getPartitionIds()) {
-				this.partitionManagers.put(partitionId,
-						new PartitionTaskManager(this));
-			}
-		}
-	}
+            // the Map MUST be thread safe
+            this.partitionManagers = new ConcurrentHashMap<RuleBasePartitionId, PartitionTaskManager>();
 
-	/**
-	 * This method is called to start the multiple partition threads when
-	 * running in multi-thread mode
-	 */
-	public void startPartitionManagers() {
-		if (this.ruleBase.getConfiguration().isPartitionsEnabled()) {
-			for (PartitionTaskManager task : this.partitionManagers.values()) {
-				task.startService();
-			}
-		}
-	}
+            for ( RuleBasePartitionId partitionId : this.ruleBase.getPartitionIds() ) {
+                this.partitionManagers.put( partitionId,
+                                            new PartitionTaskManager( this ) );
+            }
+        }
+    }
 
-	public void stopPartitionManagers() {
-		if (this.ruleBase.getConfiguration().isPartitionsEnabled()) {
-			for (PartitionTaskManager task : this.partitionManagers.values()) {
-				// what to do here? should we simply wait for a timeout and give
-				// up?
-				task.stopServiceAndWait();
-			}
-		}
-	}
+    /**
+     * This method is called to start the multiple partition threads when
+     * running in multi-thread mode
+     */
+    public void startPartitionManagers() {
+        if ( this.ruleBase.getConfiguration().isPartitionsEnabled() ) {
+            for ( PartitionTaskManager task : this.partitionManagers.values() ) {
+                task.startService();
+            }
+        }
+    }
 
-	private void initTransient() {
-		this.entryPointNode = this.ruleBase.getRete().getEntryPointNode(
-				this.entryPoint);
-		this.typeConfReg = new ObjectTypeConfigurationRegistry(this.ruleBase);
-	}
+    public void stopPartitionManagers() {
+        if ( this.ruleBase.getConfiguration().isPartitionsEnabled() ) {
+            for ( PartitionTaskManager task : this.partitionManagers.values() ) {
+                // what to do here? should we simply wait for a timeout and give
+                // up?
+                task.stopServiceAndWait();
+            }
+        }
+    }
 
-	public void reset(int handleId, long handleCounter, long propagationCounter) {
-		this.nodeMemories.clear();
-		this.agenda.clear();
-		this.objectStore.clear();
-		this.handleFactory.clear(handleId, handleCounter);
-		this.tms.clear();
-		this.liaPropagations.clear();
-		this.actionQueue.clear();
+    private void initTransient() {
+        this.entryPointNode = this.ruleBase.getRete().getEntryPointNode( this.entryPoint );
+        this.typeConfReg = new ObjectTypeConfigurationRegistry( this.ruleBase );
+    }
 
-		this.propagationIdCounter = new AtomicLong(propagationCounter);
+    public void reset(int handleId,
+                      long handleCounter,
+                      long propagationCounter) {
+        this.nodeMemories.clear();
+        this.agenda.clear();
+        this.objectStore.clear();
+        this.handleFactory.clear( handleId,
+                                  handleCounter );
+        this.tms.clear();
+        this.liaPropagations.clear();
+        this.actionQueue.clear();
 
-		// TODO should these be cleared?
-		// we probably neeed to do CEP and Flow timers too
-		// this.processInstanceManager.clear()
-		// this.workItemManager.clear();
-	}
+        this.propagationIdCounter = new AtomicLong( propagationCounter );
 
-	public void setWorkingMemoryEventSupport(
-			WorkingMemoryEventSupport workingMemoryEventSupport) {
-		this.workingMemoryEventSupport = workingMemoryEventSupport;
-	}
+        // TODO should these be cleared?
+        // we probably neeed to do CEP and Flow timers too
+        // this.processInstanceManager.clear()
+        // this.workItemManager.clear();
+    }
 
-	public void setAgendaEventSupport(AgendaEventSupport agendaEventSupport) {
-		this.agendaEventSupport = agendaEventSupport;
-	}
+    public void setWorkingMemoryEventSupport(WorkingMemoryEventSupport workingMemoryEventSupport) {
+        this.workingMemoryEventSupport = workingMemoryEventSupport;
+    }
 
-	public void setRuleFlowEventSupport(
-			RuleFlowEventSupport ruleFlowEventSupport) {
-		this.workflowEventSupport = ruleFlowEventSupport;
-	}
+    public void setAgendaEventSupport(AgendaEventSupport agendaEventSupport) {
+        this.agendaEventSupport = agendaEventSupport;
+    }
 
-	public boolean isSequential() {
-		return this.sequential;
-	}
+    public void setRuleFlowEventSupport(RuleFlowEventSupport ruleFlowEventSupport) {
+        this.workflowEventSupport = ruleFlowEventSupport;
+    }
 
-	public void addLIANodePropagation(LIANodePropagation liaNodePropagation) {
-		if (this.liaPropagations == Collections.EMPTY_LIST) {
-			this.liaPropagations = new ArrayList();
-		}
-		this.liaPropagations.add(liaNodePropagation);
-	}
+    public boolean isSequential() {
+        return this.sequential;
+    }
 
-	public void addEventListener(final WorkingMemoryEventListener listener) {
-		this.workingMemoryEventSupport.addEventListener(listener);
-	}
+    public void addLIANodePropagation(LIANodePropagation liaNodePropagation) {
+        if ( this.liaPropagations == Collections.EMPTY_LIST ) {
+            this.liaPropagations = new ArrayList();
+        }
+        this.liaPropagations.add( liaNodePropagation );
+    }
 
-	public void removeEventListener(final WorkingMemoryEventListener listener) {
-		this.workingMemoryEventSupport.removeEventListener(listener);
-	}
+    public void addEventListener(final WorkingMemoryEventListener listener) {
+        this.workingMemoryEventSupport.addEventListener( listener );
+    }
 
-	public List getWorkingMemoryEventListeners() {
-		return this.workingMemoryEventSupport.getEventListeners();
-	}
+    public void removeEventListener(final WorkingMemoryEventListener listener) {
+        this.workingMemoryEventSupport.removeEventListener( listener );
+    }
 
-	public void addEventListener(final AgendaEventListener listener) {
-		this.agendaEventSupport.addEventListener(listener);
-	}
+    public List getWorkingMemoryEventListeners() {
+        return this.workingMemoryEventSupport.getEventListeners();
+    }
 
-	public void removeEventListener(final AgendaEventListener listener) {
-		this.agendaEventSupport.removeEventListener(listener);
-	}
+    public void addEventListener(final AgendaEventListener listener) {
+        this.agendaEventSupport.addEventListener( listener );
+    }
 
-	public List getAgendaEventListeners() {
-		return this.agendaEventSupport.getEventListeners();
-	}
+    public void removeEventListener(final AgendaEventListener listener) {
+        this.agendaEventSupport.removeEventListener( listener );
+    }
 
-	public void addEventListener(final RuleFlowEventListener listener) {
-		this.workflowEventSupport.addEventListener(listener);
-	}
+    public List getAgendaEventListeners() {
+        return this.agendaEventSupport.getEventListeners();
+    }
 
-	public void removeEventListener(final RuleFlowEventListener listener) {
-		this.workflowEventSupport.removeEventListener(listener);
-	}
+    public void addEventListener(final RuleFlowEventListener listener) {
+        this.workflowEventSupport.addEventListener( listener );
+    }
 
-	public List getRuleFlowEventListeners() {
-		return this.workflowEventSupport.getEventListeners();
-	}
+    public void removeEventListener(final RuleFlowEventListener listener) {
+        this.workflowEventSupport.removeEventListener( listener );
+    }
 
-	public void addEventListener(RuleBaseEventListener listener) {
-		this.ruleBase.addEventListener(listener);
-		this.__ruleBaseEventListeners.add(listener);
-	}
+    public List getRuleFlowEventListeners() {
+        return this.workflowEventSupport.getEventListeners();
+    }
 
-	public List getRuleBaseEventListeners() {
-		return Collections.unmodifiableList(this.__ruleBaseEventListeners);
-	}
+    public void addEventListener(RuleBaseEventListener listener) {
+        this.ruleBase.addEventListener( listener );
+        this.__ruleBaseEventListeners.add( listener );
+    }
 
-	public void removeEventListener(RuleBaseEventListener listener) {
-		this.ruleBase.removeEventListener(listener);
-		this.__ruleBaseEventListeners.remove(listener);
-	}
+    public List getRuleBaseEventListeners() {
+        return Collections.unmodifiableList( this.__ruleBaseEventListeners );
+    }
 
-	public FactHandleFactory getFactHandleFactory() {
-		return this.handleFactory;
-	}
+    public void removeEventListener(RuleBaseEventListener listener) {
+        this.ruleBase.removeEventListener( listener );
+        this.__ruleBaseEventListeners.remove( listener );
+    }
 
-	public void setGlobal(final String identifier, final Object value) {
-		// Cannot set null values
-		if (value == null) {
-			return;
-		}
+    public FactHandleFactory getFactHandleFactory() {
+        return this.handleFactory;
+    }
 
-		try {
-			this.lock.lock();
-			// Make sure the global has been declared in the RuleBase
-			final Map globalDefintions = this.ruleBase.getGlobals();
-			final Class type = (Class) globalDefintions.get(identifier);
-			if ((type == null)) {
-				throw new RuntimeException("Unexpected global [" + identifier
-						+ "]");
-			} else if (!type.isInstance(value)) {
-				throw new RuntimeException("Illegal class for global. "
-						+ "Expected [" + type.getName() + "], " + "found ["
-						+ value.getClass().getName() + "].");
+    public void setGlobal(final String identifier,
+                          final Object value) {
+        // Cannot set null values
+        if ( value == null ) {
+            return;
+        }
 
-			} else {
-				this.globalResolver.setGlobal(identifier, value);
-			}
-		} finally {
-			this.lock.unlock();
-		}
-	}
+        try {
+            this.lock.lock();
+            // Make sure the global has been declared in the RuleBase
+            final Map globalDefintions = this.ruleBase.getGlobals();
+            final Class type = (Class) globalDefintions.get( identifier );
+            if ( (type == null) ) {
+                throw new RuntimeException( "Unexpected global [" + identifier + "]" );
+            } else if ( !type.isInstance( value ) ) {
+                throw new RuntimeException( "Illegal class for global. " + "Expected [" + type.getName() + "], " + "found [" + value.getClass().getName() + "]." );
 
-	public void setGlobalResolver(final GlobalResolver globalResolver) {
-		try {
-			this.lock.lock();
-			this.globalResolver = globalResolver;
-		} finally {
-			this.lock.unlock();
-		}
-	}
+            } else {
+                this.globalResolver.setGlobal( identifier,
+                                               value );
+            }
+        } finally {
+            this.lock.unlock();
+        }
+    }
 
-	public GlobalResolver getGlobalResolver() {
-		return this.globalResolver;
-	}
+    public void setGlobalResolver(final GlobalResolver globalResolver) {
+        try {
+            this.lock.lock();
+            this.globalResolver = globalResolver;
+        } finally {
+            this.lock.unlock();
+        }
+    }
 
-	public long getId() {
-		return this.id;
-	}
+    public GlobalResolver getGlobalResolver() {
+        return this.globalResolver;
+    }
 
-	public void setId(long id) {
-		this.id = id;
-	}
+    public long getId() {
+        return this.id;
+    }
 
-	public Object getGlobal(final String identifier) {
-		try {
-			this.lock.lock();
-			return this.globalResolver.resolveGlobal(identifier);
-		} finally {
-			this.lock.unlock();
-		}
-	}
+    public void setId(long id) {
+        this.id = id;
+    }
 
-	public Agenda getAgenda() {
-		return this.agenda;
-	}
+    public Object getGlobal(final String identifier) {
+        try {
+            this.lock.lock();
+            return this.globalResolver.resolveGlobal( identifier );
+        } finally {
+            this.lock.unlock();
+        }
+    }
 
-	public void clearAgenda() {
-		this.agenda.clearAndCancel();
-	}
+    public Agenda getAgenda() {
+        return this.agenda;
+    }
 
-	public void clearAgendaGroup(final String group) {
-		this.agenda.clearAndCancelAgendaGroup(group);
-	}
+    public void clearAgenda() {
+        this.agenda.clearAndCancel();
+    }
 
-	public void clearActivationGroup(final String group) {
-		this.agenda.clearAndCancelActivationGroup(group);
-	}
+    public void clearAgendaGroup(final String group) {
+        this.agenda.clearAndCancelAgendaGroup( group );
+    }
 
-	public void clearRuleFlowGroup(final String group) {
-		this.agenda.clearAndCancelRuleFlowGroup(group);
-	}
+    public void clearActivationGroup(final String group) {
+        this.agenda.clearAndCancelActivationGroup( group );
+    }
 
-	public RuleBase getRuleBase() {
-		return this.ruleBase;
-	}
+    public void clearRuleFlowGroup(final String group) {
+        this.agenda.clearAndCancelRuleFlowGroup( group );
+    }
 
-	public void halt() {
-		this.agenda.halt();
-	}
+    public RuleBase getRuleBase() {
+        return this.ruleBase;
+    }
 
-	// /**
-	// * This is a synchronous call that will keep the engine running
-	// * until halt() is called. If no more activations exist, the engine
-	// * will wait until either halt is called or new activations are
-	// * created. In the later case, it will fire them.
-	// */
-	// public void runUntilHalt() {
-	// do {
-	// fireAllRules();
-	// synchronized( this.agenda ) {
-	// if( !halt && this.agenda.agendaSize() == 0 ) {
-	// try {
-	// this.agenda.wait();
-	// } catch (InterruptedException e) {
-	// // set status and continue
-	// Thread.currentThread().interrupted();
-	// break;
-	// }
-	// }
-	// }
-	// } while( !halt );
-	//    	
-	// }
+    public void halt() {
+        this.agenda.halt();
+    }
 
-	public synchronized int fireAllRules() throws FactException {
-		return fireAllRules(null, -1);
-	}
+    // /**
+    // * This is a synchronous call that will keep the engine running
+    // * until halt() is called. If no more activations exist, the engine
+    // * will wait until either halt is called or new activations are
+    // * created. In the later case, it will fire them.
+    // */
+    // public void runUntilHalt() {
+    // do {
+    // fireAllRules();
+    // synchronized( this.agenda ) {
+    // if( !halt && this.agenda.agendaSize() == 0 ) {
+    // try {
+    // this.agenda.wait();
+    // } catch (InterruptedException e) {
+    // // set status and continue
+    // Thread.currentThread().interrupted();
+    // break;
+    // }
+    // }
+    // }
+    // } while( !halt );
+    //    	
+    // }
 
-	public synchronized int fireAllRules(int fireLimit) throws FactException {
-		return fireAllRules(null, fireLimit);
-	}
+    public synchronized int fireAllRules() throws FactException {
+        return fireAllRules( null,
+                             -1 );
+    }
 
-	public synchronized int fireAllRules(final AgendaFilter agendaFilter)
-			throws FactException {
-		return fireAllRules(agendaFilter, -1);
-	}
+    public synchronized int fireAllRules(int fireLimit) throws FactException {
+        return fireAllRules( null,
+                             fireLimit );
+    }
 
-	public synchronized int fireAllRules(final AgendaFilter agendaFilter,
-			int fireLimit) throws FactException {
-		// If we're already firing a rule, then it'll pick up
-		// the firing for any other assertObject(..) that get
-		// nested inside, avoiding concurrent-modification
-		// exceptions, depending on code paths of the actions.
-		if (isSequential()) {
-			for (Iterator it = this.liaPropagations.iterator(); it.hasNext();) {
-				((LIANodePropagation) it.next()).doPropagation(this);
-			}
-		}
+    public synchronized int fireAllRules(final AgendaFilter agendaFilter) throws FactException {
+        return fireAllRules( agendaFilter,
+                             -1 );
+    }
 
-		// do we need to call this in advance?
-		executeQueuedActions();
+    public synchronized int fireAllRules(final AgendaFilter agendaFilter,
+                                         int fireLimit) throws FactException {
+        // If we're already firing a rule, then it'll pick up
+        // the firing for any other assertObject(..) that get
+        // nested inside, avoiding concurrent-modification
+        // exceptions, depending on code paths of the actions.
+        if ( isSequential() ) {
+            for ( Iterator it = this.liaPropagations.iterator(); it.hasNext(); ) {
+                ((LIANodePropagation) it.next()).doPropagation( this );
+            }
+        }
 
-		int fireCount = 0;
-		try {
-			if (this.firing.compareAndSet(false, true)) {
-				fireCount = this.agenda.fireAllRules(agendaFilter, fireLimit);
-			}
-		} finally {
-			this.firing.set(false);
-		}
-		return fireCount;
-	}
+        // do we need to call this in advance?
+        executeQueuedActions();
 
-	/**
-	 * Keeps firing activations until a halt is called. If in a given moment,
-	 * there is no activation to fire, it will wait for an activation to be
-	 * added to an active agenda group or rule flow group.
-	 * 
-	 * @throws IllegalStateException
-	 *             if this method is called when running in sequential mode
-	 */
-	public synchronized void fireUntilHalt() {
-		fireUntilHalt(null);
-	}
+        int fireCount = 0;
+        try {
+            if ( this.firing.compareAndSet( false,
+                                            true ) ) {
+                fireCount = this.agenda.fireAllRules( agendaFilter,
+                                                      fireLimit );
+            }
+        } finally {
+            this.firing.set( false );
+        }
+        return fireCount;
+    }
 
-	/**
-	 * Keeps firing activations until a halt is called. If in a given moment,
-	 * there is no activation to fire, it will wait for an activation to be
-	 * added to an active agenda group or rule flow group.
-	 * 
-	 * @param agendaFilter
-	 *            filters the activations that may fire
-	 * 
-	 * @throws IllegalStateException
-	 *             if this method is called when running in sequential mode
-	 */
-	public synchronized void fireUntilHalt(final AgendaFilter agendaFilter) {
-		if (isSequential()) {
-			throw new IllegalStateException(
-					"fireUntilHalt() can not be called in sequential mode.");
-		}
+    /**
+     * Keeps firing activations until a halt is called. If in a given moment,
+     * there is no activation to fire, it will wait for an activation to be
+     * added to an active agenda group or rule flow group.
+     * 
+     * @throws IllegalStateException
+     *             if this method is called when running in sequential mode
+     */
+    public synchronized void fireUntilHalt() {
+        fireUntilHalt( null );
+    }
 
-		executeQueuedActions();
-		try {
-			if (this.firing.compareAndSet(false, true)) {
-				this.agenda.fireUntilHalt(agendaFilter);
-			}
-		} finally {
-			this.firing.set(false);
-		}
-	}
+    /**
+     * Keeps firing activations until a halt is called. If in a given moment,
+     * there is no activation to fire, it will wait for an activation to be
+     * added to an active agenda group or rule flow group.
+     * 
+     * @param agendaFilter
+     *            filters the activations that may fire
+     * 
+     * @throws IllegalStateException
+     *             if this method is called when running in sequential mode
+     */
+    public synchronized void fireUntilHalt(final AgendaFilter agendaFilter) {
+        if ( isSequential() ) {
+            throw new IllegalStateException( "fireUntilHalt() can not be called in sequential mode." );
+        }
 
-	/**
-	 * Returns the fact Object for the given <code>FactHandle</code>. It
-	 * actually attempts to return the value from the handle, before retrieving
-	 * it from objects map.
-	 * 
-	 * @see WorkingMemory
-	 * 
-	 * @param handle
-	 *            The <code>FactHandle</code> reference for the
-	 *            <code>Object</code> lookup
-	 * 
-	 */
-	public Object getObject(final FactHandle handle) {
-		return this.objectStore.getObjectForHandle((InternalFactHandle) handle);
-	}
+        executeQueuedActions();
+        try {
+            if ( this.firing.compareAndSet( false,
+                                            true ) ) {
+                this.agenda.fireUntilHalt( agendaFilter );
+            }
+        } finally {
+            this.firing.set( false );
+        }
+    }
 
-	public ObjectStore getObjectStore() {
-		return this.objectStore;
-	}
+    /**
+     * Returns the fact Object for the given <code>FactHandle</code>. It
+     * actually attempts to return the value from the handle, before retrieving
+     * it from objects map.
+     * 
+     * @see WorkingMemory
+     * 
+     * @param handle
+     *            The <code>FactHandle</code> reference for the
+     *            <code>Object</code> lookup
+     * 
+     */
+    public Object getObject(final FactHandle handle) {
+        return this.objectStore.getObjectForHandle( (InternalFactHandle) handle );
+    }
 
-	/**
-	 * @see WorkingMemory
-	 */
-	public FactHandle getFactHandle(final Object object) {
-		return this.objectStore.getHandleForObject(object);
-	}
+    public ObjectStore getObjectStore() {
+        return this.objectStore;
+    }
 
-	/**
-	 * @see WorkingMemory
-	 */
-	public FactHandle getFactHandleByIdentity(final Object object) {
-		return this.objectStore.getHandleForObjectIdentity(object);
-	}
+    /**
+     * @see WorkingMemory
+     */
+    public FactHandle getFactHandle(final Object object) {
+        return this.objectStore.getHandleForObject( object );
+    }
 
-	/**
-	 * This class is not thread safe, changes to the working memory during
-	 * iteration may give unexpected results
-	 */
-	public Iterator iterateObjects() {
-		return this.objectStore.iterateObjects();
-	}
+    /**
+     * @see WorkingMemory
+     */
+    public FactHandle getFactHandleByIdentity(final Object object) {
+        return this.objectStore.getHandleForObjectIdentity( object );
+    }
 
-	/**
-	 * This class is not thread safe, changes to the working memory during
-	 * iteration may give unexpected results
-	 */
-	public Iterator iterateObjects(ObjectFilter filter) {
-		return this.objectStore.iterateObjects(filter);
-	}
+    /**
+     * This class is not thread safe, changes to the working memory during
+     * iteration may give unexpected results
+     */
+    public Iterator iterateObjects() {
+        return this.objectStore.iterateObjects();
+    }
 
-	/**
-	 * This class is not thread safe, changes to the working memory during
-	 * iteration may give unexpected results
-	 */
-	public Iterator iterateFactHandles() {
-		return this.objectStore.iterateFactHandles();
-	}
+    /**
+     * This class is not thread safe, changes to the working memory during
+     * iteration may give unexpected results
+     */
+    public Iterator iterateObjects(ObjectFilter filter) {
+        return this.objectStore.iterateObjects( filter );
+    }
 
-	/**
-	 * This class is not thread safe, changes to the working memory during
-	 * iteration may give unexpected results
-	 */
-	public Iterator iterateFactHandles(ObjectFilter filter) {
-		return this.objectStore.iterateFactHandles(filter);
-	}
+    /**
+     * This class is not thread safe, changes to the working memory during
+     * iteration may give unexpected results
+     */
+    public Iterator iterateFactHandles() {
+        return this.objectStore.iterateFactHandles();
+    }
 
-	public abstract QueryResults getQueryResults(String query);
+    /**
+     * This class is not thread safe, changes to the working memory during
+     * iteration may give unexpected results
+     */
+    public Iterator iterateFactHandles(ObjectFilter filter) {
+        return this.objectStore.iterateFactHandles( filter );
+    }
 
-	public void setFocus(final String focus) {
-		this.agenda.setFocus(focus);
-	}
+    public abstract QueryResults getQueryResults(String query);
 
-	public TruthMaintenanceSystem getTruthMaintenanceSystem() {
-		return this.tms;
-	}
+    public void setFocus(final String focus) {
+        this.agenda.setFocus( focus );
+    }
 
-	/**
-	 * @see WorkingMemory
-	 */
-	public FactHandle insert(final Object object) throws FactException {
-		return insert(object, /* Not-Dynamic */
-		false, false, null, null);
-	}
+    public TruthMaintenanceSystem getTruthMaintenanceSystem() {
+        return this.tms;
+    }
 
-	/**
-	 * @see WorkingMemory
-	 */
-	public FactHandle insertLogical(final Object object) throws FactException {
-		return insert(object, // Not-Dynamic
-				false, true, null, null);
-	}
+    /**
+     * @see WorkingMemory
+     */
+    public FactHandle insert(final Object object) throws FactException {
+        return insert( object, /* Not-Dynamic */
+                       false,
+                       false,
+                       null,
+                       null );
+    }
 
-	public FactHandle insert(final Object object, final boolean dynamic)
-			throws FactException {
-		return insert(object, dynamic, false, null, null);
-	}
+    /**
+     * @see WorkingMemory
+     */
+    public FactHandle insertLogical(final Object object) throws FactException {
+        return insert( object, // Not-Dynamic
+                       false,
+                       true,
+                       null,
+                       null );
+    }
 
-	public FactHandle insertLogical(final Object object, final boolean dynamic)
-			throws FactException {
-		return insert(object, dynamic, true, null, null);
-	}
+    public FactHandle insert(final Object object,
+                             final boolean dynamic) throws FactException {
+        return insert( object,
+                       dynamic,
+                       false,
+                       null,
+                       null );
+    }
 
-	// protected FactHandle insert(final EntryPoint entryPoint,
-	// final Object object,
-	// final boolean dynamic,
-	// boolean logical,
-	// final Rule rule,
-	// final Activation activation) throws FactException {
-	// return this.insert( entryPoint,
-	// object,
-	// 0,
-	// dynamic,
-	// logical,
-	// rule,
-	// activation );
-	// }
+    public FactHandle insertLogical(final Object object,
+                                    final boolean dynamic) throws FactException {
+        return insert( object,
+                       dynamic,
+                       true,
+                       null,
+                       null );
+    }
 
-	public FactHandle insert(final Object object, final boolean dynamic,
-			boolean logical, final Rule rule, final Activation activation)
-			throws FactException {
-		if (object == null) {
-			// you cannot assert a null object
-			return null;
-		}
+    // protected FactHandle insert(final EntryPoint entryPoint,
+    // final Object object,
+    // final boolean dynamic,
+    // boolean logical,
+    // final Rule rule,
+    // final Activation activation) throws FactException {
+    // return this.insert( entryPoint,
+    // object,
+    // 0,
+    // dynamic,
+    // logical,
+    // rule,
+    // activation );
+    // }
 
-		ObjectTypeConf typeConf = this.typeConfReg.getObjectTypeConf(
-				this.entryPoint, object);
+    public FactHandle insert(final Object object,
+                             final boolean dynamic,
+                             boolean logical,
+                             final Rule rule,
+                             final Activation activation) throws FactException {
+        if ( object == null ) {
+            // you cannot assert a null object
+            return null;
+        }
 
-		InternalFactHandle handle = null;
+        ObjectTypeConf typeConf = this.typeConfReg.getObjectTypeConf( this.entryPoint,
+                                                                      object );
 
-		if (isSequential()) {
-			handle = this.handleFactory.newFactHandle(object, typeConf, this);
-			this.objectStore.addHandle(handle, object);
-			insert(handle, object, rule, activation, typeConf);
-			return handle;
-		}
+        InternalFactHandle handle = null;
 
-		try {
-			this.lock.lock();
-			// check if the object already exists in the WM
-			handle = (InternalFactHandle) this.objectStore
-					.getHandleForObject(object);
+        if ( isSequential() ) {
+            handle = this.handleFactory.newFactHandle( object,
+                                                       typeConf,
+                                                       this );
+            this.objectStore.addHandle( handle,
+                                        object );
+            insert( handle,
+                    object,
+                    rule,
+                    activation,
+                    typeConf );
+            return handle;
+        }
 
-			if (this.maintainTms) {
+        try {
+            this.lock.lock();
+            // check if the object already exists in the WM
+            handle = (InternalFactHandle) this.objectStore.getHandleForObject( object );
 
-				EqualityKey key = null;
+            if ( this.maintainTms ) {
 
-				if (handle == null) {
-					// lets see if the object is already logical asserted
-					key = this.tms.get(object);
-				} else {
-					// Object is already asserted, so check and possibly correct
-					// its
-					// status and then return the handle
-					key = handle.getEqualityKey();
+                EqualityKey key = null;
 
-					if (key.getStatus() == EqualityKey.STATED) {
-						// return null as you cannot justify a stated object.
-						return handle;
-					}
+                if ( handle == null ) {
+                    // lets see if the object is already logical asserted
+                    key = this.tms.get( object );
+                } else {
+                    // Object is already asserted, so check and possibly correct
+                    // its
+                    // status and then return the handle
+                    key = handle.getEqualityKey();
 
-					if (!logical) {
-						// this object was previously justified, so we have to
-						// override it to stated
-						key.setStatus(EqualityKey.STATED);
-						this.tms.removeLogicalDependencies(handle);
-					} else {
-						// this was object is already justified, so just add new
-						// logical dependency
-						this.tms.addLogicalDependency(handle, activation,
-								activation.getPropagationContext(), rule);
-					}
+                    if ( key.getStatus() == EqualityKey.STATED ) {
+                        // return null as you cannot justify a stated object.
+                        return handle;
+                    }
 
-					return handle;
-				}
+                    if ( !logical ) {
+                        // this object was previously justified, so we have to
+                        // override it to stated
+                        key.setStatus( EqualityKey.STATED );
+                        this.tms.removeLogicalDependencies( handle );
+                    } else {
+                        // this was object is already justified, so just add new
+                        // logical dependency
+                        this.tms.addLogicalDependency( handle,
+                                                       activation,
+                                                       activation.getPropagationContext(),
+                                                       rule );
+                    }
 
-				// At this point we know the handle is null
-				if (key == null) {
-					// key is also null, so treat as a totally new
-					// stated/logical
-					// assert
-					handle = this.handleFactory.newFactHandle(object, typeConf,
-							this);
-					this.objectStore.addHandle(handle, object);
+                    return handle;
+                }
 
-					key = new EqualityKey(handle);
-					handle.setEqualityKey(key);
-					this.tms.put(key);
-					if (!logical) {
-						key.setStatus(EqualityKey.STATED);
-					} else {
-						key.setStatus(EqualityKey.JUSTIFIED);
-						this.tms.addLogicalDependency(handle, activation,
-								activation.getPropagationContext(), rule);
-					}
-				} else if (!logical) {
-					if (key.getStatus() == EqualityKey.JUSTIFIED) {
-						// Its previous justified, so switch to stated and
-						// remove
-						// logical dependencies
-						final InternalFactHandle justifiedHandle = key
-								.getFactHandle();
-						this.tms.removeLogicalDependencies(justifiedHandle);
+                // At this point we know the handle is null
+                if ( key == null ) {
+                    // key is also null, so treat as a totally new
+                    // stated/logical
+                    // assert
+                    handle = this.handleFactory.newFactHandle( object,
+                                                               typeConf,
+                                                               this );
+                    this.objectStore.addHandle( handle,
+                                                object );
 
-						if (this.discardOnLogicalOverride) {
-							// override, setting to new instance, and return
-							// existing handle
-							key.setStatus(EqualityKey.STATED);
-							handle = key.getFactHandle();
+                    key = new EqualityKey( handle );
+                    handle.setEqualityKey( key );
+                    this.tms.put( key );
+                    if ( !logical ) {
+                        key.setStatus( EqualityKey.STATED );
+                    } else {
+                        key.setStatus( EqualityKey.JUSTIFIED );
+                        this.tms.addLogicalDependency( handle,
+                                                       activation,
+                                                       activation.getPropagationContext(),
+                                                       rule );
+                    }
+                } else if ( !logical ) {
+                    if ( key.getStatus() == EqualityKey.JUSTIFIED ) {
+                        // Its previous justified, so switch to stated and
+                        // remove
+                        // logical dependencies
+                        final InternalFactHandle justifiedHandle = key.getFactHandle();
+                        this.tms.removeLogicalDependencies( justifiedHandle );
 
-							if (AssertBehaviour.IDENTITY.equals(this.ruleBase
-									.getConfiguration().getAssertBehaviour())) {
-								// as assertMap may be using an "identity"
-								// equality comparator,
-								// we need to remove the handle from the map,
-								// before replacing the object
-								// and then re-add the handle. Otherwise we may
-								// end up with a leak.
-								this.objectStore.updateHandle(handle, object);
-							} else {
-								Object oldObject = handle.getObject();
-							}
-							return handle;
-						} else {
-							// override, then instantiate new handle for
-							// assertion
-							key.setStatus(EqualityKey.STATED);
-							handle = this.handleFactory.newFactHandle(object,
-									typeConf, this);
-							handle.setEqualityKey(key);
-							key.addFactHandle(handle);
-							this.objectStore.addHandle(handle, object);
+                        if ( this.discardOnLogicalOverride ) {
+                            // override, setting to new instance, and return
+                            // existing handle
+                            key.setStatus( EqualityKey.STATED );
+                            handle = key.getFactHandle();
 
-						}
+                            if ( AssertBehaviour.IDENTITY.equals( this.ruleBase.getConfiguration().getAssertBehaviour() ) ) {
+                                // as assertMap may be using an "identity"
+                                // equality comparator,
+                                // we need to remove the handle from the map,
+                                // before replacing the object
+                                // and then re-add the handle. Otherwise we may
+                                // end up with a leak.
+                                this.objectStore.updateHandle( handle,
+                                                               object );
+                            } else {
+                                Object oldObject = handle.getObject();
+                            }
+                            return handle;
+                        } else {
+                            // override, then instantiate new handle for
+                            // assertion
+                            key.setStatus( EqualityKey.STATED );
+                            handle = this.handleFactory.newFactHandle( object,
+                                                                       typeConf,
+                                                                       this );
+                            handle.setEqualityKey( key );
+                            key.addFactHandle( handle );
+                            this.objectStore.addHandle( handle,
+                                                        object );
 
-					} else {
-						handle = this.handleFactory.newFactHandle(object,
-								typeConf, this);
-						this.objectStore.addHandle(handle, object);
-						key.addFactHandle(handle);
-						handle.setEqualityKey(key);
+                        }
 
-					}
+                    } else {
+                        handle = this.handleFactory.newFactHandle( object,
+                                                                   typeConf,
+                                                                   this );
+                        this.objectStore.addHandle( handle,
+                                                    object );
+                        key.addFactHandle( handle );
+                        handle.setEqualityKey( key );
 
-				} else {
-					if (key.getStatus() == EqualityKey.JUSTIFIED) {
-						// only add as logical dependency if this wasn't
-						// previously
-						// stated
-						this.tms.addLogicalDependency(key.getFactHandle(),
-								activation, activation.getPropagationContext(),
-								rule);
-						return key.getFactHandle();
-					} else {
-						// You cannot justify a previously stated equality equal
-						// object, so return null
-						return null;
-					}
-				}
+                    }
 
-			} else {
-				if (handle != null) {
-					return handle;
-				}
-				handle = this.handleFactory.newFactHandle(object, typeConf,
-						this);
-				this.objectStore.addHandle(handle, object);
+                } else {
+                    if ( key.getStatus() == EqualityKey.JUSTIFIED ) {
+                        // only add as logical dependency if this wasn't
+                        // previously
+                        // stated
+                        this.tms.addLogicalDependency( key.getFactHandle(),
+                                                       activation,
+                                                       activation.getPropagationContext(),
+                                                       rule );
+                        return key.getFactHandle();
+                    } else {
+                        // You cannot justify a previously stated equality equal
+                        // object, so return null
+                        return null;
+                    }
+                }
 
-			}
+            } else {
+                if ( handle != null ) {
+                    return handle;
+                }
+                handle = this.handleFactory.newFactHandle( object,
+                                                           typeConf,
+                                                           this );
+                this.objectStore.addHandle( handle,
+                                            object );
 
-			if (dynamic) {
-				addPropertyChangeListener(object);
-			}
+            }
 
-			insert(handle, object, rule, activation, typeConf);
+            if ( dynamic ) {
+                addPropertyChangeListener( object );
+            }
 
-		} finally {
-			this.lock.unlock();
-		}
-		return handle;
-	}
+            insert( handle,
+                    object,
+                    rule,
+                    activation,
+                    typeConf );
 
-	protected void insert(final InternalFactHandle handle, final Object object,
-			final Rule rule, final Activation activation,
-			ObjectTypeConf typeConf) {
-		this.ruleBase.executeQueuedActions();
+        } finally {
+            this.lock.unlock();
+        }
+        return handle;
+    }
 
-		if (activation != null) {
-			// release resources so that they can be GC'ed
-			activation.getPropagationContext().releaseResources();
-		}
-		final PropagationContext propagationContext = new PropagationContextImpl(
-				getNextPropagationIdCounter(), PropagationContext.ASSERTION,
-				rule, (activation == null) ? null : (LeftTuple) activation
-						.getTuple(), handle,
-				this.agenda.getActiveActivations(), this.agenda
-						.getDormantActivations(), entryPoint);
+    protected void insert(final InternalFactHandle handle,
+                          final Object object,
+                          final Rule rule,
+                          final Activation activation,
+                          ObjectTypeConf typeConf) {
+        this.ruleBase.executeQueuedActions();
 
-		this.entryPointNode.assertObject(handle, propagationContext, typeConf,
-				this);
+        if ( activation != null ) {
+            // release resources so that they can be GC'ed
+            activation.getPropagationContext().releaseResources();
+        }
+        final PropagationContext propagationContext = new PropagationContextImpl( getNextPropagationIdCounter(),
+                                                                                  PropagationContext.ASSERTION,
+                                                                                  rule,
+                                                                                  (activation == null) ? null : (LeftTuple) activation.getTuple(),
+                                                                                  handle,
+                                                                                  this.agenda.getActiveActivations(),
+                                                                                  this.agenda.getDormantActivations(),
+                                                                                  entryPoint );
 
-		executeQueuedActions();
+        this.entryPointNode.assertObject( handle,
+                                          propagationContext,
+                                          typeConf,
+                                          this );
 
-		this.workingMemoryEventSupport.fireObjectInserted(propagationContext,
-				handle, object, this);
-	}
+        executeQueuedActions();
 
-	protected void addPropertyChangeListener(final Object object) {
-		try {
-			final Method method = object
-					.getClass()
-					.getMethod(
-							"addPropertyChangeListener",
-							AbstractWorkingMemory.ADD_REMOVE_PROPERTY_CHANGE_LISTENER_ARG_TYPES);
+        this.workingMemoryEventSupport.fireObjectInserted( propagationContext,
+                                                           handle,
+                                                           object,
+                                                           this );
+    }
 
-			method.invoke(object, this.addRemovePropertyChangeListenerArgs);
-		} catch (final NoSuchMethodException e) {
-			System.err
-					.println("Warning: Method addPropertyChangeListener not found"
-							+ " on the class "
-							+ object.getClass()
-							+ " so Drools will be unable to process JavaBean"
-							+ " PropertyChangeEvents on the asserted Object");
-		} catch (final IllegalArgumentException e) {
-			System.err.println("Warning: The addPropertyChangeListener method"
-					+ " on the class " + object.getClass() + " does not take"
-					+ " a simple PropertyChangeListener argument"
-					+ " so Drools will be unable to process JavaBean"
-					+ " PropertyChangeEvents on the asserted Object");
-		} catch (final IllegalAccessException e) {
-			System.err.println("Warning: The addPropertyChangeListener method"
-					+ " on the class " + object.getClass() + " is not public"
-					+ " so Drools will be unable to process JavaBean"
-					+ " PropertyChangeEvents on the asserted Object");
-		} catch (final InvocationTargetException e) {
-			System.err.println("Warning: The addPropertyChangeListener method"
-					+ " on the class " + object.getClass()
-					+ " threw an InvocationTargetException"
-					+ " so Drools will be unable to process JavaBean"
-					+ " PropertyChangeEvents on the asserted Object: "
-					+ e.getMessage());
-		} catch (final SecurityException e) {
-			System.err
-					.println("Warning: The SecurityManager controlling the class "
-							+ object.getClass()
-							+ " did not allow the lookup of a"
-							+ " addPropertyChangeListener method"
-							+ " so Drools will be unable to process JavaBean"
-							+ " PropertyChangeEvents on the asserted Object: "
-							+ e.getMessage());
-		}
-	}
+    protected void addPropertyChangeListener(final Object object) {
+        try {
+            final Method method = object.getClass().getMethod( "addPropertyChangeListener",
+                                                               AbstractWorkingMemory.ADD_REMOVE_PROPERTY_CHANGE_LISTENER_ARG_TYPES );
 
-	protected void removePropertyChangeListener(final FactHandle handle) {
-		Object object = null;
-		try {
-			object = ((InternalFactHandle) handle).getObject();
+            method.invoke( object,
+                           this.addRemovePropertyChangeListenerArgs );
+        } catch ( final NoSuchMethodException e ) {
+            System.err.println( "Warning: Method addPropertyChangeListener not found" + " on the class " + object.getClass() + " so Drools will be unable to process JavaBean" + " PropertyChangeEvents on the asserted Object" );
+        } catch ( final IllegalArgumentException e ) {
+            System.err.println( "Warning: The addPropertyChangeListener method" + " on the class " + object.getClass() + " does not take" + " a simple PropertyChangeListener argument" + " so Drools will be unable to process JavaBean"
+                                + " PropertyChangeEvents on the asserted Object" );
+        } catch ( final IllegalAccessException e ) {
+            System.err.println( "Warning: The addPropertyChangeListener method" + " on the class " + object.getClass() + " is not public" + " so Drools will be unable to process JavaBean" + " PropertyChangeEvents on the asserted Object" );
+        } catch ( final InvocationTargetException e ) {
+            System.err.println( "Warning: The addPropertyChangeListener method" + " on the class " + object.getClass() + " threw an InvocationTargetException" + " so Drools will be unable to process JavaBean"
+                                + " PropertyChangeEvents on the asserted Object: " + e.getMessage() );
+        } catch ( final SecurityException e ) {
+            System.err.println( "Warning: The SecurityManager controlling the class " + object.getClass() + " did not allow the lookup of a" + " addPropertyChangeListener method" + " so Drools will be unable to process JavaBean"
+                                + " PropertyChangeEvents on the asserted Object: " + e.getMessage() );
+        }
+    }
 
-			if (object != null) {
-				final Method mehod = object
-						.getClass()
-						.getMethod(
-								"removePropertyChangeListener",
-								AbstractWorkingMemory.ADD_REMOVE_PROPERTY_CHANGE_LISTENER_ARG_TYPES);
+    protected void removePropertyChangeListener(final FactHandle handle) {
+        Object object = null;
+        try {
+            object = ((InternalFactHandle) handle).getObject();
 
-				mehod.invoke(object, this.addRemovePropertyChangeListenerArgs);
-			}
-		} catch (final NoSuchMethodException e) {
-			// The removePropertyChangeListener method on the class
-			// was not found so Drools will be unable to
-			// stop processing JavaBean PropertyChangeEvents
-			// on the retracted Object
-		} catch (final IllegalArgumentException e) {
-			throw new RuntimeDroolsException(
-					"Warning: The removePropertyChangeListener method on the class "
-							+ object.getClass()
-							+ " does not take a simple PropertyChangeListener argument so Drools will be unable to stop processing JavaBean"
-							+ " PropertyChangeEvents on the retracted Object");
-		} catch (final IllegalAccessException e) {
-			throw new RuntimeDroolsException(
-					"Warning: The removePropertyChangeListener method on the class "
-							+ object.getClass()
-							+ " is not public so Drools will be unable to stop processing JavaBean PropertyChangeEvents on the retracted Object");
-		} catch (final InvocationTargetException e) {
-			throw new RuntimeDroolsException(
-					"Warning: The removePropertyChangeL istener method on the class "
-							+ object.getClass()
-							+ " threw an InvocationTargetException so Drools will be unable to stop processing JavaBean"
-							+ " PropertyChangeEvents on the retracted Object: "
-							+ e.getMessage());
-		} catch (final SecurityException e) {
-			throw new RuntimeDroolsException(
-					"Warning: The SecurityManager controlling the class "
-							+ object.getClass()
-							+ " did not allow the lookup of a removePropertyChangeListener method so Drools will be unable to stop processing JavaBean"
-							+ " PropertyChangeEvents on the retracted Object: "
-							+ e.getMessage());
-		}
-	}
+            if ( object != null ) {
+                final Method mehod = object.getClass().getMethod( "removePropertyChangeListener",
+                                                                  AbstractWorkingMemory.ADD_REMOVE_PROPERTY_CHANGE_LISTENER_ARG_TYPES );
 
-	public void retract(final FactHandle handle) throws FactException {
-		retract(handle, true, true, null, null);
-	}
+                mehod.invoke( object,
+                              this.addRemovePropertyChangeListenerArgs );
+            }
+        } catch ( final NoSuchMethodException e ) {
+            // The removePropertyChangeListener method on the class
+            // was not found so Drools will be unable to
+            // stop processing JavaBean PropertyChangeEvents
+            // on the retracted Object
+        } catch ( final IllegalArgumentException e ) {
+            throw new RuntimeDroolsException( "Warning: The removePropertyChangeListener method on the class " + object.getClass() + " does not take a simple PropertyChangeListener argument so Drools will be unable to stop processing JavaBean"
+                                              + " PropertyChangeEvents on the retracted Object" );
+        } catch ( final IllegalAccessException e ) {
+            throw new RuntimeDroolsException( "Warning: The removePropertyChangeListener method on the class " + object.getClass() + " is not public so Drools will be unable to stop processing JavaBean PropertyChangeEvents on the retracted Object" );
+        } catch ( final InvocationTargetException e ) {
+            throw new RuntimeDroolsException( "Warning: The removePropertyChangeL istener method on the class " + object.getClass() + " threw an InvocationTargetException so Drools will be unable to stop processing JavaBean"
+                                              + " PropertyChangeEvents on the retracted Object: " + e.getMessage() );
+        } catch ( final SecurityException e ) {
+            throw new RuntimeDroolsException( "Warning: The SecurityManager controlling the class " + object.getClass() + " did not allow the lookup of a removePropertyChangeListener method so Drools will be unable to stop processing JavaBean"
+                                              + " PropertyChangeEvents on the retracted Object: " + e.getMessage() );
+        }
+    }
 
-	public void retract(final FactHandle factHandle,
-			final boolean removeLogical, final boolean updateEqualsMap,
-			final Rule rule, final Activation activation) throws FactException {
-		try {
-			this.lock.lock();
-			this.ruleBase.executeQueuedActions();
+    public void retract(final FactHandle handle) throws FactException {
+        retract( handle,
+                 true,
+                 true,
+                 null,
+                 null );
+    }
 
-			final InternalFactHandle handle = (InternalFactHandle) factHandle;
-			if (handle.getId() == -1) {
-				// can't retract an already retracted handle
-				return;
-			}
-			removePropertyChangeListener(handle);
+    public void retract(final FactHandle factHandle,
+                        final boolean removeLogical,
+                        final boolean updateEqualsMap,
+                        final Rule rule,
+                        final Activation activation) throws FactException {
+        try {
+            this.lock.lock();
+            this.ruleBase.executeQueuedActions();
 
-			if (activation != null) {
-				// release resources so that they can be GC'ed
-				activation.getPropagationContext().releaseResources();
-			}
-			final PropagationContext propagationContext = new PropagationContextImpl(
-					getNextPropagationIdCounter(),
-					PropagationContext.RETRACTION, rule,
-					(activation == null) ? null : (LeftTuple) activation
-							.getTuple(), handle, this.agenda
-							.getActiveActivations(), this.agenda
-							.getDormantActivations(), this.entryPoint);
+            final InternalFactHandle handle = (InternalFactHandle) factHandle;
+            if ( handle.getId() == -1 ) {
+                // can't retract an already retracted handle
+                return;
+            }
+            removePropertyChangeListener( handle );
 
-			final Object object = handle.getObject();
+            if ( activation != null ) {
+                // release resources so that they can be GC'ed
+                activation.getPropagationContext().releaseResources();
+            }
+            final PropagationContext propagationContext = new PropagationContextImpl( getNextPropagationIdCounter(),
+                                                                                      PropagationContext.RETRACTION,
+                                                                                      rule,
+                                                                                      (activation == null) ? null : (LeftTuple) activation.getTuple(),
+                                                                                      handle,
+                                                                                      this.agenda.getActiveActivations(),
+                                                                                      this.agenda.getDormantActivations(),
+                                                                                      this.entryPoint );
 
-			this.entryPointNode
-					.retractObject(handle, propagationContext, this.typeConfReg
-							.getObjectTypeConf(this.entryPoint, object), this);
+            final Object object = handle.getObject();
 
-			if (this.maintainTms) {
-				// Update the equality key, which maintains a list of stated
-				// FactHandles
-				final EqualityKey key = handle.getEqualityKey();
+            this.entryPointNode.retractObject( handle,
+                                               propagationContext,
+                                               this.typeConfReg.getObjectTypeConf( this.entryPoint,
+                                                                                   object ),
+                                               this );
 
-				// Its justified so attempt to remove any logical dependencies
-				// for
-				// the handle
-				if (key.getStatus() == EqualityKey.JUSTIFIED) {
-					this.tms.removeLogicalDependencies(handle);
-				}
+            if ( this.maintainTms ) {
+                // Update the equality key, which maintains a list of stated
+                // FactHandles
+                final EqualityKey key = handle.getEqualityKey();
 
-				key.removeFactHandle(handle);
-				handle.setEqualityKey(null);
+                // Its justified so attempt to remove any logical dependencies
+                // for
+                // the handle
+                if ( key.getStatus() == EqualityKey.JUSTIFIED ) {
+                    this.tms.removeLogicalDependencies( handle );
+                }
 
-				// If the equality key is now empty, then remove it
-				if (key.isEmpty()) {
-					this.tms.remove(key);
-				}
-			}
+                key.removeFactHandle( handle );
+                handle.setEqualityKey( null );
 
-			this.workingMemoryEventSupport.fireObjectRetracted(
-					propagationContext, handle, object, this);
+                // If the equality key is now empty, then remove it
+                if ( key.isEmpty() ) {
+                    this.tms.remove( key );
+                }
+            }
 
-			this.objectStore.removeHandle(handle);
+            this.workingMemoryEventSupport.fireObjectRetracted( propagationContext,
+                                                                handle,
+                                                                object,
+                                                                this );
 
-			this.handleFactory.destroyFactHandle(handle);
+            this.objectStore.removeHandle( handle );
 
-			executeQueuedActions();
-		} finally {
-			this.lock.unlock();
-		}
-	}
+            this.handleFactory.destroyFactHandle( handle );
 
-	public void modifyRetract(final FactHandle factHandle) {
-		modifyRetract(factHandle, null, null);
-	}
+            executeQueuedActions();
+        } finally {
+            this.lock.unlock();
+        }
+    }
 
-	public void modifyRetract(final FactHandle factHandle, final Rule rule,
-			final Activation activation) {
-		try {
-			this.lock.lock();
-			this.ruleBase.executeQueuedActions();
+    public void modifyRetract(final FactHandle factHandle) {
+        modifyRetract( factHandle,
+                       null,
+                       null );
+    }
 
-			// only needed if we maintain tms, but either way we must get it
-			// before we do the retract
-			int status = -1;
-			if (this.maintainTms) {
-				status = ((InternalFactHandle) factHandle).getEqualityKey()
-						.getStatus();
-			}
-			final InternalFactHandle handle = (InternalFactHandle) factHandle;
-			// final Object originalObject = (handle.isShadowFact()) ?
-			// ((ShadowProxy) handle.getObject()).getShadowedObject() :
-			// handle.getObject();
+    public void modifyRetract(final FactHandle factHandle,
+                              final Rule rule,
+                              final Activation activation) {
+        try {
+            this.lock.lock();
+            this.ruleBase.executeQueuedActions();
 
-			if (handle.getId() == -1) {
-				// the handle is invalid, most likely already retracted, so
-				// return
-				return;
-			}
+            final InternalFactHandle handle = (InternalFactHandle) factHandle;
 
-			if (activation != null) {
-				// release resources so that they can be GC'ed
-				activation.getPropagationContext().releaseResources();
-			}
-			// Nowretract any trace of the original fact
-			final PropagationContext propagationContext = new PropagationContextImpl(
-					getNextPropagationIdCounter(),
-					PropagationContext.MODIFICATION, rule,
-					(activation == null) ? null : (LeftTuple) activation
-							.getTuple(), handle, this.agenda
-							.getActiveActivations(), this.agenda
-							.getDormantActivations(), entryPoint);
+            if ( handle.getId() == -1 ) {
+                // the handle is invalid, most likely already retracted, so
+                // return
+                return;
+            }
 
-			this.entryPointNode.retractObject(handle, propagationContext,
-					this.typeConfReg.getObjectTypeConf(this.entryPoint, handle
-							.getObject()), this);
+            if ( activation != null ) {
+                // release resources so that they can be GC'ed
+                activation.getPropagationContext().releaseResources();
+            }
+            // Nowretract any trace of the original fact
+            final PropagationContext propagationContext = new PropagationContextImpl( getNextPropagationIdCounter(),
+                                                                                      PropagationContext.MODIFICATION,
+                                                                                      rule,
+                                                                                      (activation == null) ? null : (LeftTuple) activation.getTuple(),
+                                                                                      handle,
+                                                                                      this.agenda.getActiveActivations(),
+                                                                                      this.agenda.getDormantActivations(),
+                                                                                      entryPoint );
 
-			if (this.maintainTms) {
+            modifyContexts.put( handle,
+                                propagationContext );
 
-				// the hashCode and equality has changed, so we must update the
-				// EqualityKey
-				EqualityKey key = handle.getEqualityKey();
-				key.removeFactHandle(handle);
+            this.entryPointNode.retractObject( handle,
+                                               propagationContext,
+                                               this.typeConfReg.getObjectTypeConf( this.entryPoint,
+                                                                                   handle.getObject() ),
+                                               this );
 
-				// If the equality key is now empty, then remove it
-				if (key.isEmpty()) {
-					this.tms.remove(key);
-				}
-			}
-		} finally {
-			this.lock.unlock();
-		}
-	}
+            if ( this.maintainTms ) {
 
-	public void modifyInsert(final FactHandle factHandle, final Object object) {
-		modifyInsert(factHandle, object, null, null);
-	}
+                // the hashCode and equality has changed, so we must update the
+                // EqualityKey
+                EqualityKey key = handle.getEqualityKey();
+                key.removeFactHandle( handle );
 
-	public void modifyInsert(final FactHandle factHandle, final Object object,
-			final Rule rule, final Activation activation) {
-		try {
-			this.lock.lock();
-			this.ruleBase.executeQueuedActions();
+                // If the equality key is now empty, then remove it
+                if ( key.isEmpty() ) {
+                    this.tms.remove( key );
+                }
+            }
+        } finally {
+            this.lock.unlock();
+        }
+    }
 
-			final InternalFactHandle handle = (InternalFactHandle) factHandle;
-			final Object originalObject = handle.getObject();
+    public void modifyInsert(final FactHandle factHandle,
+                             final Object object) {
+        modifyInsert( factHandle,
+                      object,
+                      null,
+                      null );
+    }
 
-			if (this.maintainTms) {
-				EqualityKey key = handle.getEqualityKey();
+    public void modifyInsert(final FactHandle factHandle,
+                             final Object object,
+                             final Rule rule,
+                             final Activation activation) {
+        try {
+            this.lock.lock();
+            this.ruleBase.executeQueuedActions();
 
-				// now use an existing EqualityKey, if it exists, else create a
-				// new one
-				key = this.tms.get(object);
-				if (key == null) {
-					key = new EqualityKey(handle, 0);
-					this.tms.put(key);
-				} else {
-					key.addFactHandle(handle);
-				}
+            final InternalFactHandle handle = (InternalFactHandle) factHandle;
+            final Object originalObject = handle.getObject();
 
-				handle.setEqualityKey(key);
-			}
+            if ( this.maintainTms ) {
+                int status = handle.getEqualityKey().getStatus();
 
-			this.handleFactory.increaseFactHandleRecency(handle);
+                // now use an existing EqualityKey, if it exists, else create a
+                // new one
+                EqualityKey key = this.tms.get( object );
+                if ( key == null ) {
+                    key = new EqualityKey( handle,
+                                           status );
+                    this.tms.put( key );
+                } else {
+                    key.addFactHandle( handle );
+                }
 
-			if (activation != null) {
-				// release resources so that they can be GC'ed
-				activation.getPropagationContext().releaseResources();
-			}
-			// Nowretract any trace of the original fact
-			final PropagationContext propagationContext = new PropagationContextImpl(
-					getNextPropagationIdCounter(),
-					PropagationContext.MODIFICATION, rule,
-					(activation == null) ? null : (LeftTuple) activation
-							.getTuple(), handle, this.agenda
-							.getActiveActivations(), this.agenda
-							.getDormantActivations(), entryPoint);
+                handle.setEqualityKey( key );
+            }
 
-			this.entryPointNode
-					.assertObject(handle, propagationContext, this.typeConfReg
-							.getObjectTypeConf(this.entryPoint, object), this);
+            this.handleFactory.increaseFactHandleRecency( handle );
 
-			this.workingMemoryEventSupport.fireObjectUpdated(
-					propagationContext, factHandle, originalObject, object,
-					this);
+            if ( activation != null ) {
+                // release resources so that they can be GC'ed
+                activation.getPropagationContext().releaseResources();
+            }
+            // Now retract any trace of the original fact
+            final PropagationContext propagationContext = this.modifyContexts.remove( handle );
 
-			propagationContext.clearRetractedTuples();
+            this.entryPointNode.assertObject( handle,
+                                              propagationContext,
+                                              this.typeConfReg.getObjectTypeConf( this.entryPoint,
+                                                                                  object ),
+                                              this );
 
-			executeQueuedActions();
+            this.workingMemoryEventSupport.fireObjectUpdated( propagationContext,
+                                                              factHandle,
+                                                              originalObject,
+                                                              object,
+                                                              this );
 
-		} finally {
-			this.lock.unlock();
-		}
-	}
+            propagationContext.clearRetractedTuples();
 
-	public void update(final FactHandle handle, final Object object)
-			throws FactException {
-		update(handle, object, null, null);
-	}
+            executeQueuedActions();
 
-	/**
-	 * modify is implemented as half way retract / assert due to the truth
-	 * maintenance issues.
-	 * 
-	 * @see WorkingMemory
-	 */
-	public void update(final FactHandle factHandle, final Object object,
-			final Rule rule, final Activation activation) throws FactException {
-		try {
-			this.lock.lock();
-			this.ruleBase.executeQueuedActions();
+        } finally {
+            this.lock.unlock();
+        }
+    }
 
-			// only needed if we maintain tms, but either way we must get it
-			// before we do the retract
-			int status = -1;
-			if (this.maintainTms) {
-				status = ((InternalFactHandle) factHandle).getEqualityKey()
-						.getStatus();
-			}
-			final InternalFactHandle handle = (InternalFactHandle) factHandle;
-			final Object originalObject = handle.getObject();
+    public void update(final FactHandle handle,
+                       final Object object) throws FactException {
+        update( handle,
+                object,
+                null,
+                null );
+    }
 
-			if (handle.getId() == -1 || object == null) {
-				// the handle is invalid, most likely already retracted, so
-				// return
-				// and we cannot assert a null object
-				return;
-			}
+    /**
+     * modify is implemented as half way retract / assert due to the truth
+     * maintenance issues.
+     * 
+     * @see WorkingMemory
+     */
+    public void update(final FactHandle factHandle,
+                       final Object object,
+                       final Rule rule,
+                       final Activation activation) throws FactException {
+        try {
+            this.lock.lock();
+            this.ruleBase.executeQueuedActions();
 
-			if (activation != null) {
-				// release resources so that they can be GC'ed
-				activation.getPropagationContext().releaseResources();
-			}
-			// Nowretract any trace of the original fact
-			final PropagationContext propagationContext = new PropagationContextImpl(
-					getNextPropagationIdCounter(),
-					PropagationContext.MODIFICATION, rule,
-					(activation == null) ? null : (LeftTuple) activation
-							.getTuple(), handle, this.agenda
-							.getActiveActivations(), this.agenda
-							.getDormantActivations(), entryPoint);
+            // only needed if we maintain tms, but either way we must get it
+            // before we do the retract
+            int status = -1;
+            if ( this.maintainTms ) {
+                status = ((InternalFactHandle) factHandle).getEqualityKey().getStatus();
+            }
+            final InternalFactHandle handle = (InternalFactHandle) factHandle;
+            final Object originalObject = handle.getObject();
 
-			ObjectTypeConf typeConf = this.typeConfReg.getObjectTypeConf(
-					this.entryPoint, object);
+            if ( handle.getId() == -1 || object == null ) {
+                // the handle is invalid, most likely already retracted, so
+                // return
+                // and we cannot assert a null object
+                return;
+            }
 
-			this.entryPointNode.retractObject(handle, propagationContext,
-					typeConf, this);
+            if ( activation != null ) {
+                // release resources so that they can be GC'ed
+                activation.getPropagationContext().releaseResources();
+            }
+            // Nowretract any trace of the original fact
+            final PropagationContext propagationContext = new PropagationContextImpl( getNextPropagationIdCounter(),
+                                                                                      PropagationContext.MODIFICATION,
+                                                                                      rule,
+                                                                                      (activation == null) ? null : (LeftTuple) activation.getTuple(),
+                                                                                      handle,
+                                                                                      this.agenda.getActiveActivations(),
+                                                                                      this.agenda.getDormantActivations(),
+                                                                                      entryPoint );
 
-			if (originalObject != object
-					|| !AssertBehaviour.IDENTITY.equals(this.ruleBase
-							.getConfiguration().getAssertBehaviour())) {
-				this.objectStore.removeHandle(handle);
+            ObjectTypeConf typeConf = this.typeConfReg.getObjectTypeConf( this.entryPoint,
+                                                                          object );
 
-				// set anyway, so that it updates the hashCodes
-				handle.setObject(object);
-				this.objectStore.addHandle(handle, object);
-			}
+            this.entryPointNode.retractObject( handle,
+                                               propagationContext,
+                                               typeConf,
+                                               this );
 
-			if (this.maintainTms) {
+            if ( originalObject != object || !AssertBehaviour.IDENTITY.equals( this.ruleBase.getConfiguration().getAssertBehaviour() ) ) {
+                this.objectStore.removeHandle( handle );
 
-				// the hashCode and equality has changed, so we must update the
-				// EqualityKey
-				EqualityKey key = handle.getEqualityKey();
-				key.removeFactHandle(handle);
+                // set anyway, so that it updates the hashCodes
+                handle.setObject( object );
+                this.objectStore.addHandle( handle,
+                                            object );
+            }
 
-				// If the equality key is now empty, then remove it
-				if (key.isEmpty()) {
-					this.tms.remove(key);
-				}
+            if ( this.maintainTms ) {
 
-				// now use an existing EqualityKey, if it exists, else create a
-				// new one
-				key = this.tms.get(object);
-				if (key == null) {
-					key = new EqualityKey(handle, status);
-					this.tms.put(key);
-				} else {
-					key.addFactHandle(handle);
-				}
+                // the hashCode and equality has changed, so we must update the
+                // EqualityKey
+                EqualityKey key = handle.getEqualityKey();
+                key.removeFactHandle( handle );
 
-				handle.setEqualityKey(key);
-			}
+                // If the equality key is now empty, then remove it
+                if ( key.isEmpty() ) {
+                    this.tms.remove( key );
+                }
 
-			this.handleFactory.increaseFactHandleRecency(handle);
+                // now use an existing EqualityKey, if it exists, else create a
+                // new one
+                key = this.tms.get( object );
+                if ( key == null ) {
+                    key = new EqualityKey( handle,
+                                           status );
+                    this.tms.put( key );
+                } else {
+                    key.addFactHandle( handle );
+                }
 
-			this.entryPointNode.assertObject(handle, propagationContext,
-					typeConf, this);
+                handle.setEqualityKey( key );
+            }
 
-			this.workingMemoryEventSupport.fireObjectUpdated(
-					propagationContext, factHandle, originalObject, object,
-					this);
+            this.handleFactory.increaseFactHandleRecency( handle );
 
-			propagationContext.clearRetractedTuples();
+            this.entryPointNode.assertObject( handle,
+                                              propagationContext,
+                                              typeConf,
+                                              this );
 
-			executeQueuedActions();
-		} finally {
-			this.lock.unlock();
-		}
-	}
+            this.workingMemoryEventSupport.fireObjectUpdated( propagationContext,
+                                                              factHandle,
+                                                              originalObject,
+                                                              object,
+                                                              this );
 
-	public void executeQueuedActions() {
-		synchronized (this.actionQueue) {
-			if (!this.actionQueue.isEmpty() && !evaluatingActionQueue) {
-				evaluatingActionQueue = true;
-				WorkingMemoryAction action = null;
+            propagationContext.clearRetractedTuples();
 
-				while ((action = actionQueue.poll()) != null) {
-					action.execute(this);
-				}
-				evaluatingActionQueue = false;
-			}
-		}
-	}
+            executeQueuedActions();
+        } finally {
+            this.lock.unlock();
+        }
+    }
 
-	public Queue<WorkingMemoryAction> getActionQueue() {
-		return this.actionQueue;
-	}
+    public void executeQueuedActions() {
+        synchronized ( this.actionQueue ) {
+            if ( !this.actionQueue.isEmpty() && !evaluatingActionQueue ) {
+                evaluatingActionQueue = true;
+                WorkingMemoryAction action = null;
 
-	public void queueWorkingMemoryAction(final WorkingMemoryAction action) {
-		synchronized (this.actionQueue) {
-			this.actionQueue.add(action);
-		}
-	}
+                while ( (action = actionQueue.poll()) != null ) {
+                    action.execute( this );
+                }
+                evaluatingActionQueue = false;
+            }
+        }
+    }
 
-	public void removeLogicalDependencies(final Activation activation,
-			final PropagationContext context, final Rule rule)
-			throws FactException {
-		if (this.maintainTms) {
-			this.tms.removeLogicalDependencies(activation, context, rule);
-		}
-	}
+    public Queue<WorkingMemoryAction> getActionQueue() {
+        return this.actionQueue;
+    }
 
-	/**
-	 * Retrieve the <code>JoinMemory</code> for a particular
-	 * <code>JoinNode</code>.
-	 * 
-	 * @param node
-	 *            The <code>JoinNode</code> key.
-	 * 
-	 * @return The node's memory.
-	 */
-	public Object getNodeMemory(final NodeMemory node) {
-		return this.nodeMemories.getNodeMemory(node);
-	}
+    public void queueWorkingMemoryAction(final WorkingMemoryAction action) {
+        synchronized ( this.actionQueue ) {
+            this.actionQueue.add( action );
+        }
+    }
 
-	public void clearNodeMemory(final NodeMemory node) {
-		this.nodeMemories.clearNodeMemory(node);
-	}
+    public void removeLogicalDependencies(final Activation activation,
+                                          final PropagationContext context,
+                                          final Rule rule) throws FactException {
+        if ( this.maintainTms ) {
+            this.tms.removeLogicalDependencies( activation,
+                                                context,
+                                                rule );
+        }
+    }
 
-	public WorkingMemoryEventSupport getWorkingMemoryEventSupport() {
-		return this.workingMemoryEventSupport;
-	}
+    /**
+     * Retrieve the <code>JoinMemory</code> for a particular
+     * <code>JoinNode</code>.
+     * 
+     * @param node
+     *            The <code>JoinNode</code> key.
+     * 
+     * @return The node's memory.
+     */
+    public Object getNodeMemory(final NodeMemory node) {
+        return this.nodeMemories.getNodeMemory( node );
+    }
 
-	public AgendaEventSupport getAgendaEventSupport() {
-		return this.agendaEventSupport;
-	}
+    public void clearNodeMemory(final NodeMemory node) {
+        this.nodeMemories.clearNodeMemory( node );
+    }
 
-	public RuleFlowEventSupport getRuleFlowEventSupport() {
-		return this.workflowEventSupport;
-	}
+    public WorkingMemoryEventSupport getWorkingMemoryEventSupport() {
+        return this.workingMemoryEventSupport;
+    }
 
-	/**
-	 * Sets the AsyncExceptionHandler to handle exceptions thrown by the Agenda
-	 * Scheduler used for duration rules.
-	 * 
-	 * @param handler
-	 */
-	public void setAsyncExceptionHandler(final AsyncExceptionHandler handler) {
-		// this.agenda.setAsyncExceptionHandler( handler );
-	}
+    public AgendaEventSupport getAgendaEventSupport() {
+        return this.agendaEventSupport;
+    }
 
-	/*
-	 * public void dumpMemory() { Iterator it = this.joinMemories.keySet(
-	 * ).iterator( ); while ( it.hasNext( ) ) { ((JoinMemory)
-	 * this.joinMemories.get( it.next( ) )).dump( ); } }
-	 */
+    public RuleFlowEventSupport getRuleFlowEventSupport() {
+        return this.workflowEventSupport;
+    }
 
-	public void propertyChange(final PropertyChangeEvent event) {
-		final Object object = event.getSource();
+    /**
+     * Sets the AsyncExceptionHandler to handle exceptions thrown by the Agenda
+     * Scheduler used for duration rules.
+     * 
+     * @param handler
+     */
+    public void setAsyncExceptionHandler(final AsyncExceptionHandler handler) {
+        // this.agenda.setAsyncExceptionHandler( handler );
+    }
 
-		try {
-			FactHandle handle = getFactHandle(object);
-			if (handle == null) {
-				throw new FactException(
-						"Update error: handle not found for object: " + object
-								+ ". Is it in the working memory?");
-			}
-			update(handle, object);
-		} catch (final FactException e) {
-			throw new RuntimeDroolsException(e.getMessage());
-		}
-	}
+    /*
+     * public void dumpMemory() { Iterator it = this.joinMemories.keySet(
+     * ).iterator( ); while ( it.hasNext( ) ) { ((JoinMemory)
+     * this.joinMemories.get( it.next( ) )).dump( ); } }
+     */
 
-	public long getNextPropagationIdCounter() {
-		return this.propagationIdCounter.incrementAndGet();
-	}
+    public void propertyChange(final PropertyChangeEvent event) {
+        final Object object = event.getSource();
 
-	public long getPropagationIdCounter() {
-		return this.propagationIdCounter.get();
-	}
+        try {
+            FactHandle handle = getFactHandle( object );
+            if ( handle == null ) {
+                throw new FactException( "Update error: handle not found for object: " + object + ". Is it in the working memory?" );
+            }
+            update( handle,
+                    object );
+        } catch ( final FactException e ) {
+            throw new RuntimeDroolsException( e.getMessage() );
+        }
+    }
 
-	public Lock getLock() {
-		return this.lock;
-	}
+    public long getNextPropagationIdCounter() {
+        return this.propagationIdCounter.incrementAndGet();
+    }
 
-	public class RuleFlowDeactivateEvent {
+    public long getPropagationIdCounter() {
+        return this.propagationIdCounter.get();
+    }
 
-		public void propagate() {
+    public Lock getLock() {
+        return this.lock;
+    }
 
-		}
-	}
+    public class RuleFlowDeactivateEvent {
 
-	public ProcessInstance startProcess(final String processId) {
-		return startProcess(processId, null);
-	}
+        public void propagate() {
 
-	public ProcessInstance startProcess(String processId,
-			Map<String, Object> parameters) {
-		if (!this.actionQueue.isEmpty()) {
-			executeQueuedActions();
-		}
-		final Process process = ((InternalRuleBase) getRuleBase())
-				.getProcess(processId);
-		if (process == null) {
-			throw new IllegalArgumentException("Unknown process ID: "
-					+ processId);
-		}
-		ProcessInstance processInstance = getProcessInstance(process);
-		processInstance.setWorkingMemory(this);
-		processInstance.setProcess(process);
-		processInstanceManager.addProcessInstance(processInstance);
-		// set variable default values
-		// TODO: should be part of processInstanceImpl?
-		VariableScope variableScope = (VariableScope) process
-				.getDefaultContext(VariableScope.VARIABLE_SCOPE);
-		VariableScopeInstance variableScopeInstance = (VariableScopeInstance) processInstance
-				.getContextInstance(VariableScope.VARIABLE_SCOPE);
-		// set input parameters
-		if (parameters != null) {
-			if (variableScope != null) {
-				for (Map.Entry<String, Object> entry : parameters.entrySet()) {
-					variableScopeInstance.setVariable(entry.getKey(), entry
-							.getValue());
-				}
-			} else {
-				throw new IllegalArgumentException(
-						"This process does not support parameters!");
-			}
-		}
-		// start
-		getRuleFlowEventSupport().fireBeforeRuleFlowProcessStarted(
-				processInstance, this);
-		processInstance.start();
-		getRuleFlowEventSupport().fireAfterRuleFlowProcessStarted(
-				processInstance, this);
+        }
+    }
 
-		return processInstance;
-	}
+    public ProcessInstance startProcess(final String processId) {
+        return startProcess( processId,
+                             null );
+    }
 
-	public ProcessInstance getProcessInstance(final Process process) {
-		ProcessInstanceFactoryRegistry processRegistry = ((InternalRuleBase) getRuleBase())
-				.getConfiguration().getProcessInstanceFactoryRegistry();
-		ProcessInstanceFactory conf = processRegistry
-				.getProcessInstanceFactory(process);
-		if (conf == null) {
-			throw new IllegalArgumentException("Illegal process type: "
-					+ process.getClass());
-		}
-		ProcessInstance processInstance = conf.createProcessInstance();
-		if (processInstance == null) {
-			throw new IllegalArgumentException("Illegal process type: "
-					+ process.getClass());
-		}
-		return processInstance;
-	}
+    public ProcessInstance startProcess(String processId,
+                                        Map<String, Object> parameters) {
+        if ( !this.actionQueue.isEmpty() ) {
+            executeQueuedActions();
+        }
+        final Process process = ((InternalRuleBase) getRuleBase()).getProcess( processId );
+        if ( process == null ) {
+            throw new IllegalArgumentException( "Unknown process ID: " + processId );
+        }
+        ProcessInstance processInstance = getProcessInstance( process );
+        processInstance.setWorkingMemory( this );
+        processInstance.setProcess( process );
+        processInstanceManager.addProcessInstance( processInstance );
+        // set variable default values
+        // TODO: should be part of processInstanceImpl?
+        VariableScope variableScope = (VariableScope) process.getDefaultContext( VariableScope.VARIABLE_SCOPE );
+        VariableScopeInstance variableScopeInstance = (VariableScopeInstance) processInstance.getContextInstance( VariableScope.VARIABLE_SCOPE );
+        // set input parameters
+        if ( parameters != null ) {
+            if ( variableScope != null ) {
+                for ( Map.Entry<String, Object> entry : parameters.entrySet() ) {
+                    variableScopeInstance.setVariable( entry.getKey(),
+                                                       entry.getValue() );
+                }
+            } else {
+                throw new IllegalArgumentException( "This process does not support parameters!" );
+            }
+        }
+        // start
+        getRuleFlowEventSupport().fireBeforeRuleFlowProcessStarted( processInstance,
+                                                                    this );
+        processInstance.start();
+        getRuleFlowEventSupport().fireAfterRuleFlowProcessStarted( processInstance,
+                                                                   this );
 
-	public ProcessInstanceManager getProcessInstanceManager() {
-		return processInstanceManager;
-	}
+        return processInstance;
+    }
 
-	public Collection<ProcessInstance> getProcessInstances() {
-		return processInstanceManager.getProcessInstances();
-	}
+    public ProcessInstance getProcessInstance(final Process process) {
+        ProcessInstanceFactoryRegistry processRegistry = ((InternalRuleBase) getRuleBase()).getConfiguration().getProcessInstanceFactoryRegistry();
+        ProcessInstanceFactory conf = processRegistry.getProcessInstanceFactory( process );
+        if ( conf == null ) {
+            throw new IllegalArgumentException( "Illegal process type: " + process.getClass() );
+        }
+        ProcessInstance processInstance = conf.createProcessInstance();
+        if ( processInstance == null ) {
+            throw new IllegalArgumentException( "Illegal process type: " + process.getClass() );
+        }
+        return processInstance;
+    }
 
-	public ProcessInstance getProcessInstance(long id) {
-		return processInstanceManager.getProcessInstance(id);
-	}
+    public ProcessInstanceManager getProcessInstanceManager() {
+        return processInstanceManager;
+    }
 
-	public void removeProcessInstance(ProcessInstance processInstance) {
-		processInstanceManager.removeProcessInstance(processInstance);
-	}
+    public Collection<ProcessInstance> getProcessInstances() {
+        return processInstanceManager.getProcessInstances();
+    }
 
-	public WorkItemManager getWorkItemManager() {
-		if (workItemManager == null) {
-			workItemManager = ruleBase.getConfiguration()
-					.getWorkItemManagerFactory().createWorkItemManager(this);
-			Map<String, WorkItemHandler> workItemHandlers = ((InternalRuleBase) getRuleBase())
-					.getConfiguration().getWorkItemHandlers();
-			if (workItemHandlers != null) {
-				for (Map.Entry<String, WorkItemHandler> entry : workItemHandlers
-						.entrySet()) {
-					workItemManager.registerWorkItemHandler(entry.getKey(),
-							entry.getValue());
-				}
-			}
-		}
-		return workItemManager;
-	}
+    public ProcessInstance getProcessInstance(long id) {
+        return processInstanceManager.getProcessInstance( id );
+    }
 
-	public TimerManager getTimerManager() {
-		return timerManager;
-	}
+    public void removeProcessInstance(ProcessInstance processInstance) {
+        processInstanceManager.removeProcessInstance( processInstance );
+    }
 
-	public List iterateObjectsToList() {
-		List result = new ArrayList();
-		Iterator iterator = iterateObjects();
-		for (; iterator.hasNext();) {
-			result.add(iterator.next());
-		}
-		return result;
-	}
+    public WorkItemManager getWorkItemManager() {
+        if ( workItemManager == null ) {
+            workItemManager = ruleBase.getConfiguration().getWorkItemManagerFactory().createWorkItemManager( this );
+            Map<String, WorkItemHandler> workItemHandlers = ((InternalRuleBase) getRuleBase()).getConfiguration().getWorkItemHandlers();
+            if ( workItemHandlers != null ) {
+                for ( Map.Entry<String, WorkItemHandler> entry : workItemHandlers.entrySet() ) {
+                    workItemManager.registerWorkItemHandler( entry.getKey(),
+                                                             entry.getValue() );
+                }
+            }
+        }
+        return workItemManager;
+    }
 
-	public Entry[] getActivationParameters(long activationId) {
-		Activation[] activations = getAgenda().getActivations();
-		for (int i = 0; i < activations.length; i++) {
-			if (activations[i].getActivationNumber() == activationId) {
-				Map params = getActivationParameters(activations[i]);
-				return (Entry[]) params.entrySet().toArray(
-						new Entry[params.size()]);
-			}
-		}
-		return new Entry[0];
-	}
+    public TimerManager getTimerManager() {
+        return timerManager;
+    }
 
-	/**
-	 * Helper method
-	 */
-	public Map getActivationParameters(Activation activation) {
-		Map result = new HashMap();
-		Declaration[] declarations = activation.getRule().getDeclarations();
-		for (int i = 0; i < declarations.length; i++) {
-			FactHandle handle = activation.getTuple().get(declarations[i]);
-			if (handle instanceof InternalFactHandle) {
-				result.put(declarations[i].getIdentifier(), declarations[i]
-						.getValue(this, ((InternalFactHandle) handle)
-								.getObject()));
-			}
-		}
-		return result;
-	}
+    public List iterateObjectsToList() {
+        List result = new ArrayList();
+        Iterator iterator = iterateObjects();
+        for ( ; iterator.hasNext(); ) {
+            result.add( iterator.next() );
+        }
+        return result;
+    }
 
-	/**
-	 * The time machine tells you what time it is.
-	 */
-	public TimeMachine getTimeMachine() {
-		return timeMachine;
-	}
+    public Entry[] getActivationParameters(long activationId) {
+        Activation[] activations = getAgenda().getActivations();
+        for ( int i = 0; i < activations.length; i++ ) {
+            if ( activations[i].getActivationNumber() == activationId ) {
+                Map params = getActivationParameters( activations[i] );
+                return (Entry[]) params.entrySet().toArray( new Entry[params.size()] );
+            }
+        }
+        return new Entry[0];
+    }
 
-	/**
-	 * The time machine defaults to returning the current time when asked.
-	 * However, you can use tell it to go back in time.
-	 * 
-	 * @param timeMachine
-	 */
-	public void setTimeMachine(TimeMachine timeMachine) {
-		this.timeMachine = timeMachine;
-	}
+    /**
+     * Helper method
+     */
+    public Map getActivationParameters(Activation activation) {
+        Map result = new HashMap();
+        Declaration[] declarations = activation.getRule().getDeclarations();
+        for ( int i = 0; i < declarations.length; i++ ) {
+            FactHandle handle = activation.getTuple().get( declarations[i] );
+            if ( handle instanceof InternalFactHandle ) {
+                result.put( declarations[i].getIdentifier(),
+                            declarations[i].getValue( this,
+                                                      ((InternalFactHandle) handle).getObject() ) );
+            }
+        }
+        return result;
+    }
 
-	public ExecutorService getExecutorService() {
-		return null; // no executor service
-	}
+    /**
+     * The time machine tells you what time it is.
+     */
+    public TimeMachine getTimeMachine() {
+        return timeMachine;
+    }
 
-	public void setExecutorService(ExecutorService executor) {
-		// no executor service, so nothing to set
-	}
+    /**
+     * The time machine defaults to returning the current time when asked.
+     * However, you can use tell it to go back in time.
+     * 
+     * @param timeMachine
+     */
+    public void setTimeMachine(TimeMachine timeMachine) {
+        this.timeMachine = timeMachine;
+    }
 
-	public WorkingMemoryEntryPoint getWorkingMemoryEntryPoint(String name) {
-		WorkingMemoryEntryPoint wmEntryPoint = this.entryPoints.get(name);
-		if (wmEntryPoint == null) {
-			EntryPoint entryPoint = new EntryPoint(name);
-			EntryPointNode entryPointNode = this.ruleBase.getRete()
-					.getEntryPointNode(entryPoint);
+    public ExecutorService getExecutorService() {
+        return null; // no executor service
+    }
 
-			if (entryPointNode != null) {
-				wmEntryPoint = new NamedEntryPoint(entryPoint, entryPointNode,
-						this);
-			}
+    public void setExecutorService(ExecutorService executor) {
+        // no executor service, so nothing to set
+    }
 
-			if (wmEntryPoint != null) {
-				this.entryPoints.put(name, wmEntryPoint);
-			}
-		}
-		return wmEntryPoint;
-	}
+    public WorkingMemoryEntryPoint getWorkingMemoryEntryPoint(String name) {
+        WorkingMemoryEntryPoint wmEntryPoint = this.entryPoints.get( name );
+        if ( wmEntryPoint == null ) {
+            EntryPoint entryPoint = new EntryPoint( name );
+            EntryPointNode entryPointNode = this.ruleBase.getRete().getEntryPointNode( entryPoint );
 
-	public ObjectTypeConfigurationRegistry getObjectTypeConfigurationRegistry() {
-		return this.typeConfReg;
-	}
+            if ( entryPointNode != null ) {
+                wmEntryPoint = new NamedEntryPoint( entryPoint,
+                                                    entryPointNode,
+                                                    this );
+            }
 
-	public InternalFactHandle getInitialFactHandle() {
-		return this.initialFactHandle;
-	}
+            if ( wmEntryPoint != null ) {
+                this.entryPoints.put( name,
+                                      wmEntryPoint );
+            }
+        }
+        return wmEntryPoint;
+    }
 
-	public void setInitialFactHandle(InternalFactHandle initialFactHandle) {
-		this.initialFactHandle = initialFactHandle;
-	}
+    public ObjectTypeConfigurationRegistry getObjectTypeConfigurationRegistry() {
+        return this.typeConfReg;
+    }
 
-	public TimerService getTimerService() {
-		return this.getTimerManager().getTimerService();
-	}
+    public InternalFactHandle getInitialFactHandle() {
+        return this.initialFactHandle;
+    }
 
-	public SessionClock getSessionClock() {
-		return (SessionClock) this.getTimerManager().getTimerService();
-	}
+    public void setInitialFactHandle(InternalFactHandle initialFactHandle) {
+        this.initialFactHandle = initialFactHandle;
+    }
 
-	public PartitionTaskManager getPartitionManager(
-			final RuleBasePartitionId partitionId) {
-		return partitionManagers.get(partitionId);
-	}
+    public TimerService getTimerService() {
+        return this.getTimerManager().getTimerService();
+    }
 
-	// public static class FactHandleInvalidation implements WorkingMemoryAction
-	// {
-	// private final InternalFactHandle handle;
-	//        
-	// public FactHandleInvalidation(InternalFactHandle handle) {
-	// this.handle = handle;
-	// }
-	//
-	// public void execute(InternalWorkingMemory workingMemory) {
-	// workingMemory.getFactHandleFactory().destroyFactHandle( handle );
-	// }
-	//
-	// public void write(WMSerialisationOutContext context) throws IOException {
-	// context.writeInt( handle.getId() );
-	// }
-	//
-	// public void readExternal(ObjectInput in) throws IOException,
-	// ClassNotFoundException {
-	// // TODO Auto-generated method stub
-	//            
-	// }
-	//
-	// public void writeExternal(ObjectOutput out) throws IOException {
-	// // TODO Auto-generated method stub
-	//            
-	// }
-	//        
-	// }
+    public SessionClock getSessionClock() {
+        return (SessionClock) this.getTimerManager().getTimerService();
+    }
 
-	public void dispose() {
-		this.workingMemoryEventSupport.reset();
-		this.agendaEventSupport.reset();
-		this.workflowEventSupport.reset();
-		for (Iterator it = this.__ruleBaseEventListeners.iterator(); it
-				.hasNext();) {
-			this.ruleBase
-					.removeEventListener((RuleBaseEventListener) it.next());
-		}
-		this.stopPartitionManagers();
-		this.timerManager.dispose();
-	}
+    public PartitionTaskManager getPartitionManager(final RuleBasePartitionId partitionId) {
+        return partitionManagers.get( partitionId );
+    }
 
+    // public static class FactHandleInvalidation implements WorkingMemoryAction
+    // {
+    // private final InternalFactHandle handle;
+    //        
+    // public FactHandleInvalidation(InternalFactHandle handle) {
+    // this.handle = handle;
+    // }
+    //
+    // public void execute(InternalWorkingMemory workingMemory) {
+    // workingMemory.getFactHandleFactory().destroyFactHandle( handle );
+    // }
+    //
+    // public void write(WMSerialisationOutContext context) throws IOException {
+    // context.writeInt( handle.getId() );
+    // }
+    //
+    // public void readExternal(ObjectInput in) throws IOException,
+    // ClassNotFoundException {
+    // // TODO Auto-generated method stub
+    //            
+    // }
+    //
+    // public void writeExternal(ObjectOutput out) throws IOException {
+    // // TODO Auto-generated method stub
+    //            
+    // }
+    //        
+    // }
+
+    public void dispose() {
+        this.workingMemoryEventSupport.reset();
+        this.agendaEventSupport.reset();
+        this.workflowEventSupport.reset();
+        for ( Iterator it = this.__ruleBaseEventListeners.iterator(); it.hasNext(); ) {
+            this.ruleBase.removeEventListener( (RuleBaseEventListener) it.next() );
+        }
+        this.stopPartitionManagers();
+        this.timerManager.dispose();
+    }
+
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultAgenda.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultAgenda.java	2008-09-19 18:29:01 UTC (rev 22930)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultAgenda.java	2008-09-19 22:46:08 UTC (rev 22931)
@@ -104,8 +104,8 @@
 
     private ConsequenceExceptionHandler      consequenceExceptionHandler;
 
-    protected volatile AtomicBoolean         halt = new AtomicBoolean(false);
-    
+    protected volatile AtomicBoolean         halt             = new AtomicBoolean( false );
+
     // ------------------------------------------------------------
     // Constructors
     // ------------------------------------------------------------
@@ -296,7 +296,7 @@
     /**
      * @inheritDoc
      */
-    public void addActivation(final AgendaItem activation) {
+    public boolean addActivation(final AgendaItem activation) {
         // set the focus if rule autoFocus is true
         if ( activation.getRule().getAutoFocus() ) {
             this.setFocus( activation.getRule().getAgendaGroup() );
@@ -323,7 +323,7 @@
                     if ( justifier == null ) {
                         // This rule is locked and active, do not allow new
                         // tuples to activate
-                        return;
+                        return false;
                     } else if ( activation.getRule().hasLogicalDependency() ) {
                         copyLogicalDependencies( activation.getPropagationContext(),
                                                  workingMemory,
@@ -339,7 +339,7 @@
                                              justifier );
                 }
             } else if ( activation.getRule().isLockOnActive() && agendaGroup.isActive() ) {
-                return;
+                return false;
             }
 
             agendaGroup.add( activation );
@@ -358,7 +358,7 @@
                     if ( justifier == null ) {
                         // This rule is locked and active, do not allow new
                         // tuples to activate
-                        return;
+                        return false;
                     } else if ( activation.getRule().hasLogicalDependency() ) {
                         copyLogicalDependencies( activation.getPropagationContext(),
                                                  workingMemory,
@@ -374,17 +374,18 @@
                                              justifier );
                 }
             } else if ( activation.getRule().isLockOnActive() && rfg.isActive() ) {
-                return;
+                return false;
             }
 
             rfg.addActivation( activation );
 
         }
-        
+
         // making sure we re-evaluate agenda in case we are waiting for activations
-        synchronized( this.halt ) {
+        synchronized ( this.halt ) {
             this.halt.notifyAll();
         }
+        return true;
 
     }
 
@@ -973,30 +974,30 @@
         fireUntilHalt( null );
     }
 
-    public void fireUntilHalt( final AgendaFilter agendaFilter ) {
-            this.halt.set( false );
-            while ( continueFiring( -1 ) ) {
-                boolean fired = fireNextItem( agendaFilter );
-                if( !fired ) {
-                    try {
-                        synchronized( this.halt ) {
-                            this.halt.wait();
-                        }
-                    } catch ( InterruptedException e ) {
-                        this.halt.set( true );
+    public void fireUntilHalt(final AgendaFilter agendaFilter) {
+        this.halt.set( false );
+        while ( continueFiring( -1 ) ) {
+            boolean fired = fireNextItem( agendaFilter );
+            if ( !fired ) {
+                try {
+                    synchronized ( this.halt ) {
+                        this.halt.wait();
                     }
-                } else {
-                    this.workingMemory.executeQueuedActions();
+                } catch ( InterruptedException e ) {
+                    this.halt.set( true );
                 }
+            } else {
+                this.workingMemory.executeQueuedActions();
             }
+        }
     }
-    
+
     public int fireAllRules(AgendaFilter agendaFilter,
-                             int fireLimit) {
+                            int fireLimit) {
         this.halt.set( false );
         int fireCount = 0;
         while ( continueFiring( fireLimit ) && fireNextItem( agendaFilter ) ) {
-        	fireCount++;
+            fireCount++;
             fireLimit = updateFireLimit( fireLimit );
             this.workingMemory.executeQueuedActions();
         }
@@ -1013,10 +1014,9 @@
 
     public void halt() {
         this.halt.set( true );
-        synchronized( this.halt ) {
+        synchronized ( this.halt ) {
             this.halt.notifyAll();
         }
     }
 
-    
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalAgenda.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalAgenda.java	2008-09-19 18:29:01 UTC (rev 22930)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalAgenda.java	2008-09-19 22:46:08 UTC (rev 22931)
@@ -26,8 +26,10 @@
      * asynchronously) or be executed immediately.
      * 
      * @param activation
+     * 
+     * @return true if the activation was really added, and not ignored in cases of lock-on-active or no-loop
      */
-    public void addActivation(final AgendaItem activation);
+    public boolean addActivation(final AgendaItem activation);
 
     public void addAgendaGroup(final AgendaGroup agendaGroup);
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java	2008-09-19 18:29:01 UTC (rev 22930)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java	2008-09-19 22:46:08 UTC (rev 22931)
@@ -242,12 +242,12 @@
             tuple.setActivation( item );
             memory.getTupleMemory().add( tuple );
             
-            agenda.addActivation( item );
+            boolean added = agenda.addActivation( item );
 
-            item.setActivated( true );
+            item.setActivated( added );
 
             // We only want to fire an event on a truly new Activation and not on an Activation as a result of a modify
-            if ( fireActivationCreated ) {
+            if ( added && fireActivationCreated ) {
                 ((EventSupport) workingMemory).getAgendaEventSupport().fireActivationCreated( item,
                                                                                               workingMemory );
             }

Modified: labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/java/org/drools/examples/conway/AgendaGroupDelegate.java
===================================================================
--- labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/java/org/drools/examples/conway/AgendaGroupDelegate.java	2008-09-19 18:29:01 UTC (rev 22930)
+++ labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/java/org/drools/examples/conway/AgendaGroupDelegate.java	2008-09-19 22:46:08 UTC (rev 22931)
@@ -58,8 +58,8 @@
         session.setFocus( "rest" );
         session.setFocus( "evaluate" );
         session.setFocus( "calculate" );        
-        session.fireAllRules();
-        return session.getAgenda().getAgendaGroup( "calculate" ).size() != 0;
+        return session.fireAllRules() != 0;
+        //return session.getAgenda().getAgendaGroup( "calculate" ).size() != 0;
     }
 
     /* (non-Javadoc)

Modified: labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/java/org/drools/examples/conway/RuleFlowDelegate.java
===================================================================
--- labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/java/org/drools/examples/conway/RuleFlowDelegate.java	2008-09-19 18:29:01 UTC (rev 22930)
+++ labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/java/org/drools/examples/conway/RuleFlowDelegate.java	2008-09-19 22:46:08 UTC (rev 22931)
@@ -60,8 +60,8 @@
         // System.out.println( "next generation" );
         
         session.startProcess( "generation" );
-        session.fireAllRules();
-        return session.getAgenda().getRuleFlowGroup( "calculate" ).size() != 0;
+        return session.fireAllRules() != 0;
+        //return session.getAgenda().getRuleFlowGroup( "calculate" ).size() != 0;
     }
 
     /* (non-Javadoc)

Modified: labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/rules/org/drools/examples/PetStore.drl
===================================================================
--- labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/rules/org/drools/examples/PetStore.drl	2008-09-19 18:29:01 UTC (rev 22930)
+++ labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/rules/org/drools/examples/PetStore.drl	2008-09-19 22:46:08 UTC (rev 22931)
@@ -6,7 +6,7 @@
 import org.drools.examples.PetStore.Product
 import java.util.ArrayList
 import javax.swing.JOptionPane;
-
+ 
 import javax.swing.JFrame 
         
 global JFrame frame 

Modified: labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/rules/org/drools/examples/Shopping.drl
===================================================================
--- labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/rules/org/drools/examples/Shopping.drl	2008-09-19 18:29:01 UTC (rev 22930)
+++ labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/rules/org/drools/examples/Shopping.drl	2008-09-19 22:46:08 UTC (rev 22931)
@@ -1,5 +1,5 @@
 package org.drools.examples
-
+ 
 dialect "mvel"
 
 import org.drools.examples.ShoppingExample.Customer
@@ -16,13 +16,13 @@
 	then
 	    System.out.println( "Customer " + $c.name + " just purchased " + $p.product.name );
 end	 
-
+ 
 rule "Discount removed notification"
 	when
 	    $c : Customer()
 		not Discount( customer == $c )
 	then
-		$c.discount = 0 ;
+		$c.discount = 0;
 		System.out.println( "Customer " + $c.name + " now has a discount of " + $c.discount );
 end
 

Modified: labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/rules/org/drools/examples/conway/conway-agendagroup.drl
===================================================================
--- labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/rules/org/drools/examples/conway/conway-agendagroup.drl	2008-09-19 18:29:01 UTC (rev 22930)
+++ labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/rules/org/drools/examples/conway/conway-agendagroup.drl	2008-09-19 22:46:08 UTC (rev 22931)
@@ -45,7 +45,7 @@
 rule "register west"
 	agenda-group "register neighbor"
 when
-	$cell: Cell( $row : row >= 0, $col : col > 0 )			
+	$cell: Cell( $row : row, $col : col > 0 )			
 	$west : Cell( row  == $row, col == ( $col - 1 ) )						
 then		
 	insert( new Neighbor( $cell, $west ) );
@@ -127,7 +127,7 @@
 then
 	modify( $neighbor ) {setLiveNeighbors( $neighbor.getLiveNeighbors() - 1 ), setPhase( Phase.EVALUATE )}
 end	
-
+ 
 rule "Kill All"
 	agenda-group "kill all"	
 	no-loop

Modified: labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/rules/org/drools/examples/process/order/validation.drl
===================================================================
--- labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/rules/org/drools/examples/process/order/validation.drl	2008-09-19 18:29:01 UTC (rev 22930)
+++ labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/rules/org/drools/examples/process/order/validation.drl	2008-09-19 22:46:08 UTC (rev 22931)
@@ -21,7 +21,7 @@
 	    System.err.println("Invalid item id found!");
 		o.addError("Invalid item id " + i.getItemId());
 end
-
+ 
 rule "Minimal age" ruleflow-group "validate" lock-on-active true
 	when
 		o: Order( )

Modified: labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/rules/org/drools/tutorials/banking/Example2.drl
===================================================================
--- labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/rules/org/drools/tutorials/banking/Example2.drl	2008-09-19 18:29:01 UTC (rev 22930)
+++ labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/rules/org/drools/tutorials/banking/Example2.drl	2008-09-19 22:46:08 UTC (rev 22931)
@@ -1,5 +1,5 @@
 package org.drools.tutorials.banking
-
+   
 rule "Rule 01"   
     when
         Number( $intValue : intValue )

Modified: labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/rules/org/drools/tutorials/banking/Example3.drl
===================================================================
--- labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/rules/org/drools/tutorials/banking/Example3.drl	2008-09-19 18:29:01 UTC (rev 22930)
+++ labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/rules/org/drools/tutorials/banking/Example3.drl	2008-09-19 22:46:08 UTC (rev 22931)
@@ -1,6 +1,6 @@
 package org.drools.tutorials.banking
 
-
+ 
 rule "Rule 01"   
     when
         $number : Number( )
@@ -8,4 +8,4 @@
     then
         System.out.println("Number found with value: " + $number.intValue() ); 
         retract( $number );
-end
\ No newline at end of file
+end 
\ No newline at end of file




More information about the jboss-svn-commits mailing list