private static TupleSets<LeftTuple> getTargetStagedLeftTuples(
     NetworkNode node, InternalWorkingMemory wm, SegmentMemory smem) {
   if (node == smem.getTipNode()) {
     // we are about to process the segment tip, allow it to merge insert/update/delete clashes
     if (smem.isEmpty()) {
       SegmentUtilities.createChildSegments(
           wm, smem, ((LeftTupleSource) node).getSinkPropagator());
     }
     return smem.getFirst().getStagedLeftTuples().takeAll();
   } else {
     return null;
   }
 }
  public void innerEval(
      LeftInputAdapterNode liaNode,
      PathMemory pmem,
      NetworkNode node,
      long bit,
      Memory nodeMem,
      SegmentMemory[] smems,
      int smemIndex,
      TupleSets<LeftTuple> trgTuples,
      InternalWorkingMemory wm,
      LinkedList<StackEntry> stack,
      boolean processRian,
      RuleExecutor executor) {
    TupleSets<LeftTuple> srcTuples;
    SegmentMemory smem = smems[smemIndex];
    TupleSets<LeftTuple> stagedLeftTuples = null;
    while (true) {
      srcTuples = trgTuples; // previous target, is now the source
      if (log.isTraceEnabled()) {
        int offset = getOffset(node);
        log.trace(
            "{} {} {} {}", indent(offset), ++cycle, node.toString(), srcTuples.toStringSizes());
      }

      boolean emptySrcTuples = srcTuples.isEmpty();
      if (!(NodeTypeEnums.isBetaNode(node) && ((BetaNode) node).isRightInputIsRiaNode())) {
        // The engine cannot skip a ria node, as the dirty might be several levels deep
        if (emptySrcTuples && smem.getDirtyNodeMask() == 0) {
          // empty sources and segment is not dirty, skip to non empty src tuples or dirty segment.
          boolean foundDirty = false;
          for (int i = ++smemIndex, length = smems.length; i < length; i++) {
            if (log.isTraceEnabled()) {
              int offset = getOffset(node);
              log.trace("{} Skip Segment {}", indent(offset), i - 1);
            }

            // this is needed for subnetworks that feed into a parent network that has no right
            // inputs,
            // and may not yet be initialized
            if (smem.isEmpty() && !NodeTypeEnums.isTerminalNode(smem.getTipNode())) {
              SegmentUtilities.createChildSegments(
                  wm, smem, ((LeftTupleSource) smem.getTipNode()).getSinkPropagator());
            }

            smem = smems[i];
            bit = 1;
            srcTuples = smem.getStagedLeftTuples().takeAll();
            emptySrcTuples = srcTuples.isEmpty();
            node = smem.getRootNode();
            nodeMem = smem.getNodeMemories().getFirst();
            if (!emptySrcTuples
                || smem.getDirtyNodeMask() != 0
                || (NodeTypeEnums.isBetaNode(node) && ((BetaNode) node).isRightInputIsRiaNode())) {
              // break if dirty or if we reach a subnetwork. It must break for subnetworks, so they
              // can be searched.
              foundDirty = true;
              smemIndex = i;
              break;
            }
          }
          if (!foundDirty) {
            break;
          }
        }
        if (log.isTraceEnabled()) {
          int offset = getOffset(node);
          log.trace("{} Segment {}", indent(offset), smemIndex);
          log.trace(
              "{} {} {} {}", indent(offset), cycle, node.toString(), srcTuples.toStringSizes());
        }
      }

      long dirtyMask = smem.getDirtyNodeMask();
      if (emptySrcTuples) {
        while ((dirtyMask & bit) == 0
            && node != smem.getTipNode()
            && !(NodeTypeEnums.isBetaNode(node) && ((BetaNode) node).isRightInputIsRiaNode())) {
          if (log.isTraceEnabled()) {
            int offset = getOffset(node);
            log.trace("{} Skip Node {}", indent(offset), node);
          }
          bit = bit << 1; // shift to check the next node
          node = ((LeftTupleSource) node).getSinkPropagator().getFirstLeftTupleSink();
          nodeMem = nodeMem.getNext();
        }
      }

      if (NodeTypeEnums.isTerminalNode(node)) {
        TerminalNode rtn = (TerminalNode) node;
        if (node.getType() == NodeTypeEnums.QueryTerminalNode) {
          pQtNode.doNode((QueryTerminalNode) rtn, wm, srcTuples, stack);
        } else {
          pRtNode.doNode(rtn, wm, srcTuples, executor);
        }
        break;
      } else if (NodeTypeEnums.RightInputAdaterNode == node.getType()) {
        doRiaNode2(wm, srcTuples, (RightInputAdapterNode) node);
        break;
      }

      stagedLeftTuples = getTargetStagedLeftTuples(node, wm, smem);
      LeftTupleSinkNode sink = ((LeftTupleSource) node).getSinkPropagator().getFirstLeftTupleSink();

      trgTuples =
          evalNode(
              liaNode,
              pmem,
              node,
              bit,
              nodeMem,
              smems,
              smemIndex,
              wm,
              stack,
              processRian,
              executor,
              srcTuples,
              smem,
              stagedLeftTuples,
              sink);
      if (trgTuples == null) {
        break; // Queries exists and has been placed StackEntry, and there are no current trgTuples
        // to process
      }

      if (node != smem.getTipNode()) {
        // get next node and node memory in the segment
        node = sink;
        nodeMem = nodeMem.getNext();
        bit = bit << 1;
      } else {
        // Reached end of segment, start on new segment.
        smem.getFirst().getStagedLeftTuples().addAll(stagedLeftTuples); // must put back all the LTs
        // end of SegmentMemory, so we know that stagedLeftTuples is not null
        SegmentPropagator.propagate(smem, trgTuples, wm);
        bit = 1;
        smem = smems[++smemIndex];
        trgTuples = smem.getStagedLeftTuples().takeAll();

        if (log.isTraceEnabled()) {
          int offset = getOffset(node);
          log.trace("{} Segment {}", indent(offset), smemIndex);
        }
        node = smem.getRootNode();
        nodeMem = smem.getNodeMemories().getFirst();
      }
      processRian = true; //  make sure it's reset, so ria nodes are processed
    }

    if (stagedLeftTuples != null && !stagedLeftTuples.isEmpty()) {
      smem.getFirst().getStagedLeftTuples().addAll(stagedLeftTuples); // must put back all the LTs
    }
  }