protected void notify(URL url, NotifyListener listener, List<URL> urls) {
   if (url == null) {
     throw new IllegalArgumentException("notify url == null");
   }
   if (listener == null) {
     throw new IllegalArgumentException("notify listener == null");
   }
   if ((urls == null || urls.size() == 0)
       && !Constants.ANY_VALUE.equals(url.getServiceInterface())) {
     logger.warn("Ignore empty notify urls for subscribe url " + url);
     return;
   }
   if (logger.isInfoEnabled()) {
     logger.info("Notify urls for subscribe url " + url + ", urls: " + urls);
   }
   Map<String, List<URL>> result = new HashMap<String, List<URL>>();
   for (URL u : urls) {
     if (UrlUtils.isMatch(url, u)) {
       String category = u.getParameter(Constants.CATEGORY_KEY, Constants.DEFAULT_CATEGORY);
       List<URL> categoryList = result.get(category);
       if (categoryList == null) {
         categoryList = new ArrayList<URL>();
         result.put(category, categoryList);
       }
       categoryList.add(u);
     }
   }
   if (result.size() == 0) {
     return;
   }
   Map<String, List<URL>> categoryNotified = notified.get(url);
   if (categoryNotified == null) {
     notified.putIfAbsent(url, new ConcurrentHashMap<String, List<URL>>());
     categoryNotified = notified.get(url);
   }
   for (Map.Entry<String, List<URL>> entry : result.entrySet()) {
     String category = entry.getKey();
     List<URL> categoryList = entry.getValue();
     categoryNotified.put(category, categoryList);
     saveProperties(url);
     listener.notify(categoryList);
   }
 }
  protected void notify(List<URL> urls) {
    if (urls == null || urls.isEmpty()) return;

    for (Map.Entry<URL, Set<NotifyListener>> entry : getSubscribed().entrySet()) {
      URL url = entry.getKey();

      if (!UrlUtils.isMatch(url, urls.get(0))) {
        continue;
      }

      Set<NotifyListener> listeners = entry.getValue();
      if (listeners != null) {
        for (NotifyListener listener : listeners) {
          try {
            notify(url, listener, filterEmpty(url, urls));
          } catch (Throwable t) {
            logger.error(
                "Failed to notify registry event, urls: " + urls + ", cause: " + t.getMessage(), t);
          }
        }
      }
    }
  }