code: public static <S, I, O> AbstractSULOmegaOracle<S, I, O, ?> newOracle(ObservableSUL<S, I, O> sul,
                                                                           boolean deepCopies) {
          final AbstractSULOmegaOracle<S, I, O, ?> abstractSulOmegaOracle;
          if (deepCopies) {
              if (!sul.deepCopies()) {
                  throw new IllegalArgumentException("SUL can not make deep copies of states.");
              } else {
                  abstractSulOmegaOracle = new DeepCopySULOmegaOracle<>(sul);
              }
          } else {
              if (!sul.canFork()) {
                  throw new IllegalArgumentException("SUL must be forkable.");
              } else {
                  abstractSulOmegaOracle = new ShallowCopySULOmegaOracle<>(sul);
              }
          }
  
          return abstractSulOmegaOracle;
      }
docs: Creates a new {@link AbstractSULOmegaOracle}, while making sure the invariants of the {@link ObservableSUL} are
  satisfied.
  
  @param sul the {@link ObservableSUL} to wrap around.
  @param deepCopies whether to test for state equivalence directly on the retrieved state.
  
  @param <S> the state type
  @param <I> the input type
  @param <O> the output type
  
  @return the {@link AbstractSULOmegaOracle}.