public static long digest(Path file) throws IOException {
    BasicFileAttributes attrs = Files.readAttributes(file, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS);

    if (attrs.isSymbolicLink()) {
      Path target = Files.readSymbolicLink(file);
      if (target.isAbsolute()) throw new IOException("An absolute link: " + file + " -> " + target);
      return digestStream(new ByteArrayInputStream(target.toString().getBytes(StandardCharsets.UTF_8))) | SYM_LINK;
    }

    if (attrs.isDirectory()) return DIRECTORY;

    long executable = !Utils.IS_WINDOWS && Files.isExecutable(file) ? EXECUTABLE : 0;
    try (InputStream in = Files.newInputStream(file)) {
      return digestStream(in) | executable;
    }
    catch (IOException e) {
      throw new IOException(file.toString(), e);
    }
  }
public static long digest(Path file)