code: public static <S, I, O> ADTNode<S, I, O> buildADSFromObservation(final Word<I> input,
                                                                       final Word<O> output,
                                                                       final S finalState) {
  
          if (input.size() != output.size()) {
              throw new IllegalArgumentException("Arguments differ in length");
          }
  
          final Iterator<I> inputIterator = input.iterator();
          final Iterator<O> outputIterator = output.iterator();
  
          final ADTNode<S, I, O> result = new ADTSymbolNode<>(null, inputIterator.next());
          ADTNode<S, I, O> nodeIter = result;
  
          while (inputIterator.hasNext()) {
              final ADTNode<S, I, O> nextNode = new ADTSymbolNode<>(nodeIter, inputIterator.next());
              nodeIter.getChildren().put(outputIterator.next(), nextNode);
  
              nodeIter = nextNode;
          }
  
          final ADTNode<S, I, O> finalNode = new ADTLeafNode<>(nodeIter, finalState);
          nodeIter.getChildren().put(outputIterator.next(), finalNode);
  
          return result;
      }
docs: Build a single trace ADS from the given information.
  
  @param input
  the input sequence of the trace
  @param output
  the output sequence of the trace
  @param finalState
  the hypothesis state that should be referenced in the leaf of the ADS
  @param <S>
  (hypothesis) state type
  @param <I>
  input alphabet type
  @param <O>
  output alphabet type
  
  @return the root node of the constructed ADS