Namespace resolveNamespace(Namespace fromNamespace, LongLongHashtable conflictSymbolIDMap)
			throws DuplicateNameException, InvalidInputException {
		Namespace fromGlobalNs = fromProgram.getGlobalNamespace();
		if (fromNamespace == null) {
			return null;
		}
		if (fromNamespace.equals(fromGlobalNs)) {
			return toProgram.getGlobalNamespace();
		}
		Namespace resolvedNamespace = DiffUtility.getNamespace(fromNamespace, toProgram);
		if (resolvedNamespace != null) {
			return resolvedNamespace;
		}
		Symbol fromNamespaceSymbol = fromNamespace.getSymbol();

		// Try to resolve the parent namespace and use it to get/create a namespace.
		Namespace fromParentNs = fromNamespace.getParentNamespace();
		Namespace resolvedParentNs = resolveNamespace(fromParentNs, conflictSymbolIDMap);
		String name = fromNamespaceSymbol.getName();
		SymbolType fromNamespaceSymbolType = fromNamespaceSymbol.getSymbolType();
		Address toNamespaceSymbolAddr =
			originToResultTranslator.getAddress(fromNamespaceSymbol.getAddress());

		// For the resolved parent namespace try to get the namespace we want.
		List<Symbol> toNamespaceSymbols = toSymbolTable.getSymbols(name, resolvedParentNs);
		for (Symbol toNamespaceSymbol : toNamespaceSymbols) {
			SymbolType toNamespaceSymbolType = toNamespaceSymbol.getSymbolType();
			if (toNamespaceSymbolType.isNamespace()) {
				if (toNamespaceSymbolType.equals(fromNamespaceSymbolType) &&
					toNamespaceSymbolAddr.equals(toNamespaceSymbol.getAddress())) {
					return (Namespace) toNamespaceSymbol.getObject(); // Found the equivalent namespace so return it.
				}
			}
		}

		// If we can't get the desired namespace from the resolved parent, then create it.
		resolvedNamespace = createNamespace(name, fromNamespaceSymbolType, toNamespaceSymbolAddr,
			resolvedParentNs, fromNamespaceSymbol.getSource());
		if (!resolvedNamespace.getName().equals(name)) {
			conflictSymbolIDMap.put(fromNamespace.getSymbol().getID(),
				resolvedNamespace.getSymbol().getID());
		}
		return resolvedNamespace;
	}
This method creates a namespace in one program (the "to" program) that is effectively the
same as the namespace from another program (the "from" program.) It will resolve each
parent namespace in this namespace's parent hierarchy until reaching the global namespace
for the program or until there is no parent namespace.
When resolving any namespace the type of namespace will be the same as it was in the "from"
program. However, the name of the namespace will match the original name in the "from"
program or will be the original name with a conflict suffix attached.
<br>If a namespace that is effectively the same can't be found then this method will create
one and the name may match the original or have a conflict name.
<br>If the namespace can't be resolved, an exception is thrown.
<br>Any namespaces that are created with a conflict name will have their symbol IDs mapped
into the <code>conflictSymbolIDMap</code>.

@param fromNamespace the namespace in the "from" program.
@param conflictSymbolIDMap maps the symbol IDs in the "from" program to the symbol IDs
in the "to" program for any symbols (and their associated objects) that were created
with conflict names.
(key = "from" program's symbol ID; value = "to" program's symbol ID)
@return the resolved namespace in the "to" program. Also the <code>conflictSymbolIDMap</code>
will have been modified, if this namespace had to be created with a conflict name.

@throws DuplicateNameException if the name space can't be resolved due
to a name conflict that can't be dealt with.
@throws InvalidInputException if the name space is not validly named
for the "to" program.
Ghidra/Features/Base/src/main/java/ghidra/program/util/SymbolMerge.java