void (final Supplier<Collection<? extends File>> pathsProvider, final boolean notifyDeletion) { // ensure events are processed in the order they arrived runCommand(() -> { final Collection<? extends File> paths = pathsProvider.get(); if (paths.isEmpty()) { return; } final List<String> filtered = new ArrayList<>(paths.size()); for (File file : paths) { final String path = FileUtil.toSystemIndependentName(file.getPath()); if (PATH_FILTER.apply(path)) { filtered.add(path); } } if (filtered.isEmpty()) { return; } synchronized (myProjectDataMap) { for (Map.Entry<String, ProjectData> entry : myProjectDataMap.entrySet()) { final ProjectData data = entry.getValue(); if (notifyDeletion) { data.addDeleted(filtered); } else { data.addChanged(filtered); } RequestFuture<?> future = myBuildsInProgress.get(entry.getKey()); if (future != null && !future.isCancelled() && !future.isDone()) { final UUID sessionId = future.getRequestID(); final Channel channel = myMessageDispatcher.getConnectedChannel(sessionId); if (channel != null) { CmdlineRemoteProto.Message.ControllerMessage.FSEvent event = data.createNextEvent(wslPathMapper(entry.getKey())); final CmdlineRemoteProto.Message.ControllerMessage message = CmdlineRemoteProto.Message.ControllerMessage.newBuilder().setType( CmdlineRemoteProto.Message.ControllerMessage.Type.FS_EVENT ).setFsEvent(event).build(); if (LOG.isDebugEnabled()) { LOG.debug("Sending to running build, ordinal=" + event.getOrdinal()); } channel.writeAndFlush(CmdlineProtoUtil.toMessage(sessionId, message)); } } } } }); }