protected Path convertToRelative(final Path path) {
    if (path != null) {
      final RelativePathService service = property().service(RelativePathService.class);

      if (service == null) {
        if (enclosed()) {
          for (Path root : getBasePaths()) {
            if (root.isPrefixOf(path)) {
              return path.makeRelativeTo(root);
            }
          }
        } else {
          final String pathDevice = path.getDevice();

          for (Path root : getBasePaths()) {
            if (MiscUtil.equal(pathDevice, root.getDevice())) {
              return path.makeRelativeTo(root);
            }
          }
        }
      } else {
        return service.convertToRelative(path);
      }
    }

    return null;
  }
  protected Path convertToAbsolute(final Path path) {
    if (path != null) {
      final RelativePathService service = property().service(RelativePathService.class);

      if (service == null) {
        if (enclosed() && path.segmentCount() > 0 && path.segment(0).equals("..")) {
          return null;
        }

        Path absolute = null;

        for (Path root : getBasePaths()) {
          try {
            final File file = root.append(path).toFile().getCanonicalFile();
            absolute = new Path(file.getPath());

            if (file.exists()) {
              break;
            }
          } catch (IOException e) {
            // Intentionally ignoring to continue to the next root. If none of the roots
            // produce a viable absolute path, a null return from this method signifies
            // being unable to convert the relative path. That is sufficient.
          }
        }

        return absolute;
      } else {
        return service.convertToAbsolute(path);
      }
    }

    return null;
  }
  protected boolean enclosed() {
    final RelativePathService service = property().service(RelativePathService.class);

    if (service == null) {
      return true;
    } else {
      return service.enclosed();
    }
  }