@Override
  public Pair<SvnChangeList, FilePath> getOneList(final VirtualFile file, VcsRevisionNumber number)
      throws VcsException {
    final RootUrlInfo rootUrlInfo =
        myVcs.getSvnFileUrlMapping().getWcRootForFilePath(new File(file.getPath()));
    if (rootUrlInfo == null) return null;
    final VirtualFile root = rootUrlInfo.getVirtualFile();
    if (root == null) return null;
    final SvnRepositoryLocation svnRootLocation =
        (SvnRepositoryLocation) getLocationFor(new FilePathImpl(root));
    if (svnRootLocation == null) return null;
    final String url = svnRootLocation.getURL();
    final long revision;
    try {
      revision = Long.parseLong(number.asString());
    } catch (NumberFormatException e) {
      throw new VcsException(e);
    }

    final SvnChangeList[] result = new SvnChangeList[1];
    final SVNLogClient logger;
    final SVNRevision revisionBefore;
    final SVNURL repositoryUrl;
    final SVNURL svnurl;
    final SVNInfo targetInfo;
    try {
      logger = myVcs.createLogClient();
      revisionBefore = SVNRevision.create(revision);

      svnurl = SVNURL.parseURIEncoded(url);
      final SVNWCClient client = myVcs.createWCClient();
      final SVNInfo info = client.doInfo(svnurl, SVNRevision.UNDEFINED, SVNRevision.HEAD);
      targetInfo = client.doInfo(new File(file.getPath()), SVNRevision.UNDEFINED);
      if (info == null) {
        throw new VcsException("Can not get repository URL");
      }
      repositoryUrl = info.getRepositoryRootURL();
    } catch (SVNException e) {
      LOG.info(e);
      throw new VcsException(e);
    }

    tryExactHit(svnRootLocation, result, logger, revisionBefore, repositoryUrl, svnurl);
    if (result[0] == null) {
      tryByRoot(result, logger, revisionBefore, repositoryUrl);
      if (result[0] == null) {
        FilePath path =
            tryStepByStep(svnRootLocation, result, logger, revisionBefore, targetInfo, svnurl);
        path = path == null ? new FilePathImpl(file) : path;
        // and pass & take rename context there
        return new Pair<SvnChangeList, FilePath>(result[0], path);
      }
    }
    if (result[0].getChanges().size() == 1) {
      final Collection<Change> changes = result[0].getChanges();
      final Change change = changes.iterator().next();
      final ContentRevision afterRevision = change.getAfterRevision();
      if (afterRevision != null) {
        return new Pair<SvnChangeList, FilePath>(result[0], afterRevision.getFile());
      } else {
        return new Pair<SvnChangeList, FilePath>(result[0], new FilePathImpl(file));
      }
    }
    String relativePath =
        SVNPathUtil.getRelativePath(
            targetInfo.getRepositoryRootURL().toString(), targetInfo.getURL().toString());
    relativePath = relativePath.startsWith("/") ? relativePath : "/" + relativePath;
    final Change targetChange = result[0].getByPath(relativePath);
    if (targetChange == null) {
      FilePath path =
          tryStepByStep(svnRootLocation, result, logger, revisionBefore, targetInfo, svnurl);
      path = path == null ? new FilePathImpl(file) : path;
      // and pass & take rename context there
      return new Pair<SvnChangeList, FilePath>(result[0], path);
    }
    return new Pair<SvnChangeList, FilePath>(result[0], new FilePathImpl(file));
  }
  private void getCommittedChangesImpl(
      ChangeBrowserSettings settings,
      final String url,
      final String[] filterUrls,
      final int maxCount,
      final Consumer<SVNLogEntry> resultConsumer,
      final boolean includeMergedRevisions,
      final boolean filterOutByDate)
      throws VcsException {
    final ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
    if (progress != null) {
      progress.setText(SvnBundle.message("progress.text.changes.collecting.changes"));
      progress.setText2(SvnBundle.message("progress.text2.changes.establishing.connection", url));
    }
    try {
      SVNLogClient logger = myVcs.createLogClient();

      final String author = settings.getUserFilter();
      final Date dateFrom = settings.getDateAfterFilter();
      final Long changeFrom = settings.getChangeAfterFilter();
      final Date dateTo = settings.getDateBeforeFilter();
      final Long changeTo = settings.getChangeBeforeFilter();

      final SVNRevision revisionBefore;
      if (dateTo != null) {
        revisionBefore = SVNRevision.create(dateTo);
      } else if (changeTo != null) {
        revisionBefore = SVNRevision.create(changeTo.longValue());
      } else {
        SVNRepository repository = null;
        final long revision;
        try {
          repository = myVcs.createRepository(url);
          revision = repository.getLatestRevision();
        } finally {
          if (repository != null) {
            repository.closeSession();
          }
        }
        revisionBefore = SVNRevision.create(revision);
      }
      final SVNRevision revisionAfter;
      if (dateFrom != null) {
        revisionAfter = SVNRevision.create(dateFrom);
      } else if (changeFrom != null) {
        revisionAfter = SVNRevision.create(changeFrom.longValue());
      } else {
        revisionAfter = SVNRevision.create(1);
      }

      logger.doLog(
          SVNURL.parseURIEncoded(url),
          filterUrls,
          revisionBefore,
          revisionBefore,
          revisionAfter,
          settings.STOP_ON_COPY,
          true,
          includeMergedRevisions,
          maxCount,
          null,
          new ISVNLogEntryHandler() {
            public void handleLogEntry(SVNLogEntry logEntry) {
              if (myProject.isDisposed()) throw new ProcessCanceledException();
              if (progress != null) {
                progress.setText2(
                    SvnBundle.message(
                        "progress.text2.processing.revision", logEntry.getRevision()));
                progress.checkCanceled();
              }
              if (filterOutByDate && logEntry.getDate() == null) {
                // do not add lists without info - this situation is possible for lists where there
                // are paths that user has no rights to observe
                return;
              }
              if (author == null || author.equalsIgnoreCase(logEntry.getAuthor())) {
                resultConsumer.consume(logEntry);
              }
            }
          });
    } catch (SVNException e) {
      throw new VcsException(e);
    }
  }