protected void fixupProgramTree(String suffix) throws Exception {
		if (suffix == null) {
			suffix = "";
		}
		ProgramModule rootModule = listing.getDefaultRootModule();
		for (SegmentCommand segment : machoHeader.getAllSegments()) {
			AddressSpace segmentSpace =
				segmentOverlayMap.getOrDefault(segment.getSegmentName(), space);
			Address segmentStart = segmentSpace.getAddress(segment.getVMaddress());
			Address segmentEnd = segmentStart.add(segment.getVMsize() - 1);
			if (!memory.contains(segmentStart)) {
				continue;
			}
			if (!memory.contains(segmentEnd)) {
				segmentEnd = memory.getBlock(segmentStart).getEnd();
			}
			// Move original segment fragment into module and rename it.  After we add new 
			// section fragments, it will represent the parts of the segment that weren't in any
			// section.
			String segmentName = segment.getSegmentName();
			String noSectionsName = segmentName + " <no section>" + suffix;
			ProgramFragment segmentFragment = null;
			for (Group group : rootModule.getChildren()) {
				if (group instanceof ProgramFragment fragment &&
					fragment.getName().equals(segmentName)) {
					fragment.setName(noSectionsName);
					segmentFragment = fragment;
					break;
				}
			}
			if (segmentFragment == null) {
				if (segment.getVMsize() != 0 || segment.getFileSize() != 0) {
					log.appendMsg("Could not find/fixup segment in Program Tree: " + segmentName);
				}
				continue;
			}
			ProgramModule segmentModule = rootModule.createModule(segmentName + suffix);
			try {
				segmentModule.reparent(noSectionsName, rootModule);
			}
			catch (NotFoundException e) {
				log.appendException(e);
				continue;
			}

			// Add the sections, which will remove overlapped ranges from the segment fragment
			for (Section section : segment.getSections()) {
				if (section.getSize() == 0) {
					continue;
				}
				Address sectionStart = segmentSpace.getAddress(section.getAddress());
				Address sectionEnd = sectionStart.add(section.getSize() - 1);
				if (!memory.contains(sectionStart)) {
					log.appendMsg("Warning: Section %s.%s is not contained within its segment"
							.formatted(section.getSegmentName(), section.getSectionName()));
					continue;
				}
				if (!memory.contains(sectionEnd)) {
					sectionEnd = memory.getBlock(sectionStart).getEnd();
				}
				ProgramFragment sectionFragment =
					segmentModule.createFragment(String.format("%s %s", section.getSegmentName(),
						section.getSectionName() + suffix));
				sectionFragment.move(sectionStart, sectionEnd);
			}

			// If the sections fully filled the segment, we can remove the now-empty segment
			if (segmentFragment.isEmpty()) {
				segmentModule.removeChild(segmentFragment.getName());
			}
		}

		// Update EXTERNAL block if it exists
		for (Group group : rootModule.getChildren()) {
			if (group instanceof ProgramFragment fragment &&
				fragment.getName().equals(MemoryBlock.EXTERNAL_BLOCK_NAME)) {
				fragment.setName(MemoryBlock.EXTERNAL_BLOCK_NAME + suffix);
				break;
			}
		}
	}
Fixes up the Program Tree to better visualize the memory blocks that were split into sections

@param suffix An optional suffix that will get appended to tree segment and segment nodes
@throws Exception if there was a problem fixing up the Program Tree
Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoProgramBuilder.java