void refresh(boolean recursive, boolean force, TaskMonitor monitor) throws IOException {
		synchronized (fileSystem) {
			if (recursive && !force) {
				throw new IllegalArgumentException("force must be true when recursive");
			}
			if (monitor != null && monitor.isCancelled()) {
				return;
			}
			if (visited && !force) {
				return;
			}
			try {
				updateExistenceState();
			}
			catch (IOException e) {
				if (parent != null) {
					parent.folderRemoved(name);
				}
				throw e;
			}

			if (!folderExists && !versionedFolderExists) {
				if (parent != null) {
					parent.folderRemoved(name);
				}
				throw new FileNotFoundException("Folder not found: " + getPathname());
			}

			try {
				refreshFiles(monitor);

				if (monitor != null && monitor.isCancelled()) {
					return; // break-out from recursion on cancel
				}

				refreshFolders(recursive, monitor);
			}
			finally {
				visited = true;
			}
		}
	}
Full refresh of names of children is performed.  This method
should only be invoked when a full list of folders or
children is requested - which may be in response to 
a "folder changed" notification.
@param recursive if true a recursive refresh will be done (force must also be true).
Sub-folders will only be refreshed if they have been visited.
@param force if true, refresh will be forced regardless
of visited state, if false refresh is lazy and will not be 
performed if a previous refresh set the visited state.
@param monitor recursion task monitor - break from recursion if cancelled
@throws IOException if an IO error occurs during the refresh
Ghidra/Framework/Project/src/main/java/ghidra/framework/data/GhidraFolderData.java