// Loosely based on the workaround posted here:
  // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4993360
  // XXX why isn't this in Apache Commons?
  public static boolean isFileWritable(File file) {
    boolean isWritable = false;

    if (file != null) {
      boolean fileAlreadyExists = file.isFile(); // i.e. exists and is a File

      if (fileAlreadyExists || !file.exists()) {
        try {
          // true: open for append: make sure the open
          // doesn't clobber the file
          new FileOutputStream(file, true).close();
          isWritable = true;

          if (!fileAlreadyExists) { // a new file has been "touch"ed; try to remove it
            try {
              if (!file.delete()) {
                LOGGER.warn("Can't delete temporary test file: {}", file.getAbsolutePath());
              }
            } catch (SecurityException se) {
              LOGGER.error("Error deleting temporary test file: " + file.getAbsolutePath(), se);
            }
          }
        } catch (IOException | SecurityException ioe) {
        }
      }
    }

    return isWritable;
  }
  // XXX dir.canWrite() has issues on Windows, so verify it directly:
  // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6203387
  public static boolean isDirectoryWritable(File dir) {
    boolean isWritable = false;

    if (dir != null) {
      // new File("").isDirectory() is false, even though getAbsolutePath() returns the right path.
      // this resolves it
      dir = dir.getAbsoluteFile();

      if (dir.isDirectory()) {
        File file =
            new File(
                dir,
                String.format(
                    "pms_directory_write_test_%d_%d.tmp",
                    System.currentTimeMillis(), Thread.currentThread().getId()));

        try {
          if (file.createNewFile()) {
            if (isFileWritable(file)) {
              isWritable = true;
            }

            if (!file.delete()) {
              LOGGER.warn("Can't delete temporary test file: {}", file.getAbsolutePath());
            }
          }
        } catch (IOException | SecurityException ioe) {
        }
      }
    }

    return isWritable;
  }