public void addCacheListenerImpl(CacheListener listener) {
    List keys = listener.getInterestedFields();
    Iterator i = keys.iterator();
    while (i.hasNext()) {
      String key = (String) i.next();
      // Peer.column names are the fields
      if (validFields != null && validFields.containsKey(key)) {
        List listeners = (List) listenersMap.get(key);
        if (listeners == null) {
          listeners = createSubsetList(key);
        }

        boolean isNew = true;
        Iterator j = listeners.iterator();
        while (j.hasNext()) {
          Object listener2 = ((WeakReference) j.next()).get();
          if (listener2 == null) {
            // do a little cleanup while checking for dupes
            // not thread-safe, not likely to be many nulls
            // but should revisit
            // j.remove();
          } else if (listener2 == listener) {
            isNew = false;
            break;
          }
        }
        if (isNew) {
          listeners.add(new WeakReference(listener));
        }
      }
    }
  }