static void registerRefreshNotification(NotificationListener client, Object userData,
      RefreshNotificationType type, long refreshInterval) {
    if (client == null) {
      throw new IllegalArgumentException(
          "NotificationListener is required");
    }
    if (type == null) {
      throw new IllegalArgumentException(
          "RefreshNotificationType is required");
    }
    if (refreshTimerObjectName == null || refreshTimer == null) {
      throw new IllegalStateException(
          "RefreshTimer has not been properly initialized.");
    }

    try {
      // get the notifications for the specified client...
      Map<RefreshNotificationType, Integer> notifications = null;
      synchronized (refreshClients) {
        notifications = refreshClients.get(client);
      }

      if (notifications == null) {
        // If refreshInterval is being set to zero and notifications is removed return
        if (refreshInterval <= 0) {
          return;
        }

        // never registered before, so add client...
        notifications = new HashMap<>();
        synchronized (refreshClients) {
          refreshClients.put(client, notifications);
        }
        validateRefreshTimer();
        try {
          // register client as a listener with MBeanServer...
          mbeanServer.addNotificationListener(refreshTimerObjectName, // timer to listen to
              client, // the NotificationListener object
              null, // optional NotificationFilter TODO: convert to using
              new Object() // not used but null throws IllegalArgumentException
          );
        } catch (InstanceNotFoundException e) {
          // should not happen since we already checked refreshTimerObjectName
          logStackTrace(Level.WARN, e,
              "Could not find registered RefreshTimer instance.");
        }
      }

      // TODO: change to manipulating timer indirectly thru mserver...

      // check for pre-existing refresh notification entry...
      Integer timerNotificationId = notifications.get(type);
      if (timerNotificationId != null) {
        try {
          // found one, so let's remove it...
          refreshTimer.removeNotification(timerNotificationId);
        } catch (InstanceNotFoundException e) {
          // that's ok cause we just wanted to remove it anyway
        } finally {
          // null out the map entry for that notification type...
          notifications.put(type, null);
        }
      }

      if (refreshInterval > 0) {
        // add notification to the refresh timer...
        timerNotificationId = refreshTimer.addNotification(type.getType(), // type
            type.getMessage(), // message = "refresh"
            userData, // userData
            new Date(System.currentTimeMillis() + refreshInterval * 1000L), // first occurrence
            refreshInterval * 1000L); // period to repeat

        // put an entry into the map for the listener...
        notifications.put(type, timerNotificationId);
      } else {
        // do nothing! refreshInterval must be over 0 to do anything...
      }
    } catch (java.lang.RuntimeException e) {
      logStackTrace(Level.WARN, e);
      throw e;
    } catch (VirtualMachineError err) {
      SystemFailure.initiateFailure(err);
      // If this ever returns, rethrow the error. We're poisoned
      // now, so don't let this thread continue.
      throw err;
    } catch (java.lang.Error e) {
      // Whenever you catch Error or Throwable, you must also
      // catch VirtualMachineError (see above). However, there is
      // _still_ a possibility that you are dealing with a cascading
      // error condition, so you also need to check to see if the JVM
      // is still usable:
      SystemFailure.checkFailure();
      logStackTrace(Level.ERROR, e);
      throw e;
    }
  }
Registers a refresh notification for the specified client MBean. Specifying zero for the
refreshInterval disables notification for the refresh client. Note: this does not currently
support remote connections.

@param client client to listen for refresh notifications
@param userData userData to register with the Notification
@param type refresh notification type the client will use
@param refreshInterval the seconds between refreshes
geode-core/src/main/java/org/apache/geode/admin/jmx/internal/MBeanUtils.java