public void apply(
        final SvnVcs vcs, final List<RootUrlInfo> roots, final List<VirtualFile> lonelyRoots) {
      final SvnMapping mapping = new SvnMapping();
      mapping.addAll(roots);
      mapping.reportLonelyRoots(lonelyRoots);

      final SvnMapping groupedMapping = new SvnMapping();
      final List<RootUrlInfo> filtered = new ArrayList<RootUrlInfo>();
      ForNestedRootChecker.filterOutSuperfluousChildren(vcs, roots, filtered);

      groupedMapping.addAll(filtered);

      ApplicationManager.getApplication()
          .runReadAction(
              new Runnable() {
                @Override
                public void run() {
                  synchronized (myMonitor) {
                    myMapping.copyFrom(mapping);
                    myMoreRealMapping.copyFrom(groupedMapping);
                  }
                }
              });
      myProject.getMessageBus().syncPublisher(SvnVcs.ROOTS_RELOADED).run();
    }
  public List<VirtualFile> convertRoots(final List<VirtualFile> result) {
    if (ThreadLocalDefendedInvoker.isInside()) return result;

    synchronized (myMonitor) {
      final List<VirtualFile> cachedRoots = myMapping.getUnderVcsRoots();
      final List<VirtualFile> lonelyRoots = myMapping.getLonelyRoots();
      if (!lonelyRoots.isEmpty()) {
        myChecker.reportNoRoots(lonelyRoots);
      }
      if (cachedRoots.isEmpty()) {
        // todo +-
        return result;
      }
      return cachedRoots;
    }
  }
 @Nullable
 public String getUrlRootForUrl(final String currentUrl) {
   for (String url : myMapping.getUrls()) {
     if (SVNPathUtil.isAncestor(url, currentUrl)) {
       return url;
     }
   }
   return null;
 }
 @Nullable
 public String getRootForPath(final File currentPath) {
   String convertedPath = currentPath.getAbsolutePath();
   convertedPath =
       (currentPath.isDirectory() && (!convertedPath.endsWith(File.separator)))
           ? convertedPath + File.separator
           : convertedPath;
   synchronized (myMonitor) {
     return myMapping.getRootForPath(convertedPath);
   }
 }
  @Nullable
  public RootUrlInfo getWcRootForFilePath(final File file) {
    synchronized (myMonitor) {
      final String root = getRootForPath(file);
      if (root == null) {
        return null;
      }

      return myMapping.byFile(root);
    }
  }
  @Nullable
  public String getLocalPath(final String url) {
    synchronized (myMonitor) {
      final String rootUrl = getUrlRootForUrl(url);
      if (rootUrl == null) {
        return null;
      }
      final RootUrlInfo parentInfo = myMapping.byUrl(rootUrl);
      if (parentInfo == null) {
        return null;
      }

      return fileByUrl(parentInfo.getIoFile().getAbsolutePath(), rootUrl, url).getAbsolutePath();
    }
  }
  @Nullable
  public RootUrlInfo getWcRootForUrl(final String url) {
    synchronized (myMonitor) {
      final String rootUrl = getUrlRootForUrl(url);
      if (rootUrl == null) {
        return null;
      }

      final RootUrlInfo result = myMapping.byUrl(rootUrl);
      if (result == null) {
        LOG.info("Inconsistent maps for url:" + url + " found root url: " + rootUrl);
        return null;
      }
      return result;
    }
  }
  private void fillMapping(final SvnMapping mapping, final List<SvnCopyRootSimple> list) {
    final LocalFileSystem lfs = LocalFileSystem.getInstance();

    for (SvnCopyRootSimple simple : list) {
      final VirtualFile copyRoot = lfs.findFileByIoFile(new File(simple.myCopyRoot));
      final VirtualFile vcsRoot = lfs.findFileByIoFile(new File(simple.myVcsRoot));

      if (copyRoot == null || vcsRoot == null) continue;

      final SvnVcs vcs = SvnVcs.getInstance(myProject);
      final SVNInfo svnInfo = vcs.getInfo(copyRoot);
      if ((svnInfo == null) || (svnInfo.getRepositoryRootURL() == null)) continue;

      final RootUrlInfo info =
          new RootUrlInfo(
              svnInfo.getRepositoryRootURL(),
              svnInfo.getURL(),
              SvnFormatSelector.getWorkingCopyFormat(svnInfo.getFile()),
              copyRoot,
              vcsRoot);
      mapping.add(info);
    }
  }
  public SvnMappingSavedPart getState() {
    final SvnMappingSavedPart result = new SvnMappingSavedPart();

    final SvnMapping mapping = new SvnMapping();
    final SvnMapping realMapping = new SvnMapping();
    synchronized (myMonitor) {
      mapping.copyFrom(myMapping);
      realMapping.copyFrom(myMoreRealMapping);
    }

    for (RootUrlInfo info : mapping.getAllCopies()) {
      result.add(convert(info));
    }
    for (RootUrlInfo info : realMapping.getAllCopies()) {
      result.addReal(convert(info));
    }
    return result;
  }
 public boolean isEmpty() {
   synchronized (myMonitor) {
     return myMapping.isEmpty();
   }
 }
 /**
  * Returns real working copies roots - if there is <Project Root> -> Subversion setting, and there
  * is one working copy, will return one root
  */
 public List<RootUrlInfo> getAllWcInfos() {
   synchronized (myMonitor) {
     // a copy is created inside
     return myMoreRealMapping.getAllCopies();
   }
 }
 public boolean rootsDiffer() {
   synchronized (myMonitor) {
     return myMapping.isRootsDifferFromSettings();
   }
 }