code: private ContextPair<I> prepareSplit(DTNode<I> node, Splitter<I> splitter) {
          ContextPair<I> discriminator = splitter.getNewDiscriminator();
  
          Deque<DTNode<I>> dfsStack = new ArrayDeque<>();
  
          DTNode<I> succSeparator = splitter.succSeparator;
  
          dfsStack.push(node);
          assert node.getSplitData() == null;
  
          while (!dfsStack.isEmpty()) {
              DTNode<I> curr = dfsStack.pop();
              assert curr.getSplitData() == null;
  
              curr.setSplitData(new SplitData<>(TransList::new));
  
              for (AbstractHypTrans<I> trans : curr.getIncoming()) {
                  Boolean outcome = query(trans, discriminator);
                  curr.getSplitData().getIncoming(outcome).add(trans);
                  markAndPropagate(curr, outcome);
              }
  
              if (curr.isInner()) {
                  for (DTNode<I> child : curr.getChildren()) {
                      dfsStack.push(child);
                  }
              } else {
                  HypLoc<I> loc = curr.getData();
                  assert loc != null;
  
                  // Try to deduct the outcome from the DT target of
                  // the respective transition
                  AbstractHypTrans<I> trans = getSplitterTrans(loc, splitter);
                  Boolean outcome = succSeparator.subtreeLabel(trans.getTargetNode());
                  assert outcome != null;
                  curr.getSplitData().setStateLabel(outcome);
                  markAndPropagate(curr, outcome);
              }
  
          }
  
          return discriminator;
      }
docs: Prepare a split operation on a block, by marking all the nodes and transitions in the subtree (and annotating
  them with {@link SplitData} objects).
  
  @param node
  the block root to be split
  @param splitter
  the splitter to use for splitting the block
  
  @return the discriminator to use for splitting