docs: public static UrlParts parseUrl(String theUrl) {
  		String url = theUrl;
  		UrlParts retVal = new UrlParts();
  		if (url.startsWith("http")) {
  			if (url.startsWith("/")) {
  				url = url.substring(1);
  			}
  
  			int qmIdx = url.indexOf('?');
  			if (qmIdx != -1) {
  				retVal.setParams(defaultIfBlank(url.substring(qmIdx + 1), null));
  				url = url.substring(0, qmIdx);
  			}
  
  			IdDt id = new IdDt(url);
  			retVal.setResourceType(id.getResourceType());
  			retVal.setResourceId(id.getIdPart());
  			retVal.setVersionId(id.getVersionIdPart());
  			return retVal;
  		}
  		if (url.matches("/[a-zA-Z]+\\?.*")) {
  			url = url.substring(1);
  		}
  		int nextStart = 0;
  		boolean nextIsHistory = false;
  
  		for (int idx = 0; idx < url.length(); idx++) {
  			char nextChar = url.charAt(idx);
  			boolean atEnd = (idx + 1) == url.length();
  			if (nextChar == '?' || nextChar == '/' || atEnd) {
  				int endIdx = (atEnd && nextChar != '?') ? idx + 1 : idx;
  				String nextSubstring = url.substring(nextStart, endIdx);
  				if (retVal.getResourceType() == null) {
  					retVal.setResourceType(nextSubstring);
  				} else if (retVal.getResourceId() == null) {
  					retVal.setResourceId(nextSubstring);
  				} else if (nextIsHistory) {
  					retVal.setVersionId(nextSubstring);
  				} else {
  					if (nextSubstring.equals(Constants.URL_TOKEN_HISTORY)) {
  						nextIsHistory = true;
  					} else {
  						throw new InvalidRequestException("Invalid FHIR resource URL: " + url);
  					}
  				}
  				if (nextChar == '?') {
  					if (url.length() > idx + 1) {
  						retVal.setParams(url.substring(idx + 1, url.length()));
  					}
  					break;
  				}
  				nextStart = idx + 1;
  			}
  		}
  
  		return retVal;
  
  	}