class FileWatcher extends ThreadServer implements Runnable {

  @Override
  @SuppressWarnings({"unchecked", "unsafe"})
  protected void process() throws Exception {
    trySleep(getInterval());
    final HashSet<File> checkedFiles = new HashSet<>();
    final HashSet<File> changed = new HashSet<>();

    rake(checkedFiles, changed);
    logger.debug("Changed: {}", changed);

    final BeforeAndAfter<File> beforeAndAfter =
        new BeforeAndAfter<>(previouslyChecked, checkedFiles);
    previouslyChecked = checkedFiles;

    final Set<File> added = beforeAndAfter.getAddedItems();
    final Set<File> removed = beforeAndAfter.getRemovedItems();
    final Set<File> any = asList(added, removed, changed).stream()
        .flatMap(Collection::stream).collect(toSet());

    asList(
        new Pair<>(added, FILE_ADDED),
        new Pair<>(removed, FILE_REMOVED),
        new Pair<>(changed, FILE_CHANGED),
        new Pair<>(any, ANY_CHANGED)
    ).stream().filter(pair -> !pair.v1.isEmpty())
        .map(pair -> new ServerEvent(this, pair.v2, unmodifiableCollection(pair.v1)))
        .forEach(this::fireEvent);
  }

  public  FileWatcher(final File basePath);

}