@NotNull
  private <S> List<S> filterUniqueByUrl(@NotNull List<? extends S> in, @NotNull Function<? super S, ? extends VirtualFile> convertor) {
    List<MyPair<S>> infos = new ArrayList<>();
    List<S> notMatched = new ArrayList<>();
    for (S s : in) {
      VirtualFile vf = convertor.apply(s);
      if (vf == null) continue;

      File ioFile = virtualToIoFile(vf);
      Url url = getSvnFileUrlMapping().getUrlForFile(ioFile);
      if (url == null) {
        url = SvnUtil.getUrl(this, ioFile);
        if (url == null) {
          notMatched.add(s);
          continue;
        }
      }
      infos.add(new MyPair<>(vf, url, s));
    }
    List<MyPair<S>> filtered = new UniqueRootsFilter().filter(infos);
    List<S> converted = map(filtered, MyPair::getSrc);

    // potential bug is here: order is not kept. but seems it only occurs for cases where result is sorted after filtering so ok
    return concat(converted, notMatched);
  }
@NotNull
  private <S> List<S> filterUniqueByUrl(@NotNull List<? extends S> in, @NotNull Function<? super S, ? extends VirtualFile> convertor)