docs: public static URI getRelativePath(final URI base, final URI ref) {
          final String baseScheme = base.getScheme();
          final String refScheme = ref.getScheme();
          final String baseAuth = base.getAuthority();
          final String refAuth = ref.getAuthority();
          if (!(((baseScheme == null && refScheme == null) || (baseScheme != null && refScheme != null && baseScheme.equals(refScheme))) &&
                  ((baseAuth == null && refAuth == null) || (baseAuth != null && refAuth != null && baseAuth.equals(refAuth))))) {
              return ref;
          }
  
          URI rel;
          if (base.getPath().equals(ref.getPath()) && ref.getFragment() != null) {
              rel = toURI("");
          } else {
              final StringBuilder upPathBuffer = new StringBuilder(128);
              final StringBuilder downPathBuffer = new StringBuilder(128);
              String basePath = base.normalize().getPath();
              if (basePath.endsWith("/")) {
                  basePath = basePath + "dummy";
              }
              String refPath = ref.normalize().getPath();
              final StringTokenizer baseTokenizer = new StringTokenizer(basePath, URI_SEPARATOR);
              final StringTokenizer refTokenizer = new StringTokenizer(refPath, URI_SEPARATOR);
  
              while (baseTokenizer.countTokens() > 1 && refTokenizer.countTokens() > 1) {
                  final String baseToken = baseTokenizer.nextToken();
                  final String refToken = refTokenizer.nextToken();
                  //if OS is Windows, we need to ignore case when comparing path names.
                  final boolean equals = OS_NAME.toLowerCase().contains(OS_NAME_WINDOWS)
                                         ? baseToken.equalsIgnoreCase(refToken)
                                         : baseToken.equals(refToken);
                  if (!equals) {
                      if (baseToken.endsWith(COLON) || refToken.endsWith(COLON)) {
                          //the two files are in different disks under Windows
                          return ref;
                      }
                      upPathBuffer.append("..");
                      upPathBuffer.append(URI_SEPARATOR);
                      downPathBuffer.append(refToken);
                      downPathBuffer.append(URI_SEPARATOR);
                      break;
                  }
              }
  
              while (baseTokenizer.countTokens() > 1) {
                  baseTokenizer.nextToken();
                  upPathBuffer.append("..");
                  upPathBuffer.append(URI_SEPARATOR);
              }
  
              while (refTokenizer.hasMoreTokens()) {
                  downPathBuffer.append(refTokenizer.nextToken());
                  if (refTokenizer.hasMoreTokens()) {
                      downPathBuffer.append(URI_SEPARATOR);
                  }
              }
              upPathBuffer.append(downPathBuffer);
  
              try {
                  rel = new URI(null, null, upPathBuffer.toString(), null, null);
              } catch (final URISyntaxException e) {
                  throw new IllegalArgumentException(e);
              }
          }
  
          return setFragment(rel, ref.getFragment());
      }