code: public ADTNode<S, I, O> extendLeaf(final ADTNode<S, I, O> nodeToSplit,
                                         final Word<I> distinguishingSuffix,
                                         final Word<O> oldOutput,
                                         final Word<O> newOutput) {
  
          if (!ADTUtil.isLeafNode(nodeToSplit)) {
              throw new IllegalArgumentException("Node to split is not a leaf node");
          }
          if (!(distinguishingSuffix.length() == oldOutput.length() && oldOutput.length() == newOutput.length())) {
              throw new IllegalArgumentException("Distinguishing suffixes and outputs differ in length");
          }
          if (oldOutput.equals(newOutput)) {
              throw new IllegalArgumentException("Old and new output are equal");
          }
  
          // initial split
          if (this.root.equals(nodeToSplit)) {
              return splitLeaf(nodeToSplit, distinguishingSuffix, oldOutput, newOutput);
          }
          return LeafSplitters.splitParent(nodeToSplit, distinguishingSuffix, oldOutput, newOutput);
      }
docs: Splitting a leaf node by extending the trace leading into the node to split.
  
  @param nodeToSplit
  the leaf node to extends
  @param distinguishingSuffix
  the input sequence that splits the hypothesis state of the leaf to split and the new node. The current
  trace leading into the node to split must be a prefix of this word.
  @param oldOutput
  the hypothesis output of the node to split given the distinguishing suffix
  @param newOutput
  the hypothesis output of the new leaf given the distinguishing suffix
  
  @return the new leaf node