code: public void addResourceChangeListener(ResourceChangeListener pListener,
                                            Object pResourceId, long pPeriod) throws IOException {
          // Create the task
          ResourceMonitorTask task = new ResourceMonitorTask(pListener, pResourceId);
  
          // Get unique Id
          Object resourceId = getResourceId(pResourceId, pListener);
  
          // Remove the old task for this Id, if any, and register the new one
          synchronized (timerEntries) {
              removeListenerInternal(resourceId);
              timerEntries.put(resourceId, task);
          }
  
          timer.schedule(task, pPeriod, pPeriod);
      }
docs: Add a monitored {@code Resource} with a {@code ResourceChangeListener}.
  
  The {@code reourceId} might be a {@code File} a {@code URL} or a
  {@code String} containing a file path, or a path to a resource in the
  class path. Note that class path resources are resolved using the
  given {@code ResourceChangeListener}'s {@code ClassLoader}, then
  the current {@code Thread}'s context class loader, if not found.
  
  @param pListener   pListener to notify when the file changed.
  @param pResourceId id of the resource to monitor (a {@code File}
  a {@code URL} or a {@code String} containing a file path).
  @param pPeriod     polling pPeriod in milliseconds.
  
  @see ClassLoader#getResource(String)