protected FileData<METADATATYPE> lookup(FileData<METADATATYPE> baseDir, String[] nameparts,
			int maxpart, boolean createIfMissing, boolean followSymlinks, int depth,
			StringBuilder symlinkPathDebug, Comparator<String> nameComp) throws IOException {
		symlinkPathDebug = Objects.requireNonNullElseGet(symlinkPathDebug, StringBuilder::new);
		maxpart = maxpart < 0 ? nameparts.length : maxpart;

		if (depth > MAX_SYMLINK_RECURSE_DEPTH) {
			throw new IOException(
				"Too many symlinks: %s, %s".formatted(symlinkPathDebug, Arrays.asList(nameparts)));
		}

		symlinkPathDebug.append("[");
		FileData<METADATATYPE> currentFile = Objects.requireNonNullElse(baseDir, rootDir);
		for (int i = 0; i < maxpart && currentFile != null; i++) {
			String name = nameparts[i];
			symlinkPathDebug.append(i != 0 ? "," : "").append(name);
			if (name.isEmpty()) {
				continue;
			}
			if (followSymlinks) {
				// otherwise "." and ".." are valid path elements that need to be matched exactly
				if (".".equals(name)) {
					continue;
				}
				if ("..".equals(name)) {
					currentFile = getParentFileData(currentFile);
					continue;
				}
			}

			Map<String, FileData<METADATATYPE>> currentDirContents =
				getDirectoryContents(currentFile.file, createIfMissing);
			FileData<METADATATYPE> next = lookupFileInDir(currentDirContents, name, nameComp);
			if (next == null && createIfMissing) {
				next = doStoreMissingDir(name, currentFile.file);
			}
			if (next != null && next.symlinkPath != null && followSymlinks) {
				next = lookup(currentFile, splitPath(next.symlinkPath), -1, createIfMissing,
					followSymlinks, depth + 1, symlinkPathDebug, nameComp);
			}
			currentFile = next;
		}

		symlinkPathDebug.append("]");
		return currentFile;
	}
Mirrors {@link GFileSystem#lookup(String)} interface, with additional parameters to
control the lookup.

@param baseDir optional starting directory to perform lookup
@param path path and filename of a file to find
@param nameComp optional {@link Comparator} that compares file names.  Suggested values are 
{@code String::compareTo} or {@code String::compareToIgnoreCase} or {@code null} (also exact).
@return {@link GFile} instance or null if no file was added to the index at that path
Ghidra/Features/Base/src/main/java/ghidra/formats/gfilesystem/FileSystemIndexHelper.java