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

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Thu Sep 18 13:46:12 EDT 2008


Author: tirelli
Date: 2008-09-18 13:46:11 -0400 (Thu, 18 Sep 2008)
New Revision: 22891

Modified:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/Agenda.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/WorkingMemory.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-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/common/business/SolutionBusiness.java
   labs/jbossrules/trunk/drools-templates/src/test/java/org/drools/template/parser/ExternalSheetListenerTest.java
Log:
Returning the number of fired rules in fireAllRules()

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/Agenda.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/Agenda.java	2008-09-18 17:42:55 UTC (rev 22890)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/Agenda.java	2008-09-18 17:46:11 UTC (rev 22891)
@@ -33,14 +33,6 @@
      */
     public WorkingMemory getWorkingMemory();
 
-// NOTE: AgendaGroup should not be exposed
-//    /**
-//     * Sets the Agenda's focus to the specified AgendaGroup
-//     * @param agendaGroup
-//     * @return
-//     */
-//    public boolean setFocus(AgendaGroup agendaGroup);
-
     /**
      * Sets the Agenda's focus to the specified AgendaGroup
      * @param agendaGroup
@@ -48,12 +40,6 @@
      */    
     public void setFocus(String name);
 
-//    public AgendaGroup getFocus();
-//
-//    public AgendaGroup getAgendaGroup(String name);
-//
-//    public RuleFlowGroup getRuleFlowGroup(String name);
-
     /**
      * Activates the <code>RuleFlowGroup</code> with the given name.
      * All activations in the given <code>RuleFlowGroup</code> are added to the agenda.
@@ -74,8 +60,6 @@
 
     public AgendaGroup[] getStack();
 
-//    public ActivationGroup getActivationGroup(String name);
-
     /**
      * Iterates all the <code>AgendGroup<code>s in the focus stack returning the total number of <code>Activation</code>s
      * @return

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/WorkingMemory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/WorkingMemory.java	2008-09-18 17:42:55 UTC (rev 22890)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/WorkingMemory.java	2008-09-18 17:46:11 UTC (rev 22891)
@@ -95,7 +95,7 @@
      * @throws FactException
      *             If a RuntimeException error occurs.
      */
-    void fireAllRules() throws FactException;
+    int fireAllRules() throws FactException;
 
     /**
      * Fire all items on the agenda until empty, using the given AgendaFiler
@@ -103,7 +103,7 @@
      * @throws FactException
      *             If a RuntimeException error occurs.
      */
-    void fireAllRules(AgendaFilter agendaFilter) throws FactException;
+    int fireAllRules(AgendaFilter agendaFilter) throws FactException;
 
     /**
      * Fire all items on the agenda until empty or at most 'fireLimit' rules have fired
@@ -111,7 +111,7 @@
      * @throws FactException
      *             If a RuntimeException error occurs.
      */
-    void fireAllRules( int fireLimit ) throws FactException;
+    int fireAllRules( int fireLimit ) throws FactException;
 
     /**
      * Fire all items on the agenda using the given AgendaFiler
@@ -120,7 +120,7 @@
      * @throws FactException
      *             If a RuntimeException error occurs.
      */
-    void fireAllRules(final AgendaFilter agendaFilter, int fireLimit ) throws FactException;
+    int fireAllRules(final AgendaFilter agendaFilter, int fireLimit ) throws FactException;
 
     /**
      * Retrieve the object associated with a <code>FactHandle</code>.
@@ -151,7 +151,7 @@
      * @return
      *     the Iterator
      */
-    Iterator iterateObjects();
+    Iterator<?> iterateObjects();
 
     /**
      *  Returns an Iterator for the Objects in the Working Memory. This Iterator will filter out
@@ -163,7 +163,7 @@
      * @return
      *     the Iterator
      */
-    Iterator iterateObjects(ObjectFilter filter);
+    Iterator<?> iterateObjects(ObjectFilter filter);
 
     /**
      * Returns an Iterator for the FactHandles in the Working Memory. This Iterator is not thread safe.
@@ -171,7 +171,7 @@
      * @return
      *     the Iterator
      */
-    Iterator iterateFactHandles();
+    Iterator<?> iterateFactHandles();
 
     /**
      *  Returns an Iterator for the Objects in the Working Memory. This Iterator will filter out
@@ -183,7 +183,7 @@
      * @return
      *     the Iterator
      */
-    Iterator iterateFactHandles(ObjectFilter filter);
+    Iterator<?> iterateFactHandles(ObjectFilter filter);
 
     /**
      * Set the focus to the specified AgendaGroup

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-18 17:42:55 UTC (rev 22890)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java	2008-09-18 17:46:11 UTC (rev 22891)
@@ -97,1615 +97,1580 @@
  * @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 SessionConfiguration                      config;
+	protected InternalFactHandle initialFactHandle;
 
-    protected Map<RuleBasePartitionId, PartitionTaskManager> partitionManagers;
+	protected SessionConfiguration config;
 
-    // ------------------------------------------------------------
-    // Constructors
-    // ------------------------------------------------------------
-    public AbstractWorkingMemory() {
+	protected Map<RuleBasePartitionId, PartitionTaskManager> partitionManagers;
 
-    }
+	// ------------------------------------------------------------
+	// 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();
-        
-        final RuleBaseConfiguration conf = this.ruleBase.getConfiguration();
+	/**
+	 * 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);
+	}
 
-        this.maintainTms = conf.isMaintainTms();
-        this.sequential = conf.isSequential();
+	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();
 
-        if ( initialFactHandle == null ) {
-            this.initialFactHandle = new InitialFactHandle( handleFactory.newFactHandle( new InitialFactHandleDummyObject(),
-                                                                                         null,
-                                                                                         this ) );
-        } else {
-            this.initialFactHandle = initialFactHandle;
-        }
+		final RuleBaseConfiguration conf = this.ruleBase.getConfiguration();
 
-        this.actionQueue = new LinkedList<WorkingMemoryAction>();
+		this.maintainTms = conf.isMaintainTms();
+		this.sequential = conf.isSequential();
 
-        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();
-        
-        TimerService timerService = TimerServiceFactory.getTimerService( this.config.getClockType() );
-        this.timerManager = new TimerManager(this, timerService);
+		if (initialFactHandle == null) {
+			this.initialFactHandle = new InitialFactHandle(handleFactory
+					.newFactHandle(new InitialFactHandleDummyObject(), null,
+							this));
+		} else {
+			this.initialFactHandle = initialFactHandle;
+		}
 
-        this.nodeMemories = new ConcurrentNodeMemories( this.ruleBase );
+		this.actionQueue = new LinkedList<WorkingMemoryAction>();
 
-        if ( this.maintainTms ) {
-            this.tms = new TruthMaintenanceSystem( this );
-        } else {
-            this.tms = null;
-        }
+		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.propagationIdCounter = new AtomicLong( propagationContext );
+		TimerService timerService = TimerServiceFactory
+				.getTimerService(this.config.getClockType());
+		this.timerManager = new TimerManager(this, timerService);
 
-        this.objectStore = new SingleThreadedObjectStore( conf,
-                                                          this.lock );
+		this.nodeMemories = new ConcurrentNodeMemories(this.ruleBase);
 
-        // Only takes effect if are using idententity behaviour for assert
-        if ( LogicalOverride.DISCARD.equals( conf.getLogicalOverride() ) ) {
-            this.discardOnLogicalOverride = true;
-        } else {
-            this.discardOnLogicalOverride = false;
-        }
+		if (this.maintainTms) {
+			this.tms = new TruthMaintenanceSystem(this);
+		} else {
+			this.tms = null;
+		}
 
-        this.entryPoints = new ConcurrentHashMap();
-        this.entryPoints.put( "DEFAULT",
-                              this );
+		this.propagationIdCounter = new AtomicLong(propagationContext);
 
-        this.entryPoint = EntryPoint.DEFAULT;
-        this.firing = new AtomicBoolean( false );
+		this.objectStore = new SingleThreadedObjectStore(conf, this.lock);
 
-        initPartitionManagers();
-        initTransient();
-    }
+		// Only takes effect if are using idententity behaviour for assert
+		if (LogicalOverride.DISCARD.equals(conf.getLogicalOverride())) {
+			this.discardOnLogicalOverride = true;
+		} else {
+			this.discardOnLogicalOverride = false;
+		}
 
-    // ------------------------------------------------------------
-    // Instance methods
-    // ------------------------------------------------------------
+		this.entryPoints = new ConcurrentHashMap();
+		this.entryPoints.put("DEFAULT", this);
 
-    public void setRuleBase(final InternalRuleBase ruleBase) {
-        this.ruleBase = ruleBase;
-        this.nodeMemories.setRuleBaseReference( this.ruleBase );
-        initTransient();
-    }
+		this.entryPoint = EntryPoint.DEFAULT;
+		this.firing = new AtomicBoolean(false);
 
-    /**
-     * Creates the actual partition managers and their tasks for multi-thread processing
-     */
-    private void initPartitionManagers() {
-        if( this.ruleBase.getConfiguration().isPartitionsEnabled() ) {
+		initPartitionManagers();
+		initTransient();
+	}
 
-            // the Map MUST be thread safe
-            this.partitionManagers = new ConcurrentHashMap<RuleBasePartitionId, PartitionTaskManager>();
+	// ------------------------------------------------------------
+	// Instance methods
+	// ------------------------------------------------------------
 
-            for( RuleBasePartitionId partitionId : this.ruleBase.getPartitionIds() ) {
-                this.partitionManagers.put( partitionId, new PartitionTaskManager( this ) );
-            }
-        }
-    }
+	public void setRuleBase(final InternalRuleBase ruleBase) {
+		this.ruleBase = ruleBase;
+		this.nodeMemories.setRuleBaseReference(this.ruleBase);
+		initTransient();
+	}
 
+	/**
+	 * Creates the actual partition managers and their tasks for multi-thread
+	 * processing
+	 */
+	private void initPartitionManagers() {
+		if (this.ruleBase.getConfiguration().isPartitionsEnabled()) {
 
-    /**
-     *  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();
-            }
-        }
-    }
+			// the Map MUST be thread safe
+			this.partitionManagers = new ConcurrentHashMap<RuleBasePartitionId, PartitionTaskManager>();
 
-    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();
-            }
-        }
-    }
+			for (RuleBasePartitionId partitionId : this.ruleBase
+					.getPartitionIds()) {
+				this.partitionManagers.put(partitionId,
+						new PartitionTaskManager(this));
+			}
+		}
+	}
 
-    private void initTransient() {
-        this.entryPointNode = this.ruleBase.getRete().getEntryPointNode( this.entryPoint );
-        this.typeConfReg = new ObjectTypeConfigurationRegistry( this.ruleBase );
-    }
-    
-    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();
-        
-        this.propagationIdCounter = new AtomicLong( propagationCounter );
+	/**
+	 * 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();
+			}
+		}
+	}
 
-        // TODO should these be cleared?
-        // we probably neeed to do CEP and Flow timers too        
-        // this.processInstanceManager.clear()
-        // this.workItemManager.clear();        
-    }
+	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 setWorkingMemoryEventSupport(WorkingMemoryEventSupport workingMemoryEventSupport) {
-        this.workingMemoryEventSupport = workingMemoryEventSupport;
-    }
+	private void initTransient() {
+		this.entryPointNode = this.ruleBase.getRete().getEntryPointNode(
+				this.entryPoint);
+		this.typeConfReg = new ObjectTypeConfigurationRegistry(this.ruleBase);
+	}
 
-    public void setAgendaEventSupport(AgendaEventSupport agendaEventSupport) {
-        this.agendaEventSupport = agendaEventSupport;
-    }
+	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();
 
-    public void setRuleFlowEventSupport(RuleFlowEventSupport ruleFlowEventSupport) {
-        this.workflowEventSupport = ruleFlowEventSupport;
-    }
+		this.propagationIdCounter = new AtomicLong(propagationCounter);
 
-    public boolean isSequential() {
-        return this.sequential;
-    }
+		// TODO should these be cleared?
+		// we probably neeed to do CEP and Flow timers too
+		// this.processInstanceManager.clear()
+		// this.workItemManager.clear();
+	}
 
-    public void addLIANodePropagation(LIANodePropagation liaNodePropagation) {
-        if ( this.liaPropagations == Collections.EMPTY_LIST ) {
-            this.liaPropagations = new ArrayList();
-        }
-        this.liaPropagations.add( liaNodePropagation );
-    }
+	public void setWorkingMemoryEventSupport(
+			WorkingMemoryEventSupport workingMemoryEventSupport) {
+		this.workingMemoryEventSupport = workingMemoryEventSupport;
+	}
 
-    public void addEventListener(final WorkingMemoryEventListener listener) {
-        this.workingMemoryEventSupport.addEventListener( listener );
-    }
+	public void setAgendaEventSupport(AgendaEventSupport agendaEventSupport) {
+		this.agendaEventSupport = agendaEventSupport;
+	}
 
-    public void removeEventListener(final WorkingMemoryEventListener listener) {
-        this.workingMemoryEventSupport.removeEventListener( listener );
-    }
+	public void setRuleFlowEventSupport(
+			RuleFlowEventSupport ruleFlowEventSupport) {
+		this.workflowEventSupport = ruleFlowEventSupport;
+	}
 
-    public List getWorkingMemoryEventListeners() {
-        return this.workingMemoryEventSupport.getEventListeners();
-    }
+	public boolean isSequential() {
+		return this.sequential;
+	}
 
-    public void addEventListener(final AgendaEventListener listener) {
-        this.agendaEventSupport.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 AgendaEventListener listener) {
-        this.agendaEventSupport.removeEventListener( listener );
-    }
+	public void addEventListener(final WorkingMemoryEventListener listener) {
+		this.workingMemoryEventSupport.addEventListener(listener);
+	}
 
-    public List getAgendaEventListeners() {
-        return this.agendaEventSupport.getEventListeners();
-    }
+	public void removeEventListener(final WorkingMemoryEventListener listener) {
+		this.workingMemoryEventSupport.removeEventListener(listener);
+	}
 
-    public void addEventListener(final RuleFlowEventListener listener) {
-        this.workflowEventSupport.addEventListener( listener );
-    }
+	public List getWorkingMemoryEventListeners() {
+		return this.workingMemoryEventSupport.getEventListeners();
+	}
 
-    public void removeEventListener(final RuleFlowEventListener listener) {
-        this.workflowEventSupport.removeEventListener( listener );
-    }
+	public void addEventListener(final AgendaEventListener listener) {
+		this.agendaEventSupport.addEventListener(listener);
+	}
 
-    public List getRuleFlowEventListeners() {
-        return this.workflowEventSupport.getEventListeners();
-    }
+	public void removeEventListener(final AgendaEventListener listener) {
+		this.agendaEventSupport.removeEventListener(listener);
+	}
 
-    public void addEventListener(RuleBaseEventListener listener) {
-        this.ruleBase.addEventListener( listener );
-        this.__ruleBaseEventListeners.add( listener );
-    }
+	public List getAgendaEventListeners() {
+		return this.agendaEventSupport.getEventListeners();
+	}
 
-    public List getRuleBaseEventListeners() {
-        return Collections.unmodifiableList( this.__ruleBaseEventListeners );
-    }
+	public void addEventListener(final RuleFlowEventListener listener) {
+		this.workflowEventSupport.addEventListener(listener);
+	}
 
-    public void removeEventListener(RuleBaseEventListener listener) {
-        this.ruleBase.removeEventListener( listener );
-        this.__ruleBaseEventListeners.remove( listener );
-    }
+	public void removeEventListener(final RuleFlowEventListener listener) {
+		this.workflowEventSupport.removeEventListener(listener);
+	}
 
-    public FactHandleFactory getFactHandleFactory() {
-        return this.handleFactory;
-    }
+	public List getRuleFlowEventListeners() {
+		return this.workflowEventSupport.getEventListeners();
+	}
 
-    public void setGlobal(final String identifier,
-                          final Object value) {
-        // Cannot set null values
-        if ( value == null ) {
-            return;
-        }
+	public void addEventListener(RuleBaseEventListener listener) {
+		this.ruleBase.addEventListener(listener);
+		this.__ruleBaseEventListeners.add(listener);
+	}
 
-        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 List getRuleBaseEventListeners() {
+		return Collections.unmodifiableList(this.__ruleBaseEventListeners);
+	}
 
-            } else {
-                this.globalResolver.setGlobal( identifier,
-                                               value );
-            }
-        } finally {
-            this.lock.unlock();
-        }
-    }
+	public void removeEventListener(RuleBaseEventListener listener) {
+		this.ruleBase.removeEventListener(listener);
+		this.__ruleBaseEventListeners.remove(listener);
+	}
 
-    public void setGlobalResolver(final GlobalResolver globalResolver) {
-        try {
-            this.lock.lock();
-            this.globalResolver = globalResolver;
-        } finally {
-            this.lock.unlock();
-        }
-    }
+	public FactHandleFactory getFactHandleFactory() {
+		return this.handleFactory;
+	}
 
-    public GlobalResolver getGlobalResolver() {
-        return this.globalResolver;
-    }
+	public void setGlobal(final String identifier, final Object value) {
+		// Cannot set null values
+		if (value == null) {
+			return;
+		}
 
-    public long getId() {
-        return this.id;
-    }
+		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 setId(long id) {
-        this.id = id;
-    }
+			} else {
+				this.globalResolver.setGlobal(identifier, value);
+			}
+		} finally {
+			this.lock.unlock();
+		}
+	}
 
-    public Object getGlobal(final String identifier) {
-        try {
-            this.lock.lock();
-            return this.globalResolver.resolveGlobal( identifier );
-        } finally {
-            this.lock.unlock();
-        }
-    }
+	public void setGlobalResolver(final GlobalResolver globalResolver) {
+		try {
+			this.lock.lock();
+			this.globalResolver = globalResolver;
+		} finally {
+			this.lock.unlock();
+		}
+	}
 
-    public Agenda getAgenda() {
-        return this.agenda;
-    }
+	public GlobalResolver getGlobalResolver() {
+		return this.globalResolver;
+	}
 
-    public void clearAgenda() {
-        this.agenda.clearAndCancel();
-    }
+	public long getId() {
+		return this.id;
+	}
 
-    public void clearAgendaGroup(final String group) {
-        this.agenda.clearAndCancelAgendaGroup( group );
-    }
+	public void setId(long id) {
+		this.id = id;
+	}
 
-    public void clearActivationGroup(final String group) {
-        this.agenda.clearAndCancelActivationGroup( group );
-    }
+	public Object getGlobal(final String identifier) {
+		try {
+			this.lock.lock();
+			return this.globalResolver.resolveGlobal(identifier);
+		} finally {
+			this.lock.unlock();
+		}
+	}
 
-    public void clearRuleFlowGroup(final String group) {
-        this.agenda.clearAndCancelRuleFlowGroup( group );
-    }
+	public Agenda getAgenda() {
+		return this.agenda;
+	}
 
-    public RuleBase getRuleBase() {
-        return this.ruleBase;
-    }
+	public void clearAgenda() {
+		this.agenda.clearAndCancel();
+	}
 
-    public void halt() {
-        this.agenda.halt();
-    }
-    
-//    /**
-//     * 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 clearAgendaGroup(final String group) {
+		this.agenda.clearAndCancelAgendaGroup(group);
+	}
 
-    public synchronized void fireAllRules() throws FactException {
-        fireAllRules( null,
-                      -1 );
-    }
+	public void clearActivationGroup(final String group) {
+		this.agenda.clearAndCancelActivationGroup(group);
+	}
 
-    public synchronized void fireAllRules(int fireLimit) throws FactException {
-        fireAllRules( null,
-                      fireLimit );
-    }
+	public void clearRuleFlowGroup(final String group) {
+		this.agenda.clearAndCancelRuleFlowGroup(group);
+	}
 
-    public synchronized void fireAllRules(final AgendaFilter agendaFilter) throws FactException {
-        fireAllRules( agendaFilter,
-                      -1 );
-    }
+	public RuleBase getRuleBase() {
+		return this.ruleBase;
+	}
 
-    public synchronized void 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 void halt() {
+		this.agenda.halt();
+	}
 
-        // do we need to call this in advance?
-        executeQueuedActions();
+	// /**
+	// * 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 );
+	//    	
+	// }
 
-        try {
-            if( this.firing.compareAndSet( false, true ) ) {
-                this.agenda.fireAllRules( agendaFilter, fireLimit );
-            }
-        } finally {
-            this.firing.set( false );
-        }
-    }
+	public synchronized int fireAllRules() throws FactException {
+		return fireAllRules(null, -1);
+	}
 
-    /**
-     * 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 );
-    }
-    
-    /**
-     * 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.");
-        }
-        
-        executeQueuedActions();
-        try {
-            if( this.firing.compareAndSet( false, true ) ) {
-                this.agenda.fireUntilHalt( agendaFilter );
-            }
-        } finally {
-            this.firing.set( false );
-        }
-    }
+	public synchronized int fireAllRules(int fireLimit) throws FactException {
+		return fireAllRules(null, fireLimit);
+	}
 
-    /**
-     * 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 );
-    }
+	public synchronized int fireAllRules(final AgendaFilter agendaFilter)
+			throws FactException {
+		return fireAllRules(agendaFilter, -1);
+	}
 
-    public ObjectStore getObjectStore() {
-        return this.objectStore;
-    }
+	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);
+			}
+		}
 
-    /**
-     * @see WorkingMemory
-     */
-    public FactHandle getFactHandle(final Object object) {
-        return this.objectStore.getHandleForObject( object );
-    }
+		// do we need to call this in advance?
+		executeQueuedActions();
 
-    /**
-     * @see WorkingMemory
-     */
-    public FactHandle getFactHandleByIdentity(final Object object) {
-        return this.objectStore.getHandleForObjectIdentity( object );
-    }
+		int fireCount = 0;
+		try {
+			if (this.firing.compareAndSet(false, true)) {
+				fireCount = this.agenda.fireAllRules(agendaFilter, fireLimit);
+			}
+		} finally {
+			this.firing.set(false);
+		}
+		return fireCount;
+	}
 
-    /**
-     * This class is not thread safe, changes to the working memory during
-     * iteration may give unexpected results
-     */
-    public Iterator iterateObjects() {
-        return this.objectStore.iterateObjects();
-    }
+	/**
+	 * 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);
+	}
 
-    /**
-     * 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 );
-    }
+	/**
+	 * 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.");
+		}
 
-    /**
-     * This class is not thread safe, changes to the working memory during
-     * iteration may give unexpected results
-     */
-    public Iterator iterateFactHandles() {
-        return this.objectStore.iterateFactHandles();
-    }
+		executeQueuedActions();
+		try {
+			if (this.firing.compareAndSet(false, true)) {
+				this.agenda.fireUntilHalt(agendaFilter);
+			}
+		} finally {
+			this.firing.set(false);
+		}
+	}
 
-    /**
-     * 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 );
-    }
+	/**
+	 * 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);
+	}
 
-    public abstract QueryResults getQueryResults(String query);
+	public ObjectStore getObjectStore() {
+		return this.objectStore;
+	}
 
-    public void setFocus(final String focus) {
-        this.agenda.setFocus( focus );
-    }
+	/**
+	 * @see WorkingMemory
+	 */
+	public FactHandle getFactHandle(final Object object) {
+		return this.objectStore.getHandleForObject(object);
+	}
 
-    public TruthMaintenanceSystem getTruthMaintenanceSystem() {
-        return this.tms;
-    }
+	/**
+	 * @see WorkingMemory
+	 */
+	public FactHandle getFactHandleByIdentity(final Object object) {
+		return this.objectStore.getHandleForObjectIdentity(object);
+	}
 
-    /**
-     * @see WorkingMemory
-     */
-    public FactHandle insert(final Object object) throws FactException {
-        return insert( object, /* Not-Dynamic */
-                       false,
-                       false,
-                       null,
-                       null );
-    }
+	/**
+	 * 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 insertLogical(final Object object) throws FactException {
-        return insert( object, // Not-Dynamic
-                       false,
-                       true,
-                       null,
-                       null );
-    }
+	/**
+	 * 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);
+	}
 
-    public FactHandle insert(final Object object,
-                             final boolean dynamic) throws FactException {
-        return insert( object,
-                       dynamic,
-                       false,
-                       null,
-                       null );
-    }
+	/**
+	 * 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 FactHandle insertLogical(final Object object,
-                                    final boolean dynamic) throws FactException {
-        return insert( object,
-                       dynamic,
-                       true,
-                       null,
-                       null );
-    }
+	/**
+	 * 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);
+	}
 
-    // 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 abstract QueryResults getQueryResults(String query);
 
-    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;
-        }
+	public void setFocus(final String focus) {
+		this.agenda.setFocus(focus);
+	}
 
-        ObjectTypeConf typeConf = this.typeConfReg.getObjectTypeConf( this.entryPoint,
-                                                                      object );
+	public TruthMaintenanceSystem getTruthMaintenanceSystem() {
+		return this.tms;
+	}
 
-        InternalFactHandle handle = null;
+	/**
+	 * @see WorkingMemory
+	 */
+	public FactHandle insert(final Object object) throws FactException {
+		return insert(object, /* Not-Dynamic */
+		false, false, null, null);
+	}
 
-        if ( isSequential() ) {
-            handle = this.handleFactory.newFactHandle( object,
-                                                       typeConf,
-                                                       this );
-            this.objectStore.addHandle( handle,
-                                        object );
-            insert( handle,
-                    object,
-                    rule,
-                    activation,
-                    typeConf );
-            return handle;
-        }
+	/**
+	 * @see WorkingMemory
+	 */
+	public FactHandle insertLogical(final Object object) throws FactException {
+		return insert(object, // Not-Dynamic
+				false, true, null, null);
+	}
 
-        try {
-            this.lock.lock();
-            // check if the object already exists in the WM
-            handle = (InternalFactHandle) this.objectStore.getHandleForObject( object );
+	public FactHandle insert(final Object object, final boolean dynamic)
+			throws FactException {
+		return insert(object, dynamic, false, null, null);
+	}
 
-            if ( this.maintainTms ) {
+	public FactHandle insertLogical(final Object object, final boolean dynamic)
+			throws FactException {
+		return insert(object, dynamic, true, null, null);
+	}
 
-                EqualityKey key = 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 );
+	// }
 
-                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();
+	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;
+		}
 
-                    if ( key.getStatus() == EqualityKey.STATED ) {
-                        // return null as you cannot justify a stated object.
-                        return handle;
-                    }
+		ObjectTypeConf typeConf = this.typeConfReg.getObjectTypeConf(
+				this.entryPoint, object);
 
-                    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 );
-                    }
+		InternalFactHandle handle = null;
 
-                    return handle;
-                }
+		if (isSequential()) {
+			handle = this.handleFactory.newFactHandle(object, typeConf, this);
+			this.objectStore.addHandle(handle, object);
+			insert(handle, object, rule, activation, typeConf);
+			return handle;
+		}
 
-                // 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 );
+		try {
+			this.lock.lock();
+			// check if the object already exists in the WM
+			handle = (InternalFactHandle) this.objectStore
+					.getHandleForObject(object);
 
-                    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 (this.maintainTms) {
 
-                        if ( this.discardOnLogicalOverride ) {
-                            // override, setting to new instance, and return
-                            // existing handle
-                            key.setStatus( EqualityKey.STATED );
-                            handle = key.getFactHandle();
+				EqualityKey key = null;
 
-                            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 (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 (key.getStatus() == EqualityKey.STATED) {
+						// return null as you cannot justify a stated object.
+						return handle;
+					}
 
-                    } else {
-                        handle = this.handleFactory.newFactHandle( object,
-                                                                   typeConf,
-                                                                   this );
-                        this.objectStore.addHandle( handle,
-                                                    object );
-                        key.addFactHandle( handle );
-                        handle.setEqualityKey( key );
+					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);
+					}
 
-                    }
+					return handle;
+				}
 
-                } 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;
-                    }
-                }
+				// 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);
 
-            } else {
-                if ( handle != null ) {
-                    return handle;
-                }
-                handle = this.handleFactory.newFactHandle( object,
-                                                           typeConf,
-                                                           this );
-                this.objectStore.addHandle( handle,
-                                            object );
+					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 (this.discardOnLogicalOverride) {
+							// override, setting to new instance, and return
+							// existing handle
+							key.setStatus(EqualityKey.STATED);
+							handle = key.getFactHandle();
 
-            if ( dynamic ) {
-                addPropertyChangeListener( object );
-            }
+							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);
 
-            insert( handle,
-                    object,
-                    rule,
-                    activation,
-                    typeConf );
+						}
 
-        } finally {
-            this.lock.unlock();
-        }
-        return handle;
-    }
+					} else {
+						handle = this.handleFactory.newFactHandle(object,
+								typeConf, this);
+						this.objectStore.addHandle(handle, object);
+						key.addFactHandle(handle);
+						handle.setEqualityKey(key);
 
-    protected void insert(final InternalFactHandle handle,
-                          final Object object,
-                          final Rule rule,
-                          final Activation activation,
-                          ObjectTypeConf typeConf) {
-        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.ASSERTION,
-                                                                                  rule,
-                                                                                  (activation == null) ? null : (LeftTuple) activation.getTuple(),
-                                                                                  handle,
-                                                                                  this.agenda.getActiveActivations(),
-                                                                                  this.agenda.getDormantActivations(),
-                                                                                  entryPoint );
+				} 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;
+					}
+				}
 
-        this.entryPointNode.assertObject( handle,
-                                          propagationContext,
-                                          typeConf,
-                                          this );
+			} else {
+				if (handle != null) {
+					return handle;
+				}
+				handle = this.handleFactory.newFactHandle(object, typeConf,
+						this);
+				this.objectStore.addHandle(handle, object);
 
-        executeQueuedActions();
+			}
 
-        this.workingMemoryEventSupport.fireObjectInserted( propagationContext,
-                                                           handle,
-                                                           object,
-                                                           this );
-    }
+			if (dynamic) {
+				addPropertyChangeListener(object);
+			}
 
-    protected void addPropertyChangeListener(final Object object) {
-        try {
-            final Method method = object.getClass().getMethod( "addPropertyChangeListener",
-                                                               AbstractWorkingMemory.ADD_REMOVE_PROPERTY_CHANGE_LISTENER_ARG_TYPES );
+			insert(handle, object, rule, activation, typeConf);
 
-            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() );
-        }
-    }
+		} finally {
+			this.lock.unlock();
+		}
+		return handle;
+	}
 
-    protected void removePropertyChangeListener(final FactHandle handle) {
-        Object object = null;
-        try {
-            object = ((InternalFactHandle) handle).getObject();
+	protected void insert(final InternalFactHandle handle, final Object object,
+			final Rule rule, final Activation activation,
+			ObjectTypeConf typeConf) {
+		this.ruleBase.executeQueuedActions();
 
-            if ( object != null ) {
-                final Method mehod = object.getClass().getMethod( "removePropertyChangeListener",
-                                                                  AbstractWorkingMemory.ADD_REMOVE_PROPERTY_CHANGE_LISTENER_ARG_TYPES );
+		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);
 
-                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() );
-        }
-    }
+		this.entryPointNode.assertObject(handle, propagationContext, typeConf,
+				this);
 
-    public void retract(final FactHandle handle) throws FactException {
-        retract( handle,
-                 true,
-                 true,
-                 null,
-                 null );
-    }
+		executeQueuedActions();
 
-    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();
+		this.workingMemoryEventSupport.fireObjectInserted(propagationContext,
+				handle, object, this);
+	}
 
-            final InternalFactHandle handle = (InternalFactHandle) factHandle;
-            if ( handle.getId() == -1 ) {
-                // can't retract an already retracted handle
-                return;
-            }
-            removePropertyChangeListener( handle );
+	protected void addPropertyChangeListener(final Object object) {
+		try {
+			final Method method = object
+					.getClass()
+					.getMethod(
+							"addPropertyChangeListener",
+							AbstractWorkingMemory.ADD_REMOVE_PROPERTY_CHANGE_LISTENER_ARG_TYPES);
 
-            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 );
+			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());
+		}
+	}
 
-            final Object object = handle.getObject();
+	protected void removePropertyChangeListener(final FactHandle handle) {
+		Object object = null;
+		try {
+			object = ((InternalFactHandle) handle).getObject();
 
-            this.entryPointNode.retractObject( handle,
-                                               propagationContext,
-                                               this.typeConfReg.getObjectTypeConf( this.entryPoint,
-                                                                                   object ),
-                                               this );
+			if (object != null) {
+				final Method mehod = object
+						.getClass()
+						.getMethod(
+								"removePropertyChangeListener",
+								AbstractWorkingMemory.ADD_REMOVE_PROPERTY_CHANGE_LISTENER_ARG_TYPES);
 
-            if ( this.maintainTms ) {
-                // Update the equality key, which maintains a list of stated
-                // FactHandles
-                final EqualityKey key = handle.getEqualityKey();
+				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());
+		}
+	}
 
-                // Its justified so attempt to remove any logical dependencies
-                // for
-                // the handle
-                if ( key.getStatus() == EqualityKey.JUSTIFIED ) {
-                    this.tms.removeLogicalDependencies( handle );
-                }
+	public void retract(final FactHandle handle) throws FactException {
+		retract(handle, true, true, null, null);
+	}
 
-                key.removeFactHandle( handle );
-                handle.setEqualityKey( null );
+	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 the equality key is now empty, then remove it
-                if ( key.isEmpty() ) {
-                    this.tms.remove( key );
-                }
-            }
+			final InternalFactHandle handle = (InternalFactHandle) factHandle;
+			if (handle.getId() == -1) {
+				// can't retract an already retracted handle
+				return;
+			}
+			removePropertyChangeListener(handle);
 
-            this.workingMemoryEventSupport.fireObjectRetracted( propagationContext,
-                                                                handle,
-                                                                object,
-                                                                this );
+			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.objectStore.removeHandle( handle );
+			final Object object = handle.getObject();
 
-            this.handleFactory.destroyFactHandle( handle );
-            
-            executeQueuedActions();
-        } finally {
-            this.lock.unlock();
-        }
-    }
+			this.entryPointNode
+					.retractObject(handle, propagationContext, this.typeConfReg
+							.getObjectTypeConf(this.entryPoint, object), this);
 
-    public void modifyRetract(final FactHandle factHandle) {
-        modifyRetract( factHandle,
-                       null,
-                       null );
-    }
+			if (this.maintainTms) {
+				// Update the equality key, which maintains a list of stated
+				// FactHandles
+				final EqualityKey key = handle.getEqualityKey();
 
-    public void modifyRetract(final FactHandle factHandle,
-                              final Rule rule,
-                              final Activation activation) {
-        try {
-            this.lock.lock();
-            this.ruleBase.executeQueuedActions();
+				// Its justified so attempt to remove any logical dependencies
+				// for
+				// the handle
+				if (key.getStatus() == EqualityKey.JUSTIFIED) {
+					this.tms.removeLogicalDependencies(handle);
+				}
 
-            // 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();
+				key.removeFactHandle(handle);
+				handle.setEqualityKey(null);
 
-            if ( handle.getId() == -1 ) {
-                // the handle is invalid, most likely already retracted, so
-                // return
-                return;
-            }
+				// If the equality key is now empty, then remove it
+				if (key.isEmpty()) {
+					this.tms.remove(key);
+				}
+			}
 
-            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 );
+			this.workingMemoryEventSupport.fireObjectRetracted(
+					propagationContext, handle, object, this);
 
-            this.entryPointNode.retractObject( handle,
-                                               propagationContext,
-                                               this.typeConfReg.getObjectTypeConf( this.entryPoint,
-                                                                                   handle.getObject() ),
-                                               this );
+			this.objectStore.removeHandle(handle);
 
-            if ( this.maintainTms ) {
+			this.handleFactory.destroyFactHandle(handle);
 
-                // the hashCode and equality has changed, so we must update the
-                // EqualityKey
-                EqualityKey key = handle.getEqualityKey();
-                key.removeFactHandle( handle );
+			executeQueuedActions();
+		} finally {
+			this.lock.unlock();
+		}
+	}
 
-                // If the equality key is now empty, then remove it
-                if ( key.isEmpty() ) {
-                    this.tms.remove( key );
-                }
-            }
-        } finally {
-            this.lock.unlock();
-        }
-    }
+	public void modifyRetract(final FactHandle factHandle) {
+		modifyRetract(factHandle, null, null);
+	}
 
-    public void modifyInsert(final FactHandle factHandle,
-                             final Object object) {
-        modifyInsert( factHandle,
-                      object,
-                      null,
-                      null );
-    }
+	public void modifyRetract(final FactHandle factHandle, final Rule rule,
+			final Activation activation) {
+		try {
+			this.lock.lock();
+			this.ruleBase.executeQueuedActions();
 
-    public void modifyInsert(final FactHandle factHandle,
-                             final Object object,
-                             final Rule rule,
-                             final Activation activation) {
-        try {
-            this.lock.lock();
-            this.ruleBase.executeQueuedActions();
+			// 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();
 
-            final InternalFactHandle handle = (InternalFactHandle) factHandle;
-            final Object originalObject = handle.getObject();
+			if (handle.getId() == -1) {
+				// the handle is invalid, most likely already retracted, so
+				// return
+				return;
+			}
 
-            if ( this.maintainTms ) {
-                EqualityKey key = handle.getEqualityKey();
+			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);
 
-                // 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 );
-                }
+			this.entryPointNode.retractObject(handle, propagationContext,
+					this.typeConfReg.getObjectTypeConf(this.entryPoint, handle
+							.getObject()), this);
 
-                handle.setEqualityKey( key );
-            }
+			if (this.maintainTms) {
 
-            this.handleFactory.increaseFactHandleRecency( handle );
+				// the hashCode and equality has changed, so we must update the
+				// EqualityKey
+				EqualityKey key = handle.getEqualityKey();
+				key.removeFactHandle(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 );
+				// If the equality key is now empty, then remove it
+				if (key.isEmpty()) {
+					this.tms.remove(key);
+				}
+			}
+		} finally {
+			this.lock.unlock();
+		}
+	}
 
-            this.entryPointNode.assertObject( handle,
-                                              propagationContext,
-                                              this.typeConfReg.getObjectTypeConf( this.entryPoint,
-                                                                                  object ),
-                                              this );
+	public void modifyInsert(final FactHandle factHandle, final Object object) {
+		modifyInsert(factHandle, object, null, null);
+	}
 
-            this.workingMemoryEventSupport.fireObjectUpdated( propagationContext,
-                                                              factHandle,
-                                                              originalObject,
-                                                              object,
-                                                              this );
+	public void modifyInsert(final FactHandle factHandle, final Object object,
+			final Rule rule, final Activation activation) {
+		try {
+			this.lock.lock();
+			this.ruleBase.executeQueuedActions();
 
-            propagationContext.clearRetractedTuples();
+			final InternalFactHandle handle = (InternalFactHandle) factHandle;
+			final Object originalObject = handle.getObject();
 
-            executeQueuedActions();
+			if (this.maintainTms) {
+				EqualityKey key = handle.getEqualityKey();
 
-        } finally {
-            this.lock.unlock();
-        }
-    }
+				// 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);
+				}
 
-    public void update(final FactHandle handle,
-                       final Object object) throws FactException {
-        update( handle,
-                object,
-                null,
-                null );
-    }
+				handle.setEqualityKey(key);
+			}
 
-    /**
-     * 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();
+			this.handleFactory.increaseFactHandleRecency(handle);
 
-            // 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();
+			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 || object == null ) {
-                // the handle is invalid, most likely already retracted, so
-                // return
-                // and we cannot assert a null object
-                return;
-            }
+			this.entryPointNode
+					.assertObject(handle, propagationContext, this.typeConfReg
+							.getObjectTypeConf(this.entryPoint, object), 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 );
+			this.workingMemoryEventSupport.fireObjectUpdated(
+					propagationContext, factHandle, originalObject, object,
+					this);
 
-            ObjectTypeConf typeConf = this.typeConfReg.getObjectTypeConf( this.entryPoint,
-                                                                          object );
+			propagationContext.clearRetractedTuples();
 
-            this.entryPointNode.retractObject( handle,
-                                               propagationContext,
-                                               typeConf,
-                                               this );
+			executeQueuedActions();
 
-            if ( originalObject != object || !AssertBehaviour.IDENTITY.equals( this.ruleBase.getConfiguration().getAssertBehaviour() ) ) {
-                this.objectStore.removeHandle( handle );
+		} finally {
+			this.lock.unlock();
+		}
+	}
 
-                // set anyway, so that it updates the hashCodes
-                handle.setObject( object );
-                this.objectStore.addHandle( handle,
-                                            object );
-            }
+	public void update(final FactHandle handle, final Object object)
+			throws FactException {
+		update(handle, object, null, null);
+	}
 
-            if ( this.maintainTms ) {
+	/**
+	 * 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();
 
-                // the hashCode and equality has changed, so we must update the
-                // EqualityKey
-                EqualityKey key = handle.getEqualityKey();
-                key.removeFactHandle( handle );
+			// 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();
 
-                // If the equality key is now empty, then remove it
-                if ( key.isEmpty() ) {
-                    this.tms.remove( key );
-                }
+			if (handle.getId() == -1 || object == null) {
+				// the handle is invalid, most likely already retracted, so
+				// return
+				// and we cannot assert a null object
+				return;
+			}
 
-                // 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 );
-                }
+			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 );
-            }
+			ObjectTypeConf typeConf = this.typeConfReg.getObjectTypeConf(
+					this.entryPoint, object);
 
-            this.handleFactory.increaseFactHandleRecency( handle );
+			this.entryPointNode.retractObject(handle, propagationContext,
+					typeConf, this);
 
-            this.entryPointNode.assertObject( handle,
-                                              propagationContext,
-                                              typeConf,
-                                              this );
+			if (originalObject != object
+					|| !AssertBehaviour.IDENTITY.equals(this.ruleBase
+							.getConfiguration().getAssertBehaviour())) {
+				this.objectStore.removeHandle(handle);
 
-            this.workingMemoryEventSupport.fireObjectUpdated( propagationContext,
-                                                              factHandle,
-                                                              originalObject,
-                                                              object,
-                                                              this );
+				// set anyway, so that it updates the hashCodes
+				handle.setObject(object);
+				this.objectStore.addHandle(handle, object);
+			}
 
-            propagationContext.clearRetractedTuples();
+			if (this.maintainTms) {
 
-            executeQueuedActions();
-        } finally {
-            this.lock.unlock();
-        }
-    }
+				// the hashCode and equality has changed, so we must update the
+				// EqualityKey
+				EqualityKey key = handle.getEqualityKey();
+				key.removeFactHandle(handle);
 
-    public void executeQueuedActions() {
-        synchronized ( this.actionQueue ) {
-            if ( !this.actionQueue.isEmpty() && !evaluatingActionQueue ) {
-                evaluatingActionQueue = true;
-                WorkingMemoryAction action = null;
+				// If the equality key is now empty, then remove it
+				if (key.isEmpty()) {
+					this.tms.remove(key);
+				}
 
-                while ( (action = actionQueue.poll()) != null ) {
-                    action.execute( this );
-                }
-                evaluatingActionQueue = false;
-            }
-        }
-    }
+				// 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);
+				}
 
-    public Queue<WorkingMemoryAction> getActionQueue() {
-        return this.actionQueue;
-    }
+				handle.setEqualityKey(key);
+			}
 
-    public void queueWorkingMemoryAction(final WorkingMemoryAction action) {
-        synchronized ( this.actionQueue ) {
-            this.actionQueue.add( action );
-        }
-    }
+			this.handleFactory.increaseFactHandleRecency(handle);
 
-    public void removeLogicalDependencies(final Activation activation,
-                                          final PropagationContext context,
-                                          final Rule rule) throws FactException {
-        if ( this.maintainTms ) {
-            this.tms.removeLogicalDependencies( activation,
-                                                context,
-                                                rule );
-        }
-    }
+			this.entryPointNode.assertObject(handle, propagationContext,
+					typeConf, this);
 
-    /**
-     * 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 );
-    }
+			this.workingMemoryEventSupport.fireObjectUpdated(
+					propagationContext, factHandle, originalObject, object,
+					this);
 
-    public void clearNodeMemory(final NodeMemory node) {
-        this.nodeMemories.clearNodeMemory( node );
-    }
+			propagationContext.clearRetractedTuples();
 
-    public WorkingMemoryEventSupport getWorkingMemoryEventSupport() {
-        return this.workingMemoryEventSupport;
-    }
+			executeQueuedActions();
+		} finally {
+			this.lock.unlock();
+		}
+	}
 
-    public AgendaEventSupport getAgendaEventSupport() {
-        return this.agendaEventSupport;
-    }
+	public void executeQueuedActions() {
+		synchronized (this.actionQueue) {
+			if (!this.actionQueue.isEmpty() && !evaluatingActionQueue) {
+				evaluatingActionQueue = true;
+				WorkingMemoryAction action = null;
 
-    public RuleFlowEventSupport getRuleFlowEventSupport() {
-        return this.workflowEventSupport;
-    }
+				while ((action = actionQueue.poll()) != null) {
+					action.execute(this);
+				}
+				evaluatingActionQueue = false;
+			}
+		}
+	}
 
-    /**
-     * 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 Queue<WorkingMemoryAction> getActionQueue() {
+		return this.actionQueue;
+	}
 
-    /*
-     * public void dumpMemory() { Iterator it = this.joinMemories.keySet(
-     * ).iterator( ); while ( it.hasNext( ) ) { ((JoinMemory)
-     * this.joinMemories.get( it.next( ) )).dump( ); } }
-     */
+	public void queueWorkingMemoryAction(final WorkingMemoryAction action) {
+		synchronized (this.actionQueue) {
+			this.actionQueue.add(action);
+		}
+	}
 
-    public void propertyChange(final PropertyChangeEvent event) {
-        final Object object = event.getSource();
+	public void removeLogicalDependencies(final Activation activation,
+			final PropagationContext context, final Rule rule)
+			throws FactException {
+		if (this.maintainTms) {
+			this.tms.removeLogicalDependencies(activation, context, rule);
+		}
+	}
 
-        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() );
-        }
-    }
+	/**
+	 * 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 long getNextPropagationIdCounter() {
-        return this.propagationIdCounter.incrementAndGet();
-    }
+	public void clearNodeMemory(final NodeMemory node) {
+		this.nodeMemories.clearNodeMemory(node);
+	}
 
-    public long getPropagationIdCounter() {
-        return this.propagationIdCounter.get();
-    }
+	public WorkingMemoryEventSupport getWorkingMemoryEventSupport() {
+		return this.workingMemoryEventSupport;
+	}
 
-    public Lock getLock() {
-        return this.lock;
-    }
+	public AgendaEventSupport getAgendaEventSupport() {
+		return this.agendaEventSupport;
+	}
 
-    public class RuleFlowDeactivateEvent {
+	public RuleFlowEventSupport getRuleFlowEventSupport() {
+		return this.workflowEventSupport;
+	}
 
-        public void propagate() {
+	/**
+	 * 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 void dumpMemory() { Iterator it = this.joinMemories.keySet(
+	 * ).iterator( ); while ( it.hasNext( ) ) { ((JoinMemory)
+	 * this.joinMemories.get( it.next( ) )).dump( ); } }
+	 */
 
-    public ProcessInstance startProcess(final String processId) {
-        return startProcess( processId,
-                             null );
-    }
+	public void propertyChange(final PropertyChangeEvent event) {
+		final Object object = event.getSource();
 
-    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 );
+		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());
+		}
+	}
 
-        return processInstance;
-    }
-    
-    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 ProcessInstanceManager getProcessInstanceManager() {
-        return processInstanceManager;
-    }
+	public long getNextPropagationIdCounter() {
+		return this.propagationIdCounter.incrementAndGet();
+	}
 
-    public Collection<ProcessInstance> getProcessInstances() {
-        return processInstanceManager.getProcessInstances();
-    }
+	public long getPropagationIdCounter() {
+		return this.propagationIdCounter.get();
+	}
 
-    public ProcessInstance getProcessInstance(long id) {
-        return processInstanceManager.getProcessInstance(id);
-    }
+	public Lock getLock() {
+		return this.lock;
+	}
 
-    public void removeProcessInstance(ProcessInstance processInstance) {
-        processInstanceManager.removeProcessInstance(processInstance);
-    }
+	public class RuleFlowDeactivateEvent {
 
-    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 void propagate() {
 
-    public TimerManager getTimerManager() {
-        return timerManager;
-    }
+		}
+	}
 
-    public List iterateObjectsToList() {
-        List result = new ArrayList();
-        Iterator iterator = iterateObjects();
-        for ( ; iterator.hasNext(); ) {
-            result.add( iterator.next() );
-        }
-        return result;
-    }
+	public ProcessInstance startProcess(final String processId) {
+		return startProcess(processId, null);
+	}
 
-    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 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);
 
-    /**
-     * 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;
-    }
+		return processInstance;
+	}
 
-    /**
-     * The time machine tells you what time it is.
-     */
-    public TimeMachine getTimeMachine() {
-        return timeMachine;
-    }
+	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;
+	}
 
-    /**
-     * 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 ProcessInstanceManager getProcessInstanceManager() {
+		return processInstanceManager;
+	}
 
-    public ExecutorService getExecutorService() {
-        return null; // no executor service
-    }
+	public Collection<ProcessInstance> getProcessInstances() {
+		return processInstanceManager.getProcessInstances();
+	}
 
-    public void setExecutorService(ExecutorService executor) {
-        // no executor service, so nothing to set
-    }
+	public ProcessInstance getProcessInstance(long id) {
+		return processInstanceManager.getProcessInstance(id);
+	}
 
-    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 void removeProcessInstance(ProcessInstance processInstance) {
+		processInstanceManager.removeProcessInstance(processInstance);
+	}
 
-            if ( entryPointNode != null ) {
-                wmEntryPoint = new NamedEntryPoint( entryPoint,
-                                                    entryPointNode,
-                                                    this );
-            }
+	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;
+	}
 
-            if ( wmEntryPoint != null ) {
-                this.entryPoints.put( name,
-                                      wmEntryPoint );
-            }
-        }
-        return wmEntryPoint;
-    }
+	public TimerManager getTimerManager() {
+		return timerManager;
+	}
 
-    public ObjectTypeConfigurationRegistry getObjectTypeConfigurationRegistry() {
-        return this.typeConfReg;
-    }
+	public List iterateObjectsToList() {
+		List result = new ArrayList();
+		Iterator iterator = iterateObjects();
+		for (; iterator.hasNext();) {
+			result.add(iterator.next());
+		}
+		return result;
+	}
 
-    public InternalFactHandle getInitialFactHandle() {
-        return this.initialFactHandle;
-    }
+	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 void setInitialFactHandle(InternalFactHandle initialFactHandle) {
-        this.initialFactHandle = initialFactHandle;
-    }
-    
-    public TimerService getTimerService() {
-        return this.getTimerManager().getTimerService();
-    }
-    
-    public SessionClock getSessionClock() {
-        return (SessionClock) this.getTimerManager().getTimerService();
-    }
+	/**
+	 * 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 PartitionTaskManager getPartitionManager( final RuleBasePartitionId partitionId ) {
-        return partitionManagers.get( partitionId );
-    }
+	/**
+	 * The time machine tells you what time it is.
+	 */
+	public TimeMachine getTimeMachine() {
+		return timeMachine;
+	}
 
-    //    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();
-    }
+	/**
+	 * 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 ExecutorService getExecutorService() {
+		return null; // no executor service
+	}
+
+	public void setExecutorService(ExecutorService executor) {
+		// no executor service, so nothing to set
+	}
+
+	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);
+
+			if (entryPointNode != null) {
+				wmEntryPoint = new NamedEntryPoint(entryPoint, entryPointNode,
+						this);
+			}
+
+			if (wmEntryPoint != null) {
+				this.entryPoints.put(name, wmEntryPoint);
+			}
+		}
+		return wmEntryPoint;
+	}
+
+	public ObjectTypeConfigurationRegistry getObjectTypeConfigurationRegistry() {
+		return this.typeConfReg;
+	}
+
+	public InternalFactHandle getInitialFactHandle() {
+		return this.initialFactHandle;
+	}
+
+	public void setInitialFactHandle(InternalFactHandle initialFactHandle) {
+		this.initialFactHandle = initialFactHandle;
+	}
+
+	public TimerService getTimerService() {
+		return this.getTimerManager().getTimerService();
+	}
+
+	public SessionClock getSessionClock() {
+		return (SessionClock) this.getTimerManager().getTimerService();
+	}
+
+	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-18 17:42:55 UTC (rev 22890)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultAgenda.java	2008-09-18 17:46:11 UTC (rev 22891)
@@ -991,13 +991,16 @@
             }
     }
     
-    public void fireAllRules(AgendaFilter agendaFilter,
+    public int fireAllRules(AgendaFilter agendaFilter,
                              int fireLimit) {
         this.halt.set( false );
+        int fireCount = 0;
         while ( continueFiring( fireLimit ) && fireNextItem( agendaFilter ) ) {
+        	fireCount++;
             fireLimit = updateFireLimit( fireLimit );
             this.workingMemory.executeQueuedActions();
         }
+        return fireCount;
     }
 
     private final boolean continueFiring(final int fireLimit) {

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-18 17:42:55 UTC (rev 22890)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalAgenda.java	2008-09-18 17:46:11 UTC (rev 22891)
@@ -83,8 +83,10 @@
      * @param agendaFilter the filter on which activations may fire.
      * @param fireLimit the maximum number of activations that may fire. If -1, then it will
      *                  fire until no more activations exist.
+     *                  
+     * @return the number of rules that were actually fired                 
      */
-    public void fireAllRules(AgendaFilter agendaFilter,
+    public int fireAllRules(AgendaFilter agendaFilter,
                              int fireLimit);
 
     /**

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/common/business/SolutionBusiness.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/common/business/SolutionBusiness.java	2008-09-18 17:42:55 UTC (rev 22890)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/common/business/SolutionBusiness.java	2008-09-18 17:46:11 UTC (rev 22891)
@@ -97,7 +97,7 @@
         if (workingMemory == null) {
             return Collections.emptyList();
         }
-        Iterator<ConstraintOccurrence> it = workingMemory.iterateObjects(
+        Iterator<ConstraintOccurrence> it = (Iterator<ConstraintOccurrence>) workingMemory.iterateObjects(
                 new ClassObjectFilter(ConstraintOccurrence.class));
         while (it.hasNext()) {
             ConstraintOccurrence occurrence = it.next();

Modified: labs/jbossrules/trunk/drools-templates/src/test/java/org/drools/template/parser/ExternalSheetListenerTest.java
===================================================================
--- labs/jbossrules/trunk/drools-templates/src/test/java/org/drools/template/parser/ExternalSheetListenerTest.java	2008-09-18 17:42:55 UTC (rev 22890)
+++ labs/jbossrules/trunk/drools-templates/src/test/java/org/drools/template/parser/ExternalSheetListenerTest.java	2008-09-18 17:46:11 UTC (rev 22891)
@@ -150,13 +150,13 @@
 
 				}
 
-				public void fireAllRules() throws FactException {
-
+				public int fireAllRules() throws FactException {
+					return 0;
 				}
 
-				public void fireAllRules(AgendaFilter arg0)
+				public int fireAllRules(AgendaFilter arg0)
 						throws FactException {
-
+					return 0;
 				}
 
 				public Agenda getAgenda() {
@@ -316,15 +316,14 @@
 
                 }
 
-                public void fireAllRules(int fireLimit) throws FactException {
-                    
-
+                public int fireAllRules(int fireLimit) throws FactException {
+                	return 0;
                 }
 
-                public void fireAllRules(AgendaFilter agendaFilter,
+                public int fireAllRules(AgendaFilter agendaFilter,
                                          int fireLimit) throws FactException {
-                    
-
+                	
+                	return 0;
                 }
 
 				public GlobalResolver getGlobalResolver() {




More information about the jboss-svn-commits mailing list