private FileCacheEntry addTmpFileToCache(File tmpFile, String md5) throws IOException {
		String relPath = getCacheRelPath(md5);

		File destCacheFile = new File(cacheDir, relPath);
		File destCacheFileDir = destCacheFile.getParentFile();

		if (!destCacheFileDir.exists() && !FileUtilities.mkdirs(destCacheFileDir)) {
			throw new IOException("Failed to create cache dir " + destCacheFileDir);
		}

		try {
			tmpFile.renameTo(destCacheFile);
		}
		finally {
			tmpFile.delete();
			if (!destCacheFile.exists()) {
				throw new IOException("Failed to move " + tmpFile + " to " + destCacheFile);
			}
		}
		destCacheFile.setLastModified(System.currentTimeMillis());
		return new FileCacheEntry(destCacheFile, md5);
	}
Adds an already obfuscated File to this cache, consuming the file.
<p>
This method makes some assumptions:
<p>
1) Directories are never removed - when ensuring that a nested directory exists
before placing a new file into that directory, there is no locking mechanism
and if another process removed the directory between the check for the directory's
existence and the attempt to place the file into the directory.  Solution: no
process may remove a nested directory after it has been created.
2) The source file is co-located with the cache directory to ensure its on the
same physical filesystem volume, and is already obfuscated.

@param tmpFile the File to add to the cache
@param md5 hex string md5 of the file
@return a new {@link FileCacheEntry} with the File's location and its md5
@throws IOException if an file error occurs
Ghidra/Features/Base/src/main/java/ghidra/formats/gfilesystem/FileCache.java