public static ExecutableRecord restoreXml(XmlPullParser parser, DescriptionManager man)
			throws LSHException {
		final XmlElement el = parser.start("exe");
		final boolean islib = SpecXmlUtils.decodeBoolean(el.getAttribute("library"));
		parser.start("md5");
		final String md5sum = parser.end().getText();
		parser.start("name");
		final String name_exec = parser.end().getText();
		String name_compiler = "";
		String architecture = "";
		long seconds = 0;
		long millis = 0;
		RowKey id = null;
		String repo = null;
		String path = null;
		List<CategoryRecord> cats = null;
		while (parser.peek().isStart()) {
			if (parser.peek().getName().equals("category")) {
				if (cats == null) {
					cats = new ArrayList<CategoryRecord>();
				}
				final CategoryRecord newrec = CategoryRecord.restoreXml(parser);
				cats.add(newrec);
			}
			else {
				final XmlElement subel = parser.start();
				final String nm = subel.getName();
				if (nm.equals("arch")) {
					architecture = parser.end().getText();
				}
				else if (nm.equals("compiler")) {
					name_compiler = parser.end().getText();
				}
				else if (nm.equals("date")) {
					millis = SpecXmlUtils.decodeLong(subel.getAttribute("millis"));
					if ((millis < 0) || (millis > 1000)) {
						millis = 0;
					}
					seconds = SpecXmlUtils.decodeLong(parser.end().getText());
				}
				else if (nm.equals("repository")) {
					repo = parser.end().getText();
				}
				else if (nm.equals("path")) {
					path = parser.end().getText();
				}
				else {
					parser.end();
				}
			}
		}

		parser.end(el);
		ExecutableRecord res;

		if (islib) {
			res = man.newExecutableLibrary(name_exec, architecture, id);
			if ((!res.getMd5().equals(md5sum))) {
				throw new LSHException("Read bad library placeholder md5 for ExecutableRecord");
			}
		}
		else {
			final long date_milli = seconds * 1000 + millis;
			res = man.newExecutableRecord(md5sum, name_exec, name_compiler, architecture,
				new Date(date_milli), repo, path, id);
		}
		res.setCategory(cats);
		return res;
	}
Build a new {@link ExecutableRecord} by deserializing from an XML stream
@param parser is the XML parser
@param man is the DescriptionManager that should hold the new executable
@return the new ExecutableRecord
@throws LSHException if there are inconsistencies in the XML description
Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/description/ExecutableRecord.java