public final String relativize(final Path base) {
		Path p = this;
		synchronized (Path.relativizer) {
			Path.relativizer.clear();
			while (p.getNameCount() > base.getNameCount()) {
				p = p.getParent();
			}
			int same = p.getNameCount();
			if (p != base) {
				Path q = base;
				if (q.getNameCount() > p.getNameCount()) {
					while (q.getNameCount() > p.getNameCount()) {
						q = q.getParent();
						Path.relativizer.appendLast("../");
					}
				}
				while (p != q) {
					if (--same == 0) {
						return this.str;
					}
					p = p.getParent();
					q = q.getParent();
					Path.relativizer.appendLast("../");
				}
			}
			while (same < getNameCount()) {
				Path.relativizer.appendLast(getComponentAt(same++));
				Path.relativizer.appendLast("/");
			}
			Path.relativizer.removeLast();
			return Path.relativizer.toString();
		}
	}