private ProgramDB buildNotepadMergeListingTestProgram() throws Exception {

		ToyProgramBuilder builder =
			new ToyProgramBuilder("NotepadMergeListingTest", true, consumer);

		builder.createMemory(".text", "0x1001000", 0x6600);
		builder.createMemory(".data", "0x1008000", 0x600);
		builder.createMemory(".data", "0x1008600", 0x1344);
		builder.createMemory(".rsrc", "0x100a000", 0x5400);

		builder.createNamespace("FirstNamespace");
		builder.createNamespace("SecondNamespace");
		builder.createNamespace("EmptyNamespace");
		builder.createNamespace("SubNamespace", "SecondNamespace", SourceType.USER_DEFINED);

		builder.createLabel("0x100e483", "AAA");

		Function function =
			builder.createEmptyFunction("FUN_100248f", "0x100248f", 1214, new Undefined1DataType());

		String namespace = function.getName();
		builder.createLabel("0x1002691", "AAA", namespace);

		function = builder.createEmptyFunction("entry", "0x1006420", 396, new Undefined1DataType());
		namespace = function.getName();
		builder.createLabel("0x1006420", "ABC", namespace);

		function =
			builder.createEmptyFunction("FUN_10033f6", "0x10033f6", 87, new Undefined1DataType());
		namespace = function.getName();
		builder.createLabel("0x1003439", "BBB", namespace);

		function =
			builder.createEmptyFunction("FUN_1003bed", "0x1003bed", 783, new Undefined1DataType());
		namespace = function.getName();
		builder.createLabel("0x1003e25", "CCC", namespace);

		builder.createLabel("0x10044d0", "DDD");
		builder.createLabel("0x1006420", "DEF");

		function =
			builder.createEmptyFunction("FUN_1004444", "0x1004444", 652, new Undefined1DataType());
		namespace = function.getName();
		builder.createLabel("0x10044d0", "DDD6", "FUN_01004444");

		function =
			builder.createEmptyFunction("FUN_1004bc0", "FirstNamespace", "0x1004bc0", 93,
				new Undefined1DataType());
		namespace = function.getName();
		builder.createLabel("0x1004bdc", "EEE4", namespace);
		builder.createLabel("0x1004bdc", "EEE");

		builder.createLabel("0x1003075", "YYY");
		builder.createLabel("0x1003075", "QQQ"); // Instruction Label?
		builder.createLabel("0x1002721", "XXX");
		builder.createLabel("0x1003075", "ZZZ");

		// bookmarks
		builder.createBookmark("0x1001978", BookmarkType.ANALYSIS, "Found Code",
			"Found code from operand reference");
		builder.createBookmark("0x100248f", BookmarkType.ANALYSIS, "Found Code",
			"Found code from operand reference");
		builder.createBookmark("0x1001978", BookmarkType.ANALYSIS, "Found Code",
			"Found code from operand reference");
		builder.createBookmark("0x1002f01", BookmarkType.ANALYSIS, "Found Code",
			"Found code from operand reference");

		// equates (note we need instructions where there are equates for the merger to work)
		builder.addBytesMoveImmediate("0x1001d0b", (byte) 1);
		builder.disassemble("0x1001d0b", 1);
		builder.createEquate("0x1001d0b", "01", 1, 1);

		builder.addBytesMoveImmediate("0x1001da6", (byte) 1);
		builder.disassemble("0x1001da6", 1);
		builder.createEquate("0x1001da6", "1", 1, 1);

		builder.addBytesMoveImmediate("0x1001cea", (byte) 1);
		builder.disassemble("0x1001cea", 1);
		builder.createEquate("0x1001cea", "ein", 1, 1);

		builder.addBytesMoveImmediate("0x10019a4", (byte) 0);
		builder.disassemble("0x10019a4", 1);
		builder.createEquate("0x10019a4", "nothing", 0, 1);

		builder.addBytesMoveImmediate("0x1001b5d", (byte) 1);
		builder.disassemble("0x1001b5d", 1);
		builder.createEquate("0x1001b5d", "one", 1, 1);

		builder.addBytesMoveImmediate("0x1001dd8", (byte) 3);
		builder.disassemble("0x1001dd8", 1);
		builder.createEquate("0x1001dd8", "tres", 3, 1);

		builder.addBytesMoveImmediate("0x1001bc9", (byte) 1);
		builder.disassemble("0x1001bc9", 1);
		builder.createEquate("0x1001bc9", "uno", 1, 1);

		builder.addBytesMoveImmediate("0x10019a2", (byte) 0);
		builder.disassemble("0x10019a2", 1);
		builder.createEquate("0x10019a2", "zero", 0, 1);

		builder.addBytesMoveImmediate("0x10019f8", (byte) 0);
		builder.disassemble("0x10019f8", 1);
		builder.createEquate("0x10019f8", "zero", 0, 1);

		// equate references
		builder.addBytesMoveImmediate("0x1002d18", (byte) 1);
		builder.disassemble("0x1002d18", 1);

		builder.addBytesMoveImmediate("0x1002533", (byte) 1);
		builder.disassemble("0x1002533", 1);

		// code units
		builder.addBytesNOP("0x1001bbd", 6);
		builder.disassemble("0x1001bbd", 1);

		builder.addBytesNOP("0x1001c2b", 9);
		builder.disassemble("0x1001c2b", 1);

		builder.addBytesFallthroughSetNoFlowContext("0x1004ab5", 0);
		builder.disassemble("0x1004ab5", 1);
		builder.addBytesNOP("0x1004aa5", 6);
		builder.disassemble("0x1004aa5", 16);
		builder.addBytesFallthrough("0x1004adb");
		builder.disassemble("0x1004adb", 1);
		builder.addBytesNOP("0x1004b19", 6);
		builder.disassemble("0x1004b19", 1);

		builder.addBytesFallthrough("0x10024ea");
		builder.disassemble("0x10024ea", 1);
		builder.addBytesFallthrough("0x01002f49");
		builder.disassemble("0x01002f49", 1);
		builder.addBytesFallthrough("0x01002f38");
		builder.disassemble("0x01002f38", 1);
		builder.addBytesFallthrough("0x01002ff6");
		builder.disassemble("0x01002ff6", 1);
		builder.addBytesFallthrough("0x01003059");
		builder.disassemble("0x01003059", 1);
		builder.addBytesFallthrough("0x1002f5d");
		builder.disassemble("0x1002f5d", 1);
		builder.addBytesFallthrough("0x01003105");
		builder.disassemble("0x01003105", 1);
		builder.addBytesFallthrough("0x0100319a");
		builder.disassemble("0x0100319a", 1);

		builder.addBytesFallthrough("0x1001a92");
		builder.disassemble("0x1001a92", 1);
		builder.addBytesFallthrough("0x1001abb");
		builder.disassemble("0x1001abb", 1);
		builder.addBytesFallthrough("0x1001aec");
		builder.disassemble("0x1001aec", 1);
		builder.addBytesFallthrough("0x1002eaf");
		builder.disassemble("0x1002eaf", 1);
		builder.addBytesFallthrough("0x1002f3e");
		builder.disassemble("0x1002f3e", 1);
		builder.addBytesFallthrough("0x1002f73");
		builder.disassemble("0x1002f73", 1);
		builder.addBytesFallthrough("0x01006421");
		builder.disassemble("0x01006421", 1);
		builder.addBytesNOP("0x0100642f", 6);
		builder.disassemble("0x0100642f", 1);
		builder.setFallthrough("0x0100642f", "0x01006435");
		builder.addBytesFallthrough("0x01006443");
		builder.disassemble("0x01006443", 1);
		builder.setFallthrough("0x01006443", "0x01006446");

		builder.applyDataType("0x100a2c5", new WordDataType(), 1);
		builder.createEncodedString("0x100a2d8", "hi", StandardCharsets.US_ASCII, false);
		builder.applyDataType("0x100a2f4", new DWordDataType(), 1);
		builder.applyDataType("0x1006654", new DWordDataType(), 1);
		builder.applyDataType("0x1006674", new DWordDataType(), 1);
		builder.applyDataType("0x1006be2", new WordDataType(), 1);
		builder.applyDataType("0x1007446", new WordDataType(), 1);

		// data types
		Structure myStruct = new StructureDataType("ThreeBytes", 0);
		myStruct.add(new ByteDataType());
		myStruct.add(new ByteDataType());
		myStruct.add(new ByteDataType());
		builder.addDataType(myStruct);

		Union union = new UnionDataType("UnionSize4");
		union.add(new ByteDataType());
		union.add(new WordDataType());
		union.add(new DWordDataType());
		union.add(new Pointer32DataType());
		builder.addDataType(union);

		// references
		builder.createMemoryReadReference("0x1001a92", "0x1001370");
		builder.createMemoryReadReference("0x1001abb", "0x1001ac1");
		builder.createMemoryReference("0x1001aec", "0x1001398", RefType.READ,
			SourceType.USER_DEFINED, 1);
		builder.createMemoryReadReference("0x1002eaf", "0x1002ee2");

		//
		//
		//
		builder.setProperty(Program.DATE_CREATED, new Date(100000000)); // arbitrary, but consistent

		builder.createExternalLibraries("ADVAPI32.DLL", "COMDLG32.DLL", "GDI32.DLL",
			"KERNEL32.DLL", "MSVCRT.DLL", "SHELL32.DLL", "USER32.DLL", "WINSPOOL.DRV");
		builder.bindExternalLibrary("ADVAPI32.DLL", "//advapi32.dll");
		builder.bindExternalLibrary("USER32.DLL", "//user32.dll");

		builder.createExternalReference("0x1001000", "ADVAPI32.DLL", "IsTextUnicode", 0);
		builder.createExternalReference("0x1001004", "ADVAPI32.DLL", "RegCreateKeyW", 0);
		builder.createExternalReference("0x1001008", "ADVAPI32.DLL", "RegQueryValueExW", 0);
		builder.createExternalReference("0x1001010", "ADVAPI32.DLL", "RegOpenKeyExA", "77db82ac", 0);
		builder.createExternalReference("0x10010C0", "ADVAPI32.DLL", "WhatEver", 0);
		builder.createExternalReference("0x10011e4", "USER32.DLL", "setCursor", 0);

		builder.createEmptyFunction(null, "0x1002950", 78, null);
		builder.createEmptyFunction(null, "0x1002cf5", 121, null);
		builder.createEmptyFunction(null, "0x1002b7d", 278, null);
		builder.createEmptyFunction(null, "0x10031ee", 98, null);
		builder.createEmptyFunction(null, "0x1002a91", 179, null);
		builder.createEmptyFunction(null, "0x1002b44", 57, null);
		builder.createEmptyFunction(null, "0x1002c93", 98, null);
		builder.createEmptyFunction(null, "FirstNamespace", "0x100194b", 45, null);
		builder.createEmptyFunction(null, "0x1001ae3", 1721, null);
		builder.createEmptyFunction(null, "0x1003250", 133, null);
		builder.createEmptyFunction(null, "0x10059a3", 716, null);
		builder.createLabel("1001000", "ADVAPI32.DLL::IsTextUnicode");

		// SymbolMergeManager2Test
		builder.createLabel("10044d0", "DDD");

		DataType dt = new Undefined4DataType();
		ParameterImpl p = new ParameterImpl(null, dt, builder.getProgram());
		builder.createEmptyFunction(null, "1004132", 20, null, p);
		builder.createEmptyFunction(null, "1004c1d", 20, null, p, p);

		builder.createMemoryCallReference("1002950", "0x100194b"); // thunk merge tests
		builder.createMemoryCallReference("1002cf5", "0x1004132"); // thunk merge tests
		builder.createMemoryCallReference("1002b7d", "0x1004c1d"); // thunk merge tests

		builder.createFunction("0x0100219c");	// symbolMergeManagerFunctionSourceTest
		builder.createEmptyFunction(null, "100415a", 20, null, p, p, p);

		builder.createClassNamespace("EmptyClass", null, SourceType.ANALYSIS);

		builder.createClassNamespace("FirstClass", null, SourceType.ANALYSIS);
		builder.createEmptyFunction(null, "FirstClass", "1005887", 20, null);
		builder.createEmptyFunction(null, "FirstClass", "10058b8", 20, null);
		builder.createEmptyFunction(null, "SecondNamespace", "0x1002239", 10, null);

		ProgramDB program = builder.getProgram();

		AbstractGenericTest.setInstanceField("recordChanges", program, Boolean.TRUE);

		UniversalID ID = UniversalIdGenerator.nextID();

		if (lastGeneratedUniversalID != null) {
			if (!lastGeneratedUniversalID.equals(ID)) {
				// if this happens, update initializeStaticUniversalIDUsage()
				throw new AssertException("Expected Test UniversalID has changed.  "
					+ "This is probably due to an new static usage of the UniversalIDGenerator.");
			}
		}

		return program;
	}
We keep track of this to know if there are any changes in static initialization.  We want
to make sure that all program building runs result in the same ID sequences.  The first
program built triggers static loading, which will cause the IDs for that run to be 
larger than the subsequent runs.  So, we call all known static initializers before we 
run.  This variable lets us know if a new initializer was added, as the ID value between
the first run and the second run will be different.
Ghidra/Features/Base/src/test/java/ghidra/program/database/MergeProgramGenerator_Notepads.java