/**
   * Open/creates file, returning FileChannel to access the file
   *
   * @param pathForWindows The path of the file to open/create
   * @param pathToCheck The path used for permission checks (if security manager)
   */
  static FileChannel newFileChannel(
      String pathForWindows,
      String pathToCheck,
      Set<? extends OpenOption> options,
      long pSecurityDescriptor)
      throws WindowsException {
    Flags flags = Flags.toFlags(options);

    // default is reading; append => writing
    if (!flags.read && !flags.write) {
      if (flags.append) {
        flags.write = true;
      } else {
        flags.read = true;
      }
    }

    // validation
    if (flags.read && flags.append) throw new IllegalArgumentException("READ + APPEND not allowed");
    if (flags.append && flags.truncateExisting)
      throw new IllegalArgumentException("APPEND + TRUNCATE_EXISTING not allowed");

    FileDescriptor fdObj = open(pathForWindows, pathToCheck, flags, pSecurityDescriptor);
    return FileChannelImpl.open(fdObj, pathForWindows, flags.read, flags.write, flags.append, null);
  }
  /**
   * Open/creates file, returning AsynchronousFileChannel to access the file
   *
   * @param pathForWindows The path of the file to open/create
   * @param pathToCheck The path used for permission checks (if security manager)
   * @param pool The thread pool that the channel is associated with
   */
  static AsynchronousFileChannel newAsynchronousFileChannel(
      String pathForWindows,
      String pathToCheck,
      Set<? extends OpenOption> options,
      long pSecurityDescriptor,
      ThreadPool pool)
      throws IOException {
    Flags flags = Flags.toFlags(options);

    // Overlapped I/O required
    flags.overlapped = true;

    // default is reading
    if (!flags.read && !flags.write) {
      flags.read = true;
    }

    // validation
    if (flags.append) throw new UnsupportedOperationException("APPEND not allowed");

    // open file for overlapped I/O
    FileDescriptor fdObj;
    try {
      fdObj = open(pathForWindows, pathToCheck, flags, pSecurityDescriptor);
    } catch (WindowsException x) {
      x.rethrowAsIOException(pathForWindows);
      return null;
    }

    // create the AsynchronousFileChannel
    try {
      return WindowsAsynchronousFileChannelImpl.open(fdObj, flags.read, flags.write, pool);
    } catch (IOException x) {
      // IOException is thrown if the file handle cannot be associated
      // with the completion port. All we can do is close the file.
      long handle = fdAccess.getHandle(fdObj);
      CloseHandle(handle);
      throw x;
    }
  }
 static Flags toFlags(Set<? extends OpenOption> options) {
   Flags flags = new Flags();
   for (OpenOption option : options) {
     if (option instanceof StandardOpenOption) {
       switch ((StandardOpenOption) option) {
         case READ:
           flags.read = true;
           break;
         case WRITE:
           flags.write = true;
           break;
         case APPEND:
           flags.append = true;
           break;
         case TRUNCATE_EXISTING:
           flags.truncateExisting = true;
           break;
         case CREATE:
           flags.create = true;
           break;
         case CREATE_NEW:
           flags.createNew = true;
           break;
         case DELETE_ON_CLOSE:
           flags.deleteOnClose = true;
           break;
         case SPARSE:
           flags.sparse = true;
           break;
         case SYNC:
           flags.sync = true;
           break;
         case DSYNC:
           flags.dsync = true;
           break;
         default:
           throw new UnsupportedOperationException();
       }
       continue;
     }
     if (option instanceof ExtendedOpenOption) {
       switch ((ExtendedOpenOption) option) {
         case NOSHARE_READ:
           flags.shareRead = false;
           break;
         case NOSHARE_WRITE:
           flags.shareWrite = false;
           break;
         case NOSHARE_DELETE:
           flags.shareDelete = false;
           break;
         default:
           throw new UnsupportedOperationException();
       }
       continue;
     }
     if (option == LinkOption.NOFOLLOW_LINKS) {
       flags.noFollowLinks = true;
       continue;
     }
     if (option == OPEN_REPARSE_POINT) {
       flags.openReparsePoint = true;
       continue;
     }
     if (option == null) throw new NullPointerException();
     throw new UnsupportedOperationException();
   }
   return flags;
 }