code: synchronized final F addLink(String path) throws IOException {
          if (++linksTraversed > MAXSYMLINKS) {
              throw new IllegalArgumentException("Too many links to follow (> " + MAXSYMLINKS + ").");
          }
  
          F resolvedPath = _resolvedPaths.get(path);
  
          if (resolvedPath == null) {
              for (String unresolvedPath : _unresolvedPaths) {
                  if (path.equals(unresolvedPath) || path.startsWith(unresolvedPath + "/")) {
                      throw new IOException("Links form a loop: " + path);
                  }
              }
              _unresolvedPaths.add(path);
          }
  
          return resolvedPath;
      }
docs: Checks for problems. If the link has already been resolved, it returns
  the final file. If not, it adds the link path to the list of unresolved
  paths that have been seen while evaluating this chain.
  
  @param path
  The path to the link that is currently being resolved.
  @return The file, if that link has already been resolved.
  @throws IOException
  If there are too many links in the chain (more than
  MAXSYMLINKS)