void (@NotNull List<String> recursive, @NotNull List<String> flat, boolean shuttingDown) { if (shuttingDown) { myShuttingDown = true; for (Map.Entry<String, VmData> entry : myVMs.entrySet()) { shutdownProcess(entry.getValue(), false); } } if (myShuttingDown) return; Map<String, VmData> newVMs = new HashMap<>(); List<String> ignored = new ArrayList<>(); sortRoots(recursive, newVMs, ignored, true); sortRoots(flat, newVMs, ignored, false); myNotificationSink.notifyManualWatchRoots(this, ignored); for (Map.Entry<String, VmData> entry : newVMs.entrySet()) { VmData upcoming = entry.getValue(), vm = myVMs.computeIfAbsent(entry.getKey(), k -> upcoming); assert vm != null : entry; if (vm == upcoming) { setupProcess(vm); } else if (!vm.recursive.equals(upcoming.recursive) || !vm.flat.equals(upcoming.flat)) { vm.reload(upcoming); setupProcess(vm); } else { myNotificationSink.notifyManualWatchRoots(this, vm.ignored); } } for (Iterator<Map.Entry<String, VmData>> iterator = myVMs.entrySet().iterator(); iterator.hasNext(); ) { Map.Entry<String, VmData> entry = iterator.next(); if (!newVMs.containsKey(entry.getKey())) { iterator.remove(); shutdownProcess(entry.getValue(), true); } } }