class FileWatcher {

    public boolean processEvents() {
        if (watchKeyPathMap.isEmpty()) {
            return false;
        }
        // wait for key to be signalled
        WatchKey key;
        try {
            key = watchService.take();
        } catch (ClosedWatchServiceException|InterruptedException ex) {
            LOG.info("Watch service interrupted or closed while waiting to get next watch key. Exiting!", ex);
            return false;
        }
        Path dir = watchKeyPathMap.get(key);
        if (dir == null) {
            LOG.info("Unrecognized watch key: " + key + ". Skipping the key without reseting it.");
            return true;
        }
        for (WatchEvent<?> event: key.pollEvents()) {
            WatchEvent.Kind kind = event.kind();
            if (kind == StandardWatchEventKinds.OVERFLOW) {
                LOG.warn("Overflow event received for key: " + key + ". This means events have been missed or discarded. Please verify.");
                return true;
            }
            // Context for directory entry event is the file name of entry
            WatchEvent<Path> ev = (WatchEvent<Path>) event;
            Path name = ev.context();
            Path child = dir.resolve(name);
            LOG.info("{}: {}", event.kind().name(), child);
            try {
                if (kind == StandardWatchEventKinds.ENTRY_CREATE) {
                    watchKeyFileEventHandlerMap.get(key).created(child);
                } else if (kind == StandardWatchEventKinds.ENTRY_MODIFY) {
                    watchKeyFileEventHandlerMap.get(key).modified(child);
                } else if (kind == StandardWatchEventKinds.ENTRY_DELETE) {
                    watchKeyFileEventHandlerMap.get(key).deleted(child);
                }
            } catch (RuntimeException ex) {
                LOG.warn("Exception thrown by handler {} while processing event {}", watchKeyFileEventHandlerMap.get(key), event.kind().name(), ex);
            }
        }
        // reset key and remove from set if directory no longer accessible
        boolean valid = key.reset();
        if (!valid) {
            LOG.info("Key " + key + " not being watched any more as it could not be reset.");
            watchKeyPathMap.remove(key);
            watchKeyFileEventHandlerMap.remove(key);

        }
        return true;
    }

    public  FileWatcher(List<FileEventHandler> fileEventHandlers);

}