docs: void update(Dictionary<String, Object> props) {
          if (deleted) {
              return;
          }
  
          final String instancePid = (String) props.get("service.pid");
          final String instanceId = (String) props.get("id");
          if (instanceId == null) {
              Tr.error(tc, "cls.library.id.missing");
          }
          if (libraryListenersTracker == null) {
              //set up a tracker for notification listeners for this library
              Filter listenerFilter = null;
              // To better support parent first nested config, also filter on libraryRef,
              // which will be a list of pid (or, if cardinality=0, then just a pid).
              try {
                  listenerFilter = FrameworkUtil.createFilter("(&(objectClass=" + LibraryChangeListener.class.getName() +
                                                              ")(|(library=" + instanceId + ")(libraryRef=*" + instancePid + "*)))");
              } catch (InvalidSyntaxException e) {
                  //auto FFDC because the syntax shouldn't be wrong!
                  Tr.error(tc, "cls.library.id.invalid", instanceId, e.toString());
              }
  
              ServiceTracker<LibraryChangeListener, LibraryChangeListener> tracker;
              tracker = new ServiceTracker<LibraryChangeListener, LibraryChangeListener>(this.ctx, listenerFilter, null);
              tracker.open();
              libraryListenersTracker = tracker;
          }
  
          LibraryGeneration nextGen;
          synchronized (generationLock) {
              nextGen = nextGeneration;
              if (nextGen != null) {
                  // there is already a new generation in the process of being updated.
                  // since it is using stale properties we want to cancel that generation
                  // and start a new one.
                  nextGeneration = null;
                  nextGen.cancel();
              }
              nextGeneration = nextGen = new LibraryGeneration(this, instanceId, props);
          }
          nextGen.fetchFilesets();
      }