static <T, D extends Difference> Specifier<T, D> deepDiff(@Nullable Iterable<T> past, @Nullable Iterable<T> now, BiPredicate<? super T, ? super T> isSameImpl, Function<? super T, Integer> diffHashImpl, BiFunction<? super T, ? super T, ? extends D> diffImpl) {
    Iterators.Function<T, DiffCapable.Adapter<T, D>> mapper = obj -> DiffCapable.wrap(obj, isSameImpl, diffHashImpl, diffImpl);
    Specifier<DiffCapable.Adapter<T, D>, D> adapterDiff = deepDiff(map(past, mapper), map(now, mapper));
    return new Specifier<>() {
      @Override
      public Iterable<T> added() {
        return map(adapterDiff.added(), DiffCapable.Adapter::getValue);
      }

      @Override
      public Iterable<T> removed() {
        return map(adapterDiff.removed(), DiffCapable.Adapter::getValue);
      }

      @Override
      public Iterable<Change<T, D>> changed() {
        return map(adapterDiff.changed(), ch -> new Change<T, D>() {
          @Override
          public T getPast() {
            return ch.getPast().getValue();
          }

          @Override
          public T getNow() {
            return ch.getNow().getValue();
          }

          @Override
          public D getDiff() {
            return ch.getDiff();
          }
        });
      }

      @Override
      public boolean unchanged() {
        return adapterDiff.unchanged();
      }
    };
  }
static <T, D extends Difference> Specifier<T, D> deepDiff(@Nullable Iterable<T> past, @Nullable Iterable<T> now, BiPredicate<? super T, ? super T> isSameImpl, Function<? super T, Integer> diffHashImpl, BiFunction<? super T, ? super T, ? extends D> diffImpl)