public void byPassModifyToBetaNode(
      final InternalFactHandle factHandle,
      final ModifyPreviousTuples modifyPreviousTuples,
      final PropagationContext context,
      final InternalWorkingMemory workingMemory) {
    final Object object = factHandle.getObject();

    // We need to iterate in the same order as the assert
    if (this.hashedFieldIndexes != null) {
      // Iterate the FieldIndexes to see if any are hashed
      for (FieldIndex fieldIndex = this.hashedFieldIndexes.getFirst();
          fieldIndex != null;
          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 AlphaNode sink = (AlphaNode) this.hashedSinkMap.get(new HashKey(fieldIndex, object));
        if (sink != null) {
          // only alpha nodes are hashable
          sink.getObjectSinkPropagator()
              .byPassModifyToBetaNode(factHandle, modifyPreviousTuples, context, workingMemory);
        }
      }
    }

    // propagate unhashed
    if (this.hashableSinks != null) {
      for (ObjectSinkNode sink = this.hashableSinks.getFirst();
          sink != null;
          sink = sink.getNextObjectSinkNode()) {
        // only alpha nodes are hashable
        ((AlphaNode) sink)
            .getObjectSinkPropagator()
            .byPassModifyToBetaNode(factHandle, modifyPreviousTuples, context, workingMemory);
      }
    }

    if (this.otherSinks != null) {
      // propagate others
      for (ObjectSinkNode sink = this.otherSinks.getFirst();
          sink != null;
          sink = sink.getNextObjectSinkNode()) {
        // compound alpha, lianode or betanode
        sink.byPassModifyToBetaNode(factHandle, modifyPreviousTuples, context, workingMemory);
      }
    }
  }
  public void propagateModifyObject(
      final InternalFactHandle factHandle,
      final ModifyPreviousTuples modifyPreviousTuples,
      final PropagationContext context,
      final InternalWorkingMemory workingMemory) {
    final Object object = factHandle.getObject();

    // Iterates the 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 = this.hashedFieldIndexes.getFirst();
          fieldIndex != null;
          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 AlphaNode sink = (AlphaNode) this.hashedSinkMap.get(new HashKey(fieldIndex, object));
        if (sink != null) {
          // go straight to the AlphaNode's propagator, as we know it's true and no need to retest
          sink.getObjectSinkPropagator()
              .propagateModifyObject(factHandle, modifyPreviousTuples, context, workingMemory);
        }
      }
    }

    // propagate unhashed
    if (this.hashableSinks != null) {
      for (ObjectSinkNode sink = this.hashableSinks.getFirst();
          sink != null;
          sink = sink.getNextObjectSinkNode()) {
        doPropagateModifyObject(factHandle, modifyPreviousTuples, context, workingMemory, sink);
      }
    }

    if (this.otherSinks != null) {
      // propagate others
      for (ObjectSinkNode sink = this.otherSinks.getFirst();
          sink != null;
          sink = sink.getNextObjectSinkNode()) {
        doPropagateModifyObject(factHandle, modifyPreviousTuples, context, workingMemory, sink);
      }
    }
  }