docs: public static void removeRule( TerminalNode tn, Collection<InternalWorkingMemory> wms, InternalKnowledgeBase kBase) {
          if (log.isTraceEnabled()) {
              log.trace("Removing Rule {}", tn.getRule().getName());
          }
  
          boolean hasProtos = kBase.hasSegmentPrototypes();
          boolean hasWms = !wms.isEmpty();
  
          if (!hasProtos && !hasWms) {
              return;
          }
  
          RuleImpl      rule       = tn.getRule();
          LeftTupleNode firstSplit = getNetworkSplitPoint(tn);
          PathEndNodes pathEndNodes = getPathEndNodes(kBase, firstSplit, tn, rule, hasProtos, hasWms);
  
          for (InternalWorkingMemory wm : wms) {
              wm.flushPropagations();
  
              PathEndNodeMemories tnms = getPathEndMemories(wm, pathEndNodes);
  
              if ( !tnms.subjectPmems.isEmpty() ) {
                  if (NodeTypeEnums.LeftInputAdapterNode == firstSplit.getType() && firstSplit.getAssociationsSize() == 1) {
                      if (tnms.subjectPmem != null) {
                          flushStagedTuples(firstSplit, tnms.subjectPmem, wm);
                      }
  
                      processLeftTuples(firstSplit, wm, false, tn.getRule());
  
                      removeNewPaths(wm, tnms.subjectPmems);
                  } else {
                      flushStagedTuples(tn, tnms.subjectPmem, pathEndNodes, wm);
  
                      processLeftTuples(firstSplit, wm, false, tn.getRule());
  
                      removeNewPaths(wm, tnms.subjectPmems);
  
                      Map<PathMemory, SegmentMemory[]> prevSmemsLookup = reInitPathMemories(tnms.otherPmems, tn);
  
                      // must collect all visited SegmentMemories, for link notification
                      Set<SegmentMemory> smemsToNotify = handleExistingPaths(tn, prevSmemsLookup, tnms.otherPmems, wm, ExistingPathStrategy.REMOVE_STRATEGY);
  
                      notifySegments(smemsToNotify, wm);
                  }
              }
  
              if (tnms.subjectPmem != null && tnms.subjectPmem.isInitialized() && tnms.subjectPmem.getRuleAgendaItem().isQueued()) {
                  // SubjectPmem can be null, if it was never initialized
                  tnms.subjectPmem.getRuleAgendaItem().dequeue();
              }
          }
      }