static Set<Path> computeChangedPaths(Path projectBasedir, SVNClientManager clientManager) throws SVNException {
    SVNWCClient wcClient = clientManager.getWCClient();
    SVNInfo svnInfo = wcClient.doInfo(projectBasedir.toFile(), null);

    // SVN path of the repo root, for example: /C:/Users/JANOSG~1/AppData/Local/Temp/x/y
    Path svnRootPath = toPath(svnInfo.getRepositoryRootURL());

    // the svn root path may be "" for urls like http://svnserver/
    // -> set it to "/" to avoid crashing when using Path.relativize later
    if (svnRootPath.equals(Paths.get(""))) {
      svnRootPath = Paths.get("/");
    }

    // SVN path of projectBasedir, for example: /C:/Users/JANOSG~1/AppData/Local/Temp/x/y/branches/b1
    Path svnProjectPath = toPath(svnInfo.getURL());
    // path of projectBasedir, as "absolute path within the SVN repo", for example: /branches/b1
    Path inRepoProjectPath = Paths.get("/").resolve(svnRootPath.relativize(svnProjectPath));

    // We inspect "svn log" from latest revision until copy-point.
    // The same path may appear in multiple commits, the ordering of changes and removals is important.
    Set<Path> paths = new HashSet<>();
    Set<Path> removed = new HashSet<>();

    SVNLogClient svnLogClient = clientManager.getLogClient();
    svnLogClient.doLog(new File[] {projectBasedir.toFile()}, null, null, null, true, true, 0, svnLogEntry ->
      svnLogEntry.getChangedPaths().values().forEach(entry -> {
        if (entry.getKind().equals(SVNNodeKind.FILE)) {
          Path path = projectBasedir.resolve(inRepoProjectPath.relativize(Paths.get(entry.getPath())));
          if (isModified(entry)) {
            // Skip if the path is removed in a more recent commit
            if (!removed.contains(path)) {
              paths.add(path);
            }
          } else if (entry.getType() == SVNLogEntryPath.TYPE_DELETED) {
            removed.add(path);
          }
        }
      }));
    return paths;
  }
@Test
  public void computeChangedPaths_should_not_crash_when_getRepositoryRootURL_getPath_is_empty() throws SVNException {
    // verify assumptions about what SVNKit returns as svn root path for urls like http://svnserver/
    assertThat(SVNURL.parseURIEncoded("http://svnserver/").getPath()).isEmpty();
    assertThat(SVNURL.parseURIEncoded("http://svnserver").getPath()).isEmpty();

    SVNClientManager svnClientManagerMock = mock(SVNClientManager.class);

    SVNWCClient svnwcClientMock = mock(SVNWCClient.class);
    when(svnClientManagerMock.getWCClient()).thenReturn(svnwcClientMock);

    SVNLogClient svnLogClient = mock(SVNLogClient.class);
    when(svnClientManagerMock.getLogClient()).thenReturn(svnLogClient);

    SVNInfo svnInfoMock = mock(SVNInfo.class);
    when(svnwcClientMock.doInfo(any(), any())).thenReturn(svnInfoMock);

    // Simulate repository root on /, SVNKIT then returns an repository root url WITHOUT / at the end.
    when(svnInfoMock.getRepositoryRootURL()).thenReturn(SVNURL.parseURIEncoded("http://svnserver"));
    when(svnInfoMock.getURL()).thenReturn(SVNURL.parseURIEncoded("http://svnserver/myproject/trunk/"));

    assertThat(SvnScmProvider.computeChangedPaths(Paths.get("/"), svnClientManagerMock)).isEmpty();
  }