docs: def addWatchedDirectory(self, dirname, watching=Purr.WATCHED, save_config=True):
          """Starts watching the specified directories for changes"""
          # see if we're alredy watching this exact set of directories -- do nothing if so
          dirname = Purr.canonizePath(dirname)
          # do nothing if already watching
          if dirname in self.watched_dirs:
              dprint(1, "addWatchDirectory(): already watching %s\n", dirname)
              # watching=None means do not change the watch-state
              if watching is None:
                  return
          else:
              if watching is None:
                  watching = Purr.WATCHED
              # make watcher object
              wdir = Purrer.WatchedDir(dirname, mtime=self.timestamp,
                                       watch_patterns=self._watch_patterns, ignore_patterns=self._ignore_patterns)
              # fileset=None indicates error reading directory, so ignore it
              if wdir.fileset is None:
                  print("There was an error reading the directory %s, will stop watching it." % dirname)
                  self.setWatchingState(dirname, Purr.REMOVED, save_config=True)
                  return
              self.watchers[dirname] = wdir
              self.watched_dirs.append(dirname)
              dprintf(2, "watching directory %s, mtime %s, %d files\n",
                      dirname, time.strftime("%x %X", time.localtime(wdir.mtime)), len(wdir.fileset))
              # find files in this directory matching the watch_patterns, and watch them for changes
              watchset = set()
              for patt in self._watch_patterns:
                  watchset.update(fnmatch.filter(wdir.fileset, patt))
              for fname in watchset:
                  quiet = matches_patterns(fname, self._quiet_patterns)
                  fullname = Purr.canonizePath(os.path.join(dirname, fname))
                  if fullname not in self.watchers:
                      wfile = Purrer.WatchedFile(fullname, quiet=quiet, mtime=self.timestamp)
                      self.watchers[fullname] = wfile
                      dprintf(3, "watching file %s, timestamp %s, quiet %d\n",
                              fullname, time.strftime("%x %X", time.localtime(wfile.mtime)), quiet)
              # find subdirectories  matching the subdir_patterns, and watch them for changes
              for fname in wdir.fileset:
                  fullname = Purr.canonizePath(os.path.join(dirname, fname))
                  if os.path.isdir(fullname):
                      for desc, dir_patts, canary_patts in self._subdir_patterns:
                          if matches_patterns(fname, dir_patts):
                              quiet = matches_patterns(fname, self._quiet_patterns)
                              wdir = Purrer.WatchedSubdir(fullname, canary_patterns=canary_patts, quiet=quiet,
                                                          mtime=self.timestamp)
                              self.watchers[fullname] = wdir
                              dprintf(3, "watching subdirectory %s/{%s}, timestamp %s, quiet %d\n",
                                      fullname, ",".join(canary_patts),
                                      time.strftime("%x %X", time.localtime(wdir.mtime)), quiet)
                              break
          # set state and save config
          self.setWatchingState(dirname, watching, save_config=save_config)