public void processEvents() {

		for (;;) {

			// wait for key to be signalled
			WatchKey key;
			try {
				key = watcher.take();
			} catch (InterruptedException x) {
				return;
			}

			Path dir = keys.get(key);
			if (dir == null) {
				log.error("WatchKey not recognized!!");
				continue;
			}

			for (WatchEvent<?> event : key.pollEvents()) {
				WatchEvent.Kind kind = event.kind();
				
				// Context for directory entry event is the file name of entry
				WatchEvent<Path> ev = cast(event);
				Path name = ev.context();
				Path child = dir.resolve(name);
				String fullFilePath = child.toString();

				// TBD - provide example of how OVERFLOW event is handled
				if (kind == OVERFLOW) {
					log.error(" Some events might have been discarded, overflow has occured while reading \""+fullFilePath+"\"");
					continue;
				}
				// print out event
				log.debug(String.format("%s: %s %s\n", name, event.kind().name(),child));

				if (readerContext.containsKey(fullFilePath)) {

					LogClientContext context = getContextFromList(fullFilePath);
					readFile(fullFilePath, context);
				}
			}

			// reset key and remove from set if directory no longer accessible
			boolean valid = key.reset();
			if (!valid) {
				keys.remove(key);

				// all directories are inaccessible
				if (keys.isEmpty()) {
					break;
				}
			}
		}
	}