@Override
	public synchronized PathWatchKey register(Path path, Kind<?>[] kinds, Modifier[] modifiers) throws IOException {
		PathImpl pathImpl;
		try {
			pathImpl = (PathImpl)path;
		}catch(ClassCastException ccx){
			throw new IllegalArgumentException("the provided Path was not created by the newPath factory method of name.pachler.nio.file.ext.Bootstrapper");
		}
		if(!pathImpl.getFile().isDirectory())
			throw new IOException("path "+pathImpl.toString()+" is not a directory");	// JDK 1.7 throws NotDirectoryException in this case, but for now we'll just throw an IOException

		int flags = makeFlagMask(kinds, modifiers);

		WatchRecord wr = pathToWatchRecordMap.get(path);
		boolean commandResult;
		if(wr == null){
			// no WatchRecord for this path yet
			long directoryHandle = openDirectoryHandle(pathImpl);

			if(directoryHandle == INVALID_HANDLE_VALUE){
				int errorCode = GetLastError();
				throw new IOException(GetLastError_toString(errorCode));
			}

			WindowsPathWatchThread currentThread = null;
			for(WindowsPathWatchThread t : startedThreads){
				if(!t.isFull()){
					currentThread = t;
					break;
				}
			}
			if (currentThread == null)
			{
				currentThread = new WindowsPathWatchThread();
				// make this thread a deamon thread so that if users forget to close
				// this WatchService (which instructs the thread to terminate), it will
				// at least not prevent the JVM from shutting down (the app would
				// appear to 'hang' on shutdown otherwise)
				currentThread.setDaemon(true);
				currentThread.start();
				startedThreads.add(currentThread);
			}

			wr = new WatchRecord(this, pathImpl, flags, currentThread);
			wr.buffer = new ByteBuffer(DEFAULT_BUFFER_SIZE);
			wr.overlapped = new OVERLAPPED();
			wr.overlapped.setEvent(CreateEvent(null, true, false, null));
			wr.handle = directoryHandle;

			commandResult = currentThread.executeCommand(new Command(Command.TYPE_ADD_WATCHRECORD, wr));
		} else {
			// a WatchRecord already exists for this path, so modify it
			commandResult = wr.thread.executeCommand(new Command(Command.TYPE_MODIFY_WATCHRECORD, wr, flags));
		}

		// granted, that's not very inspired, but probably enough for something
		// that should hardly ever happen anyways.
		if(!commandResult)
			throw new IOException("register() failed, details are in log.");

		return wr;
	}