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

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Fri Mar 21 12:07:17 EDT 2008


Author: mark.proctor at jboss.com
Date: 2008-03-21 12:07:16 -0400 (Fri, 21 Mar 2008)
New Revision: 19178

Added:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/CompositeRightTupleSinkAdapter.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EmptyLeftTupleSinkAdapter.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EmptyRightTupleSinkAdapter.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightTuple.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightTupleMemory.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightTupleSink.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightTupleSinkNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightTupleSinkNodeList.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightTupleSinkPropagator.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightTupleSource.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/SingleLeftTupleSinkAdapter.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/SingleRightTupleSinkAdapter.java
Removed:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/CompositeObjectSinkAdapter.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EmptyObjectSinkAdapter.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EmptyTupleSinkAdapter.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/FactHandleMemory.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectSink.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectSinkNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectSinkNodeList.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectSinkPropagator.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectSource.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/SingleObjectSinkAdapter.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/SingleTupleSinkAdapter.java
Modified:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultBetaConstraints.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultFactHandle.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DoubleBetaConstraints.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/EmptyBetaConstraints.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalFactHandle.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/QuadroupleBetaConstraints.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/SingleBetaConstraints.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/TripleBetaConstraints.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/AccumulateNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/AlphaNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/BetaMemory.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/BetaNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/CollectNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/CompositeTupleSinkAdapter.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EntryPointNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ExistsNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/FromNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/JoinNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/LeftInputAdapterNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/LeftTuple.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/LeftTupleMemory.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/LeftTupleSinkPropagator.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/LeftTupleSource.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/MemoryVisitor.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/NotNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectTypeNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/PropagationQueuingNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/Rete.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightInputAdapterNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/AccumulateBuilder.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/BuildContext.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/BuildUtils.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/CollectBuilder.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/GroupElementBuilder.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/PatternBuilder.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/FactHandleIndexHashTable.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/FactHashTable.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/FactList.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/common/BaseBetaConstraintsTest.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/AccumulateNodeTest.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/BetaNodeTest.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/CollectNodeTest.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/CompositeObjectSinkAdapterTest.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/ExistsNodeTest.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/FromNodeTest.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/JoinNodeTest.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/LeftInputAdapterNodeTest.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/MockObjectSink.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/MockObjectSource.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/NotNodeTest.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/ObjectSourceTest.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/TupleSourceTest.java
Log:
JBRULES-1520 RightTuple merge for asynchronous Rete propagations
-mid refactor, bit of a mess, but wan't to be prepared in case eclipse refactoring screws up.

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultBetaConstraints.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultBetaConstraints.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultBetaConstraints.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -19,7 +19,7 @@
 import org.drools.RuleBaseConfiguration;
 import org.drools.base.evaluators.Operator;
 import org.drools.reteoo.BetaMemory;
-import org.drools.reteoo.FactHandleMemory;
+import org.drools.reteoo.RightTupleMemory;
 import org.drools.reteoo.LeftTuple;
 import org.drools.reteoo.LeftTupleMemory;
 import org.drools.rule.ContextEntry;
@@ -245,18 +245,18 @@
                 tupleMemory = new TupleHashTable();
             }
 
-            FactHandleMemory factHandleMemory;
+            RightTupleMemory factHandleMemory;
             if ( config.isIndexRightBetaMemory() ) {
                 factHandleMemory = new FactHandleIndexHashTable( indexes );
             } else {
-                factHandleMemory = config.isSequential() ? (FactHandleMemory) new FactList() : (FactHandleMemory) new FactHashTable();
+                factHandleMemory = config.isSequential() ? (RightTupleMemory) new FactList() : (RightTupleMemory) new FactHashTable();
             }
             memory = new BetaMemory( config.isSequential() ? null : tupleMemory,
                                      factHandleMemory,
                                      this.createContext() );
         } else {
             memory = new BetaMemory( config.isSequential() ? null : new TupleHashTable(),
-                                     config.isSequential() ? (FactHandleMemory) new FactList() : (FactHandleMemory) new FactHashTable(),
+                                     config.isSequential() ? (RightTupleMemory) new FactList() : (RightTupleMemory) new FactHashTable(),
                                      this.createContext() );
         }
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultFactHandle.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultFactHandle.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultFactHandle.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -17,6 +17,8 @@
  */
 
 import org.drools.FactHandle;
+import org.drools.reteoo.LeftTuple;
+import org.drools.reteoo.RightTuple;
 
 import java.io.ObjectOutput;
 import java.io.IOException;
@@ -45,6 +47,8 @@
     private EqualityKey       key;
     private int               objectHashCode;
     private boolean           shadowFact;
+    private RightTuple        rightTuple;
+    private LeftTuple         leftTuple;    
 
     public void writeExternal(ObjectOutput out) throws IOException {
         out.writeInt(id);
@@ -190,4 +194,20 @@
     public boolean isEvent() {
         return false;
     }
+    
+    public RightTuple getRightTuple() {
+        return rightTuple;
+    }
+
+    public void setRightTuple(RightTuple rightTuple) {
+        this.rightTuple = rightTuple;
+    }
+    
+    public void setLeftTuple(LeftTuple leftTuple) {
+        this.leftTuple = leftTuple;
+    }
+    
+    public LeftTuple getLeftTuple(){
+        return this.leftTuple;
+    }    
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DoubleBetaConstraints.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DoubleBetaConstraints.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DoubleBetaConstraints.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -19,7 +19,7 @@
 import org.drools.RuleBaseConfiguration;
 import org.drools.base.evaluators.Operator;
 import org.drools.reteoo.BetaMemory;
-import org.drools.reteoo.FactHandleMemory;
+import org.drools.reteoo.RightTupleMemory;
 import org.drools.reteoo.LeftTuple;
 import org.drools.reteoo.LeftTupleMemory;
 import org.drools.rule.ContextEntry;
@@ -234,18 +234,18 @@
                 tupleMemory = new TupleHashTable();
             }
 
-            FactHandleMemory factHandleMemory;
+            RightTupleMemory factHandleMemory;
             if ( config.isIndexRightBetaMemory() ) {
                 factHandleMemory = new FactHandleIndexHashTable( indexes );
             } else {
-                factHandleMemory = config.isSequential() ? (FactHandleMemory) new FactList() : (FactHandleMemory) new FactHashTable();
+                factHandleMemory = config.isSequential() ? (RightTupleMemory) new FactList() : (RightTupleMemory) new FactHashTable();
             }
             memory = new BetaMemory( config.isSequential() ? null : tupleMemory,
                                      factHandleMemory,
                                      this.createContext() );
         } else {
             memory = new BetaMemory( config.isSequential() ? null : new TupleHashTable(),
-                                     config.isSequential() ? (FactHandleMemory) new FactList() : (FactHandleMemory) new FactHashTable(),
+                                     config.isSequential() ? (RightTupleMemory) new FactList() : (RightTupleMemory) new FactHashTable(),
                                      this.createContext() );
         }
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/EmptyBetaConstraints.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/EmptyBetaConstraints.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/EmptyBetaConstraints.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -18,7 +18,7 @@
 
 import org.drools.RuleBaseConfiguration;
 import org.drools.reteoo.BetaMemory;
-import org.drools.reteoo.FactHandleMemory;
+import org.drools.reteoo.RightTupleMemory;
 import org.drools.reteoo.LeftTuple;
 import org.drools.rule.ContextEntry;
 import org.drools.util.FactHashTable;
@@ -106,7 +106,7 @@
 
     public BetaMemory createBetaMemory(final RuleBaseConfiguration config) {
         final BetaMemory memory = new BetaMemory( config.isSequential() ? null : new TupleHashTable(),
-                                                  config.isSequential() ? (FactHandleMemory) new FactList() : (FactHandleMemory) new FactHashTable(),
+                                                  config.isSequential() ? (RightTupleMemory) new FactList() : (RightTupleMemory) new FactHashTable(),
                                                   this.createContext() );
 
         return memory;

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalFactHandle.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalFactHandle.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalFactHandle.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -17,6 +17,8 @@
  */
 
 import org.drools.FactHandle;
+import org.drools.reteoo.LeftTuple;
+import org.drools.reteoo.RightTuple;
 
 public interface InternalFactHandle
     extends
@@ -51,4 +53,12 @@
      * @return
      */
     public boolean isEvent();
+    
+    public RightTuple getRightTuple();
+
+    public void setRightTuple(RightTuple rightTuple);
+    
+    public void setLeftTuple(LeftTuple leftTuple);
+    
+    public LeftTuple getLeftTuple();
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/QuadroupleBetaConstraints.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/QuadroupleBetaConstraints.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/QuadroupleBetaConstraints.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -19,7 +19,7 @@
 import org.drools.RuleBaseConfiguration;
 import org.drools.base.evaluators.Operator;
 import org.drools.reteoo.BetaMemory;
-import org.drools.reteoo.FactHandleMemory;
+import org.drools.reteoo.RightTupleMemory;
 import org.drools.reteoo.LeftTuple;
 import org.drools.reteoo.LeftTupleMemory;
 import org.drools.rule.ContextEntry;
@@ -335,18 +335,18 @@
                 tupleMemory = new TupleHashTable();
             }
 
-            FactHandleMemory factHandleMemory;
+            RightTupleMemory factHandleMemory;
             if ( conf.isIndexRightBetaMemory() ) {
                 factHandleMemory = new FactHandleIndexHashTable( indexes );
             } else {
-                factHandleMemory = conf.isSequential() ? (FactHandleMemory) new FactList() : (FactHandleMemory) new FactHashTable();
+                factHandleMemory = conf.isSequential() ? (RightTupleMemory) new FactList() : (RightTupleMemory) new FactHashTable();
             }
             memory = new BetaMemory( conf.isSequential() ? null : tupleMemory,
                                      factHandleMemory,
                                      this.createContext() );
         } else {
             memory = new BetaMemory( conf.isSequential() ? null : new TupleHashTable(),
-                                     conf.isSequential() ? (FactHandleMemory) new FactList() : (FactHandleMemory) new FactHashTable(),
+                                     conf.isSequential() ? (RightTupleMemory) new FactList() : (RightTupleMemory) new FactHashTable(),
                                      this.createContext() );
         }
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/SingleBetaConstraints.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/SingleBetaConstraints.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/SingleBetaConstraints.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -23,7 +23,7 @@
 import org.drools.RuleBaseConfiguration;
 import org.drools.base.evaluators.Operator;
 import org.drools.reteoo.BetaMemory;
-import org.drools.reteoo.FactHandleMemory;
+import org.drools.reteoo.RightTupleMemory;
 import org.drools.reteoo.LeftTuple;
 import org.drools.reteoo.LeftTupleMemory;
 import org.drools.rule.ContextEntry;
@@ -176,7 +176,7 @@
                 tupleMemory = new TupleHashTable();
             }
 
-            FactHandleMemory factHandleMemory;
+            RightTupleMemory factHandleMemory;
             if ( this.conf.isIndexRightBetaMemory() ) {
                 factHandleMemory = new FactHandleIndexHashTable( new FieldIndex[]{index} );
             } else {

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/TripleBetaConstraints.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/TripleBetaConstraints.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/TripleBetaConstraints.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -25,7 +25,7 @@
 import org.drools.RuleBaseConfiguration;
 import org.drools.base.evaluators.Operator;
 import org.drools.reteoo.BetaMemory;
-import org.drools.reteoo.FactHandleMemory;
+import org.drools.reteoo.RightTupleMemory;
 import org.drools.reteoo.LeftTuple;
 import org.drools.reteoo.LeftTupleMemory;
 import org.drools.rule.ContextEntry;
@@ -281,18 +281,18 @@
                 tupleMemory = new TupleHashTable();
             }
 
-            FactHandleMemory factHandleMemory;
+            RightTupleMemory factHandleMemory;
             if ( conf.isIndexRightBetaMemory() ) {
                 factHandleMemory = new FactHandleIndexHashTable( indexes );
             } else {
-                factHandleMemory = conf.isSequential() ? (FactHandleMemory) new FactList() : (FactHandleMemory) new FactHashTable();
+                factHandleMemory = conf.isSequential() ? (RightTupleMemory) new FactList() : (RightTupleMemory) new FactHashTable();
             }
             memory = new BetaMemory( conf.isSequential() ? null : tupleMemory,
                                      factHandleMemory,
                                      this.createContext() );
         } else {
             memory = new BetaMemory( conf.isSequential() ? null : new TupleHashTable(),
-                                     conf.isSequential() ? (FactHandleMemory) new FactList() : (FactHandleMemory) new FactHashTable(),
+                                     conf.isSequential() ? (RightTupleMemory) new FactList() : (RightTupleMemory) new FactHashTable(),
                                      this.createContext() );
         }
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/AccumulateNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/AccumulateNode.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/AccumulateNode.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -61,7 +61,7 @@
 
     public AccumulateNode(final int id,
                           final LeftTupleSource leftInput,
-                          final ObjectSource rightInput,
+                          final RightTupleSource rightInput,
                           final AlphaNodeFieldConstraint[] resultConstraints,
                           final BetaConstraints sourceBinder,
                           final BetaConstraints resultBinder,
@@ -123,7 +123,7 @@
         AccumulateResult accresult = new AccumulateResult();
 
         if ( this.tupleMemoryEnabled ) {
-            memory.betaMemory.getTupleMemory().add( leftTuple );
+            memory.betaMemory.getLeftTupleMemory().add( leftTuple );
             memory.betaMemory.getCreatedHandles().put( leftTuple,
                                             accresult,
                                             false );
@@ -137,7 +137,7 @@
                               leftTuple,
                               workingMemory );
 
-        final Iterator it = memory.betaMemory.getFactHandleMemory().iterator( leftTuple );
+        final Iterator it = memory.betaMemory.getRightTupleMemory().iterator( leftTuple );
         this.constraints.updateFromTuple( memory.betaMemory.getContext(),
                                           workingMemory,
                                           leftTuple );
@@ -220,7 +220,7 @@
                              final PropagationContext context,
                              final InternalWorkingMemory workingMemory) {
         final AccumulateMemory memory = (AccumulateMemory) workingMemory.getNodeMemory( this );
-        if( memory.betaMemory.getTupleMemory().remove( leftTuple ) == null) {
+        if( memory.betaMemory.getLeftTupleMemory().remove( leftTuple ) == null) {
             return;
         }
         final AccumulateResult accresult = (AccumulateResult) memory.betaMemory.getCreatedHandles().remove( leftTuple );
@@ -247,12 +247,12 @@
      *  2. For each matching tuple, call a modify tuple
      *
      */
-    public void assertObject(final InternalFactHandle handle,
+    public void assertObject(final InternalFactHandle factHandle,
                              final PropagationContext context,
                              final InternalWorkingMemory workingMemory) {
 
         final AccumulateMemory memory = (AccumulateMemory) workingMemory.getNodeMemory( this );
-        memory.betaMemory.getFactHandleMemory().add( handle );
+        memory.betaMemory.getRightTupleMemory().add( factHandle );
 
         if ( ! this.tupleMemoryEnabled ) {
             // do nothing here, as we know there are no left tuples at this stage in sequential mode.
@@ -261,10 +261,10 @@
 
         this.constraints.updateFromFactHandle( memory.betaMemory.getContext(),
                                                workingMemory,
-                                               handle );
+                                               factHandle );
 
         // need to clone the tuples to avoid concurrent modification exceptions
-        Entry[] tuples = memory.betaMemory.getTupleMemory().toArray();
+        Entry[] tuples = memory.betaMemory.getLeftTupleMemory().toArray();
         for ( int i = 0; i < tuples.length; i++ ) {
             LeftTuple tuple = (LeftTuple) tuples[i];
             if ( this.constraints.isAllowedCachedRight( memory.betaMemory.getContext(),
@@ -272,7 +272,7 @@
                 if ( this.accumulate.supportsReverse() || context.getType() == PropagationContext.ASSERTION ) {
                     modifyTuple( true,
                                  tuple,
-                                 handle,
+                                 factHandle,
                                  context,
                                  workingMemory );
                 } else {
@@ -300,7 +300,7 @@
                               final PropagationContext context,
                               final InternalWorkingMemory workingMemory) {
         final AccumulateMemory memory = (AccumulateMemory) workingMemory.getNodeMemory( this );
-        if ( !memory.betaMemory.getFactHandleMemory().remove( handle ) ) {
+        if ( !memory.betaMemory.getRightTupleMemory().remove( handle ) ) {
             return;
         }
 
@@ -308,7 +308,7 @@
                                                workingMemory,
                                                handle );
         // need to clone the tuples to avoid concurrent modification exceptions
-        Entry[] tuples = memory.betaMemory.getTupleMemory().toArray();
+        Entry[] tuples = memory.betaMemory.getLeftTupleMemory().toArray();
         for ( int i = 0; i < tuples.length; i++ ) {
             LeftTuple tuple = (LeftTuple) tuples[i];
             if ( this.constraints.isAllowedCachedRight( memory.betaMemory.getContext(),

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/AlphaNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/AlphaNode.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/AlphaNode.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -46,26 +46,22 @@
  * @author <a href="mailto:bob at werken.com">Bob McWhirter</a>
  *
  */
-public class AlphaNode extends ObjectSource
+public class AlphaNode extends RightTupleSource
     implements
-    ObjectSinkNode,
+    RightTupleSinkNode,
     NodeMemory {
 
     /**
      *
      */
-    private static final long              serialVersionUID = 400L;
+    private static final long        serialVersionUID = 400L;
 
     /** The <code>FieldConstraint</code> */
     private AlphaNodeFieldConstraint constraint;
 
-    private ObjectSinkNode                 previousObjectSinkNode;
-    private ObjectSinkNode                 nextObjectSinkNode;
+    private RightTupleSinkNode       previousRightTupleSinkNode;
+    private RightTupleSinkNode       nextRightTupleSinkNode;
 
-    private boolean                        objectMemoryEnabled;
-
-    private boolean                        objectMemoryAllowed;
-
     public AlphaNode() {
 
     }
@@ -84,37 +80,29 @@
      */
     public AlphaNode(final int id,
                      final AlphaNodeFieldConstraint constraint,
-                     final ObjectSource objectSource,
+                     final RightTupleSource objectSource,
                      final BuildContext context) {
         super( id,
                objectSource,
                context.getRuleBase().getConfiguration().getAlphaNodeHashingThreshold() );
         this.constraint = constraint;
-        this.objectMemoryAllowed = context.isAlphaMemoryAllowed();
-        if ( this.objectMemoryAllowed ) {
-            this.objectMemoryEnabled = context.getRuleBase().getConfiguration().isAlphaMemory();
-        } else {
-            this.objectMemoryEnabled = false;
-        }
     }
 
-    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        super.readExternal(in);
-        constraint  = (AlphaNodeFieldConstraint)in.readObject();
-        previousObjectSinkNode  = (ObjectSinkNode)in.readObject();
-        nextObjectSinkNode  = (ObjectSinkNode)in.readObject();
-        objectMemoryEnabled = in.readBoolean();
-        objectMemoryAllowed = in.readBoolean();
+    public void readExternal(ObjectInput in) throws IOException,
+                                            ClassNotFoundException {
+        super.readExternal( in );
+        constraint = (AlphaNodeFieldConstraint) in.readObject();
+        previousRightTupleSinkNode = (RightTupleSinkNode) in.readObject();
+        nextRightTupleSinkNode = (RightTupleSinkNode) in.readObject();
     }
 
     public void writeExternal(ObjectOutput out) throws IOException {
-        super.writeExternal(out);
-        out.writeObject(constraint);
-        out.writeObject(previousObjectSinkNode);
-        out.writeObject(nextObjectSinkNode);
-        out.writeBoolean(objectMemoryEnabled);
-        out.writeBoolean(objectMemoryAllowed);
+        super.writeExternal( out );
+        out.writeObject( constraint );
+        out.writeObject( previousRightTupleSinkNode );
+        out.writeObject( nextRightTupleSinkNode );
     }
+
     /**
      * Retruns the <code>FieldConstraint</code>
      *
@@ -130,89 +118,54 @@
      * @see org.drools.reteoo.BaseNode#attach()
      */
     public void attach() {
-        this.objectSource.addObjectSink( this );
+        this.source.addObjectSink( this );
     }
 
     public void attach(final InternalWorkingMemory[] workingMemories) {
         attach();
 
-        // we are attaching this node with existing working memories
-        // indicating that we are in a dynamic environment, that might benefit from alpha node memory, if allowed
-        if ( this.objectMemoryAllowed ) {
-            setObjectMemoryEnabled( true );
-        }
         for ( int i = 0, length = workingMemories.length; i < length; i++ ) {
             final InternalWorkingMemory workingMemory = workingMemories[i];
             final PropagationContext propagationContext = new PropagationContextImpl( workingMemory.getNextPropagationIdCounter(),
                                                                                       PropagationContext.RULE_ADDITION,
                                                                                       null,
                                                                                       null );
-            this.objectSource.updateSink( this,
-                                          propagationContext,
-                                          workingMemory );
+            this.source.updateSink( this,
+                                    propagationContext,
+                                    workingMemory );
         }
     }
 
-    public void assertObject(final InternalFactHandle handle,
+    public void assertObject(final InternalFactHandle factHandle,
                              final PropagationContext context,
                              final InternalWorkingMemory workingMemory) throws FactException {
         final AlphaMemory memory = (AlphaMemory) workingMemory.getNodeMemory( this );
-        if ( this.constraint.isAllowed( handle,
+        if ( this.constraint.isAllowed( factHandle,
                                         workingMemory,
                                         memory.context ) ) {
-            if ( isObjectMemoryEnabled() ) {
-                memory.facts.add( handle,
-                                  false );
-            }
 
-            this.sink.propagateAssertObject( handle,
-                                             context,
-                                             workingMemory );
+            this.sink.propagateAssertFact( factHandle,
+                                           context,
+                                           workingMemory );
         }
     }
 
-    public void retractObject(final InternalFactHandle handle,
-                              final PropagationContext context,
-                              final InternalWorkingMemory workingMemory) {
-        boolean propagate = true;
-        final AlphaMemory memory = (AlphaMemory) workingMemory.getNodeMemory( this );
-        if ( isObjectMemoryEnabled() ) {
-            propagate = memory.facts.remove( handle );
-        } else {
-            propagate = this.constraint.isAllowed( handle,
-                                                   workingMemory,
-                                                   memory.context );
-        }
-        if ( propagate ) {
-            this.sink.propagateRetractObject( handle,
-                                              context,
-                                              workingMemory,
-                                              true );
-        }
+    public void retractRightTuple(RightTuple rightTuple,
+                                  PropagationContext context,
+                                  InternalWorkingMemory workingMemory) {
+        throw new UnsupportedOperationException( "AlphaNode.retractRightTuple is not supported." );
     }
 
-    public void updateSink(final ObjectSink sink,
+    public void updateSink(final RightTupleSink sink,
                            final PropagationContext context,
                            final InternalWorkingMemory workingMemory) {
         AlphaMemory memory = (AlphaMemory) workingMemory.getNodeMemory( this );
-
-        if ( !isObjectMemoryEnabled() ) {
-            // get the objects from the parent
-            ObjectSinkUpdateAdapter adapter = new ObjectSinkUpdateAdapter( sink,
-                                                                           this.constraint,
-                                                                           memory.context );
-            this.objectSource.updateSink( adapter,
-                                          context,
-                                          workingMemory );
-        } else {
-            // if already has memory, just iterate and propagate
-            final Iterator it = memory.facts.iterator();
-            for ( FactEntry entry = (FactEntry) it.next(); entry != null; entry = (FactEntry) it.next() ) {
-                sink.assertObject( entry.getFactHandle(),
-                                   context,
-                                   workingMemory );
-            }
-        }
+        // get the objects from the parent
+        RightTupleSinkUpdateAdapter adapter = new RightTupleSinkUpdateAdapter( sink,
+                                                                               this.constraint );
+        this.source.updateSink( adapter,
+                                context,
+                                workingMemory );
     }
 
     protected void doRemove(final RuleRemovalContext context,
@@ -220,47 +173,32 @@
                             final BaseNode node,
                             final InternalWorkingMemory[] workingMemories) {
         if ( !node.isInUse() ) {
-            removeObjectSink( (ObjectSink) node );
+            removeObjectSink( (RightTupleSink) node );
         }
         if ( !this.isInUse() ) {
             for ( int i = 0, length = workingMemories.length; i < length; i++ ) {
                 workingMemories[i].clearNodeMemory( this );
             }
         }
-        this.objectSource.remove( context,
-                                  builder,
-                                  this,
-                                  workingMemories );
+        this.source.remove( context,
+                            builder,
+                            this,
+                            workingMemories );
     }
 
-    public void setObjectMemoryAllowed(boolean objectMemoryAllowed) {
-        this.objectMemoryAllowed = objectMemoryAllowed;
-    }
-
-    public boolean isObjectMemoryEnabled() {
-        return this.objectMemoryEnabled;
-    }
-
-    public void setObjectMemoryEnabled(boolean objectMemoryEnabled) {
-        this.objectMemoryEnabled = objectMemoryEnabled;
-    }
-
     /**
      * Creates a HashSet for the AlphaNode's memory.
      */
     public Object createMemory(final RuleBaseConfiguration config) {
         AlphaMemory memory = new AlphaMemory();
         memory.context = this.constraint.createContextEntry();
-        if ( this.objectMemoryEnabled ) {
-            memory.facts = new FactHashTable();
-        }
         return memory;
     }
 
     /**
      * @inheritDoc
      */
-    protected void addObjectSink(final ObjectSink objectSink) {
+    protected void addObjectSink(final RightTupleSink objectSink) {
         super.addObjectSink( objectSink );
     }
 
@@ -269,7 +207,7 @@
     }
 
     public int hashCode() {
-        return this.objectSource.hashCode() * 17 + ((this.constraint != null) ? this.constraint.hashCode() : 0);
+        return this.source.hashCode() * 17 + ((this.constraint != null) ? this.constraint.hashCode() : 0);
     }
 
     /*
@@ -288,7 +226,7 @@
 
         final AlphaNode other = (AlphaNode) object;
 
-        return this.objectSource.equals( other.objectSource ) && this.constraint.equals( other.constraint );
+        return this.source.equals( other.source ) && this.constraint.equals( other.constraint );
     }
 
     /**
@@ -296,8 +234,8 @@
      * @return
      *      The next ObjectSinkNode
      */
-    public ObjectSinkNode getNextObjectSinkNode() {
-        return this.nextObjectSinkNode;
+    public RightTupleSinkNode getNextRightTupleSinkNode() {
+        return this.nextRightTupleSinkNode;
     }
 
     /**
@@ -305,8 +243,8 @@
      * @param next
      *      The next ObjectSinkNode
      */
-    public void setNextObjectSinkNode(final ObjectSinkNode next) {
-        this.nextObjectSinkNode = next;
+    public void setNextRightTupleSinkNode(final RightTupleSinkNode next) {
+        this.nextRightTupleSinkNode = next;
     }
 
     /**
@@ -314,8 +252,8 @@
      * @return
      *      The previous ObjectSinkNode
      */
-    public ObjectSinkNode getPreviousObjectSinkNode() {
-        return this.previousObjectSinkNode;
+    public RightTupleSinkNode getPreviousRightTupleSinkNode() {
+        return this.previousRightTupleSinkNode;
     }
 
     /**
@@ -323,8 +261,8 @@
      * @param previous
      *      The previous ObjectSinkNode
      */
-    public void setPreviousObjectSinkNode(final ObjectSinkNode previous) {
-        this.previousObjectSinkNode = previous;
+    public void setPreviousRightTupleSinkNode(final RightTupleSinkNode previous) {
+        this.previousRightTupleSinkNode = previous;
     }
 
     public static class AlphaMemory
@@ -332,17 +270,15 @@
         Externalizable {
         private static final long serialVersionUID = -5852576405010023458L;
 
-        public FactHashTable      facts;
         public ContextEntry       context;
 
-        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-            facts   = (FactHashTable)in.readObject();
-            context = (ContextEntry)in.readObject();
+        public void readExternal(ObjectInput in) throws IOException,
+                                                ClassNotFoundException {
+            context = (ContextEntry) in.readObject();
         }
 
         public void writeExternal(ObjectOutput out) throws IOException {
-            out.writeObject(facts);
-            out.writeObject(context);
+            out.writeObject( context );
         }
     }
 
@@ -352,51 +288,46 @@
      * @author mproctor
      *
      */
-    private static class ObjectSinkUpdateAdapter
+    private static class RightTupleSinkUpdateAdapter
         implements
-        ObjectSink {
-        private final ObjectSink               sink;
+        RightTupleSink {
+        private final RightTupleSink           sink;
         private final AlphaNodeFieldConstraint constraint;
-        private final ContextEntry             alphaContext;
 
-        public ObjectSinkUpdateAdapter(final ObjectSink sink,
-                                       final AlphaNodeFieldConstraint constraint,
-                                       final ContextEntry context ) {
+        public RightTupleSinkUpdateAdapter(final RightTupleSink sink,
+                                           final AlphaNodeFieldConstraint constraint) {
             this.sink = sink;
             this.constraint = constraint;
-            this.alphaContext = context;
         }
 
-        public void assertObject(final InternalFactHandle handle,
-                                 final PropagationContext context,
-                                 final InternalWorkingMemory workingMemory) {
+        public void assertFact(final InternalFactHandle handle,
+                               final PropagationContext propagationContext,
+                               final InternalWorkingMemory workingMemory,
+                               final ContextEntry contextEntry) {
+
             if ( this.constraint.isAllowed( handle,
                                             workingMemory,
-                                            this.alphaContext ) ) {
+                                            contextEntry ) ) {
                 this.sink.assertObject( handle,
-                                        context,
+                                        propagationContext,
                                         workingMemory );
             }
         }
 
-        public void modifyObject(final InternalFactHandle handle,
-                                 final PropagationContext context,
-                                 final InternalWorkingMemory workingMemory) {
-            throw new UnsupportedOperationException( "ObjectSinkUpdateAdapter onlys supports assertObject method calls" );
+        public void retractRightTuple(final RightTuple rightTuple,
+                                      final PropagationContext context,
+                                      final InternalWorkingMemory workingMemory) {
+            throw new UnsupportedOperationException( "RightTupleSinkUpdateAdapter.retractFact is not supported." );
         }
 
-        public void retractObject(final InternalFactHandle handle,
-                                  final PropagationContext context,
-                                  final InternalWorkingMemory workingMemory) {
-            throw new UnsupportedOperationException( "ObjectSinkUpdateAdapter onlys supports assertObject method calls" );
+        public int getId() {
+            return 0;
         }
 
-        public boolean isObjectMemoryEnabled() {
-            throw new UnsupportedOperationException( "ObjectSinkUpdateAdapter have no Object memory" );
+        public void assertObject(InternalFactHandle factHandle,
+                                 PropagationContext context,
+                                 InternalWorkingMemory workingMemory) {
+            throw new UnsupportedOperationException( "RightTupleSinkUpdateAdapter.assertFact is not supported." );
         }
-
-        public void setObjectMemoryEnabled(boolean objectMemoryEnabled) {
-            throw new UnsupportedOperationException( "ObjectSinkUpdateAdapter have no Object memory" );
-        }
     }
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/BetaMemory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/BetaMemory.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/BetaMemory.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -15,8 +15,8 @@
 
     private static final long serialVersionUID = 400L;
 
-    private LeftTupleMemory       tupleMemory;
-    private FactHandleMemory  factHandleMemory;
+    private LeftTupleMemory   leftTupleMemory;
+    private RightTupleMemory  rightTupleMemory;
     private ObjectHashMap     createdHandles;
     private ContextEntry[]    context;
 
@@ -24,33 +24,34 @@
     }
 
     public BetaMemory(final LeftTupleMemory tupleMemory,
-                      final FactHandleMemory objectMemory,
-                      final ContextEntry[] context ) {
-        this.tupleMemory = tupleMemory;
-        this.factHandleMemory = objectMemory;
+                      final RightTupleMemory objectMemory,
+                      final ContextEntry[] context) {
+        this.leftTupleMemory = tupleMemory;
+        this.rightTupleMemory = objectMemory;
         this.context = context;
     }
 
-    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        tupleMemory         = (LeftTupleMemory)in.readObject();
-        factHandleMemory    = (FactHandleMemory)in.readObject();
-        createdHandles      = (ObjectHashMap)in.readObject();
-        context             = (ContextEntry[])in.readObject();
+    public void readExternal(ObjectInput in) throws IOException,
+                                            ClassNotFoundException {
+        leftTupleMemory = (LeftTupleMemory) in.readObject();
+        rightTupleMemory = (RightTupleMemory) in.readObject();
+        createdHandles = (ObjectHashMap) in.readObject();
+        context = (ContextEntry[]) in.readObject();
     }
 
     public void writeExternal(ObjectOutput out) throws IOException {
-        out.writeObject(tupleMemory);
-        out.writeObject(factHandleMemory);
-        out.writeObject(createdHandles);
-        out.writeObject(context);
+        out.writeObject( leftTupleMemory );
+        out.writeObject( rightTupleMemory );
+        out.writeObject( createdHandles );
+        out.writeObject( context );
     }
 
-    public FactHandleMemory getFactHandleMemory() {
-        return this.factHandleMemory;
+    public RightTupleMemory getRightTupleMemory() {
+        return this.rightTupleMemory;
     }
 
-    public LeftTupleMemory getTupleMemory() {
-        return this.tupleMemory;
+    public LeftTupleMemory getLeftTupleMemory() {
+        return this.leftTupleMemory;
     }
 
     public ObjectHashMap getCreatedHandles() {

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/BetaNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/BetaNode.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/BetaNode.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -48,7 +48,7 @@
 abstract class BetaNode extends LeftTupleSource
     implements
     LeftTupleSinkNode,
-    ObjectSinkNode,
+    RightTupleSinkNode,
     NodeMemory {
     // ------------------------------------------------------------
     // Instance members
@@ -58,15 +58,15 @@
     protected LeftTupleSource     leftInput;
 
     /** The right input <code>TupleSource</code>. */
-    protected ObjectSource    rightInput;
+    protected RightTupleSource    rightInput;
 
     protected BetaConstraints constraints;
 
     private LeftTupleSinkNode           previousTupleSinkNode;
     private LeftTupleSinkNode           nextTupleSinkNode;
 
-    private ObjectSinkNode          previousObjectSinkNode;
-    private ObjectSinkNode          nextObjectSinkNode;
+    private RightTupleSinkNode          previousObjectSinkNode;
+    private RightTupleSinkNode          nextObjectSinkNode;
 
     protected boolean               objectMemory = true; // hard coded to true
     protected boolean               tupleMemoryEnabled;
@@ -88,7 +88,7 @@
      */
     BetaNode(final int id,
              final LeftTupleSource leftInput,
-             final ObjectSource rightInput,
+             final RightTupleSource rightInput,
              final BetaConstraints constraints) {
         super( id );
         this.leftInput = leftInput;
@@ -103,11 +103,11 @@
     public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
         constraints   = (BetaConstraints)in.readObject();
         leftInput   = (LeftTupleSource)in.readObject();
-        rightInput   = (ObjectSource)in.readObject();
+        rightInput   = (RightTupleSource)in.readObject();
         previousTupleSinkNode   = (LeftTupleSinkNode)in.readObject();
         nextTupleSinkNode   = (LeftTupleSinkNode)in.readObject();
-        previousObjectSinkNode   = (ObjectSinkNode)in.readObject();
-        nextObjectSinkNode   = (ObjectSinkNode)in.readObject();
+        previousObjectSinkNode   = (RightTupleSinkNode)in.readObject();
+        nextObjectSinkNode   = (RightTupleSinkNode)in.readObject();
         objectMemory    = in.readBoolean();
         tupleMemoryEnabled  = in.readBoolean();
         super.readExternal(in);
@@ -166,9 +166,9 @@
     }
 
     public ObjectTypeNode getObjectTypeNode() {
-        ObjectSource source = this.rightInput;
+        RightTupleSource source = this.rightInput;
         while ( !(source instanceof ObjectTypeNode) ) {
-            source = source.objectSource;
+            source = source.source;
         }
         return ((ObjectTypeNode) source);
     }
@@ -315,7 +315,7 @@
      * @return
      *      The next ObjectSinkNode
      */
-    public ObjectSinkNode getNextObjectSinkNode() {
+    public RightTupleSinkNode getNextRightTupleSinkNode() {
         return this.nextObjectSinkNode;
     }
 
@@ -324,7 +324,7 @@
      * @param next
      *      The next ObjectSinkNode
      */
-    public void setNextObjectSinkNode(final ObjectSinkNode next) {
+    public void setNextRightTupleSinkNode(final RightTupleSinkNode next) {
         this.nextObjectSinkNode = next;
     }
 
@@ -333,7 +333,7 @@
      * @return
      *      The previous ObjectSinkNode
      */
-    public ObjectSinkNode getPreviousObjectSinkNode() {
+    public RightTupleSinkNode getPreviousRightTupleSinkNode() {
         return this.previousObjectSinkNode;
     }
 
@@ -342,7 +342,7 @@
      * @param previous
      *      The previous ObjectSinkNode
      */
-    public void setPreviousObjectSinkNode(final ObjectSinkNode previous) {
+    public void setPreviousRightTupleSinkNode(final RightTupleSinkNode previous) {
         this.previousObjectSinkNode = previous;
     }
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/CollectNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/CollectNode.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/CollectNode.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -44,7 +44,7 @@
 public class CollectNode extends BetaNode
     implements
     LeftTupleSink,
-    ObjectSink {
+    RightTupleSink {
 
     private static final long                serialVersionUID = 400L;
 
@@ -76,7 +76,7 @@
      */
     public CollectNode(final int id,
                        final LeftTupleSource leftInput,
-                       final ObjectSource rightInput,
+                       final RightTupleSource rightInput,
                        final AlphaNodeFieldConstraint[] resultConstraints,
                        final BetaConstraints sourceBinder,
                        final BetaConstraints resultsBinder,
@@ -138,13 +138,13 @@
 
         // do not add tuple and result to the memory in sequential mode
         if ( this.tupleMemoryEnabled ) {
-            memory.betaMemory.getTupleMemory().add( leftTuple );
+            memory.betaMemory.getLeftTupleMemory().add( leftTuple );
             memory.betaMemory.getCreatedHandles().put( leftTuple,
                                                        colresult,
                                                        false );
         }
 
-        final Iterator it = memory.betaMemory.getFactHandleMemory().iterator( leftTuple );
+        final Iterator it = memory.betaMemory.getRightTupleMemory().iterator( leftTuple );
         this.constraints.updateFromTuple( memory.betaMemory.getContext(),
                                           workingMemory,
                                           leftTuple );
@@ -196,7 +196,7 @@
                              final InternalWorkingMemory workingMemory) {
 
         final CollectMemory memory = (CollectMemory) workingMemory.getNodeMemory( this );
-        if( memory.betaMemory.getTupleMemory().remove( leftTuple ) == null ) {
+        if( memory.betaMemory.getLeftTupleMemory().remove( leftTuple ) == null ) {
             return;
         }
         CollectResult result = (CollectResult) memory.betaMemory.getCreatedHandles().remove( leftTuple );
@@ -224,12 +224,12 @@
      *  2. For each matching tuple, call a modify tuple
      *
      */
-    public void assertObject(final InternalFactHandle handle,
+    public void assertObject(final InternalFactHandle factHandle,
                              final PropagationContext context,
                              final InternalWorkingMemory workingMemory) {
 
         final CollectMemory memory = (CollectMemory) workingMemory.getNodeMemory( this );
-        memory.betaMemory.getFactHandleMemory().add( handle );
+        memory.betaMemory.getRightTupleMemory().add( factHandle );
 
         if ( !this.tupleMemoryEnabled ) {
             // do nothing here, as we know there are no left tuples at this stage in sequential mode.
@@ -238,17 +238,17 @@
 
         this.constraints.updateFromFactHandle( memory.betaMemory.getContext(),
                                                workingMemory,
-                                               handle );
+                                               factHandle );
 
         // need to clone the tuples to avoid concurrent modification exceptions
-        Entry[] tuples = memory.betaMemory.getTupleMemory().toArray();
+        Entry[] tuples = memory.betaMemory.getLeftTupleMemory().toArray();
         for ( int i = 0; i < tuples.length; i++ ) {
             LeftTuple tuple = (LeftTuple) tuples[i];
             if ( this.constraints.isAllowedCachedRight( memory.betaMemory.getContext(),
                                                         tuple ) ) {
                 this.modifyTuple( true,
                                   tuple,
-                                  handle,
+                                  factHandle,
                                   context,
                                   workingMemory );
             }
@@ -268,7 +268,7 @@
                               final InternalWorkingMemory workingMemory) {
 
         final CollectMemory memory = (CollectMemory) workingMemory.getNodeMemory( this );
-        if ( !memory.betaMemory.getFactHandleMemory().remove( handle ) ) {
+        if ( !memory.betaMemory.getRightTupleMemory().remove( handle ) ) {
             return;
         }
 
@@ -277,7 +277,7 @@
                                                handle );
 
         // need to clone the tuples to avoid concurrent modification exceptions
-        Entry[] tuples = memory.betaMemory.getTupleMemory().toArray();
+        Entry[] tuples = memory.betaMemory.getLeftTupleMemory().toArray();
         for ( int i = 0; i < tuples.length; i++ ) {
             LeftTuple tuple = (LeftTuple) tuples[i];
             if ( this.constraints.isAllowedCachedRight( memory.betaMemory.getContext(),

Deleted: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/CompositeObjectSinkAdapter.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/CompositeObjectSinkAdapter.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/CompositeObjectSinkAdapter.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -1,806 +0,0 @@
-package org.drools.reteoo;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.io.Externalizable;
-
-import org.drools.base.ValueType;
-import org.drools.base.evaluators.Operator;
-import org.drools.common.InternalFactHandle;
-import org.drools.common.InternalWorkingMemory;
-import org.drools.rule.LiteralConstraint;
-import org.drools.spi.AlphaNodeFieldConstraint;
-import org.drools.spi.Evaluator;
-import org.drools.spi.Extractor;
-import org.drools.spi.FieldExtractor;
-import org.drools.spi.FieldValue;
-import org.drools.spi.PropagationContext;
-import org.drools.util.Iterator;
-import org.drools.util.LinkedList;
-import org.drools.util.LinkedListNode;
-import org.drools.util.ObjectHashMap;
-import org.drools.util.ObjectHashMap.ObjectEntry;
-
-public class CompositeObjectSinkAdapter
-    implements
-    ObjectSinkPropagator {
-
-    //    /** You can override this property via a system property (eg -Ddrools.hashThreshold=4) */
-    //    public static final String HASH_THRESHOLD_SYSTEM_PROPERTY = "drools.hashThreshold";
-    //
-    //    /** The threshold for when hashing kicks in */
-    //    public static final int    THRESHOLD_TO_HASH              = Integer.parseInt( System.getProperty( HASH_THRESHOLD_SYSTEM_PROPERTY,
-    //                                                                                                      "3" ) );
-
-    private static final long serialVersionUID = 400L;
-    ObjectSinkNodeList        otherSinks;
-    ObjectSinkNodeList        hashableSinks;
-
-    LinkedList                hashedFieldIndexes;
-
-    ObjectHashMap             hashedSinkMap;
-
-    private int         alphaNodeHashingThreshold;
-
-    public CompositeObjectSinkAdapter() {
-        this( 3 );
-    }
-
-    public CompositeObjectSinkAdapter(final int alphaNodeHashingThreshold) {
-        this.alphaNodeHashingThreshold = alphaNodeHashingThreshold;
-    }
-
-    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        otherSinks      = (ObjectSinkNodeList)in.readObject();
-        hashableSinks   = (ObjectSinkNodeList)in.readObject();
-        hashedFieldIndexes  = (LinkedList)in.readObject();
-        hashedSinkMap       = (ObjectHashMap)in.readObject();
-        alphaNodeHashingThreshold   = in.readInt();
-    }
-
-    public void writeExternal(ObjectOutput out) throws IOException {
-        out.writeObject(otherSinks);
-        out.writeObject(hashableSinks);
-        out.writeObject(hashedFieldIndexes);
-        out.writeObject(hashedSinkMap);
-        out.writeInt(alphaNodeHashingThreshold);
-    }
-
-    public void addObjectSink(final ObjectSink sink) {
-        if ( sink instanceof AlphaNode ) {
-            final AlphaNode alphaNode = (AlphaNode) sink;
-            final AlphaNodeFieldConstraint fieldConstraint = alphaNode.getConstraint();
-
-            if ( fieldConstraint instanceof LiteralConstraint ) {
-                final LiteralConstraint literalConstraint = (LiteralConstraint) fieldConstraint;
-                final Evaluator evaluator = literalConstraint.getEvaluator();
-
-                if ( evaluator.getOperator() == Operator.EQUAL && literalConstraint.getFieldExtractor().getValueType() != ValueType.OBJECT_TYPE ) {
-                    final int index = literalConstraint.getFieldExtractor().getIndex();
-                    final FieldIndex fieldIndex = registerFieldIndex( index,
-                                                                      literalConstraint.getFieldExtractor() );
-
-                    if ( fieldIndex.getCount() >= this.alphaNodeHashingThreshold && this.alphaNodeHashingThreshold != 0 ) {
-                        if ( !fieldIndex.isHashed() ) {
-                            hashSinks( fieldIndex );
-                        }
-                        final FieldValue value = literalConstraint.getField();
-                        // no need to check, we know  the sink  does not exist
-                        this.hashedSinkMap.put( new HashKey( index,
-                                                             value,
-                                                             fieldIndex.getFieldExtractor() ),
-                                                sink,
-                                                false );
-                    } else {
-                        if ( this.hashableSinks == null ) {
-                            this.hashableSinks = new ObjectSinkNodeList();
-                        }
-                        this.hashableSinks.add( (ObjectSinkNode) sink );
-                    }
-                    return;
-                }
-
-            }
-        }
-
-        if ( this.otherSinks == null ) {
-            this.otherSinks = new ObjectSinkNodeList();
-        }
-
-        this.otherSinks.add( (ObjectSinkNode) sink );
-    }
-
-    public void removeObjectSink(final ObjectSink sink) {
-        if ( sink instanceof AlphaNode ) {
-            final AlphaNode alphaNode = (AlphaNode) sink;
-            final AlphaNodeFieldConstraint fieldConstraint = alphaNode.getConstraint();
-
-            if ( fieldConstraint instanceof LiteralConstraint ) {
-                final LiteralConstraint literalConstraint = (LiteralConstraint) fieldConstraint;
-                final Evaluator evaluator = literalConstraint.getEvaluator();
-                final FieldValue value = literalConstraint.getField();
-
-                if ( evaluator.getOperator() == Operator.EQUAL && literalConstraint.getFieldExtractor().getValueType() != ValueType.OBJECT_TYPE ) {
-                    final int index = literalConstraint.getFieldExtractor().getIndex();
-                    final FieldIndex fieldIndex = unregisterFieldIndex( index );
-
-                    if ( fieldIndex.isHashed() ) {
-                        HashKey hashKey = new HashKey( index,
-                                                       value,
-                                                       fieldIndex.getFieldExtractor() );
-                        this.hashedSinkMap.remove( hashKey );
-                        if ( fieldIndex.getCount() <= this.alphaNodeHashingThreshold - 1 ) {
-                            // we have less than three so unhash
-                            unHashSinks( fieldIndex );
-                        }
-                    } else {
-                        this.hashableSinks.remove( (ObjectSinkNode) sink );
-                    }
-
-                    if ( this.hashableSinks != null && this.hashableSinks.isEmpty() ) {
-                        this.hashableSinks = null;
-                    }
-
-                    return;
-                }
-            }
-        }
-
-        this.otherSinks.remove( (ObjectSinkNode) sink );
-
-        if ( this.otherSinks.isEmpty() ) {
-            this.otherSinks = null;
-        }
-    }
-
-    public void hashSinks(final FieldIndex fieldIndex) {
-        final int index = fieldIndex.getIndex();
-
-        final List list = new ArrayList();
-
-        if ( this.hashedSinkMap == null ) {
-            this.hashedSinkMap = new ObjectHashMap();
-        }
-
-        for ( ObjectSinkNode sink = this.hashableSinks.getFirst(); sink != null; sink = sink.getNextObjectSinkNode() ) {
-            final AlphaNode alphaNode = (AlphaNode) sink;
-            final AlphaNodeFieldConstraint fieldConstraint = alphaNode.getConstraint();
-            final LiteralConstraint literalConstraint = (LiteralConstraint) fieldConstraint;
-            final Evaluator evaluator = literalConstraint.getEvaluator();
-            if ( evaluator.getOperator() == Operator.EQUAL && index == literalConstraint.getFieldExtractor().getIndex() ) {
-                final FieldValue value = literalConstraint.getField();
-                list.add( sink );
-                this.hashedSinkMap.put( new HashKey( index,
-                                                     value,
-                                                     fieldIndex.getFieldExtractor() ),
-                                        sink );
-            }
-        }
-
-        for ( final java.util.Iterator it = list.iterator(); it.hasNext(); ) {
-            final ObjectSinkNode sink = (ObjectSinkNode) it.next();
-            this.hashableSinks.remove( sink );
-        }
-
-        if ( this.hashableSinks.isEmpty() ) {
-            this.hashableSinks = null;
-        }
-
-        fieldIndex.setHashed( true );
-    }
-
-    public void unHashSinks(final FieldIndex fieldIndex) {
-        final int index = fieldIndex.getIndex();
-
-        final List sinks = new ArrayList();
-
-        //iterate twice as custom iterator is immutable
-        final Iterator mapIt = this.hashedSinkMap.newIterator();
-        for ( ObjectHashMap.ObjectEntry e = (ObjectHashMap.ObjectEntry) mapIt.next(); e != null; ) {
-
-            sinks.add( e.getValue() );
-            e = (ObjectHashMap.ObjectEntry) mapIt.next();
-        }
-
-        for ( final java.util.Iterator iter = sinks.iterator(); iter.hasNext(); ) {
-            final AlphaNode sink = (AlphaNode) iter.next();
-            final AlphaNode alphaNode = sink;
-            final AlphaNodeFieldConstraint fieldConstraint = alphaNode.getConstraint();
-            final LiteralConstraint literalConstraint = (LiteralConstraint) fieldConstraint;
-            final Evaluator evaluator = literalConstraint.getEvaluator();
-            if ( evaluator.getOperator() == Operator.EQUAL && index == literalConstraint.getFieldExtractor().getIndex() ) {
-                final FieldValue value = literalConstraint.getField();
-                if ( this.hashableSinks == null ) {
-                    this.hashableSinks = new ObjectSinkNodeList();
-                }
-                this.hashableSinks.add( sink );
-                this.hashedSinkMap.remove( new HashKey( index,
-                                                        value,
-                                                        fieldIndex.getFieldExtractor() ) );
-            };
-        }
-
-        if ( this.hashedSinkMap.isEmpty() ) {
-            this.hashedSinkMap = null;
-        }
-
-        fieldIndex.setHashed( false );
-    }
-
-    /**
-     * Returns a FieldIndex which Keeps a count on how many times a particular field is used with an equality check in the sinks.
-     * @param index
-     * @param fieldExtractor
-     * @return
-     */
-    private FieldIndex registerFieldIndex(final int index,
-                                          final FieldExtractor fieldExtractor) {
-        FieldIndex fieldIndex = null;
-
-        // is linkedlist null, if so create and add
-        if ( this.hashedFieldIndexes == null ) {
-            this.hashedFieldIndexes = new LinkedList();
-            fieldIndex = new FieldIndex( index,
-                                         fieldExtractor );
-            this.hashedFieldIndexes.add( fieldIndex );
-        }
-
-        // still null, so see if it already exists
-        if ( fieldIndex == null ) {
-            fieldIndex = findFieldIndex( index );
-        }
-
-        // doesn't exist so create it
-        if ( fieldIndex == null ) {
-            fieldIndex = new FieldIndex( index,
-                                         fieldExtractor );
-            this.hashedFieldIndexes.add( fieldIndex );
-        }
-
-        fieldIndex.increaseCounter();
-
-        return fieldIndex;
-    }
-
-    private FieldIndex unregisterFieldIndex(final int index) {
-        final FieldIndex fieldIndex = findFieldIndex( index );
-        fieldIndex.decreaseCounter();
-
-        // if the fieldcount is 0 then remove it from the linkedlist
-        if ( fieldIndex.getCount() == 0 ) {
-            this.hashedFieldIndexes.remove( fieldIndex );
-
-            // if the linkedlist is empty then null it
-            if ( this.hashedFieldIndexes.isEmpty() ) {
-                this.hashedFieldIndexes = null;
-            }
-        }
-
-        return fieldIndex;
-    }
-
-    private FieldIndex findFieldIndex(final int index) {
-        for ( FieldIndex node = (FieldIndex) this.hashedFieldIndexes.getFirst(); node != null; node = (FieldIndex) node.getNext() ) {
-            if ( node.getIndex() == index ) {
-                return node;
-            }
-        }
-
-        return null;
-    }
-
-    public void propagateAssertObject(final InternalFactHandle handle,
-                                      final PropagationContext context,
-                                      final InternalWorkingMemory workingMemory) {
-        final Object object = handle.getObject();
-
-        // Iterates t he FieldIndex collection, which tells you if particularly field is hashed or not
-        // if the field is hashed then it builds the hashkey to return the correct sink for the current objects slot's
-        // value, one object may have multiple fields indexed.
-        if ( this.hashedFieldIndexes != null ) {
-            // Iterate the FieldIndexes to see if any are hashed
-            for ( FieldIndex fieldIndex = (FieldIndex) this.hashedFieldIndexes.getFirst(); fieldIndex != null; fieldIndex = (FieldIndex) fieldIndex.getNext() ) {
-                if ( !fieldIndex.isHashed() ) {
-                    continue;
-                }
-                // this field is hashed so set the existing hashKey and see if there is a sink for it
-                final int index = fieldIndex.getIndex();
-                final FieldExtractor extractor = fieldIndex.getFieldExtactor();
-                HashKey hashKey = new HashKey( index,
-                                               object,
-                                               fieldIndex.getFieldExtractor() );
-                final ObjectSink sink = (ObjectSink) this.hashedSinkMap.get( hashKey );
-                if ( sink != null ) {
-                    // The sink exists so propagate
-                    sink.assertObject( handle,
-                                       context,
-                                       workingMemory );
-                }
-            }
-        }
-
-        // propagate unhashed
-        if ( this.hashableSinks != null ) {
-            for ( ObjectSinkNode sink = this.hashableSinks.getFirst(); sink != null; sink = sink.getNextObjectSinkNode() ) {
-                sink.assertObject( handle,
-                                   context,
-                                   workingMemory );
-            }
-        }
-
-        if ( this.otherSinks != null ) {
-            // propagate others
-            for ( ObjectSinkNode sink = this.otherSinks.getFirst(); sink != null; sink = sink.getNextObjectSinkNode() ) {
-                sink.assertObject( handle,
-                                   context,
-                                   workingMemory );
-            }
-        }
-
-    }
-
-    public void propagateRetractObject(final InternalFactHandle handle,
-                                       final PropagationContext context,
-                                       final InternalWorkingMemory workingMemory,
-                                       final boolean useHash) {
-        if ( this.hashedFieldIndexes != null ) {
-            if ( useHash && this.hashedSinkMap != null ) {
-                final Object object = handle.getObject();
-                // Iterate the FieldIndexes to see if any are hashed
-                for ( FieldIndex fieldIndex = (FieldIndex) this.hashedFieldIndexes.getFirst(); fieldIndex != null; fieldIndex = (FieldIndex) fieldIndex.getNext() ) {
-                    // this field is hashed so set the existing hashKey and see if there is a sink for it
-                    if ( !fieldIndex.isHashed() ) {
-                        continue;
-                    }
-
-                    final int index = fieldIndex.getIndex();
-                    HashKey hashKey = new HashKey( index,
-                                                   object,
-                                                   fieldIndex.getFieldExtactor() );
-                    final ObjectSink sink = (ObjectSink) this.hashedSinkMap.get( hashKey );
-                    if ( sink != null ) {
-                        // The sink exists so propagate
-                        sink.retractObject( handle,
-                                            context,
-                                            workingMemory );
-                    }
-                }
-            } else if ( this.hashedSinkMap != null ) {
-                final Iterator it = this.hashedSinkMap.newIterator();
-                for ( ObjectEntry entry = (ObjectEntry) it.next(); entry != null; entry = (ObjectEntry) it.next() ) {
-                    final ObjectSink sink = (ObjectSink) entry.getValue();
-                    sink.retractObject( handle,
-                                        context,
-                                        workingMemory );
-                }
-            }
-        }
-
-        if ( this.hashableSinks != null ) {
-            // we can't retrieve hashed sinks, as the field value might have changed, so we have to iterate and propagate to all hashed sinks
-            for ( ObjectSinkNode sink = this.hashableSinks.getFirst(); sink != null; sink = sink.getNextObjectSinkNode() ) {
-                sink.retractObject( handle,
-                                    context,
-                                    workingMemory );
-            }
-        }
-
-        if ( this.otherSinks != null ) {
-            // propagate others
-            for ( ObjectSinkNode sink = this.otherSinks.getFirst(); sink != null; sink = sink.getNextObjectSinkNode() ) {
-                sink.retractObject( handle,
-                                    context,
-                                    workingMemory );
-            }
-        }
-    }
-
-    public ObjectSink[] getSinks() {
-        final List list = new ArrayList();
-
-        if ( this.otherSinks != null ) {
-            for ( ObjectSinkNode sink = this.otherSinks.getFirst(); sink != null; sink = sink.getNextObjectSinkNode() ) {
-                list.add( sink );
-            }
-        }
-
-        if ( this.hashableSinks != null ) {
-            for ( ObjectSinkNode sink = this.hashableSinks.getFirst(); sink != null; sink = sink.getNextObjectSinkNode() ) {
-                list.add( sink );
-            }
-        }
-
-        if ( this.hashedSinkMap != null ) {
-            final Iterator it = this.hashedSinkMap.newIterator();
-            for ( ObjectEntry entry = (ObjectEntry) it.next(); entry != null; entry = (ObjectEntry) it.next() ) {
-                final ObjectSink sink = (ObjectSink) entry.getValue();
-                list.add( sink );
-            }
-        }
-
-        return (ObjectSink[]) list.toArray( new ObjectSink[list.size()] );
-    }
-
-    public int size() {
-        int size = 0;
-        size += ((this.otherSinks != null) ? this.otherSinks.size() : 0);
-        size += ((this.hashableSinks != null) ? this.hashableSinks.size() : 0);
-        size += ((this.hashedSinkMap != null) ? this.hashedSinkMap.size() : 0);
-        return size;
-    }
-
-    public static class HashKey
-        implements
-        Externalizable {
-        private static final long serialVersionUID = 400L;
-
-        private static final byte OBJECT           = 1;
-        private static final byte LONG             = 2;
-        private static final byte DOUBLE           = 3;
-        private static final byte BOOL             = 4;
-
-        private int               index;
-
-        private byte              type;
-        private Object            ovalue;
-        private long              lvalue;
-        private boolean           bvalue;
-        private double            dvalue;
-
-        private boolean           isNull;
-
-        private int               hashCode;
-
-        public HashKey() {
-        }
-
-        public HashKey(final int index,
-                       final FieldValue value,
-                       final Extractor extractor) {
-            this.setValue( index,
-                           extractor,
-                           value );
-        }
-
-        public HashKey(final int index,
-                       final Object value,
-                       final Extractor extractor) {
-            this.setValue( index,
-                           value,
-                           extractor );
-        }
-
-        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-            index   = in.readInt();
-            type    = in.readByte();
-            ovalue  = in.readObject();
-            lvalue  = in.readLong();
-            bvalue  = in.readBoolean();
-            dvalue  = in.readDouble();
-            isNull  = in.readBoolean();
-            hashCode   = in.readInt();
-        }
-
-        public void writeExternal(ObjectOutput out) throws IOException {
-            out.writeInt(index);
-            out.writeByte(type);
-            out.writeObject(ovalue);
-            out.writeLong(lvalue);
-            out.writeBoolean(bvalue);
-            out.writeDouble(dvalue);
-            out.writeBoolean(isNull);
-            out.writeInt(hashCode);
-        }
-
-        public int getIndex() {
-            return this.index;
-        }
-
-        public void setValue(final int index,
-                             final Object value,
-                             final Extractor extractor) {
-            this.index = index;
-            final ValueType vtype = extractor.getValueType();
-
-            isNull = extractor.isNullValue( null,
-                                            value );
-
-            if ( vtype.isBoolean() ) {
-                this.type = BOOL;
-                if ( !isNull ) {
-                    this.bvalue = extractor.getBooleanValue( null,
-                                                             value );
-                    this.setHashCode( this.bvalue ? 1231 : 1237 );
-                } else {
-                    this.setHashCode( 0 );
-                }
-            } else if ( vtype.isIntegerNumber() || vtype.isChar() ) {
-                this.type = LONG;
-                if ( !isNull ) {
-                    this.lvalue = extractor.getLongValue( null,
-                                                          value );
-                    this.setHashCode( (int) (this.lvalue ^ (this.lvalue >>> 32)) );
-                } else {
-                    this.setHashCode( 0 );
-                }
-            } else if ( vtype.isFloatNumber() ) {
-                this.type = DOUBLE;
-                if ( !isNull ) {
-                    this.dvalue = extractor.getDoubleValue( null,
-                                                            value );
-                    final long temp = Double.doubleToLongBits( this.dvalue );
-                    this.setHashCode( (int) (temp ^ (temp >>> 32)) );
-                } else {
-                    this.setHashCode( 0 );
-                }
-            } else {
-                this.type = OBJECT;
-                if ( !isNull ) {
-                    this.ovalue = extractor.getValue( null,
-                                                      value );
-                    this.setHashCode( this.ovalue != null ? this.ovalue.hashCode() : 0 );
-                } else {
-                    this.setHashCode( 0 );
-                }
-            }
-        }
-
-        public void setValue(final int index,
-                             final Extractor extractor,
-                             final FieldValue value) {
-            this.index = index;
-
-            this.isNull = value.isNull();
-            final ValueType vtype = extractor.getValueType();
-
-            if ( vtype.isBoolean() ) {
-                this.type = BOOL;
-                if ( !isNull ) {
-                    this.bvalue = value.getBooleanValue();
-                    this.setHashCode( this.bvalue ? 1231 : 1237 );
-                } else {
-                    this.setHashCode( 0 );
-                }
-            } else if ( vtype.isIntegerNumber() ) {
-                this.type = LONG;
-                if ( !isNull ) {
-                    this.lvalue = value.getLongValue();
-                    this.setHashCode( (int) (this.lvalue ^ (this.lvalue >>> 32)) );
-                } else {
-                    this.setHashCode( 0 );
-                }
-            } else if ( vtype.isFloatNumber() ) {
-                this.type = DOUBLE;
-                if ( !isNull ) {
-                    this.dvalue = value.getDoubleValue();
-                    final long temp = Double.doubleToLongBits( this.dvalue );
-                    this.setHashCode( (int) (temp ^ (temp >>> 32)) );
-                } else {
-                    this.setHashCode( 0 );
-                }
-            } else {
-                this.type = OBJECT;
-                if ( !isNull ) {
-                    this.ovalue = value.getValue();
-                    this.setHashCode( this.ovalue != null ? this.ovalue.hashCode() : 0 );
-                } else {
-                    this.setHashCode( 0 );
-                }
-            }
-        }
-
-        private void setHashCode(final int hashSeed) {
-            final int PRIME = 31;
-            int result = 1;
-            result = PRIME * result + hashSeed;
-            result = PRIME * result + this.index;
-            this.hashCode = result;
-        }
-
-        public boolean getBooleanValue() {
-            switch ( this.type ) {
-                case BOOL :
-                    return this.bvalue;
-                case OBJECT :
-                    if ( this.ovalue == null ) {
-                        return false;
-                    } else if ( this.ovalue instanceof Boolean ) {
-                        return ((Boolean) this.ovalue).booleanValue();
-                    } else if ( this.ovalue instanceof String ) {
-                        return Boolean.valueOf( (String) this.ovalue ).booleanValue();
-                    } else {
-                        throw new ClassCastException( "Can't convert " + this.ovalue.getClass() + " to a boolean value." );
-                    }
-                case LONG :
-                    throw new ClassCastException( "Can't convert long to a boolean value." );
-                case DOUBLE :
-                    throw new ClassCastException( "Can't convert double to a boolean value." );
-
-            }
-            return false;
-        }
-
-        public long getLongValue() {
-            switch ( this.type ) {
-                case BOOL :
-                    return this.bvalue ? 1 : 0;
-                case OBJECT :
-                    if ( this.ovalue == null ) {
-                        return 0;
-                    } else if ( this.ovalue instanceof Number ) {
-                        return ((Number) this.ovalue).longValue();
-                    } else if ( this.ovalue instanceof String ) {
-                        return Long.parseLong( (String) this.ovalue );
-                    } else {
-                        throw new ClassCastException( "Can't convert " + this.ovalue.getClass() + " to a long value." );
-                    }
-                case LONG :
-                    return this.lvalue;
-                case DOUBLE :
-                    return (long) this.dvalue;
-
-            }
-            return 0;
-        }
-
-        public double getDoubleValue() {
-            switch ( this.type ) {
-                case BOOL :
-                    return this.bvalue ? 1 : 0;
-                case OBJECT :
-                    if ( this.ovalue == null ) {
-                        return 0;
-                    } else if ( this.ovalue instanceof Number ) {
-                        return ((Number) this.ovalue).doubleValue();
-                    } else if ( this.ovalue instanceof String ) {
-                        return Double.parseDouble( (String) this.ovalue );
-                    } else {
-                        throw new ClassCastException( "Can't convert " + this.ovalue.getClass() + " to a double value." );
-                    }
-                case LONG :
-                    return this.lvalue;
-                case DOUBLE :
-                    return this.dvalue;
-            }
-            return 0;
-        }
-
-        public Object getObjectValue() {
-            switch ( this.type ) {
-                case BOOL :
-                    return this.bvalue ? Boolean.TRUE : Boolean.FALSE;
-                case OBJECT :
-                    return this.ovalue;
-                case LONG :
-                    return new Long( this.lvalue );
-                case DOUBLE :
-                    return new Double( this.dvalue );
-            }
-            return null;
-        }
-
-        public int hashCode() {
-            return this.hashCode;
-        }
-
-        public boolean equals(final Object object) {
-            final HashKey other = (HashKey) object;
-
-            if ( this.isNull ) {
-                return (other.isNull );
-            }
-
-            switch ( this.type ) {
-                case BOOL :
-                    return (this.index == other.index) && (this.bvalue == other.getBooleanValue());
-                case LONG :
-                    return (this.index == other.index) && (this.lvalue == other.getLongValue());
-                case DOUBLE :
-                    return (this.index == other.index) && (this.dvalue == other.getDoubleValue());
-                case OBJECT :
-                    final Object otherValue = other.getObjectValue();
-                    if ( (this.ovalue != null) && (this.ovalue instanceof Number) && (otherValue instanceof Number) ) {
-                        return (this.index == other.index) && (((Number) this.ovalue).doubleValue() == ((Number) otherValue).doubleValue());
-                    }
-                    return (this.index == other.index) && (this.ovalue == null ? otherValue == null : this.ovalue.equals( otherValue ));
-            }
-            return false;
-        }
-
-    }
-
-    public static class FieldIndex
-        implements
-        LinkedListNode {
-        private static final long serialVersionUID = 400L;
-        private int         index;
-        private FieldExtractor    fieldExtactor;
-
-        private int               count;
-
-        private boolean           hashed;
-
-        private LinkedListNode    previous;
-        private LinkedListNode    next;
-
-        public FieldIndex() {
-
-        }
-
-        public FieldIndex(final int index,
-                          final FieldExtractor fieldExtractor) {
-            this.index = index;
-            this.fieldExtactor = fieldExtractor;
-        }
-
-        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-            index   = in.readInt();
-            fieldExtactor  = (FieldExtractor)in.readObject();
-            count   = in.readInt();
-            hashed  = in.readBoolean();
-            previous    = (LinkedListNode)in.readObject();
-            next        = (LinkedListNode)in.readObject();
-        }
-
-        public void writeExternal(ObjectOutput out) throws IOException {
-            out.writeInt(index);
-            out.writeObject(fieldExtactor);
-            out.writeInt(count);
-            out.writeBoolean(hashed);
-            out.writeObject(previous);
-            out.writeObject(next);
-        }
-
-        public FieldExtractor getFieldExtractor() {
-            return this.fieldExtactor;
-        }
-
-        public int getIndex() {
-            return this.index;
-        }
-
-        public int getCount() {
-            return this.count;
-        }
-
-        public FieldExtractor getFieldExtactor() {
-            return this.fieldExtactor;
-        }
-
-        public boolean isHashed() {
-            return this.hashed;
-        }
-
-        public void setHashed(final boolean hashed) {
-            this.hashed = hashed;
-        }
-
-        public void increaseCounter() {
-            this.count++;
-        }
-
-        public void decreaseCounter() {
-            this.count--;
-        }
-
-        public LinkedListNode getNext() {
-            return this.next;
-        }
-
-        public LinkedListNode getPrevious() {
-            return this.previous;
-        }
-
-        public void setNext(final LinkedListNode next) {
-            this.next = next;
-
-        }
-
-        public void setPrevious(final LinkedListNode previous) {
-            this.previous = previous;
-        }
-    }
-}

Copied: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/CompositeRightTupleSinkAdapter.java (from rev 19131, labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/CompositeObjectSinkAdapter.java)
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/CompositeRightTupleSinkAdapter.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/CompositeRightTupleSinkAdapter.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -0,0 +1,750 @@
+package org.drools.reteoo;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.io.Externalizable;
+
+import org.drools.base.ValueType;
+import org.drools.base.evaluators.Operator;
+import org.drools.common.InternalFactHandle;
+import org.drools.common.InternalWorkingMemory;
+import org.drools.rule.LiteralConstraint;
+import org.drools.spi.AlphaNodeFieldConstraint;
+import org.drools.spi.Evaluator;
+import org.drools.spi.Extractor;
+import org.drools.spi.FieldExtractor;
+import org.drools.spi.FieldValue;
+import org.drools.spi.PropagationContext;
+import org.drools.util.Iterator;
+import org.drools.util.LinkedList;
+import org.drools.util.LinkedListNode;
+import org.drools.util.ObjectHashMap;
+import org.drools.util.ObjectHashMap.ObjectEntry;
+
+public class CompositeRightTupleSinkAdapter
+    implements
+    RightTupleSinkPropagator {
+
+    //    /** You can override this property via a system property (eg -Ddrools.hashThreshold=4) */
+    //    public static final String HASH_THRESHOLD_SYSTEM_PROPERTY = "drools.hashThreshold";
+    //
+    //    /** The threshold for when hashing kicks in */
+    //    public static final int    THRESHOLD_TO_HASH              = Integer.parseInt( System.getProperty( HASH_THRESHOLD_SYSTEM_PROPERTY,
+    //                                                                                                      "3" ) );
+
+    private static final long serialVersionUID = 400L;
+    RightTupleSinkNodeList        otherSinks;
+    RightTupleSinkNodeList        hashableSinks;
+
+    LinkedList                hashedFieldIndexes;
+
+    ObjectHashMap             hashedSinkMap;
+
+    private int         alphaNodeHashingThreshold;
+
+    public CompositeRightTupleSinkAdapter() {
+        this( 3 );
+    }
+
+    public CompositeRightTupleSinkAdapter(final int alphaNodeHashingThreshold) {
+        this.alphaNodeHashingThreshold = alphaNodeHashingThreshold;
+    }
+
+    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+        otherSinks      = (RightTupleSinkNodeList)in.readObject();
+        hashableSinks   = (RightTupleSinkNodeList)in.readObject();
+        hashedFieldIndexes  = (LinkedList)in.readObject();
+        hashedSinkMap       = (ObjectHashMap)in.readObject();
+        alphaNodeHashingThreshold   = in.readInt();
+    }
+
+    public void writeExternal(ObjectOutput out) throws IOException {
+        out.writeObject(otherSinks);
+        out.writeObject(hashableSinks);
+        out.writeObject(hashedFieldIndexes);
+        out.writeObject(hashedSinkMap);
+        out.writeInt(alphaNodeHashingThreshold);
+    }
+
+    public void addObjectSink(final RightTupleSink sink) {
+        if ( sink instanceof AlphaNode ) {
+            final AlphaNode alphaNode = (AlphaNode) sink;
+            final AlphaNodeFieldConstraint fieldConstraint = alphaNode.getConstraint();
+
+            if ( fieldConstraint instanceof LiteralConstraint ) {
+                final LiteralConstraint literalConstraint = (LiteralConstraint) fieldConstraint;
+                final Evaluator evaluator = literalConstraint.getEvaluator();
+
+                if ( evaluator.getOperator() == Operator.EQUAL && literalConstraint.getFieldExtractor().getValueType() != ValueType.OBJECT_TYPE ) {
+                    final int index = literalConstraint.getFieldExtractor().getIndex();
+                    final FieldIndex fieldIndex = registerFieldIndex( index,
+                                                                      literalConstraint.getFieldExtractor() );
+
+                    if ( fieldIndex.getCount() >= this.alphaNodeHashingThreshold && this.alphaNodeHashingThreshold != 0 ) {
+                        if ( !fieldIndex.isHashed() ) {
+                            hashSinks( fieldIndex );
+                        }
+                        final FieldValue value = literalConstraint.getField();
+                        // no need to check, we know  the sink  does not exist
+                        this.hashedSinkMap.put( new HashKey( index,
+                                                             value,
+                                                             fieldIndex.getFieldExtractor() ),
+                                                sink,
+                                                false );
+                    } else {
+                        if ( this.hashableSinks == null ) {
+                            this.hashableSinks = new RightTupleSinkNodeList();
+                        }
+                        this.hashableSinks.add( (RightTupleSinkNode) sink );
+                    }
+                    return;
+                }
+
+            }
+        }
+
+        if ( this.otherSinks == null ) {
+            this.otherSinks = new RightTupleSinkNodeList();
+        }
+
+        this.otherSinks.add( (RightTupleSinkNode) sink );
+    }
+
+    public void removeObjectSink(final RightTupleSink sink) {
+        if ( sink instanceof AlphaNode ) {
+            final AlphaNode alphaNode = (AlphaNode) sink;
+            final AlphaNodeFieldConstraint fieldConstraint = alphaNode.getConstraint();
+
+            if ( fieldConstraint instanceof LiteralConstraint ) {
+                final LiteralConstraint literalConstraint = (LiteralConstraint) fieldConstraint;
+                final Evaluator evaluator = literalConstraint.getEvaluator();
+                final FieldValue value = literalConstraint.getField();
+
+                if ( evaluator.getOperator() == Operator.EQUAL && literalConstraint.getFieldExtractor().getValueType() != ValueType.OBJECT_TYPE ) {
+                    final int index = literalConstraint.getFieldExtractor().getIndex();
+                    final FieldIndex fieldIndex = unregisterFieldIndex( index );
+
+                    if ( fieldIndex.isHashed() ) {
+                        HashKey hashKey = new HashKey( index,
+                                                       value,
+                                                       fieldIndex.getFieldExtractor() );
+                        this.hashedSinkMap.remove( hashKey );
+                        if ( fieldIndex.getCount() <= this.alphaNodeHashingThreshold - 1 ) {
+                            // we have less than three so unhash
+                            unHashSinks( fieldIndex );
+                        }
+                    } else {
+                        this.hashableSinks.remove( (RightTupleSinkNode) sink );
+                    }
+
+                    if ( this.hashableSinks != null && this.hashableSinks.isEmpty() ) {
+                        this.hashableSinks = null;
+                    }
+
+                    return;
+                }
+            }
+        }
+
+        this.otherSinks.remove( (RightTupleSinkNode) sink );
+
+        if ( this.otherSinks.isEmpty() ) {
+            this.otherSinks = null;
+        }
+    }
+
+    public void hashSinks(final FieldIndex fieldIndex) {
+        final int index = fieldIndex.getIndex();
+
+        final List list = new ArrayList();
+
+        if ( this.hashedSinkMap == null ) {
+            this.hashedSinkMap = new ObjectHashMap();
+        }
+
+        for ( RightTupleSinkNode sink = this.hashableSinks.getFirst(); sink != null; sink = sink.getNextRightTupleSinkNode() ) {
+            final AlphaNode alphaNode = (AlphaNode) sink;
+            final AlphaNodeFieldConstraint fieldConstraint = alphaNode.getConstraint();
+            final LiteralConstraint literalConstraint = (LiteralConstraint) fieldConstraint;
+            final Evaluator evaluator = literalConstraint.getEvaluator();
+            if ( evaluator.getOperator() == Operator.EQUAL && index == literalConstraint.getFieldExtractor().getIndex() ) {
+                final FieldValue value = literalConstraint.getField();
+                list.add( sink );
+                this.hashedSinkMap.put( new HashKey( index,
+                                                     value,
+                                                     fieldIndex.getFieldExtractor() ),
+                                        sink );
+            }
+        }
+
+        for ( final java.util.Iterator it = list.iterator(); it.hasNext(); ) {
+            final RightTupleSinkNode sink = (RightTupleSinkNode) it.next();
+            this.hashableSinks.remove( sink );
+        }
+
+        if ( this.hashableSinks.isEmpty() ) {
+            this.hashableSinks = null;
+        }
+
+        fieldIndex.setHashed( true );
+    }
+
+    public void unHashSinks(final FieldIndex fieldIndex) {
+        final int index = fieldIndex.getIndex();
+
+        final List sinks = new ArrayList();
+
+        //iterate twice as custom iterator is immutable
+        final Iterator mapIt = this.hashedSinkMap.newIterator();
+        for ( ObjectHashMap.ObjectEntry e = (ObjectHashMap.ObjectEntry) mapIt.next(); e != null; ) {
+
+            sinks.add( e.getValue() );
+            e = (ObjectHashMap.ObjectEntry) mapIt.next();
+        }
+
+        for ( final java.util.Iterator iter = sinks.iterator(); iter.hasNext(); ) {
+            final AlphaNode sink = (AlphaNode) iter.next();
+            final AlphaNode alphaNode = sink;
+            final AlphaNodeFieldConstraint fieldConstraint = alphaNode.getConstraint();
+            final LiteralConstraint literalConstraint = (LiteralConstraint) fieldConstraint;
+            final Evaluator evaluator = literalConstraint.getEvaluator();
+            if ( evaluator.getOperator() == Operator.EQUAL && index == literalConstraint.getFieldExtractor().getIndex() ) {
+                final FieldValue value = literalConstraint.getField();
+                if ( this.hashableSinks == null ) {
+                    this.hashableSinks = new RightTupleSinkNodeList();
+                }
+                this.hashableSinks.add( sink );
+                this.hashedSinkMap.remove( new HashKey( index,
+                                                        value,
+                                                        fieldIndex.getFieldExtractor() ) );
+            };
+        }
+
+        if ( this.hashedSinkMap.isEmpty() ) {
+            this.hashedSinkMap = null;
+        }
+
+        fieldIndex.setHashed( false );
+    }
+
+    /**
+     * Returns a FieldIndex which Keeps a count on how many times a particular field is used with an equality check in the sinks.
+     * @param index
+     * @param fieldExtractor
+     * @return
+     */
+    private FieldIndex registerFieldIndex(final int index,
+                                          final FieldExtractor fieldExtractor) {
+        FieldIndex fieldIndex = null;
+
+        // is linkedlist null, if so create and add
+        if ( this.hashedFieldIndexes == null ) {
+            this.hashedFieldIndexes = new LinkedList();
+            fieldIndex = new FieldIndex( index,
+                                         fieldExtractor );
+            this.hashedFieldIndexes.add( fieldIndex );
+        }
+
+        // still null, so see if it already exists
+        if ( fieldIndex == null ) {
+            fieldIndex = findFieldIndex( index );
+        }
+
+        // doesn't exist so create it
+        if ( fieldIndex == null ) {
+            fieldIndex = new FieldIndex( index,
+                                         fieldExtractor );
+            this.hashedFieldIndexes.add( fieldIndex );
+        }
+
+        fieldIndex.increaseCounter();
+
+        return fieldIndex;
+    }
+
+    private FieldIndex unregisterFieldIndex(final int index) {
+        final FieldIndex fieldIndex = findFieldIndex( index );
+        fieldIndex.decreaseCounter();
+
+        // if the fieldcount is 0 then remove it from the linkedlist
+        if ( fieldIndex.getCount() == 0 ) {
+            this.hashedFieldIndexes.remove( fieldIndex );
+
+            // if the linkedlist is empty then null it
+            if ( this.hashedFieldIndexes.isEmpty() ) {
+                this.hashedFieldIndexes = null;
+            }
+        }
+
+        return fieldIndex;
+    }
+
+    private FieldIndex findFieldIndex(final int index) {
+        for ( FieldIndex node = (FieldIndex) this.hashedFieldIndexes.getFirst(); node != null; node = (FieldIndex) node.getNext() ) {
+            if ( node.getIndex() == index ) {
+                return node;
+            }
+        }
+
+        return null;
+    }
+
+    public void propagateAssertFact(final InternalFactHandle factHandle,
+                                      final PropagationContext context,
+                                      final InternalWorkingMemory workingMemory) {
+        final Object object = factHandle.getObject();
+
+        // Iterates t he FieldIndex collection, which tells you if particularly field is hashed or not
+        // if the field is hashed then it builds the hashkey to return the correct sink for the current objects slot's
+        // value, one object may have multiple fields indexed.
+        if ( this.hashedFieldIndexes != null ) {
+            // Iterate the FieldIndexes to see if any are hashed
+            for ( FieldIndex fieldIndex = (FieldIndex) this.hashedFieldIndexes.getFirst(); fieldIndex != null; fieldIndex = (FieldIndex) fieldIndex.getNext() ) {
+                if ( !fieldIndex.isHashed() ) {
+                    continue;
+                }
+                // this field is hashed so set the existing hashKey and see if there is a sink for it
+                final int index = fieldIndex.getIndex();
+                final FieldExtractor extractor = fieldIndex.getFieldExtactor();
+                HashKey hashKey = new HashKey( index,
+                                               object,
+                                               fieldIndex.getFieldExtractor() );
+                final RightTupleSink sink = (RightTupleSink) this.hashedSinkMap.get( hashKey );
+                if ( sink != null ) {
+                    // The sink exists so propagate
+                    sink.assertObject( factHandle,
+                                       context,
+                                       workingMemory );
+                }
+            }
+        }
+
+        // propagate unhashed
+        if ( this.hashableSinks != null ) {
+            for ( RightTupleSinkNode sink = this.hashableSinks.getFirst(); sink != null; sink = sink.getNextRightTupleSinkNode() ) {
+                sink.assertObject( factHandle,
+                                   context,
+                                   workingMemory );
+            }
+        }
+
+        if ( this.otherSinks != null ) {
+            // propagate others
+            for ( RightTupleSinkNode sink = this.otherSinks.getFirst(); sink != null; sink = sink.getNextRightTupleSinkNode() ) {
+                sink.assertObject( factHandle,
+                                   context,
+                                   workingMemory );
+            }
+        }
+
+    }
+
+    public RightTupleSink[] getSinks() {
+        final List list = new ArrayList();
+
+        if ( this.otherSinks != null ) {
+            for ( RightTupleSinkNode sink = this.otherSinks.getFirst(); sink != null; sink = sink.getNextRightTupleSinkNode() ) {
+                list.add( sink );
+            }
+        }
+
+        if ( this.hashableSinks != null ) {
+            for ( RightTupleSinkNode sink = this.hashableSinks.getFirst(); sink != null; sink = sink.getNextRightTupleSinkNode() ) {
+                list.add( sink );
+            }
+        }
+
+        if ( this.hashedSinkMap != null ) {
+            final Iterator it = this.hashedSinkMap.newIterator();
+            for ( ObjectEntry entry = (ObjectEntry) it.next(); entry != null; entry = (ObjectEntry) it.next() ) {
+                final RightTupleSink sink = (RightTupleSink) entry.getValue();
+                list.add( sink );
+            }
+        }
+
+        return (RightTupleSink[]) list.toArray( new RightTupleSink[list.size()] );
+    }
+
+    public int size() {
+        int size = 0;
+        size += ((this.otherSinks != null) ? this.otherSinks.size() : 0);
+        size += ((this.hashableSinks != null) ? this.hashableSinks.size() : 0);
+        size += ((this.hashedSinkMap != null) ? this.hashedSinkMap.size() : 0);
+        return size;
+    }
+
+    public static class HashKey
+        implements
+        Externalizable {
+        private static final long serialVersionUID = 400L;
+
+        private static final byte OBJECT           = 1;
+        private static final byte LONG             = 2;
+        private static final byte DOUBLE           = 3;
+        private static final byte BOOL             = 4;
+
+        private int               index;
+
+        private byte              type;
+        private Object            ovalue;
+        private long              lvalue;
+        private boolean           bvalue;
+        private double            dvalue;
+
+        private boolean           isNull;
+
+        private int               hashCode;
+
+        public HashKey() {
+        }
+
+        public HashKey(final int index,
+                       final FieldValue value,
+                       final Extractor extractor) {
+            this.setValue( index,
+                           extractor,
+                           value );
+        }
+
+        public HashKey(final int index,
+                       final Object value,
+                       final Extractor extractor) {
+            this.setValue( index,
+                           value,
+                           extractor );
+        }
+
+        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+            index   = in.readInt();
+            type    = in.readByte();
+            ovalue  = in.readObject();
+            lvalue  = in.readLong();
+            bvalue  = in.readBoolean();
+            dvalue  = in.readDouble();
+            isNull  = in.readBoolean();
+            hashCode   = in.readInt();
+        }
+
+        public void writeExternal(ObjectOutput out) throws IOException {
+            out.writeInt(index);
+            out.writeByte(type);
+            out.writeObject(ovalue);
+            out.writeLong(lvalue);
+            out.writeBoolean(bvalue);
+            out.writeDouble(dvalue);
+            out.writeBoolean(isNull);
+            out.writeInt(hashCode);
+        }
+
+        public int getIndex() {
+            return this.index;
+        }
+
+        public void setValue(final int index,
+                             final Object value,
+                             final Extractor extractor) {
+            this.index = index;
+            final ValueType vtype = extractor.getValueType();
+
+            isNull = extractor.isNullValue( null,
+                                            value );
+
+            if ( vtype.isBoolean() ) {
+                this.type = BOOL;
+                if ( !isNull ) {
+                    this.bvalue = extractor.getBooleanValue( null,
+                                                             value );
+                    this.setHashCode( this.bvalue ? 1231 : 1237 );
+                } else {
+                    this.setHashCode( 0 );
+                }
+            } else if ( vtype.isIntegerNumber() || vtype.isChar() ) {
+                this.type = LONG;
+                if ( !isNull ) {
+                    this.lvalue = extractor.getLongValue( null,
+                                                          value );
+                    this.setHashCode( (int) (this.lvalue ^ (this.lvalue >>> 32)) );
+                } else {
+                    this.setHashCode( 0 );
+                }
+            } else if ( vtype.isFloatNumber() ) {
+                this.type = DOUBLE;
+                if ( !isNull ) {
+                    this.dvalue = extractor.getDoubleValue( null,
+                                                            value );
+                    final long temp = Double.doubleToLongBits( this.dvalue );
+                    this.setHashCode( (int) (temp ^ (temp >>> 32)) );
+                } else {
+                    this.setHashCode( 0 );
+                }
+            } else {
+                this.type = OBJECT;
+                if ( !isNull ) {
+                    this.ovalue = extractor.getValue( null,
+                                                      value );
+                    this.setHashCode( this.ovalue != null ? this.ovalue.hashCode() : 0 );
+                } else {
+                    this.setHashCode( 0 );
+                }
+            }
+        }
+
+        public void setValue(final int index,
+                             final Extractor extractor,
+                             final FieldValue value) {
+            this.index = index;
+
+            this.isNull = value.isNull();
+            final ValueType vtype = extractor.getValueType();
+
+            if ( vtype.isBoolean() ) {
+                this.type = BOOL;
+                if ( !isNull ) {
+                    this.bvalue = value.getBooleanValue();
+                    this.setHashCode( this.bvalue ? 1231 : 1237 );
+                } else {
+                    this.setHashCode( 0 );
+                }
+            } else if ( vtype.isIntegerNumber() ) {
+                this.type = LONG;
+                if ( !isNull ) {
+                    this.lvalue = value.getLongValue();
+                    this.setHashCode( (int) (this.lvalue ^ (this.lvalue >>> 32)) );
+                } else {
+                    this.setHashCode( 0 );
+                }
+            } else if ( vtype.isFloatNumber() ) {
+                this.type = DOUBLE;
+                if ( !isNull ) {
+                    this.dvalue = value.getDoubleValue();
+                    final long temp = Double.doubleToLongBits( this.dvalue );
+                    this.setHashCode( (int) (temp ^ (temp >>> 32)) );
+                } else {
+                    this.setHashCode( 0 );
+                }
+            } else {
+                this.type = OBJECT;
+                if ( !isNull ) {
+                    this.ovalue = value.getValue();
+                    this.setHashCode( this.ovalue != null ? this.ovalue.hashCode() : 0 );
+                } else {
+                    this.setHashCode( 0 );
+                }
+            }
+        }
+
+        private void setHashCode(final int hashSeed) {
+            final int PRIME = 31;
+            int result = 1;
+            result = PRIME * result + hashSeed;
+            result = PRIME * result + this.index;
+            this.hashCode = result;
+        }
+
+        public boolean getBooleanValue() {
+            switch ( this.type ) {
+                case BOOL :
+                    return this.bvalue;
+                case OBJECT :
+                    if ( this.ovalue == null ) {
+                        return false;
+                    } else if ( this.ovalue instanceof Boolean ) {
+                        return ((Boolean) this.ovalue).booleanValue();
+                    } else if ( this.ovalue instanceof String ) {
+                        return Boolean.valueOf( (String) this.ovalue ).booleanValue();
+                    } else {
+                        throw new ClassCastException( "Can't convert " + this.ovalue.getClass() + " to a boolean value." );
+                    }
+                case LONG :
+                    throw new ClassCastException( "Can't convert long to a boolean value." );
+                case DOUBLE :
+                    throw new ClassCastException( "Can't convert double to a boolean value." );
+
+            }
+            return false;
+        }
+
+        public long getLongValue() {
+            switch ( this.type ) {
+                case BOOL :
+                    return this.bvalue ? 1 : 0;
+                case OBJECT :
+                    if ( this.ovalue == null ) {
+                        return 0;
+                    } else if ( this.ovalue instanceof Number ) {
+                        return ((Number) this.ovalue).longValue();
+                    } else if ( this.ovalue instanceof String ) {
+                        return Long.parseLong( (String) this.ovalue );
+                    } else {
+                        throw new ClassCastException( "Can't convert " + this.ovalue.getClass() + " to a long value." );
+                    }
+                case LONG :
+                    return this.lvalue;
+                case DOUBLE :
+                    return (long) this.dvalue;
+
+            }
+            return 0;
+        }
+
+        public double getDoubleValue() {
+            switch ( this.type ) {
+                case BOOL :
+                    return this.bvalue ? 1 : 0;
+                case OBJECT :
+                    if ( this.ovalue == null ) {
+                        return 0;
+                    } else if ( this.ovalue instanceof Number ) {
+                        return ((Number) this.ovalue).doubleValue();
+                    } else if ( this.ovalue instanceof String ) {
+                        return Double.parseDouble( (String) this.ovalue );
+                    } else {
+                        throw new ClassCastException( "Can't convert " + this.ovalue.getClass() + " to a double value." );
+                    }
+                case LONG :
+                    return this.lvalue;
+                case DOUBLE :
+                    return this.dvalue;
+            }
+            return 0;
+        }
+
+        public Object getObjectValue() {
+            switch ( this.type ) {
+                case BOOL :
+                    return this.bvalue ? Boolean.TRUE : Boolean.FALSE;
+                case OBJECT :
+                    return this.ovalue;
+                case LONG :
+                    return new Long( this.lvalue );
+                case DOUBLE :
+                    return new Double( this.dvalue );
+            }
+            return null;
+        }
+
+        public int hashCode() {
+            return this.hashCode;
+        }
+
+        public boolean equals(final Object object) {
+            final HashKey other = (HashKey) object;
+
+            if ( this.isNull ) {
+                return (other.isNull );
+            }
+
+            switch ( this.type ) {
+                case BOOL :
+                    return (this.index == other.index) && (this.bvalue == other.getBooleanValue());
+                case LONG :
+                    return (this.index == other.index) && (this.lvalue == other.getLongValue());
+                case DOUBLE :
+                    return (this.index == other.index) && (this.dvalue == other.getDoubleValue());
+                case OBJECT :
+                    final Object otherValue = other.getObjectValue();
+                    if ( (this.ovalue != null) && (this.ovalue instanceof Number) && (otherValue instanceof Number) ) {
+                        return (this.index == other.index) && (((Number) this.ovalue).doubleValue() == ((Number) otherValue).doubleValue());
+                    }
+                    return (this.index == other.index) && (this.ovalue == null ? otherValue == null : this.ovalue.equals( otherValue ));
+            }
+            return false;
+        }
+
+    }
+
+    public static class FieldIndex
+        implements
+        LinkedListNode {
+        private static final long serialVersionUID = 400L;
+        private int         index;
+        private FieldExtractor    fieldExtactor;
+
+        private int               count;
+
+        private boolean           hashed;
+
+        private LinkedListNode    previous;
+        private LinkedListNode    next;
+
+        public FieldIndex() {
+
+        }
+
+        public FieldIndex(final int index,
+                          final FieldExtractor fieldExtractor) {
+            this.index = index;
+            this.fieldExtactor = fieldExtractor;
+        }
+
+        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+            index   = in.readInt();
+            fieldExtactor  = (FieldExtractor)in.readObject();
+            count   = in.readInt();
+            hashed  = in.readBoolean();
+            previous    = (LinkedListNode)in.readObject();
+            next        = (LinkedListNode)in.readObject();
+        }
+
+        public void writeExternal(ObjectOutput out) throws IOException {
+            out.writeInt(index);
+            out.writeObject(fieldExtactor);
+            out.writeInt(count);
+            out.writeBoolean(hashed);
+            out.writeObject(previous);
+            out.writeObject(next);
+        }
+
+        public FieldExtractor getFieldExtractor() {
+            return this.fieldExtactor;
+        }
+
+        public int getIndex() {
+            return this.index;
+        }
+
+        public int getCount() {
+            return this.count;
+        }
+
+        public FieldExtractor getFieldExtactor() {
+            return this.fieldExtactor;
+        }
+
+        public boolean isHashed() {
+            return this.hashed;
+        }
+
+        public void setHashed(final boolean hashed) {
+            this.hashed = hashed;
+        }
+
+        public void increaseCounter() {
+            this.count++;
+        }
+
+        public void decreaseCounter() {
+            this.count--;
+        }
+
+        public LinkedListNode getNext() {
+            return this.next;
+        }
+
+        public LinkedListNode getPrevious() {
+            return this.previous;
+        }
+
+        public void setNext(final LinkedListNode next) {
+            this.next = next;
+
+        }
+
+        public void setPrevious(final LinkedListNode previous) {
+            this.previous = previous;
+        }
+    }
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/CompositeTupleSinkAdapter.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/CompositeTupleSinkAdapter.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/CompositeTupleSinkAdapter.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -17,12 +17,13 @@
         this.sinks = new LeftTupleSinkNodeList();
     }
 
-    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        sinks   = (LeftTupleSinkNodeList)in.readObject();
+    public void readExternal(ObjectInput in) throws IOException,
+                                            ClassNotFoundException {
+        sinks = (LeftTupleSinkNodeList) in.readObject();
     }
 
     public void writeExternal(ObjectOutput out) throws IOException {
-        out.writeObject(sinks);
+        out.writeObject( sinks );
     }
 
     public void addTupleSink(final LeftTupleSink sink) {
@@ -34,67 +35,79 @@
     }
 
     public void propagateAssertLeftTuple(final LeftTuple tuple,
-                                     final InternalFactHandle handle,
-                                     final PropagationContext context,
-                                     final InternalWorkingMemory workingMemory) {
+                                         final RightTuple rightTuple,
+                                         final PropagationContext context,
+                                         final InternalWorkingMemory workingMemory) {
 
         for ( LeftTupleSinkNode sink = this.sinks.getFirst(); sink != null; sink = sink.getNextLeftTupleSinkNode() ) {
             sink.assertLeftTuple( new LeftTuple( tuple,
-                                             handle ),
-                              context,
-                              workingMemory );
+                                                 rightTuple,
+                                                 sink ),
+                                  context,
+                                  workingMemory );
         }
     }
 
     public void propagateAssertLeftTuple(final LeftTuple tuple,
-                                     final PropagationContext context,
-                                     final InternalWorkingMemory workingMemory) {
+                                         final PropagationContext context,
+                                         final InternalWorkingMemory workingMemory) {
         for ( LeftTupleSinkNode sink = this.sinks.getFirst(); sink != null; sink = sink.getNextLeftTupleSinkNode() ) {
-            sink.assertLeftTuple( new LeftTuple( tuple ),
-                              context,
-                              workingMemory );
+            sink.assertLeftTuple( new LeftTuple( tuple,
+                                                 sink ),
+                                  context,
+                                  workingMemory );
         }
     }
 
     public void propagateRetractLeftTuple(final LeftTuple tuple,
-                                      final InternalFactHandle handle,
-                                      final PropagationContext context,
-                                      final InternalWorkingMemory workingMemory) {
+                                          final RightTuple rightTuple,
+                                          final PropagationContext context,
+                                          final InternalWorkingMemory workingMemory) {
         for ( LeftTupleSinkNode sink = this.sinks.getFirst(); sink != null; sink = sink.getNextLeftTupleSinkNode() ) {
             sink.retractLeftTuple( new LeftTuple( tuple,
-                                              handle ),
-                               context,
-                               workingMemory );
+                                                  rightTuple,
+                                                  sink ),
+                                   context,
+                                   workingMemory );
         }
     }
 
     public void propagateRetractLeftTuple(final LeftTuple tuple,
-                                      final PropagationContext context,
-                                      final InternalWorkingMemory workingMemory) {
+                                          final PropagationContext context,
+                                          final InternalWorkingMemory workingMemory) {
         for ( LeftTupleSinkNode sink = this.sinks.getFirst(); sink != null; sink = sink.getNextLeftTupleSinkNode() ) {
-            sink.retractLeftTuple( new LeftTuple( tuple ),
-                               context,
-                               workingMemory );
+            sink.retractLeftTuple( new LeftTuple( tuple,
+                                                  sink ),
+                                   context,
+                                   workingMemory );
         }
     }
 
-    public void createAndPropagateAssertLeftTuple(final InternalFactHandle handle,
-                                              final PropagationContext context,
-                                              final InternalWorkingMemory workingMemory) {
-        for ( LeftTupleSinkNode sink = this.sinks.getFirst(); sink != null; sink = sink.getNextLeftTupleSinkNode() ) {
-            sink.assertLeftTuple( new LeftTuple( handle ),
-                              context,
-                              workingMemory );
+    public void propagateRetractRightTuple(final RightTuple rightTuple,
+                                           final PropagationContext context,
+                                           final InternalWorkingMemory workingMemory) {
+        LeftTuple child = rightTuple.getBetaChildren();
+        while ( child != null ) {
+            LeftTuple temp = child.getRightParentNext();
+            //child.unlinkFromParents();
+            child.getSink().retractLeftTuple( child,
+                                              context,
+                                              workingMemory );
+            child.unlinkFromLeftParent();
+            //child = child.getRightParentNext();
+            child = temp;
         }
+        rightTuple.setBetaChildren( null );
     }
 
-    public void createAndPropagateRetractLeftTuple(final InternalFactHandle handle,
-                                               final PropagationContext context,
-                                               final InternalWorkingMemory workingMemory) {
+    public void createAndPropagateAssertLeftTuple(final InternalFactHandle factHandle,
+                                                  final PropagationContext context,
+                                                  final InternalWorkingMemory workingMemory) {
         for ( LeftTupleSinkNode sink = this.sinks.getFirst(); sink != null; sink = sink.getNextLeftTupleSinkNode() ) {
-            sink.retractLeftTuple( new LeftTuple( handle ),
-                               context,
-                               workingMemory );
+            sink.assertLeftTuple( new LeftTuple( factHandle,
+                                                 sink ),
+                                  context,
+                                  workingMemory );
         }
     }
 

Copied: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EmptyLeftTupleSinkAdapter.java (from rev 19176, labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EmptyTupleSinkAdapter.java)
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EmptyLeftTupleSinkAdapter.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EmptyLeftTupleSinkAdapter.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -0,0 +1,67 @@
+package org.drools.reteoo;
+
+import org.drools.common.InternalFactHandle;
+import org.drools.common.InternalWorkingMemory;
+import org.drools.spi.PropagationContext;
+
+import java.io.ObjectOutput;
+import java.io.IOException;
+import java.io.ObjectInput;
+
+public class EmptyLeftTupleSinkAdapter
+    implements
+    LeftTupleSinkPropagator {
+
+    private static final EmptyLeftTupleSinkAdapter instance = new EmptyLeftTupleSinkAdapter();
+
+    public static final EmptyLeftTupleSinkAdapter getInstance() {
+        return instance;
+    }
+
+    private EmptyLeftTupleSinkAdapter() {
+    }
+
+    public void propagateAssertLeftTuple(final LeftTuple leftTuple,
+                                     final RightTuple rightTuple,
+                                     final PropagationContext context,
+                                     final InternalWorkingMemory workingMemory) {
+    }
+
+    public void propagateAssertLeftTuple(final LeftTuple tuple,
+                                     final PropagationContext context,
+                                     final InternalWorkingMemory workingMemory) {
+    }
+
+    public void propagateRetractLeftTuple(final LeftTuple tuple,
+                                      final PropagationContext context,
+                                      final InternalWorkingMemory workingMemory) {
+    }
+
+    public void createAndPropagateAssertLeftTuple(final InternalFactHandle factHandle,
+                                              final PropagationContext context,
+                                              final InternalWorkingMemory workingMemory) {
+    }
+    
+    public void propagateRetractRightTuple(RightTuple tuple,
+                                           PropagationContext context,
+                                           InternalWorkingMemory workingMemory) {
+    }
+
+    public void readExternal(ObjectInput in) throws IOException,
+                                            ClassNotFoundException {
+    }
+
+    public void writeExternal(ObjectOutput out) throws IOException {
+    }
+    
+
+    public LeftTupleSink[] getSinks() {
+        return new LeftTupleSink[]{};
+    }
+
+    public int size() {
+        return 0;
+    }
+    
+
+}

Deleted: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EmptyObjectSinkAdapter.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EmptyObjectSinkAdapter.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EmptyObjectSinkAdapter.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -1,58 +0,0 @@
-package org.drools.reteoo;
-
-import org.drools.common.InternalFactHandle;
-import org.drools.common.InternalWorkingMemory;
-import org.drools.spi.PropagationContext;
-
-import java.io.ObjectOutput;
-import java.io.IOException;
-import java.io.ObjectInput;
-
-public class EmptyObjectSinkAdapter
-    implements
-    ObjectSinkPropagator {
-
-    private static final long serialVersionUID = -631743913176779720L;
-
-    private static final EmptyObjectSinkAdapter instance = new EmptyObjectSinkAdapter();
-
-    private static final ObjectSink[] SINK_LIST = new ObjectSink[0];
-
-    public static EmptyObjectSinkAdapter getInstance() {
-        return instance;
-    }
-
-    public EmptyObjectSinkAdapter() {
-    }
-
-    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-    }
-
-    public void writeExternal(ObjectOutput out) throws IOException {
-    }
-
-    public void propagateAssertObject(final InternalFactHandle handle,
-                                      final PropagationContext context,
-                                      final InternalWorkingMemory workingMemory) {
-
-    }
-
-    public void propagateRetractObject(final InternalFactHandle handle,
-                                       final PropagationContext context,
-                                       final InternalWorkingMemory workingMemory,
-                                       final boolean useHash) {
-    }
-
-    public ObjectSink[] getSinks() {
-        return SINK_LIST;
-    }
-
-    public int size() {
-        return 0;
-    }
-
-    public boolean equals(Object obj) {
-        return obj instanceof EmptyObjectSinkAdapter;
-    }
-
-}

Copied: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EmptyRightTupleSinkAdapter.java (from rev 19131, labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EmptyObjectSinkAdapter.java)
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EmptyRightTupleSinkAdapter.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EmptyRightTupleSinkAdapter.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -0,0 +1,58 @@
+package org.drools.reteoo;
+
+import org.drools.common.InternalFactHandle;
+import org.drools.common.InternalWorkingMemory;
+import org.drools.spi.PropagationContext;
+
+import java.io.ObjectOutput;
+import java.io.IOException;
+import java.io.ObjectInput;
+
+public class EmptyRightTupleSinkAdapter
+    implements
+    RightTupleSinkPropagator {
+
+    private static final long serialVersionUID = -631743913176779720L;
+
+    private static final EmptyRightTupleSinkAdapter instance = new EmptyRightTupleSinkAdapter();
+
+    private static final RightTupleSink[] SINK_LIST = new RightTupleSink[0];
+
+    public static EmptyRightTupleSinkAdapter getInstance() {
+        return instance;
+    }
+
+    public EmptyRightTupleSinkAdapter() {
+    }
+
+    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+    }
+
+    public void writeExternal(ObjectOutput out) throws IOException {
+    }
+
+    public void propagateAssertFact(final InternalFactHandle factHandle,
+                                      final PropagationContext context,
+                                      final InternalWorkingMemory workingMemory) {
+
+    }
+
+    public void propagateRetractObject(final InternalFactHandle handle,
+                                       final PropagationContext context,
+                                       final InternalWorkingMemory workingMemory,
+                                       final boolean useHash) {
+    }
+
+    public RightTupleSink[] getSinks() {
+        return SINK_LIST;
+    }
+
+    public int size() {
+        return 0;
+    }
+
+    public boolean equals(Object obj) {
+        return obj instanceof EmptyRightTupleSinkAdapter;
+    }
+
+}

Deleted: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EmptyTupleSinkAdapter.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EmptyTupleSinkAdapter.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EmptyTupleSinkAdapter.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -1,69 +0,0 @@
-package org.drools.reteoo;
-
-import org.drools.common.InternalFactHandle;
-import org.drools.common.InternalWorkingMemory;
-import org.drools.spi.PropagationContext;
-
-import java.io.ObjectOutput;
-import java.io.IOException;
-import java.io.ObjectInput;
-
-public class EmptyTupleSinkAdapter
-    implements
-    LeftTupleSinkPropagator {
-
-    private static final EmptyTupleSinkAdapter instance = new EmptyTupleSinkAdapter();
-
-    public static final EmptyTupleSinkAdapter getInstance() {
-        return instance;
-    }
-
-    public EmptyTupleSinkAdapter() {
-    }
-
-    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-    }
-
-    public void writeExternal(ObjectOutput out) throws IOException {
-    }
-    
-    public void propagateAssertLeftTuple(final LeftTuple tuple,
-                                     final InternalFactHandle handle,
-                                     final PropagationContext context,
-                                     final InternalWorkingMemory workingMemory) {
-    }
-
-    public void propagateAssertLeftTuple(final LeftTuple tuple,
-                                     final PropagationContext context,
-                                     final InternalWorkingMemory workingMemory) {
-    }
-
-    public void propagateRetractLeftTuple(final LeftTuple tuple,
-                                      final InternalFactHandle handle,
-                                      final PropagationContext context,
-                                      final InternalWorkingMemory workingMemory) {
-    }
-
-    public void propagateRetractLeftTuple(final LeftTuple tuple,
-                                      final PropagationContext context,
-                                      final InternalWorkingMemory workingMemory) {
-    }
-
-    public void createAndPropagateAssertLeftTuple(final InternalFactHandle handle,
-                                              final PropagationContext context,
-                                              final InternalWorkingMemory workingMemory) {
-    }
-
-    public void createAndPropagateRetractLeftTuple(final InternalFactHandle handle,
-                                               final PropagationContext context,
-                                               final InternalWorkingMemory workingMemory) {
-    }
-
-    public LeftTupleSink[] getSinks() {
-        return new LeftTupleSink[]{};
-    }
-
-    public int size() {
-        return 0;
-    }
-}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EntryPointNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EntryPointNode.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EntryPointNode.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -54,10 +54,10 @@
  *
  * @author <a href="mailto:tirelli at post.com">Edson Tirelli</a>
  */
-public class EntryPointNode extends ObjectSource
+public class EntryPointNode extends RightTupleSource
     implements
     Externalizable,
-    ObjectSink {
+    RightTupleSink {
     // ------------------------------------------------------------
     // Instance members
     // ------------------------------------------------------------
@@ -82,7 +82,7 @@
     }
 
     public EntryPointNode(final int id,
-                          final ObjectSource objectSource,
+                          final RightTupleSource objectSource,
                           final BuildContext context) {
         this( id,
               objectSource,
@@ -90,7 +90,7 @@
     }
 
     public EntryPointNode(final int id,
-                          final ObjectSource objectSource,
+                          final RightTupleSource objectSource,
                           final EntryPoint entryPoint) {
         super( id,
                objectSource,
@@ -151,14 +151,14 @@
      * of matching <code>ObjectTypdeNode</code>s asserting the Fact. If the cache does not
      * exist it first iterates and builds the cache.
      *
-     * @param handle
+     * @param factHandle
      *            The FactHandle of the fact to assert
      * @param context
      *            The <code>PropagationContext</code> of the <code>WorkingMemory</code> action
      * @param workingMemory
      *            The working memory session.
      */
-    public void assertObject(final InternalFactHandle handle,
+    public void assertObject(final InternalFactHandle factHandle,
                              final PropagationContext context,
                              final InternalWorkingMemory workingMemory) {
         // do nothing, dummy method to impl the interface
@@ -208,19 +208,19 @@
      *            <code>Objects</code>. Rete only accepts <code>ObjectTypeNode</code>s
      *            as parameters to this method, though.
      */
-    protected void addObjectSink(final ObjectSink objectSink) {
+    protected void addObjectSink(final RightTupleSink objectSink) {
         final ObjectTypeNode node = (ObjectTypeNode) objectSink;
         this.objectTypeNodes.put( node.getObjectType(),
                                   node );
     }
 
-    protected void removeObjectSink(final ObjectSink objectSink) {
+    protected void removeObjectSink(final RightTupleSink objectSink) {
         final ObjectTypeNode node = (ObjectTypeNode) objectSink;
         this.objectTypeNodes.remove( node.getObjectType() );
     }
 
     public void attach() {
-        this.objectSource.addObjectSink( this );
+        this.source.addObjectSink( this );
     }
 
     public void attach(final InternalWorkingMemory[] workingMemories) {
@@ -232,7 +232,7 @@
                                                                                       PropagationContext.RULE_ADDITION,
                                                                                       null,
                                                                                       null );
-            this.objectSource.updateSink( this,
+            this.source.updateSink( this,
                                           propagationContext,
                                           workingMemory );
         }
@@ -271,7 +271,7 @@
         return this.entryPoint.equals( other.entryPoint );
     }
 
-    public void updateSink(final ObjectSink sink,
+    public void updateSink(final RightTupleSink sink,
                            final PropagationContext context,
                            final InternalWorkingMemory workingMemory) {
         // JBRULES-612: the cache MUST be invalidated when a new node type is added to the network, so iterate and reset all caches.

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ExistsNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ExistsNode.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ExistsNode.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -67,7 +67,7 @@
      */
     public ExistsNode(final int id,
                       final LeftTupleSource leftInput,
-                      final ObjectSource rightInput,
+                      final RightTupleSource rightInput,
                       final BetaConstraints joinNodeBinder,
                       final BuildContext context) {
         super( id,
@@ -95,10 +95,10 @@
         final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
 
         if ( this.tupleMemoryEnabled ) {
-            memory.getTupleMemory().add( leftTuple );
+            memory.getLeftTupleMemory().add( leftTuple );
         }
 
-        final Iterator it = memory.getFactHandleMemory().iterator( leftTuple );
+        final Iterator it = memory.getRightTupleMemory().iterator( leftTuple );
         this.constraints.updateFromTuple( memory.getContext(),
                                           workingMemory,
                                           leftTuple );
@@ -125,32 +125,32 @@
      * matches any left ReteTuple's that had no matches before, propagate
      * tuple as an assertion.
      *
-     * @param handle
+     * @param factHandle
      *            The <code>FactHandleImpl</code> being asserted.
      * @param context
      *            The <code>PropagationContext</code>
      * @param workingMemory
      *            The working memory session.
      */
-    public void assertObject(final InternalFactHandle handle,
+    public void assertObject(final InternalFactHandle factHandle,
                              final PropagationContext context,
                              final InternalWorkingMemory workingMemory) {
         final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
-        memory.getFactHandleMemory().add( handle );
+        memory.getRightTupleMemory().add( factHandle );
 
         if ( !this.tupleMemoryEnabled ) {
             // do nothing here, as we know there are no left tuples at this stage in sequential mode.
             return;
         }
 
-        final Iterator it = memory.getTupleMemory().iterator( handle );
+        final Iterator it = memory.getLeftTupleMemory().iterator( factHandle );
         this.constraints.updateFromFactHandle( memory.getContext(),
                                                workingMemory,
-                                               handle );
+                                               factHandle );
         for ( LeftTuple tuple = (LeftTuple) it.next(); tuple != null; tuple = (LeftTuple) it.next() ) {
             if ( this.constraints.isAllowedCachedRight( memory.getContext(),
                                                         tuple ) && tuple.getMatch() == null) {
-                    tuple.setMatch( handle );
+                    tuple.setMatch( factHandle );
                     this.sink.propagateAssertLeftTuple( tuple,
                                                      context,
                                                      workingMemory );
@@ -176,11 +176,11 @@
                               final PropagationContext context,
                               final InternalWorkingMemory workingMemory) {
         final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
-        if ( !memory.getFactHandleMemory().remove( handle ) ) {
+        if ( !memory.getRightTupleMemory().remove( handle ) ) {
             return;
         }
 
-        final Iterator it = memory.getTupleMemory().iterator( handle );
+        final Iterator it = memory.getLeftTupleMemory().iterator( handle );
         this.constraints.updateFromFactHandle( memory.getContext(),
                                                workingMemory,
                                                handle );
@@ -192,7 +192,7 @@
                     tuple.setMatch( null );
 
                     // find next match, remember it and break.
-                    final Iterator tupleIt = memory.getFactHandleMemory().iterator( tuple );
+                    final Iterator tupleIt = memory.getRightTupleMemory().iterator( tuple );
                     this.constraints.updateFromTuple( memory.getContext(),
                                                       workingMemory, tuple );
 
@@ -238,7 +238,7 @@
         final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
 
         // Must use the tuple in memory as it has the tuple matches count
-        final LeftTuple tuple = memory.getTupleMemory().remove( leftTuple );
+        final LeftTuple tuple = memory.getLeftTupleMemory().remove( leftTuple );
         if ( tuple == null ) {
             return;
         }
@@ -259,7 +259,7 @@
                            final InternalWorkingMemory workingMemory) {
         final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
 
-        final Iterator tupleIter = memory.getTupleMemory().iterator();
+        final Iterator tupleIter = memory.getLeftTupleMemory().iterator();
         for ( LeftTuple tuple = (LeftTuple) tupleIter.next(); tuple != null; tuple = (LeftTuple) tupleIter.next() ) {
             if ( tuple.getMatch() != null ) {
                 sink.assertLeftTuple( new LeftTuple( tuple ),
@@ -270,9 +270,9 @@
     }
 
     public String toString() {
-        ObjectSource source = this.rightInput;
+        RightTupleSource source = this.rightInput;
         while ( source.getClass() != ObjectTypeNode.class ) {
-            source = source.objectSource;
+            source = source.source;
         }
 
         return "[ExistsNode - " + ((ObjectTypeNode) source).getObjectType() + "]";

Deleted: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/FactHandleMemory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/FactHandleMemory.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/FactHandleMemory.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -1,27 +0,0 @@
-package org.drools.reteoo;
-
-import org.drools.common.InternalFactHandle;
-import org.drools.util.Entry;
-import org.drools.util.Iterator;
-
-public interface FactHandleMemory {
-    public Iterator iterator();
-
-    public Iterator iterator(LeftTuple tuple);
-
-    public boolean add(InternalFactHandle handle,
-                       boolean checkExists);
-
-    public boolean add(InternalFactHandle handle);
-
-    public boolean remove(InternalFactHandle handle);
-
-    public boolean contains(InternalFactHandle handle);
-
-    public boolean isIndexed();
-
-    public int size();
-
-//    public Entry[] getTable();
-
-}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/FromNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/FromNode.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/FromNode.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -86,7 +86,7 @@
                             final InternalWorkingMemory workingMemory) {
         final FromMemory memory = (FromMemory) workingMemory.getNodeMemory( this );
 
-        memory.betaMemory.getTupleMemory().add( leftTuple );
+        memory.betaMemory.getLeftTupleMemory().add( leftTuple );
         final LinkedList list = new LinkedList();
         this.betaConstraints.updateFromTuple( memory.betaMemory.getContext(),
                                               workingMemory,
@@ -143,7 +143,7 @@
                              final InternalWorkingMemory workingMemory) {
 
         final FromMemory memory = (FromMemory) workingMemory.getNodeMemory( this );
-        final LeftTuple tuple = memory.betaMemory.getTupleMemory().remove( leftTuple );
+        final LeftTuple tuple = memory.betaMemory.getLeftTupleMemory().remove( leftTuple );
 
         if ( tuple == null ) {
             return;
@@ -215,7 +215,7 @@
 
         final FromMemory memory = (FromMemory) workingMemory.getNodeMemory( this );
 
-        final Iterator tupleIter = memory.betaMemory.getTupleMemory().iterator();
+        final Iterator tupleIter = memory.betaMemory.getLeftTupleMemory().iterator();
         for ( LeftTuple tuple = (LeftTuple) tupleIter.next(); tuple != null; tuple = (LeftTuple) tupleIter.next() ) {
             final LinkedList list = (LinkedList) memory.betaMemory.getCreatedHandles().remove( tuple );
             if ( list == null ) {

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/JoinNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/JoinNode.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/JoinNode.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -60,12 +60,12 @@
     private static final long serialVersionUID = 400L;
 
     public JoinNode() {
-        
+
     }
 
     public JoinNode(final int id,
                     final LeftTupleSource leftInput,
-                    final ObjectSource rightInput,
+                    final RightTupleSource rightInput,
                     final BetaConstraints binder,
                     final BuildContext context) {
         super( id,
@@ -94,26 +94,25 @@
      *            The working memory seesion.
      */
     public void assertLeftTuple(final LeftTuple leftTuple,
-                            final PropagationContext context,
-                            final InternalWorkingMemory workingMemory) {
+                                final PropagationContext context,
+                                final InternalWorkingMemory workingMemory) {
         final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
 
         if ( this.tupleMemoryEnabled ) {
-            memory.getTupleMemory().add( leftTuple );
+            memory.getLeftTupleMemory().add( leftTuple );
         }
 
-        final Iterator it = memory.getFactHandleMemory().iterator( leftTuple );
         this.constraints.updateFromTuple( memory.getContext(),
                                           workingMemory,
                                           leftTuple );
-        for ( FactEntry entry = (FactEntry) it.next(); entry != null; entry = (FactEntry) it.next() ) {
-            final InternalFactHandle handle = entry.getFactHandle();
+        for ( RightTuple rightTuple = memory.getRightTupleMemory().getFirst( leftTuple ); rightTuple != null; rightTuple = (RightTuple) rightTuple.getNext() ) {
+            final InternalFactHandle handle = rightTuple.getFactHandle();
             if ( this.constraints.isAllowedCachedLeft( memory.getContext(),
                                                        handle ) ) {
                 this.sink.propagateAssertLeftTuple( leftTuple,
-                                                handle,
-                                                context,
-                                                workingMemory );
+                                                    rightTuple,
+                                                    context,
+                                                    workingMemory );
             }
         }
 
@@ -131,35 +130,37 @@
      * @see LeftTupleSink
      * @see TupleMatch
      *
-     * @param handle
+     * @param factHandle
      *            The <code>FactHandleImpl</code> being asserted.
      * @param context
      *            The <code>PropagationContext</code>
      * @param workingMemory
      *            The working memory seesion.
      */
-    public void assertObject(final InternalFactHandle handle,
-                             final PropagationContext context,
-                             final InternalWorkingMemory workingMemory) {
+    public void assertObject(final InternalFactHandle factHandle,
+                           final PropagationContext context,
+                           final InternalWorkingMemory workingMemory) {
         final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
+        
+        RightTuple rightTuple = new RightTuple( factHandle,
+                                                this );        
 
-        memory.getFactHandleMemory().add( handle );
-        if ( ! this.tupleMemoryEnabled ) {
+        memory.getRightTupleMemory().add( rightTuple );
+        if ( !this.tupleMemoryEnabled ) {
             // do nothing here, as we know there are no left tuples at this stage in sequential mode.
             return;
         }
 
-        final Iterator it = memory.getTupleMemory().iterator( handle );
         this.constraints.updateFromFactHandle( memory.getContext(),
                                                workingMemory,
-                                               handle );
-        for ( LeftTuple leftTuple = (LeftTuple) it.next(); leftTuple != null; leftTuple = (LeftTuple) it.next() ) {
+                                               factHandle );
+        for ( LeftTuple leftTuple = memory.getLeftTupleMemory().getFirst( rightTuple ); leftTuple != null; leftTuple = (LeftTuple) leftTuple.getNext() ) {
             if ( this.constraints.isAllowedCachedRight( memory.getContext(),
                                                         leftTuple ) ) {
                 this.sink.propagateAssertLeftTuple( leftTuple,
-                                                handle,
-                                                context,
-                                                workingMemory );
+                                                    rightTuple,
+                                                    context,
+                                                    workingMemory );
             }
         }
         this.constraints.resetFactHandle( memory.getContext() );
@@ -176,29 +177,17 @@
      * @param workingMemory
      *            The working memory seesion.
      */
-    public void retractObject(final InternalFactHandle handle,
-                              final PropagationContext context,
-                              final InternalWorkingMemory workingMemory) {
+    public void retractRightTuple(final RightTuple rightTuple,
+                            final PropagationContext context,
+                            final InternalWorkingMemory workingMemory) {
         final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
-        if ( !memory.getFactHandleMemory().remove( handle ) ) {
-            return;
+        memory.getRightTupleMemory().remove( rightTuple );
+        
+        if ( rightTuple.getBetaChildren() != null ) {
+            this.sink.propagateRetractRightTuple( rightTuple,
+                                                  context,
+                                                  workingMemory );
         }
-
-        final Iterator it = memory.getTupleMemory().iterator( handle );
-        this.constraints.updateFromFactHandle( memory.getContext(),
-                                               workingMemory,
-                                               handle );
-        for ( LeftTuple leftTuple = (LeftTuple) it.next(); leftTuple != null; leftTuple = (LeftTuple) it.next() ) {
-            if ( this.constraints.isAllowedCachedRight( memory.getContext(),
-                                                        leftTuple ) ) {
-                this.sink.propagateRetractLeftTuple( leftTuple,
-                                                 handle,
-                                                 context,
-                                                 workingMemory );
-            }
-        }
-
-        this.constraints.resetFactHandle( memory.getContext() );
     }
 
     /**
@@ -214,30 +203,15 @@
      *            The working memory seesion.
      */
     public void retractLeftTuple(final LeftTuple leftTuple,
-                             final PropagationContext context,
-                             final InternalWorkingMemory workingMemory) {
+                                 final PropagationContext context,
+                                 final InternalWorkingMemory workingMemory) {
         final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
-        final LeftTuple tuple = memory.getTupleMemory().remove( leftTuple );
-        if ( tuple == null ) {
-            return;
-        }
-
-        final Iterator it = memory.getFactHandleMemory().iterator( leftTuple );
-        this.constraints.updateFromTuple( memory.getContext(),
-                                          workingMemory,
-                                          leftTuple );
-        for ( FactEntry entry = (FactEntry) it.next(); entry != null; entry = (FactEntry) it.next() ) {
-            final InternalFactHandle handle = entry.getFactHandle();
-            if ( this.constraints.isAllowedCachedLeft( memory.getContext(),
-                                                       handle ) ) {
-                this.sink.propagateRetractLeftTuple( leftTuple,
-                                                 handle,
+        memory.getLeftTupleMemory().remove( leftTuple );
+        if ( leftTuple.getBetaChildren() != null ) {
+            this.sink.propagateRetractLeftTuple( leftTuple,
                                                  context,
                                                  workingMemory );
-            }
         }
-
-        this.constraints.resetTuple( memory.getContext() );
     }
 
     /* (non-Javadoc)
@@ -249,20 +223,19 @@
 
         final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
 
-        final Iterator tupleIter = memory.getTupleMemory().iterator();
-        for ( LeftTuple LeftTuple = (LeftTuple) tupleIter.next(); LeftTuple != null; LeftTuple = (LeftTuple) tupleIter.next() ) {
-            final Iterator objectIter = memory.getFactHandleMemory().iterator( LeftTuple );
+        final Iterator tupleIter = memory.getLeftTupleMemory().iterator();
+        for ( LeftTuple leftTuple = (LeftTuple) tupleIter.next(); leftTuple != null; leftTuple = (LeftTuple) tupleIter.next() ) {
             this.constraints.updateFromTuple( memory.getContext(),
                                               workingMemory,
-                                              LeftTuple );
-            for ( FactEntry entry = (FactEntry) objectIter.next(); entry != null; entry = (FactEntry) objectIter.next() ) {
-                final InternalFactHandle handle = entry.getFactHandle();
+                                              leftTuple );
+            for ( RightTuple rightTuple = memory.getRightTupleMemory().getFirst( leftTuple ); rightTuple != null; rightTuple = (RightTuple) rightTuple.getNext() ) {
                 if ( this.constraints.isAllowedCachedLeft( memory.getContext(),
-                                                           handle ) ) {
-                    sink.assertLeftTuple( new LeftTuple( LeftTuple,
-                                                     handle ),
-                                      context,
-                                      workingMemory );
+                                                           rightTuple.getFactHandle() ) ) {
+                    sink.assertLeftTuple( new LeftTuple( leftTuple,
+                                                         rightTuple,
+                                                         this ),
+                                          context,
+                                          workingMemory );
                 }
             }
 
@@ -271,11 +244,11 @@
     }
 
     public String toString() {
-        ObjectSource source = this.rightInput;
+        RightTupleSource source = this.rightInput;
         while ( !(source instanceof ObjectTypeNode) ) {
-            source = source.objectSource;
+            source = source.source;
         }
 
-        return "[JoinNode("+this.getId()+") - " + ((ObjectTypeNode) source).getObjectType() + "]";
+        return "[JoinNode(" + this.getId() + ") - " + ((ObjectTypeNode) source).getObjectType() + "]";
     }
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/LeftInputAdapterNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/LeftInputAdapterNode.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/LeftInputAdapterNode.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -44,20 +44,18 @@
  */
 public class LeftInputAdapterNode extends LeftTupleSource
     implements
-    ObjectSinkNode,
+    RightTupleSinkNode,
     NodeMemory {
 
     /**
      *
      */
     private static final long  serialVersionUID = 400L;
-    private ObjectSource objectSource;
+    private RightTupleSource   objectSource;
 
-    private ObjectSinkNode     previousObjectSinkNode;
-    private ObjectSinkNode     nextObjectSinkNode;
+    private RightTupleSinkNode previousRightTupleSinkNode;
+    private RightTupleSinkNode nextRightTupleSinkNode;
 
-    private boolean           objectMemoryEnabled;
-
     public LeftInputAdapterNode() {
 
     }
@@ -75,29 +73,27 @@
      *      a predicate is used in the first pattern, for instance
      */
     public LeftInputAdapterNode(final int id,
-                                final ObjectSource source,
+                                final RightTupleSource source,
                                 final BuildContext context) {
         super( id );
         this.objectSource = source;
-        //this.constraints = constraints;
-        setObjectMemoryEnabled( false );
     }
 
-    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        super.readExternal(in);
-        objectSource    = (ObjectSource)in.readObject();
-        previousObjectSinkNode  = (ObjectSinkNode)in.readObject();
-        nextObjectSinkNode  = (ObjectSinkNode)in.readObject();
-        objectMemoryEnabled = in.readBoolean();
+    public void readExternal(ObjectInput in) throws IOException,
+                                            ClassNotFoundException {
+        super.readExternal( in );
+        objectSource = (RightTupleSource) in.readObject();
+        previousRightTupleSinkNode = (RightTupleSinkNode) in.readObject();
+        nextRightTupleSinkNode = (RightTupleSinkNode) in.readObject();
     }
 
     public void writeExternal(ObjectOutput out) throws IOException {
-        super.writeExternal(out);
-        out.writeObject(objectSource);
-        out.writeObject(previousObjectSinkNode);
-        out.writeObject(nextObjectSinkNode);
-        out.writeBoolean(objectMemoryEnabled);
+        super.writeExternal( out );
+        out.writeObject( objectSource );
+        out.writeObject( previousRightTupleSinkNode );
+        out.writeObject( nextRightTupleSinkNode );
     }
+
     /* (non-Javadoc)
      * @see org.drools.reteoo.BaseNode#attach()
      */
@@ -123,34 +119,28 @@
     public void networkUpdated() {
         this.objectSource.networkUpdated();
     }
-    
+
     /**
      * Takes the asserted <code>FactHandleImpl</code> received from the <code>ObjectSource</code> and puts it
      * in a new <code>ReteTuple</code> before propagating to the <code>TupleSinks</code>
      *
-     * @param handle
+     * @param factHandle
      *            The asserted <code>FactHandle/code>.
      * @param context
      *             The <code>PropagationContext</code> of the <code>WorkingMemory<code> action.
      * @param workingMemory
      *            the <code>WorkingMemory</code> session.
      */
-    public void assertObject(final InternalFactHandle handle,
-                             final PropagationContext context,
-                             final InternalWorkingMemory workingMemory) {
-
+    public void assertObject(final InternalFactHandle factHandle,
+                           final PropagationContext context,
+                           final InternalWorkingMemory workingMemory) {
         if ( !workingMemory.isSequential() ) {
-            this.sink.createAndPropagateAssertLeftTuple( handle,
-                                                     context,
-                                                     workingMemory );
-
-            if ( this.objectMemoryEnabled ) {
-                final FactHashTable memory = (FactHashTable) workingMemory.getNodeMemory( this );
-                memory.add( handle,
-                            false );
-            }
+            this.sink.createAndPropagateAssertLeftTuple( factHandle,
+                                                         context,
+                                                         workingMemory );
         } else {
-            workingMemory.addLIANodePropagation( new LIANodePropagation(this, handle, context) );
+            // @todo
+            //workingMemory.addLIANodePropagation( new LIANodePropagation(this, rightTuple, context) );
         }
     }
 
@@ -165,41 +155,19 @@
      * @param workingMemory
      *            the <code>WorkingMemory</code> session.
      */
-    public void retractObject(final InternalFactHandle handle,
-                              final PropagationContext context,
-                              final InternalWorkingMemory workingMemory) {
-        boolean propagate = true;
-        if ( this.objectMemoryEnabled ) {
-            final FactHashTable memory = (FactHashTable) workingMemory.getNodeMemory( this );
-            propagate = memory.remove( handle );
-        }
-
-        if ( propagate ) {
-            this.sink.createAndPropagateRetractLeftTuple( handle,
-                                                      context,
-                                                      workingMemory );
-        }
+    public void retractRightTuple(final RightTuple rightTuple,
+                            final PropagationContext context,
+                            final InternalWorkingMemory workingMemory) {
+        throw new UnsupportedOperationException( "LeftInputAdapterNode.retractRightTuple is not supported." );
     }
 
     public void updateSink(final LeftTupleSink sink,
                            final PropagationContext context,
                            final InternalWorkingMemory workingMemory) {
-        if ( this.objectMemoryEnabled ) {
-            // We have memory so iterate over all entries
-            final FactHashTable memory = (FactHashTable) workingMemory.getNodeMemory( this );
-            final Iterator it = memory.iterator();
-            for ( FactEntry entry = (FactEntry) it.next(); entry != null; entry = (FactEntry) it.next() ) {
-                final InternalFactHandle handle = entry.getFactHandle();
-                sink.assertLeftTuple( new LeftTuple( handle ),
-                                  context,
-                                  workingMemory );
-            }
-        } else {
-            final ObjectSinkAdapter adapter = new ObjectSinkAdapter( sink );
-            this.objectSource.updateSink( adapter,
-                                          context,
-                                          workingMemory );
-        }
+        final RightTupleSinkAdapter adapter = new RightTupleSinkAdapter( sink );
+        this.objectSource.updateSink( adapter,
+                                      context,
+                                      workingMemory );
     }
 
     protected void doRemove(final RuleRemovalContext context,
@@ -221,21 +189,13 @@
                                   workingMemories );
     }
 
-    public boolean isObjectMemoryEnabled() {
-        return this.objectMemoryEnabled;
-    }
-
-    public void setObjectMemoryEnabled(boolean objectMemoryEnabled) {
-        this.objectMemoryEnabled = objectMemoryEnabled;
-    }
-
     /**
      * Returns the next node
      * @return
      *      The next ObjectSinkNode
      */
-    public ObjectSinkNode getNextObjectSinkNode() {
-        return this.nextObjectSinkNode;
+    public RightTupleSinkNode getNextRightTupleSinkNode() {
+        return this.nextRightTupleSinkNode;
     }
 
     /**
@@ -243,8 +203,8 @@
      * @param next
      *      The next ObjectSinkNode
      */
-    public void setNextObjectSinkNode(final ObjectSinkNode next) {
-        this.nextObjectSinkNode = next;
+    public void setNextRightTupleSinkNode(final RightTupleSinkNode next) {
+        this.nextRightTupleSinkNode = next;
     }
 
     /**
@@ -252,8 +212,8 @@
      * @return
      *      The previous ObjectSinkNode
      */
-    public ObjectSinkNode getPreviousObjectSinkNode() {
-        return this.previousObjectSinkNode;
+    public RightTupleSinkNode getPreviousRightTupleSinkNode() {
+        return this.previousRightTupleSinkNode;
     }
 
     /**
@@ -261,8 +221,8 @@
      * @param previous
      *      The previous ObjectSinkNode
      */
-    public void setPreviousObjectSinkNode(final ObjectSinkNode previous) {
-        this.previousObjectSinkNode = previous;
+    public void setPreviousRightTupleSinkNode(final RightTupleSinkNode previous) {
+        this.previousRightTupleSinkNode = previous;
     }
 
     public int hashCode() {
@@ -293,43 +253,30 @@
      * @author mproctor
      *
      */
-    private static class ObjectSinkAdapter
+    private static class RightTupleSinkAdapter
         implements
-        ObjectSink {
+        RightTupleSink {
         private LeftTupleSink sink;
 
-        public ObjectSinkAdapter(final LeftTupleSink sink) {
+        public RightTupleSinkAdapter(final LeftTupleSink sink) {
             this.sink = sink;
         }
 
-        public void assertObject(final InternalFactHandle handle,
-                                 final PropagationContext context,
-                                 final InternalWorkingMemory workingMemory) {
-            final LeftTuple tuple = new LeftTuple( handle );
+        public void assertObject(final InternalFactHandle factHandle,
+                               final PropagationContext context,
+                               final InternalWorkingMemory workingMemory) {
+            final LeftTuple tuple = new LeftTuple( factHandle,
+                                                   this.sink );
             this.sink.assertLeftTuple( tuple,
-                                   context,
-                                   workingMemory );
+                                       context,
+                                       workingMemory );
         }
 
-        public void modifyObject(final InternalFactHandle handle,
-                                 final PropagationContext context,
-                                 final InternalWorkingMemory workingMemory) {
+        public void retractRightTuple(final RightTuple rightTuple,
+                                final PropagationContext context,
+                                final InternalWorkingMemory workingMemory) {
             throw new UnsupportedOperationException( "ObjectSinkAdapter onlys supports assertObject method calls" );
         }
-
-        public void retractObject(final InternalFactHandle handle,
-                                  final PropagationContext context,
-                                  final InternalWorkingMemory workingMemory) {
-            throw new UnsupportedOperationException( "ObjectSinkAdapter onlys supports assertObject method calls" );
-        }
-
-        public boolean isObjectMemoryEnabled() {
-            throw new UnsupportedOperationException("ObjectSinkAdapters have no Object memory");
-        }
-
-        public void setObjectMemoryEnabled(boolean objectMemoryEnabled) {
-            throw new UnsupportedOperationException("ObjectSinkAdapters have no Object memory");
-        }
     }
 
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/LeftTuple.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/LeftTuple.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/LeftTuple.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -1,10 +1,10 @@
 package org.drools.reteoo;
 
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
 import java.util.ArrayList;
 import java.util.List;
-import java.io.ObjectOutput;
-import java.io.IOException;
-import java.io.ObjectInput;
 
 import org.drools.base.ShadowProxy;
 import org.drools.common.InternalFactHandle;
@@ -12,6 +12,8 @@
 import org.drools.spi.Activation;
 import org.drools.spi.Tuple;
 import org.drools.util.Entry;
+import org.drools.util.FactHashTable;
+import org.drools.util.TupleHashTable;
 
 public class LeftTuple
     implements
@@ -21,7 +23,7 @@
 
     private int                      index;
 
-    private InternalFactHandle handle;
+    private final InternalFactHandle handle;
 
     private LeftTuple                parent;
 
@@ -31,67 +33,223 @@
 
     private int                      hashCode;
 
-    private InternalFactHandle       match;
+    private RightTuple               blocker;
 
+    private LeftTuple                blockedPrevious;
+
+    private LeftTuple                blockedNext;
+
+    // left and right tuples in parent
+    private LeftTuple                leftParent;
+    private LeftTuple                leftParentPrevious;
+    private LeftTuple                leftParentNext;
+
+    private RightTuple               rightParent;
+    private LeftTuple                rightParentPrevious;
+    private LeftTuple                rightParentNext;
+
+    // node memory
+    private TupleHashTable           memory;
     private Entry                    next;
+    private Entry                    previous;
 
+    // children
+    private LeftTuple                children;
+
+    private final LeftTupleSink      sink;
+
     // ------------------------------------------------------------
     // Constructors
     // ------------------------------------------------------------
-    public LeftTuple() {
-        
-    }
-    public LeftTuple(final InternalFactHandle handle) {
-        this.recency = handle.getRecency();
-        this.handle = handle;
+    public LeftTuple(final InternalFactHandle factHandle,
+                     LeftTupleSink sink) {
+        this.handle = factHandle;
+        this.recency = factHandle.getRecency();
+
         int h = handle.hashCode();
         h += ~(h << 9);
         h ^= (h >>> 14);
         h += (h << 4);
         h ^= (h >>> 10);
         this.hashCode = h;
+
+        this.sink = sink;
+        
+        LeftTuple currentFirst = handle.getLeftTuple();
+        if ( currentFirst != null ) {
+            currentFirst.leftParentPrevious =  this;
+            this.leftParentNext = currentFirst;
+        }
+        
+        handle.setLeftTuple( this );         
     }
 
-    public LeftTuple(final LeftTuple tuple) {
-        this.index = tuple.index;
-        this.parent = tuple.parent;
-        this.recency = tuple.recency;
-        this.handle = tuple.handle;
-        this.hashCode = tuple.hashCode();
+    public LeftTuple(final LeftTuple leftTuple,
+                     LeftTupleSink sink) {
+        this.index = leftTuple.index;
+        this.parent = leftTuple.parent;
+        this.recency = leftTuple.recency;
+        this.handle = leftTuple.handle;
+        this.hashCode = leftTuple.hashCode();
+
+        this.leftParent = leftTuple;
+        this.leftParentNext = leftTuple.children;
+        if ( this.leftParentNext != null ) {
+            this.leftParentNext.leftParentPrevious = this;
+        }
+        this.leftParent.children = this;
+        this.sink = sink;
     }
 
-    public LeftTuple(final LeftTuple parentTuple,
-                     final InternalFactHandle handle) {
-        this.index = parentTuple.index + 1;
-        this.parent = parentTuple;
-        this.recency = parentTuple.recency + handle.getRecency();
-        this.handle = handle;
-        this.hashCode = parentTuple.hashCode ^ (handle.hashCode() * 31);
+    public LeftTuple(final LeftTuple leftTuple,
+                     final RightTuple rightTuple,
+                     LeftTupleSink sink) {
+        this.handle = rightTuple.getFactHandle();
+        this.index = leftTuple.index + 1;
+        this.parent = leftTuple;
+        this.recency = leftTuple.recency + this.handle.getRecency();
+        this.hashCode = leftTuple.hashCode ^ (handle.hashCode() * 31);
+
+        this.rightParent = rightTuple;
+        this.rightParentNext = this.rightParent.getBetaChildren();
+        if ( this.rightParentNext != null ) {
+            this.rightParentNext.rightParentPrevious = this;
+        }
+        this.rightParent.setBetaChildren( this );
+
+        this.leftParent = leftTuple;
+        this.leftParentNext = leftTuple.children;
+        if ( this.leftParentNext != null ) {
+            this.leftParentNext.leftParentPrevious = this;
+        }
+        this.leftParent.children = this;
+        this.sink = sink;
     }
+    
+    public void unlinkFromLeftParent() {
+        LeftTuple previous = (LeftTuple) this.leftParentPrevious;
+        LeftTuple next = (LeftTuple) this.leftParentNext;
 
-    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        index   = in.readInt();
-        handle  = (InternalFactHandle)in.readObject();
-        parent  = (LeftTuple)in.readObject();
-        activation  = (Activation)in.readObject();
-        recency = in.readLong();
-        hashCode    = in.readInt();
-        match   = (InternalFactHandle)in.readObject();
-        next    = (Entry)in.readObject();
+        if ( previous != null && next != null ) {
+            //remove  from middle
+            this.leftParentPrevious.leftParentNext = this.leftParentNext;
+            this.leftParentNext.leftParentPrevious = this.leftParentPrevious;
+        } else if ( next != null ) {
+            //remove from first
+            this.leftParent.children = this.leftParentNext;
+            this.leftParentNext.leftParentPrevious = null;
+        } else if ( previous != null ) {
+            //remove from end
+            this.leftParentPrevious.leftParentNext = null;
+        } else {
+            this.leftParent.children = null;
+        }
 
+        //this.parent  = null;
+
+        this.leftParent = null;
+        this.leftParentPrevious = null;
+        this.leftParentNext = null;
+//
+        this.blocker = null;
+//
+        this.rightParent = null;
+        this.rightParentPrevious = null;
+        this.rightParentNext = null;
     }
 
-    public void writeExternal(ObjectOutput out) throws IOException {
-        out.writeInt(index);
-        out.writeObject(handle);
-        out.writeObject(parent);
-        out.writeObject(activation);
-        out.writeLong(recency);
-        out.writeInt(hashCode);
-        out.writeObject(match);
-        out.writeObject(next);
+    public void unlinkFromRightParent() {
+        LeftTuple previous = (LeftTuple) this.rightParentPrevious;
+        LeftTuple next = (LeftTuple) this.rightParentNext;
+
+        if ( previous != null && next != null ) {
+            //remove  from middle
+            this.rightParentPrevious.rightParentNext = this.rightParentNext;
+            this.rightParentNext.rightParentPrevious = this.rightParentPrevious;
+        } else if ( next != null ) {
+            //remove from first
+            this.rightParent.setBetaChildren( this.rightParentNext );
+            this.rightParentNext.rightParentPrevious = null;
+        } else if ( previous != null ) {
+            //remove from end
+            this.rightParentPrevious.rightParentNext = null;
+        } else if ( this.rightParent != null ) {
+            this.rightParent.setBetaChildren( null );
+        }
+
+        //this.parent  = null;
+
+        this.leftParent = null;
+        this.leftParentPrevious = null;
+        this.leftParentNext = null;
+
+        this.blocker = null;
+
+        this.rightParent = null;
+        this.rightParentPrevious = null;
+        this.rightParentNext = null;
     }
 
+    public LeftTupleSink getSink() {
+        return sink;
+    }
+
+    public LeftTuple getLeftParent() {
+        return leftParent;
+    }
+
+    public void setLeftParent(LeftTuple leftParent) {
+        this.leftParent = leftParent;
+    }
+
+    public LeftTuple getLeftParentPrevious() {
+        return leftParentPrevious;
+    }
+
+    public void setLeftParentPrevious(LeftTuple leftParentLeft) {
+        this.leftParentPrevious = leftParentLeft;
+    }
+
+    public LeftTuple getLeftParentNext() {
+        return leftParentNext;
+    }
+
+    public void setLeftParentNext(LeftTuple leftParentright) {
+        this.leftParentNext = leftParentright;
+    }
+
+    public RightTuple getRightParent() {
+        return rightParent;
+    }
+
+    public void setRightParent(RightTuple rightParent) {
+        this.rightParent = rightParent;
+    }
+
+    public LeftTuple getRightParentPrevious() {
+        return rightParentPrevious;
+    }
+
+    public void setRightParentPrevious(LeftTuple rightParentLeft) {
+        this.rightParentPrevious = rightParentLeft;
+    }
+
+    public LeftTuple getRightParentNext() {
+        return rightParentNext;
+    }
+
+    public void setRightParentNext(LeftTuple rightParentRight) {
+        this.rightParentNext = rightParentRight;
+    }
+
+    public void setBetaChildren(LeftTuple leftTuple) {
+        this.children = leftTuple;
+    }
+
+    public LeftTuple getBetaChildren() {
+        return this.children;
+    }
+
     public InternalFactHandle get(final int index) {
         LeftTuple entry = this;
         while ( entry.index != index ) {
@@ -99,7 +257,23 @@
         }
         return entry.handle;
     }
+    
+    public TupleHashTable getMemory() {
+        return this.memory;
+    }
 
+    public void setMemory(TupleHashTable memory) {
+        this.memory = memory;
+    }    
+
+    public Entry getPrevious() {
+        return previous;
+    }
+
+    public void setPrevious(Entry previous) {
+        this.previous = previous;
+    }
+
     public void setNext(final Entry next) {
         this.next = next;
     }
@@ -138,15 +312,30 @@
         return this.recency;
     }
 
+    public void setBlocker(RightTuple blocker) {
+        this.blocker = blocker;
+    }
 
-    public InternalFactHandle getMatch() {
-        return match;
+    public RightTuple getBlocker() {
+        return this.blocker;
     }
 
-    public void setMatch(InternalFactHandle match) {
-        this.match = match;
+    public LeftTuple getBlockedPrevious() {
+        return this.blockedPrevious;
     }
 
+    public void setBlockedPrevious(LeftTuple blockerPrevious) {
+        this.blockedPrevious = blockerPrevious;
+    }
+
+    public LeftTuple getBlockedNext() {
+        return this.blockedNext;
+    }
+
+    public void setBlockedNext(LeftTuple blockerNext) {
+        this.blockedNext = blockerNext;
+    }
+
     public void setActivation(final Activation activation) {
         this.activation = activation;
     }
@@ -195,7 +384,7 @@
     }
 
     public boolean equals(final Object object) {
-        // we know the object is never null and always of the  type ReteTuple
+        // we know the object is never null and always of the  type ReteTuple    
         return equals( (LeftTuple) object );
     }
 
@@ -206,17 +395,17 @@
     /**
      * Returns the ReteTuple that contains the "elements"
      * first elements in this tuple.
-     *
+     * 
      * Use carefully as no cloning is made during this process.
-     *
+     * 
      * This method is used by TupleStartEqualsConstraint when
      * joining a subnetwork tuple into the main network tuple;
-     *
+     * 
      * @param elements the number of elements to return, starting from
      * the begining of the tuple
-     *
+     * 
      * @return a ReteTuple containing the "elements" first elements
-     * of this tuple or null if "elements" is greater than size;
+     * of this tuple or null if "elements" is greater than size; 
      */
     public LeftTuple getSubTuple(final int elements) {
         LeftTuple entry = this;
@@ -231,16 +420,25 @@
     }
 
     public Object[] toObjectArray() {
-        Object[] objects = new Object[ this.index + 1 ];
+        Object[] objects = new Object[this.index + 1];
         LeftTuple entry = this;
         while ( entry != null ) {
             Object object = entry.getLastHandle().getObject();
             if ( object instanceof ShadowProxy ) {
-                object = ((ShadowProxy)object).getShadowedObject();
+                object = ((ShadowProxy) object).getShadowedObject();
             }
             objects[entry.index] = object;
             entry = entry.parent;
         }
         return objects;
     }
+
+    public void readExternal(ObjectInput in) throws IOException,
+                                            ClassNotFoundException {
+        // @todo        
+    }
+
+    public void writeExternal(ObjectOutput out) throws IOException {
+        // @todo        
+    }
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/LeftTupleMemory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/LeftTupleMemory.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/LeftTupleMemory.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -7,7 +7,7 @@
 public interface LeftTupleMemory {
     public Iterator iterator();
 
-    public Iterator iterator(InternalFactHandle handle);
+    public LeftTuple getFirst(RightTuple rightTuple);
 
     public void add(LeftTuple tuple);
 
@@ -19,7 +19,7 @@
 
     public int size();
 
-    public Entry[] getTable();
+//    public Entry[] getTable();
     
     public Entry[] toArray();
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/LeftTupleSinkPropagator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/LeftTupleSinkPropagator.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/LeftTupleSinkPropagator.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -10,30 +10,25 @@
     extends
     Externalizable {
     public void propagateAssertLeftTuple(LeftTuple leftTuple,
-                                     InternalFactHandle handle,
-                                     PropagationContext context,
-                                     InternalWorkingMemory workingMemory);
+                                         RightTuple rightTuple,
+                                         PropagationContext context,
+                                         InternalWorkingMemory workingMemory);
 
-    public void propagateAssertLeftTuple(LeftTuple leftTuple,
-                                     PropagationContext context,
-                                     InternalWorkingMemory workingMemory);
+    public void propagateAssertLeftTuple(LeftTuple tuple,
+                                         PropagationContext context,
+                                         InternalWorkingMemory workingMemory);
 
-    public void propagateRetractLeftTuple(LeftTuple leftTuple,
-                                      InternalFactHandle handle,
-                                      PropagationContext context,
-                                      InternalWorkingMemory workingMemory);
-
     public void propagateRetractLeftTuple(LeftTuple tuple,
-                                      PropagationContext context,
-                                      InternalWorkingMemory workingMemory);
+                                          PropagationContext context,
+                                          InternalWorkingMemory workingMemory);
 
-    public void createAndPropagateAssertLeftTuple(InternalFactHandle handle,
-                                              PropagationContext context,
-                                              InternalWorkingMemory workingMemory);
+    public void propagateRetractRightTuple(RightTuple tuple,
+                                           PropagationContext context,
+                                           InternalWorkingMemory workingMemory);
 
-    public void createAndPropagateRetractLeftTuple(InternalFactHandle handle,
-                                               PropagationContext context,
-                                               InternalWorkingMemory workingMemory);
+    public void createAndPropagateAssertLeftTuple(InternalFactHandle factHandle,
+                                                  PropagationContext context,
+                                                  InternalWorkingMemory workingMemory);
 
     public LeftTupleSink[] getSinks();
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/LeftTupleSource.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/LeftTupleSource.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/LeftTupleSource.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -63,7 +63,7 @@
      */
     LeftTupleSource(final int id) {
         super( id );
-        this.sink = EmptyTupleSinkAdapter.getInstance();
+        this.sink = EmptyLeftTupleSinkAdapter.getInstance();
     }
 
     // ------------------------------------------------------------
@@ -88,9 +88,9 @@
      *            <code>Tuples</code>.
      */
     protected void addTupleSink(final LeftTupleSink tupleSink) {
-        if ( this.sink instanceof EmptyTupleSinkAdapter ) {
-            this.sink = new SingleTupleSinkAdapter( tupleSink );
-        } else if ( this.sink instanceof SingleTupleSinkAdapter ) {
+        if ( this.sink instanceof EmptyLeftTupleSinkAdapter ) {
+            this.sink = new SingleLeftTupleSinkAdapter( tupleSink );
+        } else if ( this.sink instanceof SingleLeftTupleSinkAdapter ) {
             final CompositeTupleSinkAdapter sinkAdapter = new CompositeTupleSinkAdapter();
             sinkAdapter.addTupleSink( this.sink.getSinks()[0] );
             sinkAdapter.addTupleSink( tupleSink );
@@ -107,17 +107,17 @@
      *            The <code>TupleSink</code> to remove
      */
     protected void removeTupleSink(final LeftTupleSink tupleSink) {
-        if ( this.sink instanceof EmptyTupleSinkAdapter ) {
+        if ( this.sink instanceof EmptyLeftTupleSinkAdapter ) {
             throw new IllegalArgumentException( "Cannot remove a sink, when the list of sinks is null" );
         }
 
-        if ( this.sink instanceof SingleTupleSinkAdapter ) {
-            this.sink = EmptyTupleSinkAdapter.getInstance();
+        if ( this.sink instanceof SingleLeftTupleSinkAdapter ) {
+            this.sink = EmptyLeftTupleSinkAdapter.getInstance();
         } else {
             final CompositeTupleSinkAdapter sinkAdapter = (CompositeTupleSinkAdapter) this.sink;
             sinkAdapter.removeTupleSink( tupleSink );
             if ( sinkAdapter.size() == 1 ) {
-                this.sink = new SingleTupleSinkAdapter( sinkAdapter.getSinks()[0] );
+                this.sink = new SingleLeftTupleSinkAdapter( sinkAdapter.getSinks()[0] );
             }
         }
     }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/MemoryVisitor.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/MemoryVisitor.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/MemoryVisitor.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -65,10 +65,10 @@
 
         this.indent++;
         try {
-            final Field field = ObjectSource.class.getDeclaredField( "sink" );
+            final Field field = RightTupleSource.class.getDeclaredField( "sink" );
             field.setAccessible( true );
-            final ObjectSinkPropagator sink = (ObjectSinkPropagator) field.get( node );
-            final ObjectSink[] sinks = sink.getSinks();
+            final RightTupleSinkPropagator sink = (RightTupleSinkPropagator) field.get( node );
+            final RightTupleSink[] sinks = sink.getSinks();
             for ( int i = 0, length = sinks.length; i < length; i++ ) {
                 visit( sinks[i] );
             }
@@ -86,10 +86,10 @@
 
         this.indent++;
         try {
-            final Field field = ObjectSource.class.getDeclaredField( "sink" );
+            final Field field = RightTupleSource.class.getDeclaredField( "sink" );
             field.setAccessible( true );
-            final ObjectSinkPropagator sink = (ObjectSinkPropagator) field.get( node );
-            final ObjectSink[] sinks = sink.getSinks();
+            final RightTupleSinkPropagator sink = (RightTupleSinkPropagator) field.get( node );
+            final RightTupleSink[] sinks = sink.getSinks();
             for ( int i = 0, length = sinks.length; i < length; i++ ) {
                 visit( sinks[i] );
             }
@@ -122,8 +122,8 @@
 
         try {
             final BetaMemory memory = (BetaMemory) this.workingMemory.getNodeMemory( node );
-            checkObjectHashTable( memory.getFactHandleMemory() );
-            checkTupleMemory( memory.getTupleMemory() );
+            checkObjectHashTable( memory.getRightTupleMemory() );
+            checkTupleMemory( memory.getLeftTupleMemory() );
         } catch ( final Exception e ) {
             e.printStackTrace();
         }
@@ -147,8 +147,8 @@
         System.out.println( indent() + node );
         try {
             final BetaMemory memory = (BetaMemory) this.workingMemory.getNodeMemory( node );
-            checkObjectHashTable( memory.getFactHandleMemory() );
-            checkTupleMemory( memory.getTupleMemory() );
+            checkObjectHashTable( memory.getRightTupleMemory() );
+            checkTupleMemory( memory.getLeftTupleMemory() );
         } catch ( final Exception e ) {
             e.printStackTrace();
         }
@@ -189,7 +189,7 @@
     //        }
     //    }
 
-    private void checkObjectHashTable(final FactHandleMemory memory) {
+    private void checkObjectHashTable(final RightTupleMemory memory) {
         if ( memory instanceof FactHashTable ) {
             checkFactHashTable( (FactHashTable) memory );
         } else if ( memory instanceof FactHandleIndexHashTable ) {

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/NotNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/NotNode.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/NotNode.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -54,6 +54,7 @@
     public NotNode() {
 
     }
+
     /**
      * Construct.
      *
@@ -64,7 +65,7 @@
      */
     public NotNode(final int id,
                    final LeftTupleSource leftInput,
-                   final ObjectSource rightInput,
+                   final RightTupleSource rightInput,
                    final BetaConstraints joinNodeBinder,
                    final BuildContext context) {
         super( id,
@@ -87,31 +88,43 @@
      *            The working memory seesion.
      */
     public void assertLeftTuple(final LeftTuple leftTuple,
-                            final PropagationContext context,
-                            final InternalWorkingMemory workingMemory) {
+                                final PropagationContext context,
+                                final InternalWorkingMemory workingMemory) {
         final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
 
         if ( this.tupleMemoryEnabled ) {
-            memory.getTupleMemory().add( leftTuple );
+            memory.getLeftTupleMemory().add( leftTuple );
         }
 
-        final Iterator it = memory.getFactHandleMemory().iterator( leftTuple );
         this.constraints.updateFromTuple( memory.getContext(),
                                           workingMemory,
                                           leftTuple );
 
-        for ( FactEntry entry = (FactEntry) it.next(); entry != null; entry = (FactEntry) it.next() ) {
-            final InternalFactHandle handle = entry.getFactHandle();
+        for ( RightTuple rightTuple = memory.getRightTupleMemory().getLast( leftTuple ); rightTuple != null; rightTuple = (RightTuple) rightTuple.getPrevious() ) {
             if ( this.constraints.isAllowedCachedLeft( memory.getContext(),
-                                                       handle ) ) {
-                leftTuple.setMatch( handle );
+                                                       rightTuple.getFactHandle() ) ) {
+
+                leftTuple.setBlocker( rightTuple );
+
+                LeftTuple blockedPrevious = rightTuple.getBlocked();
+                if ( blockedPrevious != null ) {
+                    leftTuple.setBlockedNext( blockedPrevious );
+                    blockedPrevious.setBlockedPrevious( leftTuple );
+                }
+                rightTuple.setBlocked( leftTuple );
+
                 break;
             }
         }
 
         this.constraints.resetTuple( memory.getContext() );
 
-        if ( leftTuple.getMatch() == null ) {
+        if ( leftTuple.getBlocker() == null ) {
+            // only add it to node memory if still need Objects to attempt to match
+            if ( this.tupleMemoryEnabled ) {
+                memory.getLeftTupleMemory().add( leftTuple );
+            }
+
             this.sink.propagateAssertLeftTuple( leftTuple,
                                             context,
                                             workingMemory );
@@ -123,36 +136,57 @@
      * matches any left ReteTuple's that already has propagations then those
      * propagations are retracted.
      *
-     * @param handle
+     * @param factHandle
      *            The <code>FactHandleImpl</code> being asserted.
      * @param context
      *            The <code>PropagationContext</code>
      * @param workingMemory
      *            The working memory seesion.
      */
-    public void assertObject(final InternalFactHandle handle,
-                             final PropagationContext context,
-                             final InternalWorkingMemory workingMemory) {
+    public void assertObject(final InternalFactHandle factHandle,
+                           final PropagationContext context,
+                           final InternalWorkingMemory workingMemory) {
+        final RightTuple rightTuple = new RightTuple( factHandle, this);
+        
         final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
-        memory.getFactHandleMemory().add( handle );
+        memory.getRightTupleMemory().add( rightTuple );  
 
         if ( !this.tupleMemoryEnabled ) {
             // do nothing here, as we know there are no left tuples at this stage in sequential mode.
             return;
         }
 
-        final Iterator it = memory.getTupleMemory().iterator( handle );
         this.constraints.updateFromFactHandle( memory.getContext(),
                                                workingMemory,
-                                               handle );
-        for ( LeftTuple leftTuple = (LeftTuple) it.next(); leftTuple != null; leftTuple = (LeftTuple) it.next() ) {
+                                               factHandle );
+        for ( LeftTuple leftTuple = memory.getLeftTupleMemory().getFirst( rightTuple ); leftTuple != null; ) {
+            // preserve next now, in case we remove this leftTuple 
+            LeftTuple temp = (LeftTuple) leftTuple.getNext();
+            
+            // we know that only unblocked LeftTuples are  still in the memory
             if ( this.constraints.isAllowedCachedRight( memory.getContext(),
-                                                        leftTuple ) &&  leftTuple.getMatch() == null) {
-                    leftTuple.setMatch( handle );
+                                                        leftTuple ) ) {
+                leftTuple.setBlocker( rightTuple );
+
+                LeftTuple blockedPrevious = rightTuple.getBlocked();
+                if ( blockedPrevious != null ) {
+                    leftTuple.setBlockedNext( blockedPrevious );
+                    blockedPrevious.setBlockedPrevious( leftTuple );
+                }
+                rightTuple.setBlocked( leftTuple );
+
+                
+                // this is now blocked so remove from memory
+                memory.getLeftTupleMemory().remove( leftTuple );                
+
+                if ( leftTuple.getBetaChildren() != null ) {
                     this.sink.propagateRetractLeftTuple( leftTuple,
-                                                     context,
-                                                     workingMemory );
+                                                         context,
+                                                         workingMemory );
+                }                
             }
+            
+            leftTuple = temp;
         }
 
         this.constraints.resetFactHandle( memory.getContext() );
@@ -171,52 +205,59 @@
      *            The working memory seesion.
      * @throws AssertionException
      */
-    public void retractObject(final InternalFactHandle handle,
-                              final PropagationContext context,
-                              final InternalWorkingMemory workingMemory) {
-        final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
-        if ( !memory.getFactHandleMemory().remove( handle ) ) {
+    public void retractRightTuple(final RightTuple rightTuple,
+                            final PropagationContext context,
+                            final InternalWorkingMemory workingMemory) {
+        // assign now, so we can remove from memory before doing any possible propagations
+        final RightTuple rootBlocker = (RightTuple) rightTuple.getPrevious();     
+        
+        final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );        
+        memory.getRightTupleMemory().remove( rightTuple );
+        
+        if ( rightTuple.getBlocked() == null ) {
             return;
-        }
+        }           
 
-        final Iterator it = memory.getTupleMemory().iterator( handle );
-        this.constraints.updateFromFactHandle( memory.getContext(),
-                                               workingMemory,
-                                               handle );
-        for ( LeftTuple leftTuple = (LeftTuple) it.next(); leftTuple != null; leftTuple = (LeftTuple) it.next() ) {
-            if ( this.constraints.isAllowedCachedRight( memory.getContext(),
-                                                        leftTuple ) ) {
+        for ( LeftTuple leftTuple = (LeftTuple) rightTuple.getBlocked(); leftTuple != null; ) {
+            LeftTuple temp = leftTuple.getBlockedNext();            
+            
+            leftTuple.setBlocker( null );
+            leftTuple.setBlockedPrevious( null );
+            leftTuple.setBlockedNext( null );
+            
+            this.constraints.updateFromTuple( memory.getContext(),
+                                              workingMemory,
+                                              leftTuple );           
 
-                if ( leftTuple.getMatch() == handle ) {
-                    // reset the match
-                    leftTuple.setMatch( null );
+            // we know that older tuples have been checked so continue previously
+            for ( RightTuple newBlocker = rootBlocker; newBlocker != null; newBlocker = (RightTuple) newBlocker.getPrevious() ) {
+                if ( this.constraints.isAllowedCachedLeft( memory.getContext(),
+                                                           newBlocker.getFactHandle() ) ) {
+                    leftTuple.setBlocker( newBlocker );
 
-                    // find next match, remember it and break.
-                    final Iterator tupleIt = memory.getFactHandleMemory().iterator( leftTuple );
-                    this.constraints.updateFromTuple( memory.getContext(),
-                                                      workingMemory, leftTuple );
-
-                    for ( FactEntry entry = (FactEntry) tupleIt.next(); entry != null; entry = (FactEntry) tupleIt.next() ) {
-                        final InternalFactHandle rightHandle = entry.getFactHandle();
-                        if ( this.constraints.isAllowedCachedLeft( memory.getContext(),
-                                                                   rightHandle ) ) {
-                            leftTuple.setMatch( rightHandle );
-                            break;
-                        }
+                    LeftTuple blockedPrevious = newBlocker.getBlocked();
+                    if ( blockedPrevious != null ) {
+                        leftTuple.setBlockedNext( blockedPrevious );
+                        blockedPrevious.setBlockedPrevious( leftTuple );
                     }
+                    newBlocker.setBlocked( leftTuple );
 
-                    this.constraints.resetTuple( memory.getContext() );
-                    // if there is now no new tuple match then propagate assert.
-                    if ( leftTuple.getMatch() == null ) {
-                        this.sink.propagateAssertLeftTuple( leftTuple,
-                                                        context,
-                                                        workingMemory );
-                    }
+                    break;
                 }
             }
+            
+            if ( leftTuple.getBlocker() == null ) {
+                // was previous blocked and not in memory, so add
+                memory.getLeftTupleMemory().add( leftTuple );
+
+                this.sink.propagateAssertLeftTuple( leftTuple,
+                                                context,
+                                                workingMemory );
+            }            
+            
+            leftTuple = temp;
         }
-
-        this.constraints.resetFactHandle( memory.getContext() );
+        this.constraints.resetTuple( memory.getContext() );
     }
 
     /**
@@ -231,21 +272,34 @@
      *            The working memory seesion.
      */
     public void retractLeftTuple(final LeftTuple leftTuple,
-                             final PropagationContext context,
-                             final InternalWorkingMemory workingMemory) {
-        final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
-
-        // Must use the tuple in memory as it has the tuple matches count
-        final LeftTuple tuple = memory.getTupleMemory().remove( leftTuple );
-        if ( tuple == null ) {
-            return;
+                                 final PropagationContext context,
+                                 final InternalWorkingMemory workingMemory) {
+        RightTuple blocker = leftTuple.getBlocker();
+        if ( blocker == null ) {
+            final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
+            memory.getLeftTupleMemory().remove( leftTuple );            
+            
+            this.sink.propagateRetractLeftTuple( leftTuple,
+                                                 context,
+                                                 workingMemory );
+        } else {
+            LeftTuple previous = (LeftTuple) leftTuple.getBlockedPrevious();
+            LeftTuple next = (LeftTuple) leftTuple.getBlockedNext();
+            if ( previous != null && next != null ) {
+                //remove  from middle
+                previous.setBlockedNext( next );
+                next.setBlockedPrevious( previous );
+            } else if ( next != null ) {
+                //remove from first
+                blocker.setBlocked( next );
+                next.setBlockedPrevious( null );
+            } else if ( previous != null ) {
+                //remove from end
+                previous.setBlockedNext( null );
+            } else {
+                blocker.setBlocked( null );
+            }
         }
-
-        if ( tuple.getMatch() ==  null) {
-            this.sink.propagateRetractLeftTuple( tuple,
-                                             context,
-                                             workingMemory );
-        }
     }
 
     /* (non-Javadoc)
@@ -256,20 +310,21 @@
                            final InternalWorkingMemory workingMemory) {
         final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
 
-        final Iterator tupleIter = memory.getTupleMemory().iterator();
-        for ( LeftTuple leftTuple = (LeftTuple) tupleIter.next(); leftTuple != null; leftTuple = (LeftTuple) tupleIter.next() ) {
-            if ( leftTuple.getMatch() == null ) {
-                sink.assertLeftTuple( new LeftTuple( leftTuple ),
-                                  context,
-                                  workingMemory );
-            }
-        }
+        final Iterator tupleIter = memory.getLeftTupleMemory().iterator();
+        // @todo
+//        for ( LeftTuple leftTuple = (LeftTuple) tupleIter.next(); leftTuple != null; leftTuple = (LeftTuple) tupleIter.next() ) {
+//            if ( leftTuple.getMatch() == null ) {
+//                sink.assertLeftTuple( new LeftTuple( leftTuple ),
+//                                      context,
+//                                      workingMemory );
+//            }
+//        }
     }
 
     public String toString() {
-        ObjectSource source = this.rightInput;
+        RightTupleSource source = this.rightInput;
         while ( !(source instanceof ObjectTypeNode) ) {
-            source = source.objectSource;
+            source = source.source;
         }
 
         return "[NotNode - " + ((ObjectTypeNode) source).getObjectType() + "]";

Deleted: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectSink.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectSink.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectSink.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -1,68 +0,0 @@
-package org.drools.reteoo;
-
-/*
- * Copyright 2005 JBoss Inc
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *      http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import org.drools.common.InternalFactHandle;
-import org.drools.common.InternalWorkingMemory;
-import org.drools.spi.PropagationContext;
-
-/**
- * Receiver of propagated <code>FactHandleImpl</code>s from a
- * <code>ObjectSource</code>.
- * 
- * @see ObectSource
- * 
- * @author <a href="mailto:mark.proctor at jboss.com">Mark Proctor</a>
- * @author <a href="mailto:bob at werken.com">Bob McWhirter</a>
- *
- */
-public interface ObjectSink
-    extends
-    Sink {
-
-    /**
-     * Assert a new <code>FactHandleImpl</code>.
-     * 
-     * @param handle
-     *            The asserted <code>FactHandle/code>.
-     * @param context
-     *             The <code>PropagationContext</code> of the <code>WorkingMemory<code> action.           
-     * @param workingMemory
-     *            the <code>WorkingMemory</code> session.
-     */
-    void assertObject(InternalFactHandle handle,
-                      PropagationContext context,
-                      InternalWorkingMemory workingMemory);
-
-    /**
-     * Retract an existing <code>FactHandleImpl</code>.
-     * 
-     * @param handle
-     *            The <code>FactHandle/code> to retract.
-     * @param context
-     *             The <code>PropagationContext</code> of the <code>WorkingMemory<code> action.           
-     * @param workingMemory
-     *            the <code>WorkingMemory</code> session.
-     */
-    void retractObject(InternalFactHandle handle,
-                       PropagationContext context,
-                       InternalWorkingMemory workingMemory);
-
-    public boolean isObjectMemoryEnabled();
-
-    public void setObjectMemoryEnabled(boolean objectMemoryOn);
-}

Deleted: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectSinkNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectSinkNode.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectSinkNode.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -1,59 +0,0 @@
-package org.drools.reteoo;
-
-/*
- * Copyright 2005 JBoss Inc
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *      http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Items placed in a <code>LinkedList<code> must implement this interface .
- * 
- * @see LeftTupleSinkNodeList
- * 
- * @author <a href="mailto:mark.proctor at jboss.com">Mark Proctor</a>
- * @author <a href="mailto:bob at werken.com">Bob McWhirter</a>
- */
-public interface ObjectSinkNode
-    extends
-    ObjectSink {
-
-    /**
-     * Returns the next node
-     * @return
-     *      The next LinkedListNode
-     */
-    public ObjectSinkNode getNextObjectSinkNode();
-
-    /**
-     * Sets the next node 
-     * @param next
-     *      The next LinkedListNode
-     */
-    public void setNextObjectSinkNode(ObjectSinkNode next);
-
-    /**
-     * Returns the previous node
-     * @return
-     *      The previous LinkedListNode
-     */
-    public ObjectSinkNode getPreviousObjectSinkNode();
-
-    /**
-     * Sets the previous node 
-     * @param previous
-     *      The previous LinkedListNode
-     */
-    public void setPreviousObjectSinkNode(ObjectSinkNode previous);
-
-}

Deleted: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectSinkNodeList.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectSinkNodeList.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectSinkNodeList.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -1,243 +0,0 @@
-package org.drools.reteoo;
-
-import java.io.Externalizable;
-import java.io.ObjectInput;
-import java.io.IOException;
-import java.io.ObjectOutput;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-/*
- * Copyright 2005 JBoss Inc
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * This is a simple linked linked implementation. Each node must implement </code>LinkedListNode<code> so that it references
- * the node before and after it. This way a node can be removed without having to scan the list to find it. This class
- * does not provide an Iterator implementation as its designed for efficiency and not genericity. There are a number of
- * ways to iterate the list.
- * <p>
- * Simple iterator:
- * <pre>
- * for ( LinkedListNode node = list.getFirst(); node != null; node =  node.getNext() ) {
- * }
- * </pre>
- *
- * Iterator that pops the first entry:
- * <pre>
- * for ( LinkedListNode node = list.removeFirst(); node != null; node = list.removeFirst() ) {
- * }
- * </pre>
- *
- *
- * @author <a href="mailto:mark.proctor at jboss.com">Mark Proctor</a>
- * @author <a href="mailto:bob at werken.com">Bob McWhirter</a>
- *
- */
-public class ObjectSinkNodeList
-    implements
-    Externalizable {
-    private static final long serialVersionUID = 400L;
-
-    private ObjectSinkNode    firstNode;
-    private ObjectSinkNode    lastNode;
-
-    private int               size;
-
-    /**
-     * Construct an empty <code>LinkedList</code>
-     */
-    public ObjectSinkNodeList() {
-
-    }
-
-    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        firstNode   = (ObjectSinkNode)in.readObject();
-        lastNode    = (ObjectSinkNode)in.readObject();
-        size        = in.readInt();
-    }
-
-    public void writeExternal(ObjectOutput out) throws IOException {
-        out.writeObject(firstNode);
-        out.writeObject(lastNode);
-        out.writeInt(size);
-    }
-    /**
-     * Add a <code>ObjectSinkNode</code> to the list. If the <code>LinkedList</code> is empty then the first and
-     * last nodes are set to the added node.
-     *
-     * @param node
-     *      The <code>ObjectSinkNode</code> to be added
-     */
-    public void add(final ObjectSinkNode node) {
-        if ( this.firstNode == null ) {
-            this.firstNode = node;
-            this.lastNode = node;;
-        } else {
-            this.lastNode.setNextObjectSinkNode( node );
-            node.setPreviousObjectSinkNode( this.lastNode );
-            this.lastNode = node;
-        }
-        this.size++;
-    }
-
-    /**
-     * Removes a <code>ObjectSinkNode</code> from the list. This works by attach the previous reference to the child reference.
-     * When the node to be removed is the first node it calls <code>removeFirst()</code>. When the node to be removed is the last node
-     * it calls <code>removeLast()</code>.
-     *
-     * @param node
-     *      The <code>ObjectSinkNode</code> to be removed.
-     */
-    public void remove(final ObjectSinkNode node) {
-        if ( (this.firstNode != node) && (this.lastNode != node) ) {
-            node.getPreviousObjectSinkNode().setNextObjectSinkNode( node.getNextObjectSinkNode() );
-            node.getNextObjectSinkNode().setPreviousObjectSinkNode( node.getPreviousObjectSinkNode() );
-            this.size--;
-            node.setPreviousObjectSinkNode( null );
-            node.setNextObjectSinkNode( null );
-
-        } else {
-            if ( this.firstNode == node ) {
-                removeFirst();
-            } else if ( this.lastNode == node ) {
-                removeLast();
-            }
-        }
-    }
-
-    /**
-     * Return the first node in the list
-     * @return
-     *      The first <code>ObjectSinkNode</code>.
-     */
-    public final ObjectSinkNode getFirst() {
-        return this.firstNode;
-    }
-
-    /**
-     * Return the last node in the list
-     * @return
-     *      The last <code>ObjectSinkNode</code>.
-     */
-    public final ObjectSinkNode getLast() {
-        return this.lastNode;
-    }
-
-    /**
-     * Remove the first node from the list. The next node then becomes the first node. If this is the last
-     * node then both first and last node references are set to null.
-     *
-     * @return
-     *      The first <code>ObjectSinkNode</code>.
-     */
-    public ObjectSinkNode removeFirst() {
-        if ( this.firstNode == null ) {
-            return null;
-        }
-        final ObjectSinkNode node = this.firstNode;
-        this.firstNode = node.getNextObjectSinkNode();
-        node.setNextObjectSinkNode( null );
-        if ( this.firstNode != null ) {
-            this.firstNode.setPreviousObjectSinkNode( null );
-        } else {
-            this.lastNode = null;
-        }
-        this.size--;
-        return node;
-    }
-
-    /**
-     * Remove the last node from the list. The previous node then becomes the last node. If this is the last
-     * node then both first and last node references are set to null.
-     *
-     * @return
-     *      The first <code>ObjectSinkNode</code>.
-     */
-    public ObjectSinkNode removeLast() {
-        if ( this.lastNode == null ) {
-            return null;
-        }
-        final ObjectSinkNode node = this.lastNode;
-        this.lastNode = node.getPreviousObjectSinkNode();
-        node.setPreviousObjectSinkNode( null );
-        if ( this.lastNode != null ) {
-            this.lastNode.setNextObjectSinkNode( null );
-        } else {
-            this.firstNode = this.lastNode;
-        }
-        this.size--;
-        return node;
-    }
-
-    /**
-     * @return
-     *      boolean value indicating the empty status of the list
-     */
-    public final boolean isEmpty() {
-        return (this.firstNode == null);
-    }
-
-    /**
-     * Iterates the list removing all the nodes until there are no more nodes to remove.
-     */
-    public void clear() {
-        while ( removeFirst() != null ) {
-        }
-    }
-
-    /**
-     * @return
-     *     return size of the list as an int
-     */
-    public final int size() {
-        return this.size;
-    }
-
-    /**
-     * Returns a list iterator
-     * @return
-     */
-    public Iterator iterator() {
-        return new Iterator() {
-            private ObjectSinkNode currentNode = null;
-            private ObjectSinkNode nextNode    = getFirst();
-
-            public boolean hasNext() {
-                return (this.nextNode != null);
-            }
-
-            public Object next() {
-                this.currentNode = this.nextNode;
-                if ( this.currentNode != null ) {
-                    this.nextNode = this.currentNode.getNextObjectSinkNode();
-                } else {
-                    throw new NoSuchElementException( "No more elements to return" );
-                }
-                return this.currentNode;
-            }
-
-            public void remove() {
-                if ( this.currentNode != null ) {
-                    ObjectSinkNodeList.this.remove( this.currentNode );
-                    this.currentNode = null;
-                } else {
-                    throw new IllegalStateException( "No item to remove. Call next() before calling remove()." );
-                }
-            }
-        };
-    }
-
-}

Deleted: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectSinkPropagator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectSinkPropagator.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectSinkPropagator.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -1,25 +0,0 @@
-package org.drools.reteoo;
-
-import java.io.Serializable;
-import java.io.Externalizable;
-
-import org.drools.common.InternalFactHandle;
-import org.drools.common.InternalWorkingMemory;
-import org.drools.spi.PropagationContext;
-
-public interface ObjectSinkPropagator
-    extends
-    Externalizable {
-    public void propagateAssertObject(InternalFactHandle handle,
-                                      PropagationContext context,
-                                      InternalWorkingMemory workingMemory);
-
-    public void propagateRetractObject(InternalFactHandle handle,
-                                       PropagationContext context,
-                                       InternalWorkingMemory workingMemory,
-                                       boolean useHash);
-
-    public ObjectSink[] getSinks();
-
-    public int size();
-}

Deleted: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectSource.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectSource.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectSource.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -1,165 +0,0 @@
-package org.drools.reteoo;
-
-/*
- * Copyright 2005 JBoss Inc
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import java.io.Serializable;
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-
-import org.drools.common.BaseNode;
-import org.drools.common.DefaultFactHandle;
-import org.drools.common.InternalWorkingMemory;
-import org.drools.spi.PropagationContext;
-
-/**
- * A source of <code>FactHandle</code>s for an <code>ObjectSink</code>.
- *
- * <p>
- * Nodes that propagate <code>FactHandleImpl</code> extend this class.
- * </p>
- *
- * @see ObjectSource
- * @see DefaultFactHandle
- *
- * @author <a href="mailto:mark.proctor at jboss.com">Mark Proctor</a>
- * @author <a href="mailto:bob at werken.com">Bob McWhirter</a>
- */
-public abstract class ObjectSource extends BaseNode
-    implements
-    Externalizable {
-    // ------------------------------------------------------------
-    // Instance members
-    // ------------------------------------------------------------
-
-    /** The destination for <code>FactHandleImpl</code>. */
-    protected ObjectSinkPropagator sink;
-
-    protected ObjectSource         objectSource;
-
-    private int                    alphaNodeHashingThreshold;
-
-    // ------------------------------------------------------------
-    // Constructors
-    // ------------------------------------------------------------
-    public ObjectSource() {
-
-    }
-
-    /**
-     * Single parameter constructor that specifies the unique id of the node.
-     *
-     * @param id
-     */
-    ObjectSource(final int id) {
-        this( id,
-              null,
-              3 );
-    }
-
-    /**
-     * Single parameter constructor that specifies the unique id of the node.
-     *
-     * @param id
-     */
-    ObjectSource(final int id,
-                 final ObjectSource objectSource,
-                 final int alphaNodeHashingThreshold) {
-        super( id );
-        this.objectSource = objectSource;
-        this.alphaNodeHashingThreshold = alphaNodeHashingThreshold;
-        this.sink = EmptyObjectSinkAdapter.getInstance();
-    }
-
-    // ------------------------------------------------------------
-    // Instance methods
-    // ------------------------------------------------------------
-    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        super.readExternal(in);
-        sink    = (ObjectSinkPropagator)in.readObject();
-        objectSource    = (ObjectSource)in.readObject();
-        alphaNodeHashingThreshold   = in.readInt();
-    }
-
-    public void writeExternal(ObjectOutput out) throws IOException {
-        super.writeExternal(out);
-        out.writeObject(sink);
-        out.writeObject(objectSource);
-        out.writeInt(alphaNodeHashingThreshold);
-    }
-
-    /**
-     * Adds the <code>ObjectSink</code> so that it may receive
-     * <code>FactHandleImpl</code> propagated from this
-     * <code>ObjectSource</code>.
-     *
-     * @param objectSink
-     *            The <code>ObjectSink</code> to receive propagated
-     *            <code>FactHandleImpl</code>.
-     */
-    protected void addObjectSink(final ObjectSink objectSink) {
-        if ( this.sink instanceof EmptyObjectSinkAdapter ) {
-            this.sink = new SingleObjectSinkAdapter( objectSink );
-        } else if ( this.sink instanceof SingleObjectSinkAdapter ) {
-            final CompositeObjectSinkAdapter sinkAdapter = new CompositeObjectSinkAdapter( this.alphaNodeHashingThreshold );
-            sinkAdapter.addObjectSink( this.sink.getSinks()[0] );
-            sinkAdapter.addObjectSink( objectSink );
-            this.sink = sinkAdapter;
-        } else {
-            ((CompositeObjectSinkAdapter) this.sink).addObjectSink( objectSink );
-        }
-    }
-
-    /**
-     * Removes the <code>ObjectSink</code>
-     *
-     * @param objectSink
-     *            The <code>ObjectSink</code> to remove
-     */
-    protected void removeObjectSink(final ObjectSink objectSink) {
-        if ( this.sink instanceof EmptyObjectSinkAdapter ) {
-            throw new IllegalArgumentException( "Cannot remove a sink, when the list of sinks is null" );
-        }
-
-        if ( this.sink instanceof SingleObjectSinkAdapter ) {
-            this.sink = EmptyObjectSinkAdapter.getInstance();
-        } else {
-            final CompositeObjectSinkAdapter sinkAdapter = (CompositeObjectSinkAdapter) this.sink;
-            sinkAdapter.removeObjectSink( objectSink );
-            if ( sinkAdapter.size() == 1 ) {
-                this.sink = new SingleObjectSinkAdapter( sinkAdapter.getSinks()[0] );
-            }
-        }
-    }
-
-    public abstract void updateSink(ObjectSink sink,
-                                    PropagationContext context,
-                                    InternalWorkingMemory workingMemory);
-    
-    public void networkUpdated() {
-        this.objectSource.networkUpdated();
-    }
-
-    public ObjectSinkPropagator getSinkPropagator() {
-        return this.sink;
-    }
-
-    public boolean isInUse() {
-        return this.sink.size() > 0;
-    }
-}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectTypeNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectTypeNode.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectTypeNode.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -38,6 +38,7 @@
 import org.drools.util.FactEntry;
 import org.drools.util.FactHashTable;
 import org.drools.util.Iterator;
+import org.drools.util.ObjectHashSet;
 
 /**
  * <code>ObjectTypeNodes<code> are responsible for filtering and propagating the matching
@@ -58,9 +59,9 @@
  * @author <a href="mailto:mark.proctor at jboss.com">Mark Proctor</a>
  * @author <a href="mailto:bob at werken.com">Bob McWhirter</a>
  */
-public class ObjectTypeNode extends ObjectSource
+public class ObjectTypeNode extends RightTupleSource
     implements
-    ObjectSink,
+    RightTupleSink,
     Externalizable,
     NodeMemory
 
@@ -75,7 +76,7 @@
     private static final long serialVersionUID = 400L;
 
     /** The <code>ObjectType</code> semantic module. */
-    private ObjectType  objectType;
+    private ObjectType        objectType;
 
     private boolean           skipOnModify     = false;
 
@@ -105,19 +106,21 @@
         setObjectMemoryEnabled( context.isObjectTypeNodeMemoryEnabled() );
     }
 
-    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        super.readExternal(in);
-        objectType  = (ObjectType)in.readObject();
-        skipOnModify    = in.readBoolean();
+    public void readExternal(ObjectInput in) throws IOException,
+                                            ClassNotFoundException {
+        super.readExternal( in );
+        objectType = (ObjectType) in.readObject();
+        skipOnModify = in.readBoolean();
         objectMemoryEnabled = in.readBoolean();
     }
 
     public void writeExternal(ObjectOutput out) throws IOException {
-        super.writeExternal(out);
-        out.writeObject(objectType);
-        out.writeBoolean(skipOnModify);
-        out.writeBoolean(objectMemoryEnabled);
+        super.writeExternal( out );
+        out.writeObject( objectType );
+        out.writeBoolean( skipOnModify );
+        out.writeBoolean( objectMemoryEnabled );
     }
+
     /**
      * Retrieve the semantic <code>ObjectType</code> differentiator.
      *
@@ -149,14 +152,14 @@
      * <code>FactHandleImpl</code> should be remembered in the node memory, so that later runtime rule attachmnents
      * can have the matched facts propagated to them.
      *
-     * @param handle
+     * @param factHandle
      *            The fact handle.
      * @param object
      *            The object to assert.
      * @param workingMemory
      *            The working memory session.
      */
-    public void assertObject(final InternalFactHandle handle,
+    public void assertObject(final InternalFactHandle factHandle,
                              final PropagationContext context,
                              final InternalWorkingMemory workingMemory) {
         if ( context.getType() == PropagationContext.MODIFICATION && this.skipOnModify && context.getDormantActivations() == 0 ) {
@@ -166,44 +169,61 @@
 
         if ( this.objectMemoryEnabled ) {
             final FactHashTable memory = (FactHashTable) workingMemory.getNodeMemory( this );
-            memory.add( handle,
+            memory.add( factHandle,
                         false );
         }
 
-        this.sink.propagateAssertObject( handle,
-                                         context,
-                                         workingMemory );
+        this.sink.propagateAssertFact( factHandle,
+                                       context,
+                                       workingMemory );
     }
 
+    public void retractRightTuple(final RightTuple rightTuple,
+                                  final PropagationContext context,
+                                  final InternalWorkingMemory workingMemory) {
+        throw new UnsupportedOperationException( "ObjectTypeNode.retractRightTuple is not supported." );
+    }
+
     /**
-     * Retract the <code>FactHandleimpl</code> from the <code>Rete</code> network. Also remove the
+     * Retract the <code>FactHandleimpl</code> from the <code>Rete</code> network. Also remove the 
      * <code>FactHandleImpl</code> from the node memory.
-     *
-     * @param handle
+     * 
+     * @param rightTuple
      *            The fact handle.
      * @param object
      *            The object to assert.
      * @param workingMemory
      *            The working memory session.
      */
-    public void retractObject(final InternalFactHandle handle,
-                              final PropagationContext context,
-                              final InternalWorkingMemory workingMemory) {
+    public void retractRightTuple(final InternalFactHandle factHandle,
+                                  final PropagationContext context,
+                                  final InternalWorkingMemory workingMemory) {
 
         if ( context.getType() == PropagationContext.MODIFICATION && this.skipOnModify && context.getDormantActivations() == 0 ) {
             return;
         }
 
-        final FactHashTable memory = (FactHashTable) workingMemory.getNodeMemory( this );
-        memory.remove( handle );
+        if ( this.objectMemoryEnabled ) {
+            final ObjectHashSet memory = (ObjectHashSet) workingMemory.getNodeMemory( this );
+            memory.remove( factHandle );
+        }
 
-        this.sink.propagateRetractObject( handle,
-                                          context,
-                                          workingMemory,
-                                          true );
+        for ( RightTuple rightTuple = factHandle.getRightTuple(); rightTuple != null; rightTuple = (RightTuple) rightTuple.getHandleNext() ) {
+            rightTuple.getRightTupleSink().retractRightTuple( rightTuple,
+                                                              context,
+                                                              workingMemory );
+        }
+        factHandle.setRightTuple( null );
+
+        for ( LeftTuple leftTuple = factHandle.getLeftTuple(); leftTuple != null; leftTuple = (LeftTuple) leftTuple.getLeftParentNext() ) {
+            leftTuple.getSink().retractLeftTuple( leftTuple,
+                                                  context,
+                                                  workingMemory );
+        }
+        factHandle.setLeftTuple( null );
     }
 
-    public void updateSink(final ObjectSink sink,
+    public void updateSink(final RightTupleSink sink,
                            final PropagationContext context,
                            final InternalWorkingMemory workingMemory) {
         final FactHashTable memory = (FactHashTable) workingMemory.getNodeMemory( this );
@@ -219,7 +239,7 @@
      * Rete needs to know that this ObjectTypeNode has been added
      */
     public void attach() {
-        this.objectSource.addObjectSink( this );
+        this.source.addObjectSink( this );
     }
 
     public void attach(final InternalWorkingMemory[] workingMemories) {
@@ -234,17 +254,17 @@
                                                                                           PropagationContext.RULE_ADDITION,
                                                                                           null,
                                                                                           null );
-            propagationContext.setEntryPoint( ((EntryPointNode) this.objectSource).getEntryPoint() );
-            this.objectSource.updateSink( this,
-                                          propagationContext,
-                                          workingMemory );
+            propagationContext.setEntryPoint( ((EntryPointNode) this.source).getEntryPoint() );
+            this.source.updateSink( this,
+                                    propagationContext,
+                                    workingMemory );
         }
     }
 
     public void networkUpdated() {
         this.skipOnModify = canSkipOnModify( this.sink.getSinks() );
     }
-    
+
     /**
      * OTN needs to override remove to avoid releasing the node ID, since OTN are
      * never removed from the rulebase in the current implementation
@@ -268,7 +288,7 @@
                             final BaseNode node,
                             final InternalWorkingMemory[] workingMemories) {
         if ( !node.isInUse() ) {
-            removeObjectSink( (ObjectSink) node );
+            removeObjectSink( (RightTupleSink) node );
         }
     }
 
@@ -290,14 +310,14 @@
     }
 
     public String toString() {
-        return "[ObjectTypeNode(" + this.id + ")::" + ((EntryPointNode) this.objectSource).getEntryPoint() + " objectType=" + this.objectType + "]";
+        return "[ObjectTypeNode(" + this.id + ")::" + ((EntryPointNode) this.source).getEntryPoint() + " objectType=" + this.objectType + "]";
     }
 
     /**
      * Uses he hashCode() of the underlying ObjectType implementation.
      */
     public int hashCode() {
-        return this.objectType.hashCode() ^ this.objectSource.hashCode();
+        return this.objectType.hashCode() ^ this.source.hashCode();
     }
 
     public boolean equals(final Object object) {
@@ -311,20 +331,20 @@
 
         final ObjectTypeNode other = (ObjectTypeNode) object;
 
-        return this.objectType.equals( other.objectType ) && this.objectSource.equals( other.objectSource );
+        return this.objectType.equals( other.objectType ) && this.source.equals( other.source );
     }
 
     /**
      * @inheritDoc
      */
-    protected void addObjectSink(final ObjectSink objectSink) {
+    protected void addObjectSink(final RightTupleSink objectSink) {
         super.addObjectSink( objectSink );
     }
 
     /**
      * @inheritDoc
      */
-    protected void removeObjectSink(final ObjectSink objectSink) {
+    protected void removeObjectSink(final RightTupleSink objectSink) {
         super.removeObjectSink( objectSink );
     }
 
@@ -344,10 +364,10 @@
             } else if ( sinks[i] instanceof BetaNode && ((BetaNode) sinks[i]).getConstraints().length > 0 ) {
                 hasConstraints = this.usesDeclaration( ((BetaNode) sinks[i]).getConstraints() );
             } else if ( sinks[i] instanceof EvalConditionNode ) {
-                hasConstraints = this.usesDeclaration( ((EvalConditionNode)sinks[i]).getCondition() );
+                hasConstraints = this.usesDeclaration( ((EvalConditionNode) sinks[i]).getCondition() );
             }
-            if ( !hasConstraints && sinks[i] instanceof ObjectSource ) {
-                hasConstraints = !this.canSkipOnModify( ((ObjectSource) sinks[i]).getSinkPropagator().getSinks() );
+            if ( !hasConstraints && sinks[i] instanceof RightTupleSource ) {
+                hasConstraints = !this.canSkipOnModify( ((RightTupleSource) sinks[i]).getSinkPropagator().getSinks() );
             } else if ( !hasConstraints && sinks[i] instanceof LeftTupleSource ) {
                 hasConstraints = !this.canSkipOnModify( ((LeftTupleSource) sinks[i]).getSinkPropagator().getSinks() );
             }
@@ -357,7 +377,6 @@
         return !hasConstraints;
     }
 
-
     private boolean usesDeclaration(final Constraint[] constraints) {
         boolean usesDecl = false;
         for ( int i = 0; !usesDecl && i < constraints.length; i++ ) {
@@ -388,6 +407,6 @@
      * @return the entryPoint
      */
     public EntryPoint getEntryPoint() {
-        return ((EntryPointNode) this.objectSource).getEntryPoint();
+        return ((EntryPointNode) this.source).getEntryPoint();
     }
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/PropagationQueuingNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/PropagationQueuingNode.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/PropagationQueuingNode.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -40,9 +40,9 @@
  * @author etirelli
  *
  */
-public class PropagationQueuingNode extends ObjectSource
+public class PropagationQueuingNode extends RightTupleSource
     implements
-    ObjectSinkNode,
+    RightTupleSinkNode,
     NodeMemory {
 
     private static final long serialVersionUID = -615639068150958767L;
@@ -50,8 +50,8 @@
     // should we make this one configurable?
     private static final int PROPAGATION_SLICE_LIMIT = 1000;
 
-    private ObjectSinkNode    previousObjectSinkNode;
-    private ObjectSinkNode    nextObjectSinkNode;
+    private RightTupleSinkNode    previousObjectSinkNode;
+    private RightTupleSinkNode    nextObjectSinkNode;
     private PropagateAction   action;
 
     public PropagationQueuingNode() {
@@ -68,7 +68,7 @@
      * @param hasMemory true if node shall be configured with local memory. False otherwise.
      */
     public PropagationQueuingNode(final int id,
-                                  final ObjectSource objectSource,
+                                  final RightTupleSource objectSource,
                                   final BuildContext context) {
         super( id,
                objectSource,
@@ -78,8 +78,8 @@
 
     public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
         super.readExternal(in);
-        previousObjectSinkNode  = (ObjectSinkNode)in.readObject();
-        nextObjectSinkNode      = (ObjectSinkNode)in.readObject();
+        previousObjectSinkNode  = (RightTupleSinkNode)in.readObject();
+        nextObjectSinkNode      = (RightTupleSinkNode)in.readObject();
         action                  = (PropagateAction)in.readObject();
     }
 
@@ -91,10 +91,10 @@
     }
 
     /**
-     * @see org.drools.reteoo.ObjectSource#updateSink(org.drools.reteoo.ObjectSink, org.drools.spi.PropagationContext, org.drools.common.InternalWorkingMemory)
+     * @see org.drools.reteoo.RightTupleSource#updateSink(org.drools.reteoo.RightTupleSink, org.drools.spi.PropagationContext, org.drools.common.InternalWorkingMemory)
      */
     @Override
-    public void updateSink(ObjectSink sink,
+    public void updateSink(RightTupleSink sink,
                            PropagationContext context,
                            InternalWorkingMemory workingMemory) {
 
@@ -106,7 +106,7 @@
         }
 
         // as this node is simply a queue, ask object source to update the child sink directly
-        this.objectSource.updateSink( sink,
+        this.source.updateSink( sink,
                                       context,
                                       workingMemory );
     }
@@ -116,7 +116,7 @@
      */
     @Override
     public void attach() {
-        this.objectSource.addObjectSink( this );
+        this.source.addObjectSink( this );
     }
 
     /**
@@ -137,55 +137,55 @@
                             final BaseNode node,
                             final InternalWorkingMemory[] workingMemories) {
         if ( !node.isInUse() ) {
-            removeObjectSink( (ObjectSink) node );
+            removeObjectSink( (RightTupleSink) node );
         }
         if ( !this.isInUse() ) {
             for ( int i = 0, length = workingMemories.length; i < length; i++ ) {
                 workingMemories[i].clearNodeMemory( this );
             }
         }
-        this.objectSource.remove( context,
+        this.source.remove( context,
                                   builder,
                                   this,
                                   workingMemories );
     }
 
     /**
-     * @see org.drools.reteoo.ObjectSinkNode#getNextObjectSinkNode()
+     * @see org.drools.reteoo.RightTupleSinkNode#getNextRightTupleSinkNode()
      */
-    public ObjectSinkNode getNextObjectSinkNode() {
+    public RightTupleSinkNode getNextRightTupleSinkNode() {
         return this.nextObjectSinkNode;
     }
 
     /**
-     * @see org.drools.reteoo.ObjectSinkNode#getPreviousObjectSinkNode()
+     * @see org.drools.reteoo.RightTupleSinkNode#getPreviousRightTupleSinkNode()
      */
-    public ObjectSinkNode getPreviousObjectSinkNode() {
+    public RightTupleSinkNode getPreviousRightTupleSinkNode() {
         return this.previousObjectSinkNode;
     }
 
     /**
-     * @see org.drools.reteoo.ObjectSinkNode#setNextObjectSinkNode(org.drools.reteoo.ObjectSinkNode)
+     * @see org.drools.reteoo.RightTupleSinkNode#setNextRightTupleSinkNode(org.drools.reteoo.RightTupleSinkNode)
      */
-    public void setNextObjectSinkNode(ObjectSinkNode next) {
+    public void setNextRightTupleSinkNode(RightTupleSinkNode next) {
         this.nextObjectSinkNode = next;
     }
 
     /**
-     * @see org.drools.reteoo.ObjectSinkNode#setPreviousObjectSinkNode(org.drools.reteoo.ObjectSinkNode)
+     * @see org.drools.reteoo.RightTupleSinkNode#setPreviousRightTupleSinkNode(org.drools.reteoo.RightTupleSinkNode)
      */
-    public void setPreviousObjectSinkNode(ObjectSinkNode previous) {
+    public void setPreviousRightTupleSinkNode(RightTupleSinkNode previous) {
         this.previousObjectSinkNode = previous;
     }
 
     /**
-     * @see org.drools.reteoo.ObjectSink#assertObject(org.drools.common.InternalFactHandle, org.drools.spi.PropagationContext, org.drools.common.InternalWorkingMemory)
+     * @see org.drools.reteoo.RightTupleSink#assertObject(InternalFactHandle, org.drools.spi.PropagationContext, org.drools.common.InternalWorkingMemory)
      */
-    public void assertObject(InternalFactHandle handle,
+    public void assertObject(InternalFactHandle factHandle,
                              PropagationContext context,
                              InternalWorkingMemory workingMemory) {
         final PropagationQueueingNodeMemory memory = (PropagationQueueingNodeMemory) workingMemory.getNodeMemory( this );
-        memory.addAction( new AssertAction( handle,
+        memory.addAction( new AssertAction( factHandle,
                                             context ) );
 
         // if not queued yet, we need to queue it up
@@ -196,14 +196,14 @@
     }
 
     /**
-     * @see org.drools.reteoo.ObjectSink#isObjectMemoryEnabled()
+     * @see org.drools.reteoo.RightTupleSink#isObjectMemoryEnabled()
      */
     public boolean isObjectMemoryEnabled() {
         return true;
     }
 
     /**
-     * @see org.drools.reteoo.ObjectSink#retractObject(org.drools.common.InternalFactHandle, org.drools.spi.PropagationContext, org.drools.common.InternalWorkingMemory)
+     * @see org.drools.reteoo.RightTupleSink#retractObject(org.drools.common.InternalFactHandle, org.drools.spi.PropagationContext, org.drools.common.InternalWorkingMemory)
      */
     public void retractObject(InternalFactHandle handle,
                               PropagationContext context,
@@ -248,7 +248,7 @@
     }
 
     /**
-     * @see org.drools.reteoo.ObjectSink#setObjectMemoryEnabled(boolean)
+     * @see org.drools.reteoo.RightTupleSink#setObjectMemoryEnabled(boolean)
      */
     public void setObjectMemoryEnabled(boolean objectMemoryOn) {
         throw new UnsupportedOperationException( "PropagationQueueingNode must have its node memory enabled." );
@@ -339,7 +339,7 @@
             out.writeObject(context);
         }
 
-        public abstract void execute(final ObjectSinkPropagator sink,
+        public abstract void execute(final RightTupleSinkPropagator sink,
                                      final InternalWorkingMemory workingMemory);
     }
 
@@ -352,9 +352,9 @@
                    context );
         }
 
-        public void execute(final ObjectSinkPropagator sink,
+        public void execute(final RightTupleSinkPropagator sink,
                             final InternalWorkingMemory workingMemory) {
-            sink.propagateAssertObject( this.handle,
+            sink.propagateAssertFact( this.handle,
                                         this.context,
                                         workingMemory );
         }
@@ -372,7 +372,7 @@
                    context );
         }
 
-        public void execute(final ObjectSinkPropagator sink,
+        public void execute(final RightTupleSinkPropagator sink,
                             final InternalWorkingMemory workingMemory) {
             sink.propagateRetractObject( this.handle,
                                          this.context,

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/Rete.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/Rete.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/Rete.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -53,10 +53,10 @@
  * @author <a href="mailto:mark.proctor at jboss.com">Mark Proctor</a>
  * @author <a href="mailto:bob at werken.com">Bob McWhirter</a>
  */
-public class Rete extends ObjectSource
+public class Rete extends RightTupleSource
     implements
     Externalizable,
-    ObjectSink {
+    RightTupleSink {
     // ------------------------------------------------------------
     // Instance members
     // ------------------------------------------------------------
@@ -93,20 +93,20 @@
      * of matching <code>ObjectTypdeNode</code>s asserting the Fact. If the cache does not
      * exist it first iteraes and builds the cache.
      *
-     * @param handle
+     * @param factHandle
      *            The FactHandle of the fact to assert
      * @param context
      *            The <code>PropagationContext</code> of the <code>WorkingMemory</code> action
      * @param workingMemory
      *            The working memory session.
      */
-    public void assertObject(final InternalFactHandle handle,
+    public void assertObject(final InternalFactHandle factHandle,
                              final PropagationContext context,
                              final InternalWorkingMemory workingMemory) {
         EntryPoint entryPoint = context.getEntryPoint();
         EntryPointNode node = this.entryPoints.get( entryPoint );
-        ObjectTypeConf typeConf = ((InternalWorkingMemoryEntryPoint) workingMemory.getWorkingMemoryEntryPoint(  entryPoint.getEntryPointId() )).getObjectTypeConfigurationRegistry().getObjectTypeConf( entryPoint, handle.getObject() );
-        node.assertObject( handle,
+        ObjectTypeConf typeConf = ((InternalWorkingMemoryEntryPoint) workingMemory.getWorkingMemoryEntryPoint(  entryPoint.getEntryPointId() )).getObjectTypeConfigurationRegistry().getObjectTypeConf( entryPoint, factHandle.getObject() );
+        node.assertObject( factHandle,
                            context,
                            typeConf,
                            workingMemory );
@@ -142,13 +142,13 @@
      *            <code>Objects</code>. Rete only accepts <code>ObjectTypeNode</code>s
      *            as parameters to this method, though.
      */
-    protected void addObjectSink(final ObjectSink objectSink) {
+    protected void addObjectSink(final RightTupleSink objectSink) {
         final EntryPointNode node = (EntryPointNode) objectSink;
         this.entryPoints.put( node.getEntryPoint(),
                               node );
     }
 
-    protected void removeObjectSink(final ObjectSink objectSink) {
+    protected void removeObjectSink(final RightTupleSink objectSink) {
         final EntryPointNode node = (EntryPointNode) objectSink;
         this.entryPoints.remove( node.getEntryPoint() );
     }
@@ -210,7 +210,7 @@
         return this.entryPoints.equals( other.entryPoints );
     }
 
-    public void updateSink(final ObjectSink sink,
+    public void updateSink(final RightTupleSink sink,
                            final PropagationContext context,
                            final InternalWorkingMemory workingMemory) {
         // nothing to do, since Rete object itself holds no facts to propagate.

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightInputAdapterNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightInputAdapterNode.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightInputAdapterNode.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -42,7 +42,7 @@
  * @author <a href="mailto:etirelli at redhat.com">Edson Tirelli</a>
  *
  */
-public class RightInputAdapterNode extends ObjectSource
+public class RightInputAdapterNode extends RightTupleSource
     implements
     LeftTupleSinkNode,
     NodeMemory {
@@ -125,7 +125,7 @@
         }
 
         // propagate it
-        this.sink.propagateAssertObject( handle,
+        this.sink.propagateAssertFact( handle,
                                          context,
                                          workingMemory );
     }
@@ -176,7 +176,7 @@
         this.tupleSource.networkUpdated();
     }
 
-    public void updateSink(final ObjectSink sink,
+    public void updateSink(final RightTupleSink sink,
                            final PropagationContext context,
                            final InternalWorkingMemory workingMemory) {
 
@@ -197,7 +197,7 @@
                             final BaseNode node,
                             final InternalWorkingMemory[] workingMemories) {
         if ( !node.isInUse() ) {
-            removeObjectSink( (ObjectSink) node );
+            removeObjectSink( (RightTupleSink) node );
         }
         if( ! context.alreadyVisited( this.tupleSource ) ) {
             this.tupleSource.remove( context,

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightTuple.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightTuple.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightTuple.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -0,0 +1,195 @@
+package org.drools.reteoo;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import org.drools.common.InternalFactHandle;
+import org.drools.util.Entry;
+import org.drools.util.FactHashTable;
+
+public class RightTuple
+    implements
+    Entry {
+    private final InternalFactHandle handle;
+    
+    private RightTuple               handlePrevious;
+    private RightTuple               handleNext;
+
+    private FactHashTable            memory;
+    
+    private Entry                    previous;
+    private Entry                    next;
+
+    private LeftTuple                betaChildren;
+
+    private LeftTuple                blocked;
+
+    private RightTupleSink           sink;
+
+    private int                      hashCode;
+
+    public RightTuple(InternalFactHandle handle) {
+        this.handle = handle;
+        this.hashCode = this.handle.hashCode();
+    }
+
+    public RightTuple(InternalFactHandle handle,
+                      RightTupleSink sink) {
+        this.handle = handle;
+        this.hashCode = this.handle.hashCode();
+        this.sink = sink;
+        
+//        RightTuple currentFirst = handle.getRightTuple();
+//        if ( currentFirst != null ) {
+//            currentFirst.handlePrevious =  this;
+//            this.handleNext = currentFirst;
+//        }
+//        
+//        handle.setRightTuple( this );                
+    }
+
+    public RightTuple(RightTuple parent) {
+        this.handle = parent.getFactHandle();
+        this.hashCode = this.handle.hashCode();
+    }
+
+    public RightTuple(RightTuple parent,
+                      RightTupleSink sink) {
+        this.handle = parent.getFactHandle();
+        this.hashCode = this.handle.hashCode();
+
+        this.sink = sink;
+
+    }
+
+    public RightTupleSink getRightTupleSink() {
+        return this.sink;
+    }
+
+//    public void unlinkFromRightParent() {
+//        if ( this.parent != null ) {
+//            if ( this.parentPrevious != null ) {
+//                this.parentPrevious.parentNext = this.parentNext;
+//            } else {
+//                // first one in the chain, so treat differently                
+//                this.parent.setAlphaChildren( this.parentNext );
+//            }
+//
+//            if ( this.parentNext != null ) {
+//                this.parentNext.parentPrevious = this.parentPrevious;
+//            }
+//        }
+//
+//        this.parent = null;
+//        this.parentPrevious = null;
+//        this.parentNext = null;
+//        this.blocked = null;
+//    }
+
+    public InternalFactHandle getFactHandle() {
+        return this.handle;
+    }
+
+    public LeftTuple getBlocked() {
+        return blocked;
+    }
+
+    public void setBlocked(LeftTuple blocked) {
+        this.blocked = blocked;
+    }        
+
+    public FactHashTable getMemory() {
+        return memory;
+    }
+
+    public void setMemory(FactHashTable memory) {
+        this.memory = memory;
+    }
+
+    public Entry getPrevious() {
+        return previous;
+    }
+
+    public void setPrevious(Entry previous) {
+        this.previous = previous;
+    }        
+
+    public RightTuple getHandlePrevious() {
+        return handlePrevious;
+    }
+
+    public void setHandlePrevious(RightTuple handlePrevious) {
+        this.handlePrevious = handlePrevious;
+    }
+
+    public RightTuple getHandleNext() {
+        return handleNext;
+    }
+
+    public void setHandleNext(RightTuple handleNext) {
+        this.handleNext = handleNext;
+    }
+
+    public Entry getNext() {
+        return next;
+    }
+
+    public void setNext(Entry next) {
+        this.next = next;
+    }
+
+    public LeftTuple getBetaChildren() {
+        return betaChildren;
+    }
+
+    public void setBetaChildren(LeftTuple betachildren) {
+        this.betaChildren = betachildren;
+    }
+
+    public int getHashCode() {
+        return hashCode;
+    }
+
+    public void setHashCode(int hashCode) {
+        this.hashCode = hashCode;
+    }
+
+    public int hashCode() {
+        return this.hashCode;
+    }
+
+    public String toString() {
+        return this.handle.toString() + "\n";
+    }
+
+    public boolean equals(RightTuple other) {
+        // we know the object is never null and always of the  type ReteTuple
+        if ( other == this ) {
+            return true;
+        }
+
+        // A ReteTuple is  only the same if it has the same hashCode, factId and parent
+        if ( (other == null) || (this.hashCode != other.hashCode) ) {
+            return false;
+        }
+
+        return this.handle == other.handle;
+    }
+
+    public boolean equals(Object object) {
+        return equals( (RightTuple) object );
+    }
+
+    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
+        
+    }
+
+}

Copied: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightTupleMemory.java (from rev 19138, labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/FactHandleMemory.java)
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightTupleMemory.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightTupleMemory.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -0,0 +1,21 @@
+package org.drools.reteoo;
+
+import org.drools.common.InternalFactHandle;
+import org.drools.util.Entry;
+import org.drools.util.Iterator;
+
+public interface RightTupleMemory {
+    public RightTuple getFirst(LeftTuple leftTuple);
+    
+    public RightTuple getLast(LeftTuple leftTuple);
+
+    public void add(RightTuple rightTuple);
+
+    public void remove(RightTuple rightTuple);
+
+    public boolean contains(RightTuple rightTuple);
+
+    public boolean isIndexed();
+
+    public int size();
+}

Copied: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightTupleSink.java (from rev 19131, labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectSink.java)
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightTupleSink.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightTupleSink.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -0,0 +1,64 @@
+package org.drools.reteoo;
+
+/*
+ * Copyright 2005 JBoss Inc
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.drools.common.InternalFactHandle;
+import org.drools.common.InternalWorkingMemory;
+import org.drools.spi.PropagationContext;
+
+/**
+ * Receiver of propagated <code>FactHandleImpl</code>s from a
+ * <code>ObjectSource</code>.
+ * 
+ * @see ObectSource
+ * 
+ * @author <a href="mailto:mark.proctor at jboss.com">Mark Proctor</a>
+ * @author <a href="mailto:bob at werken.com">Bob McWhirter</a>
+ *
+ */
+public interface RightTupleSink
+    extends
+    Sink {
+
+    /**
+     * Assert a new <code>FactHandleImpl</code>.
+     * 
+     * @param factHandle
+     *            The asserted <code>FactHandle/code>.
+     * @param context
+     *             The <code>PropagationContext</code> of the <code>WorkingMemory<code> action.           
+     * @param workingMemory
+     *            the <code>WorkingMemory</code> session.
+     */
+    void assertObject(InternalFactHandle factHandle,
+                      PropagationContext context,
+                      InternalWorkingMemory workingMemory);
+
+    /**
+     * Retract an existing <code>FactHandleImpl</code>.
+     * 
+     * @param factHandle
+     *            The <code>FactHandle/code> to retract.
+     * @param context
+     *             The <code>PropagationContext</code> of the <code>WorkingMemory<code> action.           
+     * @param workingMemory
+     *            the <code>WorkingMemory</code> session.
+     */
+    void retractRightTuple(RightTuple rightTuple,
+                           PropagationContext context,
+                           InternalWorkingMemory workingMemory);
+}

Copied: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightTupleSinkNode.java (from rev 19138, labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectSinkNode.java)
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightTupleSinkNode.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightTupleSinkNode.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -0,0 +1,60 @@
+package org.drools.reteoo;
+
+/*
+ * Copyright 2005 JBoss Inc
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Items placed in a <code>LinkedList<code> must implement this interface .
+ * 
+ * @see LeftTupleSinkNodeList
+ * 
+ * @author <a href="mailto:mark.proctor at jboss.com">Mark Proctor</a>
+ * @author <a href="mailto:bob at werken.com">Bob McWhirter</a>
+ */
+public interface RightTupleSinkNode
+    extends
+    RightTupleSink {
+
+    /**
+     * Returns the next node
+     * @return
+     *      The next LinkedListNode
+     */     
+                              
+    public RightTupleSinkNode getNextRightTupleSinkNode();
+
+    /**
+     * Sets the next node 
+     * @param next
+     *      The next LinkedListNode
+     */
+    public void setNextRightTupleSinkNode(RightTupleSinkNode next);
+
+    /**
+     * Returns the previous node
+     * @return
+     *      The previous LinkedListNode
+     */
+    public RightTupleSinkNode getPreviousRightTupleSinkNode();
+
+    /**
+     * Sets the previous node 
+     * @param previous
+     *      The previous LinkedListNode
+     */
+    public void setPreviousRightTupleSinkNode(RightTupleSinkNode previous);
+
+}

Copied: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightTupleSinkNodeList.java (from rev 19131, labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectSinkNodeList.java)
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightTupleSinkNodeList.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightTupleSinkNodeList.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -0,0 +1,243 @@
+package org.drools.reteoo;
+
+import java.io.Externalizable;
+import java.io.ObjectInput;
+import java.io.IOException;
+import java.io.ObjectOutput;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * This is a simple linked linked implementation. Each node must implement </code>LinkedListNode<code> so that it references
+ * the node before and after it. This way a node can be removed without having to scan the list to find it. This class
+ * does not provide an Iterator implementation as its designed for efficiency and not genericity. There are a number of
+ * ways to iterate the list.
+ * <p>
+ * Simple iterator:
+ * <pre>
+ * for ( LinkedListNode node = list.getFirst(); node != null; node =  node.getNext() ) {
+ * }
+ * </pre>
+ *
+ * Iterator that pops the first entry:
+ * <pre>
+ * for ( LinkedListNode node = list.removeFirst(); node != null; node = list.removeFirst() ) {
+ * }
+ * </pre>
+ *
+ *
+ * @author <a href="mailto:mark.proctor at jboss.com">Mark Proctor</a>
+ * @author <a href="mailto:bob at werken.com">Bob McWhirter</a>
+ *
+ */
+public class RightTupleSinkNodeList
+    implements
+    Externalizable {
+    private static final long serialVersionUID = 400L;
+
+    private RightTupleSinkNode    firstNode;
+    private RightTupleSinkNode    lastNode;
+
+    private int               size;
+
+    /**
+     * Construct an empty <code>LinkedList</code>
+     */
+    public RightTupleSinkNodeList() {
+
+    }
+
+    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+        firstNode   = (RightTupleSinkNode)in.readObject();
+        lastNode    = (RightTupleSinkNode)in.readObject();
+        size        = in.readInt();
+    }
+
+    public void writeExternal(ObjectOutput out) throws IOException {
+        out.writeObject(firstNode);
+        out.writeObject(lastNode);
+        out.writeInt(size);
+    }
+    /**
+     * Add a <code>ObjectSinkNode</code> to the list. If the <code>LinkedList</code> is empty then the first and
+     * last nodes are set to the added node.
+     *
+     * @param node
+     *      The <code>ObjectSinkNode</code> to be added
+     */
+    public void add(final RightTupleSinkNode node) {
+        if ( this.firstNode == null ) {
+            this.firstNode = node;
+            this.lastNode = node;;
+        } else {
+            this.lastNode.setNextRightTupleSinkNode( node );
+            node.setPreviousRightTupleSinkNode( this.lastNode );
+            this.lastNode = node;
+        }
+        this.size++;
+    }
+
+    /**
+     * Removes a <code>ObjectSinkNode</code> from the list. This works by attach the previous reference to the child reference.
+     * When the node to be removed is the first node it calls <code>removeFirst()</code>. When the node to be removed is the last node
+     * it calls <code>removeLast()</code>.
+     *
+     * @param node
+     *      The <code>ObjectSinkNode</code> to be removed.
+     */
+    public void remove(final RightTupleSinkNode node) {
+        if ( (this.firstNode != node) && (this.lastNode != node) ) {
+            node.getPreviousRightTupleSinkNode().setNextRightTupleSinkNode( node.getNextRightTupleSinkNode() );
+            node.getNextRightTupleSinkNode().setPreviousRightTupleSinkNode( node.getPreviousRightTupleSinkNode() );
+            this.size--;
+            node.setPreviousRightTupleSinkNode( null );
+            node.setNextRightTupleSinkNode( null );
+
+        } else {
+            if ( this.firstNode == node ) {
+                removeFirst();
+            } else if ( this.lastNode == node ) {
+                removeLast();
+            }
+        }
+    }
+
+    /**
+     * Return the first node in the list
+     * @return
+     *      The first <code>ObjectSinkNode</code>.
+     */
+    public final RightTupleSinkNode getFirst() {
+        return this.firstNode;
+    }
+
+    /**
+     * Return the last node in the list
+     * @return
+     *      The last <code>ObjectSinkNode</code>.
+     */
+    public final RightTupleSinkNode getLast() {
+        return this.lastNode;
+    }
+
+    /**
+     * Remove the first node from the list. The next node then becomes the first node. If this is the last
+     * node then both first and last node references are set to null.
+     *
+     * @return
+     *      The first <code>ObjectSinkNode</code>.
+     */
+    public RightTupleSinkNode removeFirst() {
+        if ( this.firstNode == null ) {
+            return null;
+        }
+        final RightTupleSinkNode node = this.firstNode;
+        this.firstNode = node.getNextRightTupleSinkNode();
+        node.setNextRightTupleSinkNode( null );
+        if ( this.firstNode != null ) {
+            this.firstNode.setPreviousRightTupleSinkNode( null );
+        } else {
+            this.lastNode = null;
+        }
+        this.size--;
+        return node;
+    }
+
+    /**
+     * Remove the last node from the list. The previous node then becomes the last node. If this is the last
+     * node then both first and last node references are set to null.
+     *
+     * @return
+     *      The first <code>ObjectSinkNode</code>.
+     */
+    public RightTupleSinkNode removeLast() {
+        if ( this.lastNode == null ) {
+            return null;
+        }
+        final RightTupleSinkNode node = this.lastNode;
+        this.lastNode = node.getPreviousRightTupleSinkNode();
+        node.setPreviousRightTupleSinkNode( null );
+        if ( this.lastNode != null ) {
+            this.lastNode.setNextRightTupleSinkNode( null );
+        } else {
+            this.firstNode = this.lastNode;
+        }
+        this.size--;
+        return node;
+    }
+
+    /**
+     * @return
+     *      boolean value indicating the empty status of the list
+     */
+    public final boolean isEmpty() {
+        return (this.firstNode == null);
+    }
+
+    /**
+     * Iterates the list removing all the nodes until there are no more nodes to remove.
+     */
+    public void clear() {
+        while ( removeFirst() != null ) {
+        }
+    }
+
+    /**
+     * @return
+     *     return size of the list as an int
+     */
+    public final int size() {
+        return this.size;
+    }
+
+    /**
+     * Returns a list iterator
+     * @return
+     */
+    public Iterator iterator() {
+        return new Iterator() {
+            private RightTupleSinkNode currentNode = null;
+            private RightTupleSinkNode nextNode    = getFirst();
+
+            public boolean hasNext() {
+                return (this.nextNode != null);
+            }
+
+            public Object next() {
+                this.currentNode = this.nextNode;
+                if ( this.currentNode != null ) {
+                    this.nextNode = this.currentNode.getNextRightTupleSinkNode();
+                } else {
+                    throw new NoSuchElementException( "No more elements to return" );
+                }
+                return this.currentNode;
+            }
+
+            public void remove() {
+                if ( this.currentNode != null ) {
+                    RightTupleSinkNodeList.this.remove( this.currentNode );
+                    this.currentNode = null;
+                } else {
+                    throw new IllegalStateException( "No item to remove. Call next() before calling remove()." );
+                }
+            }
+        };
+    }
+
+}

Copied: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightTupleSinkPropagator.java (from rev 19131, labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectSinkPropagator.java)
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightTupleSinkPropagator.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightTupleSinkPropagator.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -0,0 +1,20 @@
+package org.drools.reteoo;
+
+import java.io.Serializable;
+import java.io.Externalizable;
+
+import org.drools.common.InternalFactHandle;
+import org.drools.common.InternalWorkingMemory;
+import org.drools.spi.PropagationContext;
+
+public interface RightTupleSinkPropagator
+    extends
+    Externalizable {
+    public void propagateAssertFact(InternalFactHandle factHandle,
+                                          PropagationContext context,
+                                          InternalWorkingMemory workingMemory);
+
+    public RightTupleSink[] getSinks();
+
+    public int size();
+}

Copied: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightTupleSource.java (from rev 19131, labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectSource.java)
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightTupleSource.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightTupleSource.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -0,0 +1,165 @@
+package org.drools.reteoo;
+
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.Serializable;
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import org.drools.common.BaseNode;
+import org.drools.common.DefaultFactHandle;
+import org.drools.common.InternalWorkingMemory;
+import org.drools.spi.PropagationContext;
+
+/**
+ * A source of <code>FactHandle</code>s for an <code>ObjectSink</code>.
+ *
+ * <p>
+ * Nodes that propagate <code>FactHandleImpl</code> extend this class.
+ * </p>
+ *
+ * @see RightTupleSource
+ * @see DefaultFactHandle
+ *
+ * @author <a href="mailto:mark.proctor at jboss.com">Mark Proctor</a>
+ * @author <a href="mailto:bob at werken.com">Bob McWhirter</a>
+ */
+public abstract class RightTupleSource extends BaseNode
+    implements
+    Externalizable {
+    // ------------------------------------------------------------
+    // Instance members
+    // ------------------------------------------------------------
+
+    /** The destination for <code>FactHandleImpl</code>. */
+    protected RightTupleSinkPropagator sink;
+
+    protected RightTupleSource         source;
+
+    private int                    alphaNodeHashingThreshold;
+
+    // ------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------
+    public RightTupleSource() {
+
+    }
+
+    /**
+     * Single parameter constructor that specifies the unique id of the node.
+     *
+     * @param id
+     */
+    RightTupleSource(final int id) {
+        this( id,
+              null,
+              3 );
+    }
+
+    /**
+     * Single parameter constructor that specifies the unique id of the node.
+     *
+     * @param id
+     */
+    RightTupleSource(final int id,
+                 final RightTupleSource objectSource,
+                 final int alphaNodeHashingThreshold) {
+        super( id );
+        this.source = objectSource;
+        this.alphaNodeHashingThreshold = alphaNodeHashingThreshold;
+        this.sink = EmptyRightTupleSinkAdapter.getInstance();
+    }
+
+    // ------------------------------------------------------------
+    // Instance methods
+    // ------------------------------------------------------------
+    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+        super.readExternal(in);
+        sink    = (RightTupleSinkPropagator)in.readObject();
+        source    = (RightTupleSource)in.readObject();
+        alphaNodeHashingThreshold   = in.readInt();
+    }
+
+    public void writeExternal(ObjectOutput out) throws IOException {
+        super.writeExternal(out);
+        out.writeObject(sink);
+        out.writeObject(source);
+        out.writeInt(alphaNodeHashingThreshold);
+    }
+
+    /**
+     * Adds the <code>ObjectSink</code> so that it may receive
+     * <code>FactHandleImpl</code> propagated from this
+     * <code>ObjectSource</code>.
+     *
+     * @param objectSink
+     *            The <code>ObjectSink</code> to receive propagated
+     *            <code>FactHandleImpl</code>.
+     */
+    protected void addObjectSink(final RightTupleSink objectSink) {
+        if ( this.sink instanceof EmptyRightTupleSinkAdapter ) {
+            this.sink = new SingleRightTupleSinkAdapter( objectSink );
+        } else if ( this.sink instanceof SingleRightTupleSinkAdapter ) {
+            final CompositeRightTupleSinkAdapter sinkAdapter = new CompositeRightTupleSinkAdapter( this.alphaNodeHashingThreshold );
+            sinkAdapter.addObjectSink( this.sink.getSinks()[0] );
+            sinkAdapter.addObjectSink( objectSink );
+            this.sink = sinkAdapter;
+        } else {
+            ((CompositeRightTupleSinkAdapter) this.sink).addObjectSink( objectSink );
+        }
+    }
+
+    /**
+     * Removes the <code>ObjectSink</code>
+     *
+     * @param objectSink
+     *            The <code>ObjectSink</code> to remove
+     */
+    protected void removeObjectSink(final RightTupleSink objectSink) {
+        if ( this.sink instanceof EmptyRightTupleSinkAdapter ) {
+            throw new IllegalArgumentException( "Cannot remove a sink, when the list of sinks is null" );
+        }
+
+        if ( this.sink instanceof SingleRightTupleSinkAdapter ) {
+            this.sink = EmptyRightTupleSinkAdapter.getInstance();
+        } else {
+            final CompositeRightTupleSinkAdapter sinkAdapter = (CompositeRightTupleSinkAdapter) this.sink;
+            sinkAdapter.removeObjectSink( objectSink );
+            if ( sinkAdapter.size() == 1 ) {
+                this.sink = new SingleRightTupleSinkAdapter( sinkAdapter.getSinks()[0] );
+            }
+        }
+    }
+
+    public abstract void updateSink(RightTupleSink sink,
+                                    PropagationContext context,
+                                    InternalWorkingMemory workingMemory);
+    
+    public void networkUpdated() {
+        this.source.networkUpdated();
+    }
+
+    public RightTupleSinkPropagator getSinkPropagator() {
+        return this.sink;
+    }
+
+    public boolean isInUse() {
+        return this.sink.size() > 0;
+    }
+}

Copied: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/SingleLeftTupleSinkAdapter.java (from rev 19176, labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/SingleTupleSinkAdapter.java)
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/SingleLeftTupleSinkAdapter.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/SingleLeftTupleSinkAdapter.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -0,0 +1,121 @@
+package org.drools.reteoo;
+
+import org.drools.common.InternalFactHandle;
+import org.drools.common.InternalWorkingMemory;
+import org.drools.spi.PropagationContext;
+
+import java.io.ObjectInput;
+import java.io.IOException;
+import java.io.ObjectOutput;
+
+public class SingleLeftTupleSinkAdapter
+    implements
+    LeftTupleSinkPropagator {
+    private LeftTupleSink sink;
+
+    public SingleLeftTupleSinkAdapter() {
+        
+    }
+
+    public SingleLeftTupleSinkAdapter(final LeftTupleSink sink) {
+        this.sink = sink;
+    }
+
+    public void propagateAssertLeftTuple(final LeftTuple leftTuple,
+                                     final RightTuple rightTuple,
+                                     final PropagationContext context,
+                                     final InternalWorkingMemory workingMemory) {
+        this.sink.assertLeftTuple( new LeftTuple( leftTuple,
+                                              rightTuple,
+                                              this.sink ),
+                               context,
+                               workingMemory );
+    }
+
+    public void propagateAssertLeftTuple(final LeftTuple tuple,
+                                     final PropagationContext context,
+                                     final InternalWorkingMemory workingMemory) {
+        this.sink.assertLeftTuple( new LeftTuple( tuple,
+                                              this.sink ),
+                               context,
+                               workingMemory );
+    }
+    
+//    public void propagateNotRetractLeftTuple(final LeftTuple leftTuple,
+//                                          final PropagationContext context,
+//                                          final InternalWorkingMemory workingMemory) {
+//            LeftTuple child = leftTuple.getBetaChildren();
+//            while ( child != null ) {
+//                //LeftTuple temp = leftTuple.getRightParentNext();
+//                //child.unlinkFromParents();
+//                //child.unlinkFromLeftParent();
+//                child.getSink().retractTuple( child,
+//                                              context,
+//                                              workingMemory );
+//                child = child.getLeftParentNext();
+//                //child = temp;
+//            }
+//            leftTuple.setBetaChildren( null );
+//        }    
+
+    public void propagateRetractLeftTuple(final LeftTuple leftTuple,
+                                      final PropagationContext context,
+                                      final InternalWorkingMemory workingMemory) {
+        LeftTuple child = leftTuple.getBetaChildren();
+        while ( child != null ) {
+            LeftTuple temp = child.getLeftParentNext();
+            //child.unlinkFromParents();
+            child.getSink().retractLeftTuple( child,
+                                          context,
+                                          workingMemory );
+            child.unlinkFromRightParent();            
+            //child = child.getLeftParentNext();
+            child = temp;
+        }
+        leftTuple.setBetaChildren( null );
+    }
+    
+    public void propagateRetractRightTuple(final RightTuple rightTuple,
+                                      final PropagationContext context,
+                                      final InternalWorkingMemory workingMemory) {
+        LeftTuple child = rightTuple.getBetaChildren();
+        while ( child != null ) {
+            LeftTuple temp = child.getRightParentNext();
+            //child.unlinkFromParents();
+            child.getSink().retractLeftTuple( child,
+                                          context,
+                                          workingMemory );
+            child.unlinkFromLeftParent();            
+            //child = child.getRightParentNext();
+            child = temp;
+        }
+        rightTuple.setBetaChildren( null );
+    }    
+
+    public void createAndPropagateAssertLeftTuple(final InternalFactHandle factHandle,
+                                              final PropagationContext context,
+                                              final InternalWorkingMemory workingMemory) {
+        this.sink.assertLeftTuple( new LeftTuple( factHandle,
+                                              this.sink ),
+                               context,
+                               workingMemory );
+    }
+
+    public LeftTupleSink[] getSinks() {
+        return new LeftTupleSink[]{this.sink};
+    }
+
+    public int size() {
+        return (this.sink != null) ? 1 : 0;
+    }
+
+    public void readExternal(ObjectInput in) throws IOException,
+                                            ClassNotFoundException {
+        // @todo
+        
+    }
+
+    public void writeExternal(ObjectOutput out) throws IOException {
+        // @todo        
+    }
+}

Deleted: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/SingleObjectSinkAdapter.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/SingleObjectSinkAdapter.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/SingleObjectSinkAdapter.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -1,61 +0,0 @@
-package org.drools.reteoo;
-
-import org.drools.common.InternalFactHandle;
-import org.drools.common.InternalWorkingMemory;
-import org.drools.spi.PropagationContext;
-
-import java.io.Externalizable;
-import java.io.ObjectOutput;
-import java.io.IOException;
-import java.io.ObjectInput;
-
-public class SingleObjectSinkAdapter
-    implements
-    ObjectSinkPropagator, Externalizable {
-
-    private static final long serialVersionUID = 873985743021L;
-
-    private ObjectSink sink;
-
-    public SingleObjectSinkAdapter() {
-
-    }
-    public SingleObjectSinkAdapter(final ObjectSink sink) {
-        this.sink = sink;
-    }
-
-    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        sink    = (ObjectSink)in.readObject();
-    }
-
-    public void writeExternal(ObjectOutput out) throws IOException {
-        out.writeObject(sink);
-    }
-    public void propagateAssertObject(final InternalFactHandle handle,
-                                      final PropagationContext context,
-                                      final InternalWorkingMemory workingMemory) {
-        this.sink.assertObject( handle,
-                                context,
-                                workingMemory );
-
-    }
-
-    public void propagateRetractObject(final InternalFactHandle handle,
-                                       final PropagationContext context,
-                                       final InternalWorkingMemory workingMemory,
-                                       final boolean useHash) {
-        this.sink.retractObject( handle,
-                                 context,
-                                 workingMemory );
-
-    }
-
-    public ObjectSink[] getSinks() {
-        return new ObjectSink[]{this.sink};
-    }
-
-    public int size() {
-        return 1;
-    }
-
-}

Copied: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/SingleRightTupleSinkAdapter.java (from rev 19131, labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/SingleObjectSinkAdapter.java)
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/SingleRightTupleSinkAdapter.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/SingleRightTupleSinkAdapter.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -0,0 +1,55 @@
+package org.drools.reteoo;
+
+import org.drools.common.InternalFactHandle;
+import org.drools.common.InternalWorkingMemory;
+import org.drools.spi.PropagationContext;
+
+import java.io.Externalizable;
+import java.io.ObjectOutput;
+import java.io.IOException;
+import java.io.ObjectInput;
+
+public class SingleRightTupleSinkAdapter
+    implements
+    RightTupleSinkPropagator,
+    Externalizable {
+
+    private static final long serialVersionUID = 873985743021L;
+
+    private RightTupleSink    sink;
+
+    public SingleRightTupleSinkAdapter() {
+
+    }
+
+    public SingleRightTupleSinkAdapter(final RightTupleSink sink) {
+        this.sink = sink;
+    }
+
+    public void readExternal(ObjectInput in) throws IOException,
+                                            ClassNotFoundException {
+        sink = (RightTupleSink) in.readObject();
+    }
+
+    public void writeExternal(ObjectOutput out) throws IOException {
+        out.writeObject( sink );
+    }
+
+    public void propagateAssertFact(final InternalFactHandle factHandle,
+                                          final PropagationContext context,
+                                          final InternalWorkingMemory workingMemory) {
+        this.sink.assertObject( factHandle,
+                                    context,
+                                    workingMemory );
+
+    }
+
+    public RightTupleSink[] getSinks() {
+        return new RightTupleSink[]{this.sink};
+    }
+
+    public int size() {
+        return 1;
+    }
+
+}

Deleted: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/SingleTupleSinkAdapter.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/SingleTupleSinkAdapter.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/SingleTupleSinkAdapter.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -1,91 +0,0 @@
-package org.drools.reteoo;
-
-import org.drools.common.InternalFactHandle;
-import org.drools.common.InternalWorkingMemory;
-import org.drools.spi.PropagationContext;
-
-import java.io.ObjectInput;
-import java.io.IOException;
-import java.io.ObjectOutput;
-
-public class SingleTupleSinkAdapter
-    implements
-    LeftTupleSinkPropagator {
-    private LeftTupleSink sink;
-
-    public SingleTupleSinkAdapter() {
-        
-    }
-
-    public SingleTupleSinkAdapter(final LeftTupleSink sink) {
-        this.sink = sink;
-    }
-
-    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        sink   = (LeftTupleSink)in.readObject();
-    }
-
-    public void writeExternal(ObjectOutput out) throws IOException {
-        out.writeObject(sink);
-    }
-
-    public void propagateAssertLeftTuple(final LeftTuple tuple,
-                                     final InternalFactHandle handle,
-                                     final PropagationContext context,
-                                     final InternalWorkingMemory workingMemory) {
-        this.sink.assertLeftTuple( new LeftTuple( tuple,
-                                              handle ),
-                               context,
-                               workingMemory );
-    }
-
-    public void propagateAssertLeftTuple(final LeftTuple tuple,
-                                     final PropagationContext context,
-                                     final InternalWorkingMemory workingMemory) {
-        this.sink.assertLeftTuple( new LeftTuple( tuple ),
-                               context,
-                               workingMemory );
-    }
-
-    public void propagateRetractLeftTuple(final LeftTuple tuple,
-                                      final InternalFactHandle handle,
-                                      final PropagationContext context,
-                                      final InternalWorkingMemory workingMemory) {
-        this.sink.retractLeftTuple( new LeftTuple( tuple,
-                                               handle ),
-                                context,
-                                workingMemory );
-    }
-
-    public void propagateRetractLeftTuple(final LeftTuple tuple,
-                                      final PropagationContext context,
-                                      final InternalWorkingMemory workingMemory) {
-        this.sink.retractLeftTuple( new LeftTuple( tuple ),
-                                context,
-                                workingMemory );
-    }
-
-    public void createAndPropagateAssertLeftTuple(final InternalFactHandle handle,
-                                              final PropagationContext context,
-                                              final InternalWorkingMemory workingMemory) {
-        this.sink.assertLeftTuple( new LeftTuple( handle ),
-                               context,
-                               workingMemory );
-    }
-
-    public void createAndPropagateRetractLeftTuple(final InternalFactHandle handle,
-                                               final PropagationContext context,
-                                               final InternalWorkingMemory workingMemory) {
-        this.sink.retractLeftTuple( new LeftTuple( handle ),
-                                context,
-                                workingMemory );
-    }
-
-    public LeftTupleSink[] getSinks() {
-        return new LeftTupleSink[]{this.sink};
-    }
-
-    public int size() {
-        return (this.sink != null) ? 1 : 0;
-    }
-}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/AccumulateBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/AccumulateBuilder.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/AccumulateBuilder.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -22,7 +22,7 @@
 import org.drools.common.BetaConstraints;
 import org.drools.common.TupleStartEqualsConstraint;
 import org.drools.reteoo.AccumulateNode;
-import org.drools.reteoo.ObjectSource;
+import org.drools.reteoo.RightTupleSource;
 import org.drools.reteoo.RightInputAdapterNode;
 import org.drools.reteoo.LeftTupleSource;
 import org.drools.rule.Accumulate;
@@ -67,7 +67,7 @@
         if ( context.getObjectSource() == null ) {
 
             // attach right input adapter node to convert tuple source into an object source
-            context.setObjectSource( (ObjectSource) utils.attachNode( context,
+            context.setObjectSource( (RightTupleSource) utils.attachNode( context,
                                                                       new RightInputAdapterNode( context.getNextId(),
                                                                                                  context.getTupleSource(),
                                                                                                  context ) ) );

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/BuildContext.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/BuildContext.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/BuildContext.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -25,7 +25,7 @@
 import org.drools.common.BetaConstraints;
 import org.drools.common.InternalRuleBase;
 import org.drools.common.InternalWorkingMemory;
-import org.drools.reteoo.ObjectSource;
+import org.drools.reteoo.RightTupleSource;
 import org.drools.reteoo.ReteooBuilder;
 import org.drools.reteoo.ReteooRuleBase;
 import org.drools.reteoo.LeftTupleSource;
@@ -43,7 +43,7 @@
     private LeftTupleSource               tupleSource;
 
     // object source to attach next node to
-    private ObjectSource              objectSource;
+    private RightTupleSource              objectSource;
 
     // object type cache to check for cross products
     private LinkedList                objectType;
@@ -131,14 +131,14 @@
     /**
      * @return the objectSource
      */
-    public ObjectSource getObjectSource() {
+    public RightTupleSource getObjectSource() {
         return this.objectSource;
     }
 
     /**
      * @param objectSource the objectSource to set
      */
-    public void setObjectSource(final ObjectSource objectSource) {
+    public void setObjectSource(final RightTupleSource objectSource) {
         this.objectSource = objectSource;
     }
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/BuildUtils.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/BuildUtils.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/BuildUtils.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -32,8 +32,8 @@
 import org.drools.common.SingleBetaConstraints;
 import org.drools.common.TripleBetaConstraints;
 import org.drools.reteoo.EntryPointNode;
-import org.drools.reteoo.ObjectSink;
-import org.drools.reteoo.ObjectSource;
+import org.drools.reteoo.RightTupleSink;
+import org.drools.reteoo.RightTupleSource;
 import org.drools.reteoo.ObjectTypeNode;
 import org.drools.reteoo.LeftTupleSink;
 import org.drools.reteoo.LeftTupleSource;
@@ -114,8 +114,8 @@
                         break;
                     }
                 }
-            } else if ( (context.getObjectSource() != null) && (candidate instanceof ObjectSink) ) {
-                ObjectSink[] sinks = context.getObjectSource().getSinkPropagator().getSinks();
+            } else if ( (context.getObjectSource() != null) && (candidate instanceof RightTupleSink) ) {
+                RightTupleSink[] sinks = context.getObjectSource().getSinkPropagator().getSinks();
                 for( int i = 0; i < sinks.length; i++ ) {
                     if( candidate.equals( sinks[i] ) ) {
                         node = (BaseNode) sinks[i];
@@ -157,7 +157,7 @@
                                             final BaseNode node) {
         if ( node instanceof LeftTupleSource ) {
             return context.getRuleBase().getConfiguration().isShareBetaNodes();
-        } else if ( node instanceof ObjectSource ) {
+        } else if ( node instanceof RightTupleSource ) {
             return context.getRuleBase().getConfiguration().isShareAlphaNodes();
         }
         return false;

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/CollectBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/CollectBuilder.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/CollectBuilder.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -22,7 +22,7 @@
 import org.drools.common.BetaConstraints;
 import org.drools.common.TupleStartEqualsConstraint;
 import org.drools.reteoo.CollectNode;
-import org.drools.reteoo.ObjectSource;
+import org.drools.reteoo.RightTupleSource;
 import org.drools.reteoo.RightInputAdapterNode;
 import org.drools.reteoo.LeftTupleSource;
 import org.drools.rule.Collect;
@@ -69,7 +69,7 @@
         if ( context.getObjectSource() == null ) {
 
             // attach right input adapter node to convert tuple source into an object source
-            context.setObjectSource( (ObjectSource) utils.attachNode( context,
+            context.setObjectSource( (RightTupleSource) utils.attachNode( context,
                                                                       new RightInputAdapterNode( context.getNextId(),
                                                                                                  context.getTupleSource(),
                                                                                                  context ) ) );

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/GroupElementBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/GroupElementBuilder.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/GroupElementBuilder.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -29,7 +29,7 @@
 import org.drools.reteoo.JoinNode;
 import org.drools.reteoo.LeftInputAdapterNode;
 import org.drools.reteoo.NotNode;
-import org.drools.reteoo.ObjectSource;
+import org.drools.reteoo.RightTupleSource;
 import org.drools.reteoo.RightInputAdapterNode;
 import org.drools.reteoo.LeftTupleSource;
 import org.drools.rule.GroupElement;
@@ -215,7 +215,7 @@
             if ( context.getObjectSource() == null && context.getTupleSource() != null ) {
 
                 // attach right input adapter node to convert tuple source into an object source
-                context.setObjectSource( (ObjectSource) utils.attachNode( context,
+                context.setObjectSource( (RightTupleSource) utils.attachNode( context,
                                                                           new RightInputAdapterNode( context.getNextId(),
                                                                                                      context.getTupleSource(),
                                                                                                      context ) ) );
@@ -292,7 +292,7 @@
             if ( context.getObjectSource() == null && context.getTupleSource() != null ) {
 
                 // attach right input adapter node to convert tuple source into an object source
-                context.setObjectSource( (ObjectSource) utils.attachNode( context,
+                context.setObjectSource( (RightTupleSource) utils.attachNode( context,
                                                                           new RightInputAdapterNode( context.getNextId(),
                                                                                                      context.getTupleSource(),
                                                                                                      context ) ) );

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/PatternBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/PatternBuilder.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/PatternBuilder.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -27,7 +27,7 @@
 import org.drools.common.InternalWorkingMemory;
 import org.drools.reteoo.AlphaNode;
 import org.drools.reteoo.EntryPointNode;
-import org.drools.reteoo.ObjectSource;
+import org.drools.reteoo.RightTupleSource;
 import org.drools.reteoo.ObjectTypeNode;
 import org.drools.reteoo.PropagationQueuingNode;
 import org.drools.rule.Declaration;
@@ -108,7 +108,7 @@
                               alphaConstraints );
 
             if ( context.getCurrentEntryPoint() != EntryPoint.DEFAULT ) {
-                context.setObjectSource( (ObjectSource) utils.attachNode( context,
+                context.setObjectSource( (RightTupleSource) utils.attachNode( context,
                                                                           new PropagationQueuingNode( context.getNextId(),
                                                                                                       context.getObjectSource(),
                                                                                                       context ) ) );
@@ -209,12 +209,12 @@
             }
         }
 
-        context.setObjectSource( (ObjectSource) utils.attachNode( context,
+        context.setObjectSource( (RightTupleSource) utils.attachNode( context,
                                                                   new EntryPointNode( context.getNextId(),
                                                                                       context.getRuleBase().getRete(),
                                                                                       context ) ) );
 
-        context.setObjectSource( (ObjectSource) utils.attachNode( context,
+        context.setObjectSource( (RightTupleSource) utils.attachNode( context,
                                                                   new ObjectTypeNode( context.getNextId(),
                                                                                       (EntryPointNode) context.getObjectSource(),
                                                                                       pattern.getObjectType(),
@@ -223,7 +223,7 @@
         for ( final Iterator it = alphaConstraints.iterator(); it.hasNext(); ) {
             final AlphaNodeFieldConstraint constraint = (AlphaNodeFieldConstraint) it.next();
 
-            context.setObjectSource( (ObjectSource) utils.attachNode( context,
+            context.setObjectSource( (RightTupleSource) utils.attachNode( context,
                                                                       new AlphaNode( context.getNextId(),
                                                                                      (AlphaNodeFieldConstraint) constraint,
                                                                                      context.getObjectSource(),

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/FactHandleIndexHashTable.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/FactHandleIndexHashTable.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/FactHandleIndexHashTable.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -4,7 +4,7 @@
 package org.drools.util;
 
 import org.drools.common.InternalFactHandle;
-import org.drools.reteoo.FactHandleMemory;
+import org.drools.reteoo.RightTupleMemory;
 import org.drools.reteoo.LeftTuple;
 import org.drools.util.TupleIndexHashTable.FieldIndexEntry;
 
@@ -15,7 +15,7 @@
 
 public class FactHandleIndexHashTable extends AbstractHashTable
     implements
-    FactHandleMemory, Externalizable {
+    RightTupleMemory, Externalizable {
 
     private static final long           serialVersionUID = 400L;
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/FactHashTable.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/FactHashTable.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/FactHashTable.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -4,12 +4,12 @@
 package org.drools.util;
 
 import org.drools.common.InternalFactHandle;
-import org.drools.reteoo.FactHandleMemory;
+import org.drools.reteoo.RightTupleMemory;
 import org.drools.reteoo.LeftTuple;
 
 public class FactHashTable extends AbstractHashTable
     implements
-    FactHandleMemory {
+    RightTupleMemory {
     private static final long serialVersionUID = 400L;
 
     public FactHashTable() {

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/FactList.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/FactList.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/FactList.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -6,12 +6,12 @@
 import java.io.Serializable;
 
 import org.drools.common.InternalFactHandle;
-import org.drools.reteoo.FactHandleMemory;
+import org.drools.reteoo.RightTupleMemory;
 import org.drools.reteoo.LeftTuple;
 
 public class FactList
     implements
-    FactHandleMemory {
+    RightTupleMemory {
     private static final long serialVersionUID = 400L;
 
     private final LinkedList list;

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/common/BaseBetaConstraintsTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/common/BaseBetaConstraintsTest.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/common/BaseBetaConstraintsTest.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -101,7 +101,7 @@
         BetaMemory betaMemory = betaConstraints.createBetaMemory( config );
 
         if ( indexedPositions.length > 0 ) {
-            TupleIndexHashTable tupleHashTable = (TupleIndexHashTable) betaMemory.getTupleMemory();
+            TupleIndexHashTable tupleHashTable = (TupleIndexHashTable) betaMemory.getLeftTupleMemory();
             assertTrue( tupleHashTable.isIndexed() );
             Index index = tupleHashTable.getIndex();
 
@@ -110,7 +110,7 @@
                                              index.getFieldIndex( i ) );
             }
 
-            FactHandleIndexHashTable factHashTable = (FactHandleIndexHashTable) betaMemory.getFactHandleMemory();
+            FactHandleIndexHashTable factHashTable = (FactHandleIndexHashTable) betaMemory.getRightTupleMemory();
             assertTrue( factHashTable.isIndexed() );
             index = factHashTable.getIndex();
 
@@ -119,10 +119,10 @@
                                              index.getFieldIndex( i ) );
             }
         } else {
-            TupleHashTable tupleHashTable = (TupleHashTable) betaMemory.getTupleMemory();
+            TupleHashTable tupleHashTable = (TupleHashTable) betaMemory.getLeftTupleMemory();
             assertFalse( tupleHashTable.isIndexed() );
 
-            FactHashTable factHashTable = (FactHashTable) betaMemory.getFactHandleMemory();
+            FactHashTable factHashTable = (FactHashTable) betaMemory.getRightTupleMemory();
             assertFalse( factHashTable.isIndexed() );
         }
     }

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/AccumulateNodeTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/AccumulateNodeTest.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/AccumulateNodeTest.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -105,9 +105,9 @@
 
         // check memories are empty
         assertEquals( 0,
-                      this.memory.getTupleMemory().size() );
+                      this.memory.getLeftTupleMemory().size() );
         assertEquals( 0,
-                      this.memory.getFactHandleMemory().size() );
+                      this.memory.getRightTupleMemory().size() );
     }
 
     /* (non-Javadoc)
@@ -164,9 +164,9 @@
                                this.workingMemory );
         // check memories 
         assertEquals( 1,
-                      this.memory.getTupleMemory().size() );
+                      this.memory.getLeftTupleMemory().size() );
         assertEquals( 0,
-                      this.memory.getFactHandleMemory().size() );
+                      this.memory.getRightTupleMemory().size() );
         Assert.assertTrue( "An empty matching objects list should be propagated",
                            this.accumulator.getMatchingObjects().isEmpty() );
 
@@ -178,11 +178,11 @@
                                this.context,
                                this.workingMemory );
         assertEquals( 2,
-                      this.memory.getTupleMemory().size() );
+                      this.memory.getLeftTupleMemory().size() );
         Assert.assertTrue( "An empty matching objects list should be propagated",
                            this.accumulator.getMatchingObjects().isEmpty() );
 
-        final LeftTupleMemory memory = this.memory.getTupleMemory();
+        final LeftTupleMemory memory = this.memory.getLeftTupleMemory();
         assertTrue( memory.contains( tuple0 ) );
         assertTrue( memory.contains( tuple1 ) );
 
@@ -213,9 +213,9 @@
                                this.workingMemory );
         // check memories 
         assertEquals( 1,
-                      this.memory.getTupleMemory().size() );
+                      this.memory.getLeftTupleMemory().size() );
         assertEquals( 2,
-                      this.memory.getFactHandleMemory().size() );
+                      this.memory.getRightTupleMemory().size() );
         Assert.assertEquals( "Wrong number of elements in matching objects list ",
                              2,
                              this.accumulator.getMatchingObjects().size() );
@@ -226,12 +226,12 @@
                                this.context,
                                this.workingMemory );
         assertEquals( 2,
-                      this.memory.getTupleMemory().size() );
+                      this.memory.getLeftTupleMemory().size() );
         Assert.assertEquals( "Wrong number of elements in matching objects list ",
                              2,
                              this.accumulator.getMatchingObjects().size() );
 
-        final LeftTupleMemory memory = this.memory.getTupleMemory();
+        final LeftTupleMemory memory = this.memory.getLeftTupleMemory();
         assertTrue( memory.contains( tuple0 ) );
         assertTrue( memory.contains( tuple1 ) );
 
@@ -254,9 +254,9 @@
                                this.workingMemory );
         // check memories 
         assertEquals( 1,
-                      this.memory.getTupleMemory().size() );
+                      this.memory.getLeftTupleMemory().size() );
         assertEquals( 0,
-                      this.memory.getFactHandleMemory().size() );
+                      this.memory.getRightTupleMemory().size() );
         Assert.assertTrue( "An empty matching objects list should be propagated",
                            this.accumulator.getMatchingObjects().isEmpty() );
 
@@ -264,7 +264,7 @@
                                 this.context,
                                 this.workingMemory );
         assertEquals( 0,
-                      this.memory.getTupleMemory().size() );
+                      this.memory.getLeftTupleMemory().size() );
         assertEquals( 1,
                       this.sink.getRetracted().size() );
         assertEquals( 1,
@@ -287,7 +287,7 @@
 
         // check memory 
         assertEquals( 1,
-                      this.memory.getTupleMemory().size() );
+                      this.memory.getLeftTupleMemory().size() );
         assertEquals( 1,
                       this.sink.getAsserted().size() );
         assertEquals( 0,
@@ -297,7 +297,7 @@
                                 this.context,
                                 this.workingMemory );
         assertEquals( 1,
-                      this.memory.getFactHandleMemory().size() );
+                      this.memory.getRightTupleMemory().size() );
         assertEquals( 2,
                       this.sink.getAsserted().size() );
         assertEquals( 1,
@@ -308,7 +308,7 @@
                                 this.workingMemory );
 
         assertEquals( 2,
-                      this.memory.getFactHandleMemory().size() );
+                      this.memory.getRightTupleMemory().size() );
         assertEquals( 3,
                       this.sink.getAsserted().size() );
         assertEquals( 2,
@@ -332,7 +332,7 @@
                                 this.context,
                                 this.workingMemory );
         assertEquals( 2,
-                      this.memory.getFactHandleMemory().size() );
+                      this.memory.getRightTupleMemory().size() );
 
         // assert tuple, should add one to left memory
         this.node.assertLeftTuple( tuple0,
@@ -341,7 +341,7 @@
 
         // check memory 
         assertEquals( 1,
-                      this.memory.getTupleMemory().size() );
+                      this.memory.getLeftTupleMemory().size() );
         assertEquals( 0,
                       this.sink.getRetracted().size() );
         assertEquals( 1,
@@ -353,7 +353,7 @@
                                  this.context,
                                  this.workingMemory );
         assertEquals( 1,
-                      this.memory.getFactHandleMemory().size() );
+                      this.memory.getRightTupleMemory().size() );
         assertEquals( 1,
                       this.sink.getRetracted().size() );
         assertEquals( 2,
@@ -365,7 +365,7 @@
                                  this.context,
                                  this.workingMemory );
         assertEquals( 0,
-                      this.memory.getFactHandleMemory().size() );
+                      this.memory.getRightTupleMemory().size() );
         assertEquals( 2,
                       this.sink.getRetracted().size() );
         assertEquals( 3,
@@ -448,9 +448,9 @@
                                this.context,
                                this.workingMemory );
         // check memories 
-        assertNull( this.memory.getTupleMemory() );
+        assertNull( this.memory.getLeftTupleMemory() );
         assertEquals( 2,
-                      this.memory.getFactHandleMemory().size() );
+                      this.memory.getRightTupleMemory().size() );
         Assert.assertEquals( "Wrong number of elements in matching objects list ",
                              2,
                              this.accumulator.getMatchingObjects().size() );
@@ -460,7 +460,7 @@
         this.node.assertLeftTuple( tuple1,
                                this.context,
                                this.workingMemory );
-        assertNull( this.memory.getTupleMemory() );
+        assertNull( this.memory.getLeftTupleMemory() );
         Assert.assertEquals( "Wrong number of elements in matching objects list ",
                              2,
                              this.accumulator.getMatchingObjects().size() );

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/BetaNodeTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/BetaNodeTest.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/BetaNodeTest.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -47,7 +47,7 @@
      */
     public void testEqualsObject() {
         final LeftTupleSource ts = new MockTupleSource( 1 );
-        final ObjectSource os = new MockObjectSource( 2 );
+        final RightTupleSource os = new MockObjectSource( 2 );
 
         ReteooRuleBase ruleBase = ( ReteooRuleBase ) RuleBaseFactory.newRuleBase();
         BuildContext buildContext = new BuildContext( ruleBase, ruleBase.getReteooBuilder().getIdGenerator() );        

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/CollectNodeTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/CollectNodeTest.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/CollectNodeTest.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -106,9 +106,9 @@
 
         // check memories are empty
         assertEquals( 0,
-                      this.memory.betaMemory.getTupleMemory().size() );
+                      this.memory.betaMemory.getLeftTupleMemory().size() );
         assertEquals( 0,
-                      this.memory.betaMemory.getFactHandleMemory().size() );
+                      this.memory.betaMemory.getRightTupleMemory().size() );
     }
 
     /* (non-Javadoc)
@@ -159,9 +159,9 @@
                                this.workingMemory );
         // check memories 
         assertEquals( 1,
-                      this.memory.betaMemory.getTupleMemory().size() );
+                      this.memory.betaMemory.getLeftTupleMemory().size() );
         assertEquals( 0,
-                      this.memory.betaMemory.getFactHandleMemory().size() );
+                      this.memory.betaMemory.getRightTupleMemory().size() );
         Assert.assertTrue( "An empty collection should be propagated",
                            ((Collection) ((DefaultFactHandle) ((Tuple) ((Object[]) this.sink.getAsserted().get( 0 ))[0]).get( 1 )).getObject()).isEmpty() );
 
@@ -173,12 +173,12 @@
                                this.contextAssert,
                                this.workingMemory );
         assertEquals( 2,
-                      this.memory.betaMemory.getTupleMemory().size() );
+                      this.memory.betaMemory.getLeftTupleMemory().size() );
         Assert.assertTrue( "An empty collection should be propagated",
                            ((Collection) ((DefaultFactHandle) ((Tuple) ((Object[]) this.sink.getAsserted().get( 1 ))[0]).get( 1 )).getObject()).isEmpty() );
 
-        assertTrue( this.memory.betaMemory.getTupleMemory().contains( tuple0 ) );
-        assertTrue( this.memory.betaMemory.getTupleMemory().contains( tuple1 ) );
+        assertTrue( this.memory.betaMemory.getLeftTupleMemory().contains( tuple0 ) );
+        assertTrue( this.memory.betaMemory.getLeftTupleMemory().contains( tuple1 ) );
 
         Assert.assertEquals( "Two tuples should have been propagated",
                              2,
@@ -204,9 +204,9 @@
                                this.workingMemory );
         // check memories 
         assertEquals( 1,
-                      this.memory.betaMemory.getTupleMemory().size() );
+                      this.memory.betaMemory.getLeftTupleMemory().size() );
         assertEquals( 2,
-                      this.memory.betaMemory.getFactHandleMemory().size() );
+                      this.memory.betaMemory.getRightTupleMemory().size() );
         Assert.assertEquals( "Wrong number of elements in matching objects list ",
                              2,
                              ((Collection) ((DefaultFactHandle) ((Tuple) ((Object[]) this.sink.getAsserted().get( 0 ))[0]).get( 1 )).getObject()).size() );
@@ -217,13 +217,13 @@
                                this.contextAssert,
                                this.workingMemory );
         assertEquals( 2,
-                      this.memory.betaMemory.getTupleMemory().size() );
+                      this.memory.betaMemory.getLeftTupleMemory().size() );
         Assert.assertEquals( "Wrong number of elements in matching objects list ",
                              2,
                              ((Collection) ((DefaultFactHandle) ((Tuple) ((Object[]) this.sink.getAsserted().get( 1 ))[0]).get( 1 )).getObject()).size() );
 
-        assertTrue( this.memory.betaMemory.getTupleMemory().contains( tuple0 ) );
-        assertTrue( this.memory.betaMemory.getTupleMemory().contains( tuple1 ) );
+        assertTrue( this.memory.betaMemory.getLeftTupleMemory().contains( tuple0 ) );
+        assertTrue( this.memory.betaMemory.getLeftTupleMemory().contains( tuple1 ) );
 
         Assert.assertEquals( "Two tuples should have been propagated",
                              2,
@@ -241,9 +241,9 @@
                                this.workingMemory );
         // check memories 
         assertEquals( 1,
-                      this.memory.betaMemory.getTupleMemory().size() );
+                      this.memory.betaMemory.getLeftTupleMemory().size() );
         assertEquals( 0,
-                      this.memory.betaMemory.getFactHandleMemory().size() );
+                      this.memory.betaMemory.getRightTupleMemory().size() );
         Assert.assertTrue( "An empty collection should be propagated",
                            ((Collection) ((DefaultFactHandle) ((Tuple) ((Object[]) this.sink.getAsserted().get( 0 ))[0]).get( 1 )).getObject()).isEmpty() );
 
@@ -251,7 +251,7 @@
                                 this.contextRetract,
                                 this.workingMemory );
         assertEquals( 0,
-                      this.memory.betaMemory.getTupleMemory().size() );
+                      this.memory.betaMemory.getLeftTupleMemory().size() );
         assertEquals( 1,
                       this.sink.getRetracted().size() );
         assertEquals( 1,
@@ -271,7 +271,7 @@
 
         // check memory 
         assertEquals( 1,
-                      this.memory.betaMemory.getTupleMemory().size() );
+                      this.memory.betaMemory.getLeftTupleMemory().size() );
         assertEquals( 1,
                       this.sink.getAsserted().size() );
         Assert.assertTrue( "An empty collection should be propagated",
@@ -281,7 +281,7 @@
                                 this.contextAssert,
                                 this.workingMemory );
         assertEquals( 1,
-                      this.memory.betaMemory.getFactHandleMemory().size() );
+                      this.memory.betaMemory.getRightTupleMemory().size() );
         assertEquals( 2,
                       this.sink.getAsserted().size() );
         Assert.assertEquals( "Wrong number of elements in matching objects list ",
@@ -293,7 +293,7 @@
                                 this.workingMemory );
 
         assertEquals( 2,
-                      this.memory.betaMemory.getFactHandleMemory().size() );
+                      this.memory.betaMemory.getRightTupleMemory().size() );
         assertEquals( 3,
                       this.sink.getAsserted().size() );
         Assert.assertEquals( "Wrong number of elements in matching objects list ",
@@ -315,7 +315,7 @@
                                 this.contextAssert,
                                 this.workingMemory );
         assertEquals( 2,
-                      this.memory.betaMemory.getFactHandleMemory().size() );
+                      this.memory.betaMemory.getRightTupleMemory().size() );
 
         // assert tuple, should add one to left memory
         this.node.assertLeftTuple( tuple0,
@@ -324,7 +324,7 @@
 
         // check memory 
         assertEquals( 1,
-                      this.memory.betaMemory.getTupleMemory().size() );
+                      this.memory.betaMemory.getLeftTupleMemory().size() );
         assertEquals( 0,
                       this.sink.getRetracted().size() );
         assertEquals( 1,
@@ -337,7 +337,7 @@
                                  this.contextRetract,
                                  this.workingMemory );
         assertEquals( 1,
-                      this.memory.betaMemory.getFactHandleMemory().size() );
+                      this.memory.betaMemory.getRightTupleMemory().size() );
         assertEquals( 1,
                       this.sink.getRetracted().size() );
         assertEquals( 2,
@@ -350,7 +350,7 @@
                                  this.contextRetract,
                                  this.workingMemory );
         assertEquals( 0,
-                      this.memory.betaMemory.getFactHandleMemory().size() );
+                      this.memory.betaMemory.getRightTupleMemory().size() );
         assertEquals( 2,
                       this.sink.getRetracted().size() );
         assertEquals( 3,
@@ -413,9 +413,9 @@
                                this.contextAssert,
                                this.workingMemory );
         // check memories 
-        assertNull( this.memory.betaMemory.getTupleMemory() );
+        assertNull( this.memory.betaMemory.getLeftTupleMemory() );
         assertEquals( 2,
-                      this.memory.betaMemory.getFactHandleMemory().size() );
+                      this.memory.betaMemory.getRightTupleMemory().size() );
         Assert.assertEquals( "Wrong number of elements in matching objects list ",
                              2,
                              ((Collection) ((DefaultFactHandle) ((Tuple) ((Object[]) this.sink.getAsserted().get( 0 ))[0]).get( 1 )).getObject()).size() );
@@ -425,7 +425,7 @@
         this.node.assertLeftTuple( tuple1,
                                this.contextAssert,
                                this.workingMemory );
-        assertNull( this.memory.betaMemory.getTupleMemory() );
+        assertNull( this.memory.betaMemory.getLeftTupleMemory() );
         Assert.assertEquals( "Wrong number of elements in matching objects list ",
                              2,
                              ((Collection) ((DefaultFactHandle) ((Tuple) ((Object[]) this.sink.getAsserted().get( 1 ))[0]).get( 1 )).getObject()).size() );

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/CompositeObjectSinkAdapterTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/CompositeObjectSinkAdapterTest.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/CompositeObjectSinkAdapterTest.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -41,7 +41,7 @@
     public String wah;
 
     public void testBeta() {
-        final CompositeObjectSinkAdapter ad = new CompositeObjectSinkAdapter();
+        final CompositeRightTupleSinkAdapter ad = new CompositeRightTupleSinkAdapter();
         final MockBetaNode beta = new MockBetaNode( buildContext.getNextId(),
                                                     null,
                                                     null );
@@ -67,7 +67,7 @@
     }
 
     public void testAlphaWithPredicate() {
-        final CompositeObjectSinkAdapter ad = new CompositeObjectSinkAdapter();
+        final CompositeRightTupleSinkAdapter ad = new CompositeRightTupleSinkAdapter();
         final AlphaNode al = new AlphaNode( buildContext.getNextId(),
                                             new PredicateConstraint( null,
                                                                      null ),
@@ -91,7 +91,7 @@
 
     public void testSingleAlpha() {
 
-        final CompositeObjectSinkAdapter ad = new CompositeObjectSinkAdapter();
+        final CompositeRightTupleSinkAdapter ad = new CompositeRightTupleSinkAdapter();
         final LiteralConstraint lit = new LiteralConstraint( new MockExtractor(),
                                                              equals.getEvaluator( ValueType.STRING_TYPE, Operator.EQUAL ),
                                                              new ObjectFieldImpl( "stilton" ) );
@@ -117,7 +117,7 @@
 
     public void testDoubleAlphaWithBeta() {
 
-        final CompositeObjectSinkAdapter ad = new CompositeObjectSinkAdapter();
+        final CompositeRightTupleSinkAdapter ad = new CompositeRightTupleSinkAdapter();
         final LiteralConstraint lit = new LiteralConstraint( new MockExtractor(),
                                                              equals.getEvaluator( ValueType.STRING_TYPE, Operator.EQUAL ),
                                                              new ObjectFieldImpl( "stilton" ) );
@@ -175,7 +175,7 @@
     }
 
     public void testTripleAlpha() {
-        final CompositeObjectSinkAdapter ad = new CompositeObjectSinkAdapter();
+        final CompositeRightTupleSinkAdapter ad = new CompositeRightTupleSinkAdapter();
         FieldExtractor extractor = ClassFieldExtractorCache.getInstance().getExtractor( Cheese.class,
                                                                                         "type",
                                                                                         this.getClass().getClassLoader() );
@@ -234,7 +234,7 @@
     }
 
     public void testTripleAlphaCharacterConstraint() {
-        final CompositeObjectSinkAdapter ad = new CompositeObjectSinkAdapter();
+        final CompositeRightTupleSinkAdapter ad = new CompositeRightTupleSinkAdapter();
         FieldExtractor extractor = ClassFieldExtractorCache.getInstance().getExtractor( Cheese.class,
                                                                                         "charType",
                                                                                         this.getClass().getClassLoader() );
@@ -286,13 +286,13 @@
         // test propagation
         Cheese cheese = new Cheese();
         cheese.setCharType( 'B' );
-        CompositeObjectSinkAdapter.HashKey hashKey = new CompositeObjectSinkAdapter.HashKey();
+        CompositeRightTupleSinkAdapter.HashKey hashKey = new CompositeRightTupleSinkAdapter.HashKey();
 
         // should find this
         hashKey.setValue( extractor.getIndex(),
                           cheese,
                           extractor );
-        ObjectSink sink = (ObjectSink) ad.hashedSinkMap.get( hashKey );
+        RightTupleSink sink = (RightTupleSink) ad.hashedSinkMap.get( hashKey );
         assertSame( al2, sink );
 
         // should not find this one
@@ -300,7 +300,7 @@
         hashKey.setValue( extractor.getIndex(),
                           cheese,
                           extractor );
-        sink = (ObjectSink) ad.hashedSinkMap.get( hashKey );
+        sink = (RightTupleSink) ad.hashedSinkMap.get( hashKey );
         assertNull( sink );
 
         //now remove one, check the hashing is undone
@@ -314,7 +314,7 @@
 
     public void testPropagationWithNullValue() {
 
-        final CompositeObjectSinkAdapter ad = new CompositeObjectSinkAdapter();
+        final CompositeRightTupleSinkAdapter ad = new CompositeRightTupleSinkAdapter();
         FieldExtractor extractor = ClassFieldExtractorCache.getInstance().getExtractor( Cheese.class,
                                                                                         "type",
                                                                                         this.getClass().getClassLoader() );
@@ -348,7 +348,7 @@
 
         InternalFactHandle handle = new ReteooFactHandleFactory().newFactHandle( new Cheese(), false, null );
         try {
-            ad.propagateAssertObject( handle,
+            ad.propagateAssertFact( handle,
                                       null,
                                       null );
         } catch ( RuntimeException e ) {
@@ -472,7 +472,7 @@
 
         MockBetaNode(final int id,
                      final LeftTupleSource leftInput,
-                     final ObjectSource rightInput) {
+                     final RightTupleSource rightInput) {
             super( id,
                    leftInput,
                    rightInput,
@@ -501,7 +501,7 @@
 
         }
 
-        public void assertObject(final InternalFactHandle handle,
+        public void assertObject(final InternalFactHandle factHandle,
                                  final PropagationContext context,
                                  final InternalWorkingMemory workingMemory) {
             //  Auto-generated method stub

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/ExistsNodeTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/ExistsNodeTest.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/ExistsNodeTest.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -143,9 +143,9 @@
 
         // check memory sizes
         assertEquals( 2,
-                      this.memory.getTupleMemory().size() );
+                      this.memory.getLeftTupleMemory().size() );
         assertEquals( 1,
-                      this.memory.getFactHandleMemory().size() );
+                      this.memory.getRightTupleMemory().size() );
 
         // When this is retracter both tuples should be retracted
         this.node.retractObject( f1,
@@ -241,14 +241,14 @@
 
             // Initially, no objects in right memory
             assertEquals( 0,
-                          this.memory.getFactHandleMemory().size() );
+                          this.memory.getRightTupleMemory().size() );
             this.node.assertObject( f1,
                                     this.context,
                                     this.workingMemory );
 
             // Now, needs to have 1 object in right memory
             assertEquals( 1,
-                          this.memory.getFactHandleMemory().size() );
+                          this.memory.getRightTupleMemory().size() );
 
             // simulate modify
             this.node.retractObject( f1,
@@ -259,18 +259,18 @@
                                     this.workingMemory );
             // Memory should not change
             assertEquals( 1,
-                          this.memory.getFactHandleMemory().size() );
+                          this.memory.getRightTupleMemory().size() );
 
             // When this is retracter both tuples should assert
             this.node.retractObject( f1,
                                      this.context,
                                      this.workingMemory );
             assertEquals( 0,
-                          this.memory.getFactHandleMemory().size() );
+                          this.memory.getRightTupleMemory().size() );
 
             // check memory sizes
             assertEquals( 1,
-                          this.memory.getTupleMemory().size() );
+                          this.memory.getLeftTupleMemory().size() );
 
             // simulate modify
             this.node.retractLeftTuple( tuple1,
@@ -280,12 +280,12 @@
                                    this.context,
                                    this.workingMemory );
             assertEquals( 1,
-                          this.memory.getTupleMemory().size() );
+                          this.memory.getLeftTupleMemory().size() );
             this.node.retractLeftTuple( tuple1,
                                     this.context,
                                     this.workingMemory );
             assertEquals( 0,
-                          this.memory.getTupleMemory().size() );
+                          this.memory.getLeftTupleMemory().size() );
         } catch ( final Exception e ) {
             Assert.fail( "No exception should be raised in this procedure, but got: " + e.toString() );
         }

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/FromNodeTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/FromNodeTest.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/FromNodeTest.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -286,8 +286,8 @@
 
         final FromMemory memory = (FromMemory) workingMemory.getNodeMemory( from );
         assertEquals( 1,
-                      memory.betaMemory.getTupleMemory().size() );
-        assertNull( memory.betaMemory.getFactHandleMemory() );
+                      memory.betaMemory.getLeftTupleMemory().size() );
+        assertNull( memory.betaMemory.getRightTupleMemory() );
         assertEquals( 2,
                       ((LinkedList) memory.betaMemory.getCreatedHandles().get( tuple )).size() );
 
@@ -302,8 +302,8 @@
                            context,
                            workingMemory );
         assertEquals( 0,
-                      memory.betaMemory.getTupleMemory().size() );
-        assertNull( memory.betaMemory.getFactHandleMemory() );
+                      memory.betaMemory.getLeftTupleMemory().size() );
+        assertNull( memory.betaMemory.getRightTupleMemory() );
     }
 
     public static class MockDataProvider

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/JoinNodeTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/JoinNodeTest.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/JoinNodeTest.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -82,16 +82,16 @@
 
         // check memories are empty
         assertEquals( 0,
-                      this.memory.getTupleMemory().size() );
+                      this.memory.getLeftTupleMemory().size() );
         assertEquals( 0,
-                      this.memory.getFactHandleMemory().size() );
+                      this.memory.getRightTupleMemory().size() );
 
     }
 
     public void testAttach() throws Exception {
-        final Field objectFfield = ObjectSource.class.getDeclaredField( "sink" );
+        final Field objectFfield = RightTupleSource.class.getDeclaredField( "sink" );
         objectFfield.setAccessible( true );
-        ObjectSinkPropagator objectSink = (ObjectSinkPropagator) objectFfield.get( this.objectSource );
+        RightTupleSinkPropagator objectSink = (RightTupleSinkPropagator) objectFfield.get( this.objectSource );
 
         final Field tupleField = LeftTupleSource.class.getDeclaredField( "sink" );
         tupleField.setAccessible( true );
@@ -105,7 +105,7 @@
 
         this.node.attach();
 
-        objectSink = (ObjectSinkPropagator) objectFfield.get( this.objectSource );
+        objectSink = (RightTupleSinkPropagator) objectFfield.get( this.objectSource );
         tupleSink = (LeftTupleSinkPropagator) tupleField.get( this.tupleSource );
 
         assertEquals( 1,
@@ -157,9 +157,9 @@
                                this.workingMemory );
         // check memories, left memory is populated, right memory is emptys
         assertEquals( 1,
-                      this.memory.getTupleMemory().size() );
+                      this.memory.getLeftTupleMemory().size() );
         assertEquals( 0,
-                      this.memory.getFactHandleMemory().size() );
+                      this.memory.getRightTupleMemory().size() );
 
         // assert tuple, should add left memory should be 2
         final DefaultFactHandle f1 = new DefaultFactHandle( 1,
@@ -169,9 +169,9 @@
                                this.context,
                                this.workingMemory );
         assertEquals( 2,
-                      this.memory.getTupleMemory().size() );
+                      this.memory.getLeftTupleMemory().size() );
 
-        final Iterator it = this.memory.getTupleMemory().iterator();
+        final Iterator it = this.memory.getLeftTupleMemory().iterator();
         assertEquals( tuple0,
                       it.next() );
         assertEquals( tuple1,
@@ -223,10 +223,10 @@
         assertEquals( 1,
                       this.sink.getAsserted().size() );
 
-        assertNull( this.memory.getTupleMemory() );
+        assertNull( this.memory.getLeftTupleMemory() );
 
         assertEquals( 1,
-                      this.memory.getFactHandleMemory().size() );
+                      this.memory.getRightTupleMemory().size() );
 
         assertEquals( new LeftTuple( tuple0,
                                      f0 ),
@@ -246,9 +246,9 @@
                                 this.context,
                                 this.workingMemory );
         assertEquals( 0,
-                      this.memory.getTupleMemory().size() );
+                      this.memory.getLeftTupleMemory().size() );
         assertEquals( 1,
-                      this.memory.getFactHandleMemory().size() );
+                      this.memory.getRightTupleMemory().size() );
 
         // check new objects/handles still assert
         final DefaultFactHandle f1 = (DefaultFactHandle) this.workingMemory.insert( "test1" );
@@ -256,9 +256,9 @@
                                 this.context,
                                 this.workingMemory );
         assertEquals( 2,
-                      this.memory.getFactHandleMemory().size() );
+                      this.memory.getRightTupleMemory().size() );
 
-        final Iterator it = this.memory.getFactHandleMemory().iterator( new LeftTuple( f0 ) );
+        final Iterator it = this.memory.getRightTupleMemory().iterator( new LeftTuple( f0 ) );
 
         final InternalFactHandle rf0 = ((FactEntry) it.next()).getFactHandle();
         final InternalFactHandle rf1 = ((FactEntry) it.next()).getFactHandle();
@@ -367,7 +367,7 @@
 
         // Double check the item is in memory
         final BetaMemory memory = (BetaMemory) this.workingMemory.getNodeMemory( this.node );
-        assertTrue( memory.getFactHandleMemory().contains( f0 ) );
+        assertTrue( memory.getRightTupleMemory().contains( f0 ) );
 
         // Retract an object, check propagations  and memory
         this.node.retractObject( f0,
@@ -386,7 +386,7 @@
                                                     f0 ) ) );
 
         // Now check the item  is no longer in memory
-        assertFalse( memory.getFactHandleMemory().contains( f0 ) );
+        assertFalse( memory.getRightTupleMemory().contains( f0 ) );
 
         this.node.retractLeftTuple( tuple2,
                                 this.context,

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/LeftInputAdapterNodeTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/LeftInputAdapterNodeTest.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/LeftInputAdapterNodeTest.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -65,9 +65,9 @@
         final LeftInputAdapterNode liaNode = new LeftInputAdapterNode( 1,
                                                                        source,
                                                                        buildContext );
-        final Field field = ObjectSource.class.getDeclaredField( "sink" );
+        final Field field = RightTupleSource.class.getDeclaredField( "sink" );
         field.setAccessible( true );
-        ObjectSinkPropagator sink = (ObjectSinkPropagator) field.get( source );
+        RightTupleSinkPropagator sink = (RightTupleSinkPropagator) field.get( source );
 
         assertEquals( 1,
                       liaNode.getId() );
@@ -75,7 +75,7 @@
 
         liaNode.attach();
 
-        sink = (ObjectSinkPropagator) field.get( source );
+        sink = (RightTupleSinkPropagator) field.get( source );
 
         assertEquals( 1,
                       sink.getSinks().length );

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/MockObjectSink.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/MockObjectSink.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/MockObjectSink.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -25,17 +25,17 @@
 
 public class MockObjectSink
     implements
-    ObjectSinkNode {
+    RightTupleSinkNode {
     private final List     asserted  = new ArrayList();
     private final List     retracted = new ArrayList();
 
-    private ObjectSinkNode previousObjectSinkNode;
-    private ObjectSinkNode nextObjectSinkNode;
+    private RightTupleSinkNode previousObjectSinkNode;
+    private RightTupleSinkNode nextObjectSinkNode;
 
-    public void assertObject(final InternalFactHandle handle,
+    public void assertObject(final InternalFactHandle factHandle,
                              final PropagationContext context,
                              final InternalWorkingMemory workingMemory) {
-        this.asserted.add( new Object[]{handle, context, workingMemory} );
+        this.asserted.add( new Object[]{factHandle, context, workingMemory} );
     }
 
     public void retractObject(final InternalFactHandle handle,
@@ -57,7 +57,7 @@
      * @return
      *      The next ObjectSinkNode
      */
-    public ObjectSinkNode getNextObjectSinkNode() {
+    public RightTupleSinkNode getNextRightTupleSinkNode() {
         return this.nextObjectSinkNode;
     }
 
@@ -66,7 +66,7 @@
      * @param next
      *      The next ObjectSinkNode
      */
-    public void setNextObjectSinkNode(final ObjectSinkNode next) {
+    public void setNextRightTupleSinkNode(final RightTupleSinkNode next) {
         this.nextObjectSinkNode = next;
     }
 
@@ -75,7 +75,7 @@
      * @return
      *      The previous ObjectSinkNode
      */
-    public ObjectSinkNode getPreviousObjectSinkNode() {
+    public RightTupleSinkNode getPreviousRightTupleSinkNode() {
         return this.previousObjectSinkNode;
     }
 
@@ -84,7 +84,7 @@
      * @param previous
      *      The previous ObjectSinkNode
      */
-    public void setPreviousObjectSinkNode(final ObjectSinkNode previous) {
+    public void setPreviousRightTupleSinkNode(final RightTupleSinkNode previous) {
         this.previousObjectSinkNode = previous;
     }
 

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/MockObjectSource.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/MockObjectSource.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/MockObjectSource.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -28,7 +28,7 @@
 import java.util.Iterator;
 import java.util.List;
 
-public class MockObjectSource extends ObjectSource {
+public class MockObjectSource extends RightTupleSource {
     /**
      * 
      */
@@ -79,7 +79,7 @@
         this.facts.add( handle );
     }
 
-    public void updateSink(final ObjectSink sink,
+    public void updateSink(final RightTupleSink sink,
                            final PropagationContext context,
                            final InternalWorkingMemory workingMemory) {
         this.updated++;

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/NotNodeTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/NotNodeTest.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/NotNodeTest.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -152,9 +152,9 @@
 
         // check memory sizes
         assertEquals( 2,
-                      this.memory.getTupleMemory().size() );
+                      this.memory.getLeftTupleMemory().size() );
         assertEquals( 1,
-                      this.memory.getFactHandleMemory().size() );
+                      this.memory.getRightTupleMemory().size() );
 
         // When this is retracter both tuples should assert
         this.node.retractObject( f1,
@@ -254,14 +254,14 @@
 
             // Initially, no objects in right memory
             assertEquals( 0,
-                          this.memory.getFactHandleMemory().size() );
+                          this.memory.getRightTupleMemory().size() );
             this.node.assertObject( f1,
                                     this.context,
                                     this.workingMemory );
 
             // Now, needs to have 1 object in right memory
             assertEquals( 1,
-                          this.memory.getFactHandleMemory().size() );
+                          this.memory.getRightTupleMemory().size() );
 
             // simulate modify
             this.node.retractObject( f1,
@@ -272,18 +272,18 @@
                                     this.workingMemory );
             // Memory should not change
             assertEquals( 1,
-                          this.memory.getFactHandleMemory().size() );
+                          this.memory.getRightTupleMemory().size() );
 
             // When this is retracter both tuples should assert
             this.node.retractObject( f1,
                                      this.context,
                                      this.workingMemory );
             assertEquals( 0,
-                          this.memory.getFactHandleMemory().size() );
+                          this.memory.getRightTupleMemory().size() );
 
             // check memory sizes
             assertEquals( 1,
-                          this.memory.getTupleMemory().size() );
+                          this.memory.getLeftTupleMemory().size() );
 
             // simulate modify
             this.node.retractLeftTuple( tuple1,
@@ -293,12 +293,12 @@
                                    this.context,
                                    this.workingMemory );
             assertEquals( 1,
-                          this.memory.getTupleMemory().size() );
+                          this.memory.getLeftTupleMemory().size() );
             this.node.retractLeftTuple( tuple1,
                                     this.context,
                                     this.workingMemory );
             assertEquals( 0,
-                          this.memory.getTupleMemory().size() );
+                          this.memory.getLeftTupleMemory().size() );
         } catch ( final Exception e ) {
             Assert.fail( "No exception should be raised in this procedure, but got: " + e.toString() );
         }
@@ -369,10 +369,10 @@
         assertEquals( 0,
                       this.sink.getAsserted().size() );
 
-        assertNull( this.memory.getTupleMemory() );
+        assertNull( this.memory.getLeftTupleMemory() );
 
         assertEquals( 1,
-                      this.memory.getFactHandleMemory().size() );
+                      this.memory.getRightTupleMemory().size() );
 
     }
 

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/ObjectSourceTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/ObjectSourceTest.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/ObjectSourceTest.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -38,52 +38,52 @@
         final MockObjectSource source = new MockObjectSource( 15 );
 
         // We need to re-assign this var each time the sink changes references
-        final Field field = ObjectSource.class.getDeclaredField( "sink" );
+        final Field field = RightTupleSource.class.getDeclaredField( "sink" );
         field.setAccessible( true );
-        ObjectSinkPropagator sink = (ObjectSinkPropagator) field.get( source );
+        RightTupleSinkPropagator sink = (RightTupleSinkPropagator) field.get( source );
 
-        assertSame( EmptyObjectSinkAdapter.getInstance(),
+        assertSame( EmptyRightTupleSinkAdapter.getInstance(),
                     sink );
 
         final MockObjectSink sink1 = new MockObjectSink();
         source.addObjectSink( sink1 );
-        sink = (ObjectSinkPropagator) field.get( source );
-        assertSame( SingleObjectSinkAdapter.class,
+        sink = (RightTupleSinkPropagator) field.get( source );
+        assertSame( SingleRightTupleSinkAdapter.class,
                     sink.getClass() );
         assertEquals( 1,
                       sink.getSinks().length );
 
         final MockObjectSink sink2 = new MockObjectSink();
         source.addObjectSink( sink2 );
-        sink = (ObjectSinkPropagator) field.get( source );
-        assertSame( CompositeObjectSinkAdapter.class,
+        sink = (RightTupleSinkPropagator) field.get( source );
+        assertSame( CompositeRightTupleSinkAdapter.class,
                     sink.getClass() );
         assertEquals( 2,
                       sink.getSinks().length );
 
         final MockObjectSink sink3 = new MockObjectSink();
         source.addObjectSink( sink3 );
-        assertSame( CompositeObjectSinkAdapter.class,
+        assertSame( CompositeRightTupleSinkAdapter.class,
                     sink.getClass() );
         assertEquals( 3,
                       sink.getSinks().length );
 
         source.removeObjectSink( sink2 );
-        assertSame( CompositeObjectSinkAdapter.class,
+        assertSame( CompositeRightTupleSinkAdapter.class,
                     sink.getClass() );
         assertEquals( 2,
                       sink.getSinks().length );
 
         source.removeObjectSink( sink1 );
-        sink = (ObjectSinkPropagator) field.get( source );
-        assertSame( SingleObjectSinkAdapter.class,
+        sink = (RightTupleSinkPropagator) field.get( source );
+        assertSame( SingleRightTupleSinkAdapter.class,
                     sink.getClass() );
         assertEquals( 1,
                       sink.getSinks().length );
 
         source.removeObjectSink( sink3 );
-        sink = (ObjectSinkPropagator) field.get( source );
-        assertSame( EmptyObjectSinkAdapter.getInstance(),
+        sink = (RightTupleSinkPropagator) field.get( source );
+        assertSame( EmptyRightTupleSinkAdapter.getInstance(),
                     sink );
         assertEquals( 0,
                       sink.getSinks().length );

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/TupleSourceTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/TupleSourceTest.java	2008-03-21 16:05:15 UTC (rev 19177)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/TupleSourceTest.java	2008-03-21 16:07:16 UTC (rev 19178)
@@ -36,13 +36,13 @@
         field.setAccessible( true );
         LeftTupleSinkPropagator sink = (LeftTupleSinkPropagator) field.get( source );
 
-        assertSame( EmptyTupleSinkAdapter.getInstance(),
+        assertSame( EmptyLeftTupleSinkAdapter.getInstance(),
                     sink );
 
         final MockTupleSink sink1 = new MockTupleSink();
         source.addTupleSink( sink1 );
         sink = (LeftTupleSinkPropagator) field.get( source );
-        assertSame( SingleTupleSinkAdapter.class,
+        assertSame( SingleLeftTupleSinkAdapter.class,
                     sink.getClass() );
         assertEquals( 1,
                       sink.getSinks().length );
@@ -70,14 +70,14 @@
 
         source.removeTupleSink( sink1 );
         sink = (LeftTupleSinkPropagator) field.get( source );
-        assertSame( SingleTupleSinkAdapter.class,
+        assertSame( SingleLeftTupleSinkAdapter.class,
                     sink.getClass() );
         assertEquals( 1,
                       sink.getSinks().length );
 
         source.removeTupleSink( sink3 );
         sink = (LeftTupleSinkPropagator) field.get( source );
-        assertSame( EmptyTupleSinkAdapter.getInstance(),
+        assertSame( EmptyLeftTupleSinkAdapter.getInstance(),
                     sink );
         assertEquals( 0,
                       sink.getSinks().length );




More information about the jboss-svn-commits mailing list