/**
   * Get Component MBeans. Creates, registers and deregisters MBeans for an array of components. On
   * each call the passed map is used to determine components that have already been registers and
   * those that need to be deregistered.
   *
   * @param components the components.
   * @param map A map of previously registered components to object name. If null is passed, a
   *     default map for the mbean is used.
   * @return An array of ObjectNames for each component.
   */
  protected ObjectName[] getComponentMBeans(Object[] components, Map map) {
    if (map == null) map = _components;
    ObjectName[] beans = null;
    if (components == null) beans = new ObjectName[0];
    else {
      beans = new ObjectName[components == null ? 0 : components.length];

      // Add new beans
      for (int i = 0; i < components.length; i++) {
        ObjectName on = (ObjectName) map.get(components[i]);
        if (on == null) {
          ModelMBean mbean = mbeanFor(components[i]);
          if (mbean == null) log.warn("No mbean for " + components[i]);
          else {
            try {
              if (mbean instanceof ModelMBeanImpl) {
                ((ModelMBeanImpl) mbean).setBaseObjectName(getObjectName().toString());
                on = getMBeanServer().registerMBean(mbean, null).getObjectName();
              } else {
                on = uniqueObjectName(getMBeanServer(), components[i], getObjectName().toString());
                on = getMBeanServer().registerMBean(mbean, on).getObjectName();
              }
              map.put(components[i], on);
            } catch (Exception e) {
              log.warn(LogSupport.EXCEPTION, e);
            }
          }
        }
        beans[i] = on;
      }
    }

    // Delete old beans
    if (components == null || map.size() > components.length) {
      Object[] to_delete = new Object[map.size() - beans.length];
      int d = 0;
      Iterator iter = map.keySet().iterator();
      keys:
      while (iter.hasNext()) {
        Object bean = iter.next();
        if (components != null) {
          for (int i = 0; i < components.length; i++) if (components[i] == bean) continue keys;
        }
        to_delete[d++] = bean;
      }

      for (; d-- > 0; ) {
        try {
          getMBeanServer().unregisterMBean((ObjectName) map.remove(to_delete[d]));
        } catch (Exception e) {
          log.warn(LogSupport.EXCEPTION, e);
        }
      }
    }

    return beans;
  }
  /**
   * Unregister mbeans for already registered components
   *
   * @param map
   */
  protected void destroyComponentMBeans(Map map) {
    // if no map of registered mbean names is passed,
    // use the default map
    if (null == map) map = _components;

    if (map == null) return;

    Iterator itor = map.values().iterator();
    while (itor.hasNext()) {
      try {
        ObjectName o = (ObjectName) itor.next();
        getMBeanServer().unregisterMBean(o);
        itor.remove();
      } catch (Exception e) {
        log.warn(LogSupport.EXCEPTION, e);
      }
    }
  }
 /* ------------------------------------------------------------ */
 public void preDeregister() {
   log.info("Deregister " + _objectName);
   getComponentMBeans(null, _components);
   _components.clear();
 }