commons/core/src/main/java/org/ldp4j/commons/net/URIUtils.java
private static URIRef relativeResolution(URI target, URI base) {
		URIRef Base=URIRef.create(base); // NOSONAR
		URIRef R=URIRef.create(target); // NOSONAR
		URIRef T=URIRef.create(); // NOSONAR
		if(defined(R.scheme)) {
			T.scheme    = R.scheme;
			T.authority = R.authority;
			T.path      = removeDotSegments(R.path);
			T.query     = R.query;
		} else {
			if(defined(R.authority)) {
				T.authority = R.authority;
				T.path      = removeDotSegments(R.path);
				T.query     = R.query;
			} else {
				resolvePathOnlyTarget(Base, R, T);
			}
			T.scheme = Base.scheme;
		}
		T.fragment = R.fragment;
		return T;
	}
private static URIRef relativeResolution(URI target, URI base) {
		URIRef Base=URIRef.create(base); // NOSONAR
		URIRef R=URIRef.create(target); // NOSONAR
		URIRef T=URIRef.create(); // NOSONAR
		if(defined(R.scheme)) {
			T.scheme    = R.scheme;
			T.authority = R.authority;
			T.path      = removeDotSegments(R.path);
			T.query     = R.query;
		} else {
			if(defined(R.authority)) {
				T.authority = R.authority;
				T.path      = removeDotSegments(R.path);
				T.query     = R.query;
			} else {
				resolvePathOnlyTarget(Base, R, T);
			}
			T.scheme = Base.scheme;
		}
		T.fragment = R.fragment;
		return T;
	}
5.2.  Relative Resolution

This section describes an algorithm for converting a URI reference
that might be relative to a given base URI into the parsed components
of the reference's target.  The components can then be recomposed, as
described in Section 5.3, to form the target URI.  This algorithm
provides definitive results that can be used to test the output of
other implementations.  Applications may implement relative reference
resolution by using some other algorithm, provided that the results
match what would be given by this one.

5.2.1.  Pre-parse the Base URI

The base URI (Base) is established according to the procedure of
Section 5.1 and parsed into the five main components described in
Section 3.  Note that only the scheme component is required to be
present in a base URI; the other components may be empty or
undefined.  A component is undefined if its associated delimiter does
not appear in the URI reference; the path component is never
undefined, though it may be empty.

Normalization of the base URI, as described in Sections 6.2.2 and
6.2.3, is optional.  A URI reference must be transformed to its
target URI before it can be normalized.

5.2.2.  Transform References

For each URI reference (R), the following pseudocode describes an
algorithm for transforming R into its target URI (T):
-- The URI reference is parsed into the five URI components
--
(R.scheme, R.authority, R.path, R.query, R.fragment) = parse(R);

-- A non-strict parser may ignore a scheme in the reference
-- if it is identical to the base URI's scheme.
--
if ((not strict) and (R.scheme == Base.scheme)) then
undefine(R.scheme);
endif;

if defined(R.scheme) then
T.scheme    = R.scheme;
T.authority = R.authority;
T.path      = remove_dot_segments(R.path);
T.query     = R.query;
else
if defined(R.authority) then
T.authority = R.authority;
T.path      = remove_dot_segments(R.path);
T.query     = R.query;
else
if (R.path == "") then
T.path = Base.path;
if defined(R.query) then
T.query = R.query;
else
T.query = Base.query;
endif;
else
if (R.path starts-with "/") then
T.path = remove_dot_segments(R.path);
else
T.path = merge(Base.path, R.path);
T.path = remove_dot_segments(T.path);
endif;
T.query = R.query;
endif;
T.authority = Base.authority;
endif;
T.scheme = Base.scheme;
endif;

T.fragment = R.fragment;