/**
   * 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;
    }
  }