private <T extends FolderItem> Map<String, T> itemMapOf(T[] items) {
		Map<String, T> map = new HashMap<>();
		int badItemCount = 0;
		int nullNameCount = 0;
		int unknownItemCount = 0;
		for (T item : items) {
			if (item == null) {
				++badItemCount;
				continue;
			}
			String itemName = item.getName();
			if (itemName == null) {
				++nullNameCount;
				continue;
			}
			if (item instanceof UnknownFolderItem unk) {
				if (unk.getFileType() == FolderItem.UNKNOWN_FILE_TYPE) {
					++badItemCount;
					continue;
				}
				Msg.error(this, "Unsupported folder item encountered (" + unk.getFileType() +
					"): " + getPathname(item.getName()));
				++unknownItemCount;
			}
			map.put(itemName, item);
		}
		if (badItemCount != 0) {
			Msg.error(this,
				"Project folder contains " + badItemCount + " bad items: " + getPathname());
		}
		if (nullNameCount != 0) {
			Msg.error(this,
				"Project folder contains " + nullNameCount + " null items: " + getPathname());
		}
		if (badItemCount != 0) {
			Msg.error(this, "Project folder contains " + unknownItemCount + " unsupported items: " +
				getPathname());
		}
		return map;
	}
Refresh set of sub-folder names and identify added/removed folders.
@param recursive recurse into visited subfolders if true
@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