title: Bug in Path's .relativize() documentation or am I doing something blatantly wrong here?
body: <p>OK well, here is something fun. Note that "elements" here is an instance of <code>PathElements</code>, and for these <code>.resolve()</code> and <code>.relativize()</code> are <a href="https://github.com/fge/java7-fs-base/blob/master/src/test/java/com/github/fge/filesystem/path/PathElementsTest.java" rel="nofollow">fully tested</a> and <a href="https://github.com/fge/java7-fs-base/blob/master/src/test/java/com/github/fge/filesystem/path/PathElementsFactoryTest.java" rel="nofollow">known to work</a>... Links to the relevant method implementations <a href="https://github.com/fge/java7-fs-base/blob/master/src/main/java/com/github/fge/filesystem/path/GenericPath.java#L419" rel="nofollow"><code>Path.resolve()</code></a>, <a href="https://github.com/fge/java7-fs-base/blob/master/src/main/java/com/github/fge/filesystem/path/GenericPath.java#L572" rel="nofollow"><code>Path.relativize()</code></a></p>
  
  <p>Extract of the test method that fails:</p>
  
  <pre><code>/*
   * This test this part of the Path's .relativize() method:
   *
   * &lt;p&gt; For any two {@link #normalize normalized} paths &lt;i&gt;p&lt;/i&gt; and
   * &lt;i&gt;q&lt;/i&gt;, where &lt;i&gt;q&lt;/i&gt; does not have a root component,
   * &lt;blockquote&gt;
   * &lt;i&gt;p&lt;/i&gt;&lt;tt&gt;.relativize(&lt;/tt&gt;&lt;i&gt;p&lt;/i&gt;&lt;tt&gt;.resolve(&lt;/tt&gt;&lt;i&gt;q&lt;/i&gt;&lt;tt&gt;))
   * .equals(&lt;/tt&gt;&lt;i&gt;q&lt;/i&gt;&lt;tt&gt;)&lt;/tt&gt;
   * &lt;/blockquote&gt;
   *
   * Unfortunately, that turns out NOT TO BE TRUE! Whether p is absolute or
   * relative, it is indeed the case that the path elements (root, names) are
   * the same but the filesystem DIFFERS.
   *
   * An as Path's .equals() requires that the two filesystems be equal in
   * order for two Paths to be equals, this contract can not be obeyed; or I
   * am doing something VERY wrong.
   */
  @Test(enabled = false)
  public void relativizeResolveRoundRobinWorks()
  {
      /*
       * In order to set up the environment we define a mock
       * FileSystemProvider which both our mock filesystems will return when
       * .provider() is called.
       *
       * We also suppose that the same PathElementsFactory is used; while this
       * code is not written yet, there should be only one such factory per
       * FileSystemProvider anyway (which is fed into all generated FileSystem
       * instances -- at least that's the plan).
       *
       * Note that this test method assumes that .equals() and .hashCode() are
       * not implemented on GenericPath. As such we check that the FileSystem
       * is the same (this is required by Path's equals()) and that the path
       * elements are the same (this is this package's requirements).
       */
      final FileSystemProvider fsProvider = mock(FileSystemProvider.class);
      final PathElementsFactory elementsFactory
          = new UnixPathElementsFactory();
      final FileSystem fsForP = mock(FileSystem.class);
      final FileSystem fsForQ = mock(FileSystem.class);
  
      when(fsForP.provider()).thenReturn(fsProvider);
      when(fsForQ.provider()).thenReturn(fsProvider);
  
      /*
       * The path to be operated. As the contract says, it has no root
       * component.
       */
      final GenericPath q = new GenericPath(fsForQ, elementsFactory,
          new PathElements(null, new String[] { "q1", "q2" }));
  
      /*
       * The path against which both resolution and relativization are
       * performed. We take two versions of it: a non absolute one and an
       * absolute one.
       *
       * Note that since we use a UnixPathElementsFactory, we equate an
       * absolute path (or not) to a path which has a root component (or not).
       */
      GenericPath p;
      // "rr" as in "resolved, relativized"
      GenericPath rr;
  
      final CustomSoftAssertions soft = CustomSoftAssertions.create();
  
      /*
       * Try with the absolute version first...
       */
      p = new GenericPath(fsForP, elementsFactory,
          new PathElements("/", new String[] { "p1", "p2" }));
      rr = (GenericPath) p.relativize(p.resolve(q));
  
      soft.assertThat(rr.getFileSystem())
          .as("rr and q filesystems should be the same (p absolute)")
          .isSameAs(q.getFileSystem());
      soft.assertThat(rr.elements).hasSameContentsAs(q.elements);
  
      /*
       * Now with the non absolute version
       */
      p = new GenericPath(fsForP, elementsFactory,
          new PathElements(null, new String[] { "p1", "p2" }));
      rr = (GenericPath) p.relativize(p.resolve(q));
  
      soft.assertThat(rr.getFileSystem())
          .as("rr and q filesystems should be the same (p not absolute)")
          .isSameAs(q.getFileSystem());
      soft.assertThat(rr.elements).hasSameContentsAs(q.elements);
  
      soft.assertAll();
  }
  </code></pre>
  
  <p>This test fails with:</p>
  
  <pre><code>org.assertj.core.api.SoftAssertionError: 
  The following 2 assertions failed:
  1) [rr and q filesystems should be the same (p absolute)] 
  Expecting:
   &lt;Mock for FileSystem, hashCode: 1125642929&gt;
  and actual:
   &lt;Mock for FileSystem, hashCode: 1497261280&gt;
  to refer to the same object
  2) [rr and q filesystems should be the same (p not absolute)] 
  Expecting:
   &lt;Mock for FileSystem, hashCode: 1125642929&gt;
  and actual:
   &lt;Mock for FileSystem, hashCode: 1497261280&gt;
  to refer to the same object
  </code></pre>
  
  <p>And obviously so!</p>
  
  <ul>
  <li>r = p.resolve(q) will give a Path which shares the same filesystem as p, not q;</li>
  <li>therefore, p.relativize(r) will also give a Path with the same filesystem as p;</li>
  <li>but the Path contract requires that in order for two paths to be equal, they share the same filesystem.</li>
  </ul>
  
  <p>And this is <em>always</em> false in this scenario.</p>
  
  <p>So, is this a blatant bug in the documentation or am I overlooking something?</p>