public static Map<String, GModule> findModules(Collection<ResourceFile> appRootDirs,
			Collection<ResourceFile> moduleRootDirs, Predicate<GModule> moduleFilter) {

		Map<String, GModule> map = new TreeMap<>();

		for (ResourceFile moduleRoot : moduleRootDirs) {
			GModule gModule = new GModule(appRootDirs, moduleRoot);
			if (!moduleFilter.test(gModule)) {
				continue;
			}

			if (map.put(moduleRoot.getName(), gModule) != null) {
				StringBuilder collided = new StringBuilder();
				for (ResourceFile collideRoot : moduleRootDirs) {
					if (moduleRoot.getName().equals(collideRoot.getName())) {
						collided.append("\n");
						collided.append(collideRoot.getAbsolutePath());
					}
				}
				throw new AssertException(
					"Multiple modules collided with same name: " + moduleRoot.getName() + collided);
			}
		}
		return Collections.unmodifiableMap(map);
	}
Searches for modules in a given collection of module root directories.

@param appRootDirs The collection of application root directories associated with the given
  list of module root directories.
@param moduleRootDirs A collection of module root directories to search for modules in.
@param moduleFilter a predicate used to filter modules; a given module will not be included
  when the predicate returns false.
@return The discovered modules as a map (mapping module name to module for convenience).
Ghidra/Framework/Utility/src/main/java/utility/module/ModuleUtilities.java