private void updateWatchRoots(@NotNull Collection<String> rootsToAdd,
                                @NotNull Set<WatchRequest> requestsToRemove,
                                @NotNull Set<WatchRequest> result,
                                @NotNull Map<String, List<WatchRequest>> roots,
                                boolean recursiveWatchRoots) {
    List<WatchSymlinkRequest> watchSymlinkRequestsToAdd = new SmartList<>();
    for (String root : rootsToAdd) {
      String watchRoot = prepareWatchRoot(root);
      if (watchRoot == null) continue;

      List<WatchRequest> requests = roots.computeIfAbsent(watchRoot, __ -> new SmartList<>());
      boolean foundSameRequest = false;
      if (!requestsToRemove.isEmpty()) {
        for (WatchRequest currentRequest : requests) {
          if (requestsToRemove.remove(currentRequest)) {
            foundSameRequest = true;
            result.add(currentRequest);
          }
        }
      }

      if (!foundSameRequest) {
        WatchRequestImpl newRequest = new WatchRequestImpl(watchRoot, recursiveWatchRoots);
        requests.add(newRequest);
        result.add(newRequest);
        if (recursiveWatchRoots) {
          collectSymlinkRequests(newRequest, watchSymlinkRequestsToAdd);
        }
        if (requests.size() == 1 && !WatchRootsUtil.isCoveredRecursively(myOptimizedRecursiveWatchRoots, watchRoot)) {
          myWatcherRequiresUpdate = true;
          if (recursiveWatchRoots) {
            WatchRootsUtil.insertRecursivePath(myOptimizedRecursiveWatchRoots, watchRoot);
          }
        }
      }
    }

    List<WatchSymlinkRequest> watchSymlinkRequestsToRemove = new SmartList<>();
    for (WatchRequest request : requestsToRemove) {
      removeWatchRequest(request);
      if (recursiveWatchRoots) {
        collectSymlinkRequests((WatchRequestImpl)request, watchSymlinkRequestsToRemove);
      }
    }

    if (recursiveWatchRoots) {
      addWatchSymlinkRequests(watchSymlinkRequestsToAdd);
      removeWatchSymlinkRequests(watchSymlinkRequestsToRemove);
    }
  }
private void updateWatchRoots(@NotNull Collection<String> rootsToAdd,
                                @NotNull Set<WatchRequest> requestsToRemove,
                                @NotNull Set<WatchRequest> result,
                                @NotNull Map<String, List<WatchRequest>> roots,
                                boolean recursiveWatchRoots)