private void processTree(XmlElement treeElement, XmlPullParser parser) {
		treeName = treeElement.getAttribute("NAME");
		fragmentNameList = new ArrayList<>();

		ProgramModule root = null;
		try {
			try {
				root = listing.createRootModule(treeName);
			}
			catch (DuplicateNameException dne) {
				// if name already existed, then attempt to create a 
				// unique "one-up" name
				//
				int oneUp = 1;
				while (true) {
					try {
						root = listing.createRootModule(treeName + "(" + oneUp + ")");
						break; // we located a unique name...
					}
					catch (DuplicateNameException e) {
						++oneUp;
					}
				}
				treeName = root.getTreeName();
			}
			moduleStack.push(root);

			XmlElement element = parser.next();

			while (!monitor.isCancelled()) {
				String elementName = element.getName();
				if (elementName.equals("FRAGMENT") || elementName.equals("MODULE") ||
					elementName.equals("FOLDER")) {
					if (elementName.equals("FRAGMENT")) {
						if (element.isStart()) {
							processFragment(element, parser);
						}
					}
					else {
						if (element.isStart()) {
							processModule(element, parser);
						}
						else {
							moduleStack.pop();
						}
					}
					element = parser.next();
				}
				else {
					break;
				}
			}
			removeEmptyFragments(root);
		}
		catch (Exception e) {
			log.appendException(e);
			parser.discardSubTree(treeElement);
		}
	}
Write out the XML for the program trees.
@param writer writer for XML
@param addrs the addresses
@param m monitor that can be canceled should be written
@throws CancelledException if cancelled
Ghidra/Features/Base/src/main/java/ghidra/app/util/xml/ProgramTreeXmlMgr.java