public static void dpUpdatesReorderRightMemory(BetaMemory bm, RightTupleSets srcRightTuples) {
    RightTupleMemory rtm = bm.getRightTupleMemory();

    for (RightTuple rightTuple = srcRightTuples.getUpdateFirst(); rightTuple != null; ) {
      RightTuple next = rightTuple.getStagedNext();
      if (rightTuple.getMemory() != null) {
        rightTuple.setTempRightTupleMemory(rightTuple.getMemory());
        rtm.remove(rightTuple);
      }
      rightTuple = next;
    }

    for (RightTuple rightTuple = srcRightTuples.getUpdateFirst(); rightTuple != null; ) {
      RightTuple next = rightTuple.getStagedNext();
      if (rightTuple.getTempRightTupleMemory() != null) {
        rtm.add(rightTuple);
        for (LeftTuple childLeftTuple = rightTuple.getFirstChild(); childLeftTuple != null; ) {
          LeftTuple childNext = childLeftTuple.getRightParentNext();
          childLeftTuple.reAddLeft();
          childLeftTuple = childNext;
        }
      }
      rightTuple = next;
    }
  }
    public void execute(InternalWorkingMemory workingMemory) {
      leftTuple.setLeftTupleSink(this.node);
      if (leftTuple.getFirstChild() == null) {
        this.node.assertLeftTuple(leftTuple, context, workingMemory);
      } else {
        if (retract) {
          this.node
              .getSinkPropagator()
              .propagateRetractLeftTuple(leftTuple, context, workingMemory);
        } else {
          this.node
              .getSinkPropagator()
              .propagateModifyChildLeftTuple(leftTuple, context, workingMemory, true);
        }
      }

      if (leftTuple.getLeftParent() == null) {
        // It's not an open query, as we aren't recording parent chains, so we need to clear out
        // right memory

        Object node = workingMemory.getNodeMemory(this.node);

        RightTupleMemory rightMemory = null;
        if (node instanceof BetaMemory) {
          rightMemory = ((BetaMemory) node).getRightTupleMemory();
        } else if (node instanceof AccumulateMemory) {
          rightMemory = ((AccumulateMemory) node).betaMemory.getRightTupleMemory();
        }

        final TupleStartEqualsConstraint constraint = TupleStartEqualsConstraint.getInstance();
        TupleStartEqualsConstraintContextEntry contextEntry =
            new TupleStartEqualsConstraintContextEntry();
        contextEntry.updateFromTuple(workingMemory, leftTuple);

        FastIterator rightIt = rightMemory.fastIterator();
        RightTuple temp = null;
        for (RightTuple rightTuple =
                rightMemory.getFirst(
                    leftTuple, (InternalFactHandle) context.getFactHandle(), rightIt);
            rightTuple != null; ) {
          temp = (RightTuple) rightIt.next(rightTuple);

          if (constraint.isAllowedCachedLeft(contextEntry, rightTuple.getFactHandle())) {
            rightMemory.remove(rightTuple);
          }
          rightTuple = temp;
        }
      }
    }
  public static void findLeftTupleBlocker(
      BetaNode betaNode,
      RightTupleMemory rtm,
      ContextEntry[] contextEntry,
      BetaConstraints constraints,
      LeftTuple leftTuple,
      FastIterator it,
      PropagationContext context,
      boolean useLeftMemory) {
    // This method will also remove rightTuples that are from subnetwork where no leftmemory use
    // used

    for (RightTuple rightTuple = betaNode.getFirstRightTuple(leftTuple, rtm, null, it);
        rightTuple != null; ) {
      RightTuple nextRight = (RightTuple) it.next(rightTuple);
      if (constraints.isAllowedCachedLeft(contextEntry, rightTuple.getFactHandle())) {
        leftTuple.setBlocker(rightTuple);

        if (useLeftMemory) {
          rightTuple.addBlocked(leftTuple);
          break;
        } else if (betaNode.isRightInputIsRiaNode()) {
          // If we aren't using leftMemory and the right input is a RIAN, then we must iterate and
          // find all subetwork right tuples and remove them
          // so we don't break
          rtm.remove(rightTuple);
        } else {
          break;
        }
      }
      rightTuple = nextRight;
    }
  }
  public static void dpUpdatesExistentialReorderRightMemory(
      BetaMemory bm, BetaNode betaNode, RightTupleSets srcRightTuples) {
    RightTupleMemory rtm = bm.getRightTupleMemory();

    boolean resumeFromCurrent =
        !(betaNode.isIndexedUnificationJoin() || rtm.getIndexType().isComparison());

    // remove all the staged rightTuples from the memory before to readd them all
    // this is to avoid split bucket when an updated rightTuple hasn't been moved yet
    // and so it is the first entry in the wrong bucket

    for (RightTuple rightTuple = srcRightTuples.getUpdateFirst(); rightTuple != null; ) {
      RightTuple next = rightTuple.getStagedNext();
      if (rightTuple.getMemory() != null) {
        rightTuple.setTempRightTupleMemory(rightTuple.getMemory());

        if (resumeFromCurrent) {
          if (rightTuple.getBlocked() != null) {
            // look for a non-staged right tuple first forward ...
            RightTuple tempRightTuple = (RightTuple) rightTuple.getNext();
            while (tempRightTuple != null && tempRightTuple.getStagedType() != LeftTuple.NONE) {
              // next cannot be an updated or deleted rightTuple
              tempRightTuple = (RightTuple) tempRightTuple.getNext();
            }

            // ... and if cannot find one try backward
            if (tempRightTuple == null) {
              tempRightTuple = (RightTuple) rightTuple.getPrevious();
              while (tempRightTuple != null && tempRightTuple.getStagedType() != LeftTuple.NONE) {
                // next cannot be an updated or deleted rightTuple
                tempRightTuple = (RightTuple) tempRightTuple.getPrevious();
              }
            }

            rightTuple.setTempNextRightTuple(tempRightTuple);
          }
        }

        rightTuple.setTempBlocked(rightTuple.getBlocked());
        rightTuple.nullBlocked();
        rtm.remove(rightTuple);
      }
      rightTuple = next;
    }

    for (RightTuple rightTuple = srcRightTuples.getUpdateFirst(); rightTuple != null; ) {
      RightTuple next = rightTuple.getStagedNext();
      if (rightTuple.getTempRightTupleMemory() != null) {

        rtm.add(rightTuple);

        if (resumeFromCurrent) {
          RightTuple tempRightTuple = rightTuple.getTempNextRightTuple();
          if (rightTuple.getBlocked() != null
              && tempRightTuple == null
              && rightTuple.getMemory() == rightTuple.getTempRightTupleMemory()) {
            // the next RightTuple was null, but current RightTuple was added back into the same
            // bucket, so reset as root blocker to re-match can be attempted
            rightTuple.setTempNextRightTuple(rightTuple);
          }
        }

        for (LeftTuple childLeftTuple = rightTuple.getFirstChild(); childLeftTuple != null; ) {
          LeftTuple childNext = childLeftTuple.getRightParentNext();
          childLeftTuple.reAddLeft();
          childLeftTuple = childNext;
        }
      }
      rightTuple = next;
    }
  }