/**
  * a message was received from the server. Here we dispatch the message to the listeners to
  * process - note if the listeners are not threaded, this read will block until all listeners have
  * processed the message.
  *
  * @param msg
  */
 @Override
 protected void channelRead0(ChannelHandlerContext ctx, eye.Comm.Management msg) throws Exception {
   // System.out.println(this.getClass().getName() +
   // " <- Class Name ============= Method Name -> channelRead0" );
   for (Integer id : listeners.keySet()) {
     MonitorListener ml = listeners.get(id);
     // TODO this may need to be delegated to a thread pool to allow
     // async processing of replies
     ml.onMessage(msg, ctx);
   }
 }
  public void release() {
    logger.warn("HeartMonitor releasing resources");

    for (String id : handler.listeners.keySet()) {
      MonitorListener ml = handler.listeners.get(id);
      ml.connectionClosed();

      // hold back listeners to re-apply if the connection is
      // re-established.
      listeners.add(ml);
    }

    // TODO should wait a fixed time and use a listener to reset values;s
    channel = null;
    handler = null;
  }
  public void addListener(MonitorListener listener) {
    if (listener == null) return;

    listeners.putIfAbsent(listener.getListenerID(), listener);
  }