docs: public static String getCanonicalURL(String url, String baseURL) {
  
  		try {
  			/* Build the absolute URL, from the url and the baseURL */
  			String resolvedURL = URLResolver.resolveUrl(baseURL == null ? "" : baseURL, url);
  			log.debug("Resolved URL: " + resolvedURL);
  			URI canonicalURI;
  			try {
  				canonicalURI = new URI(resolvedURL);
  			} catch (Exception e) {
  				canonicalURI = new URI(URIUtil.encodeQuery(resolvedURL));
  			}
  
  			/* Some checking. */
  			if (canonicalURI.getScheme() == null) {
  				log.warn("Protocol could not be reliably evaluated from uri: " + canonicalURI + " and base url: " + baseURL);
  				return null;
  			}
  
  			if (canonicalURI.getRawAuthority() == null) {
  				log.debug("Ignoring URI with no authority (host[\":\"port]): " + canonicalURI + " (on base " + baseURL + ")");
  				return null;
  			}
  
  			if (canonicalURI.getHost() == null) {
  				log.warn("Host could not be reliably evaluated from: " + canonicalURI + " (on base " + baseURL + ")");
  				return null;
  			}
  
  			/*
  			 * Normalize: no empty segments (i.e., "//"), no segments equal to ".", and no segments equal to
  			 * ".." that are preceded by a segment not equal to "..".
  			 */
  			String path = canonicalURI.normalize().getRawPath();
  
  			/* Convert '//' -> '/' */
  			int idx = path.indexOf("//");
  			while (idx >= 0) {
  				path = path.replace("//", "/");
  				idx = path.indexOf("//");
  			}
  
  			/* Drop starting '/../' */
  			while (path.startsWith("/../")) {
  				path = path.substring(3);
  			}
  
  			/* Trim */
  			path = path.trim();
  
  			/* Process parameters and sort them. */
  			final SortedSet<QueryParameter> params = createSortedParameters(canonicalURI.getRawQuery());
  			final String queryString;
  			String canonicalParams = canonicalize(params);
  			queryString = (canonicalParams.isEmpty() ? "" : "?" + canonicalParams);
  
  			/* Add starting slash if needed */
  			if (path.length() == 0) {
  				path = "/" + path;
  			}
  
  			/* Drop default port: example.com:80 -> example.com */
  			int port = canonicalURI.getPort();
  			if (isDefaultPort(canonicalURI.getScheme(), port)) {
  				port = -1;
  			}
  
  			/* Lowercasing protocol and host */
  			String protocol = canonicalURI.getScheme().toLowerCase();
  			String host = canonicalURI.getHost().toLowerCase();
  			String pathAndQueryString = normalizePath(path) + queryString;
  
  			URL result = new URL(protocol, host, port, pathAndQueryString);
  			return result.toExternalForm();
  
  		} catch (Exception ex) {
  			log.warn("Error while Processing URL [" + url + "] in the spidering process (on base " + baseURL + "): "
  					+ ex.getMessage());
  			return null;
  		}
  	}