public static URL deriveBSimURL(String urlString)
			throws IllegalArgumentException, MalformedURLException {
		URL url = new URL(urlString);	// URL used only for parsing purposes
		String protocol = url.getProtocol();
		if ("postgresql".equals(protocol) || "https".equals(protocol) ||
			"elastic".equals(protocol) || "file".equals(protocol)) {
			checkBSimServerURL(url);
			return url; // URL already corresponds to BSim server protocol
		}
		if (!GhidraURL.isServerRepositoryURL(url)) {
			throw new IllegalArgumentException("Unable to infer BSim URL from: " + url);
		}
		String path = url.getPath();							// Get the full path of the URL
		if (path == null || path.length() == 0 || path.equals("/")) {		// There must always be some kind of path, so we can derive the repository
			throw new MalformedURLException("URL is missing a repository path");
		}
		int endrepos = path.indexOf('/', 1);	// Find the end of the first level of the path
		String repositoryURL;
		if (url.getProtocol().equals(GhidraURL.PROTOCOL)) {	// Is this a ghidra URL
			// TODO: we could set things up so that a ghidra server could be queried for its associated BSim server
			// "ghidra://host/repo?service=bsim"
			// String repositoryURL = "ghidra://" + ghidraURL.getAuthority() + "?service=bsim";

			// Currenly all we do is assume that the BSim server is a PostgreSQL server
			// on the same host and with the same repo name as the ghidra server
			repositoryURL = "postgresql://" + url.getHost();		// Just use the hostname
		}
		else {
			// For all other URL forms, we assume we are being handed the protocol and hostname (authority)
			// explicitly. We keep them for the final BSim URL
			repositoryURL = url.getProtocol() + "://" + url.getAuthority();
		}
		// Attach the first level of the path, which indicates the repository
		if (endrepos < 0) {
			repositoryURL = repositoryURL + path;
		}
		else {
			repositoryURL = repositoryURL + path.substring(0, endrepos);
		}
		return buildURL(repositoryURL);
	}
Construct the root URL to a specific BSim repository given a "related" URL.
The root URL will have an explicit protocol, a hostname + other mods (the authority), and 1 level of path
   this first level path indicates the particular repository being referenced on the host.
The "related" URL -url- can be an explicitly provided URL pointing to the BSim repository,
   possibly with additional path levels, which are simply stripped from the final root URL.
Alternately -url- can reference a ghidra server, as indicated by the "ghidra" protocol.
   In this case the true BSim URL is derived from ghidra URL in some way
@param urlString is the "related" URL
@return the root BSim URL
@throws MalformedURLException if the given URL string cannot be parsed
@throws IllegalArgumentException if local ghidra URL is specified
Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/BSimClientFactory.java