commons/core/src/main/java/org/ldp4j/net/Path.java
public Path relativize(final Path path) {
		Objects.requireNonNull("Path cannot be null");

		final Path base=this;

		// By default, we return the normalized form of the input path
		final Path defaultRelative = path.normalize();

		// Either root or not
		if(base.isRoot()!=path.isRoot()) {
			return defaultRelative;
		}

		// If the path is not root, return its normalized base
		if(!path.isRoot()) {
			return defaultRelative;
		}

		// Beyond this point we need the normalized form
		final Path nBase = base.normalize();

		// If we are out of the scope...
		if(base.isOutOfScope()) {
			// ... we must return the input path because it will define the
			// scope
			Path relative=defaultRelative;
			if(nBase.equals(relative)) {
				// ... unless the path is the same as ourselves, in which
				// case it is safe to return the empty path
				relative=EMPTY_PATH;
			}
			return relative;
		}

		// Can only compare for equality iff normalized.
		final Path unBase=nBase.unroot();
		final Path unPath=defaultRelative.unroot();

		// If the base and the target are the same, return the empty path
		if(unBase.equals(unPath)) {
			return EMPTY_PATH;
		}

		return
			assembleRelativeSegments(
				path,
				base,
				getRelativeSegments(
					unBase.segments(),
					unPath.segments()));
	}
public Path relativize(final Path path) {
		Objects.requireNonNull("Path cannot be null");

		final Path base=this;

		// By default, we return the normalized form of the input path
		final Path defaultRelative = path.normalize();

		// Either root or not
		if(base.isRoot()!=path.isRoot()) {
			return defaultRelative;
		}

		// If the path is not root, return its normalized base
		if(!path.isRoot()) {
			return defaultRelative;
		}

		// Beyond this point we need the normalized form
		final Path nBase = base.normalize();

		// If we are out of the scope...
		if(base.isOutOfScope()) {
			// ... we must return the input path because it will define the
			// scope
			Path relative=defaultRelative;
			if(nBase.equals(relative)) {
				// ... unless the path is the same as ourselves, in which
				// case it is safe to return the empty path
				relative=EMPTY_PATH;
			}
			return relative;
		}

		// Can only compare for equality iff normalized.
		final Path unBase=nBase.unroot();
		final Path unPath=defaultRelative.unroot();

		// If the base and the target are the same, return the empty path
		if(unBase.equals(unPath)) {
			return EMPTY_PATH;
		}

		return
			assembleRelativeSegments(
				path,
				base,
				getRelativeSegments(
					unBase.segments(),
					unPath.segments()));
	}
Computes relative relative path to reference "target" from "base". Uses
".." if needed, in contrast to {@link URI#relativize(URI)}.

@param path the path to be relativized
@return the relative path