private ProgramDB openProgram(String progName, PrivateDatabase db) throws Exception {

		ProgramDB program = null;
		DBHandle dbh = null;
		boolean success = false;
		try {
			dbh = db.open(TaskMonitor.DUMMY);
			program = new ProgramDB(dbh, OpenMode.UPDATE, null, this);
			success = true;
		}
		catch (VersionException ve) {
			if (!ve.isUpgradable()) {
				throw ve;
			}

			if (dbh != null) {
				dbh.close();
			}
			dbh = null;

			// this property is set when running from the nightly batch build
			String message = System.getProperty("upgradeProgramErrorMessage");
			if (message == null) {
				message = "WARNING! Attempting data upgrade for ";
			}

			Msg.info(this, message + " '" + progName + "'");
			long startTime = System.currentTimeMillis();
			upgradeDatabase(db);
			long endTime = System.currentTimeMillis();

			message = System.getProperty("upgradeTimeErrorMessage");
			if (message == null) {
				message = "Upgrade Time (ms): ";
			}

			Msg.info(this, message + (endTime - startTime));
			dbh = db.open(TaskMonitor.DUMMY);
			program = new ProgramDB(dbh, OpenMode.UPDATE, null, this);
			dbh = null;
			success = true;
		}
		finally {
			if (!success && dbh != null) {
				dbh.close();
			}
		}

		DomainFile df = program.getDomainFile();
		if (!df.isInWritableProject()) {
			df.setName(progName);
		}
		return program;
	}
Copies the specified program zip file to the JUnit test project's folder. <b>This
means that the program will appear in the FrontEndTool as part of the project.</b>  That is
the only reason to use this method vice openProgram().

@param folder the folder into which the domain file will be inserted
@param programName the name of the program zip file without the ".gzf" extension.
@return the file
@throws FileNotFoundException if the file cannot be found
Ghidra/Features/Base/src/main/java/ghidra/test/TestProgramManager.java