// process events (list of FILE_NOTIFY_INFORMATION structures)
    private void processEvents(WindowsWatchKey key, int size) {
      long address = key.buffer().address();

      int nextOffset;
      do {
        int action = UNSAFE.getInt(address + OFFSETOF_ACTION);

        // map action to event
        WatchEvent.Kind<?> kind = translateActionToEvent(action);
        if (key.events().contains(kind)) {
          // copy the name
          int nameLengthInBytes = UNSAFE.getInt(address + OFFSETOF_FILENAMELENGTH);
          if ((nameLengthInBytes % 2) != 0) {
            throw new AssertionError("FileNameLength is not a multiple of 2");
          }
          char[] nameAsArray = new char[nameLengthInBytes / 2];
          UNSAFE.copyMemory(
              null,
              address + OFFSETOF_FILENAME,
              nameAsArray,
              Unsafe.ARRAY_CHAR_BASE_OFFSET,
              nameLengthInBytes);

          // create FileName and queue event
          WindowsPath name = WindowsPath.createFromNormalizedPath(fs, new String(nameAsArray));
          key.signalEvent(kind, name);
        }

        // next event
        nextOffset = UNSAFE.getInt(address + OFFSETOF_NEXTENTRYOFFSET);
        address += (long) nextOffset;
      } while (nextOffset != 0);
    }