/**
   * Notifies all the <code>GroupListener<code> objects, about members added/removed.
   *
   * @param event Group event
   * @param added <code>true</code> if members were added, <code>false</code> otherwise.
   */
  protected void fireGroupEvent(DeviceGroupEvent<T> event, boolean added) {
    if (groupListeners == null) {
      return;
    }

    DeviceGroupListener<T>[] l = (DeviceGroupListener<T>[]) groupListeners.toArray();

    if (added) {
      for (int i = 0; i < l.length; i++) {
        try {
          l[i].membersAdded(event);
        } catch (Exception e) {
          Logger.getLogger(DeviceCollectionMap.class)
              .warn("Error in event handler, continuing.", e);
        }
      }
    } else {
      for (int i = 0; i < l.length; i++) {
        try {
          l[i].membersRemoved(event);
        } catch (Exception e) {
          Logger.getLogger(DeviceCollectionMap.class)
              .warn("Error in event handler, continuing.", e);
        }
      }
    }
  }
  /* (non-Javadoc)
   * @see org.csstudio.dal.group.DeviceCollection#getGroupListners()
   */
  public DeviceGroupListener<T>[] getDeviceGroupListners() {
    if (groupListeners != null) {
      return (DeviceGroupListener<T>[]) groupListeners.toArray();
    }

    return new DeviceGroupListener[0];
  }
  /** @param connectionState The connectionState to set. */
  protected void setConnectionState(ConnectionState connectionState, Throwable error) {
    boolean change = false;

    try {
      change = connectionStateMachine.requestNextConnectionState(connectionState);
    } catch (IllegalStateException e) {
      Logger.getLogger(this.getClass()).error("Internal error.", e);
      throw e;
    }

    if (!change) {
      return;
    }

    LinkListener<Linkable>[] l = (LinkListener<Linkable>[]) linkListeners.toArray();

    ConnectionEvent<Linkable> e = new ConnectionEvent<Linkable>(this, connectionState, error);
    lastConnectionEvent = e;

    if (connectionState == ConnectionState.CONNECTED) {

      if (hasDynamicValueListeners() && defaultMonitor == null) {
        getDefaultMonitor();
      }

      for (MonitorProxyWrapper<T, ? extends SimpleProperty<T>> mpw : monitors) {
        if (!mpw.isInitialized()) {
          try {
            MonitorProxy mp = proxy.createMonitor(mpw, mpw.getInitialParameters());
            mpw.initialize(mp);
          } catch (RemoteException e1) {
            // TODO mark mpw for removal from monitors?
            // if yes, it has to be done outside loop
          }
        }
      }

      for (int i = 0; i < l.length; i++) {
        try {
          l[i].connected(e);
        } catch (Exception ex) {
          Logger.getLogger(DynamicValuePropertyImpl.class)
              .warn("Exception in event handler, continuing.", ex);
        }
      }
    } else if (connectionState == ConnectionState.CONNECTION_FAILED) {
      for (int i = 0; i < l.length; i++) {
        try {
          l[i].connectionFailed(e);
        } catch (Exception ex) {
          Logger.getLogger(DynamicValuePropertyImpl.class)
              .warn("Exception in event handler, continuing.", ex);
        }
      }
    } else if (connectionState == ConnectionState.CONNECTION_LOST) {
      for (int i = 0; i < l.length; i++) {
        try {
          l[i].connectionLost(e);
        } catch (Exception ex) {
          Logger.getLogger(DynamicValuePropertyImpl.class)
              .warn("Exception in event handler, continuing.", ex);
        }
      }
    } else if (connectionState == ConnectionState.DISCONNECTED) {
      for (int i = 0; i < l.length; i++) {
        try {
          l[i].disconnected(e);
        } catch (Exception ex) {
          Logger.getLogger(DynamicValuePropertyImpl.class)
              .warn("Exception in event handler, continuing.", ex);
        }
      }
    } else if (connectionState == ConnectionState.DESTROYED) {
      for (int i = 0; i < l.length; i++) {
        try {
          l[i].destroyed(e);
        } catch (Exception ex) {
          Logger.getLogger(DynamicValuePropertyImpl.class)
              .warn("Exception in event handler, continuing.", ex);
        }
      }
    } else if (connectionState == ConnectionState.OPERATIONAL) {
      for (int i = 0; i < l.length; i++) {
        try {
          l[i].operational(e);
        } catch (Exception ex) {
          Logger.getLogger(DynamicValuePropertyImpl.class)
              .warn("Exception in event handler, continuing.", ex);
        }
      }
    }
  }
 /* (non-Javadoc)
  * @see org.csstudio.dal.AsynchronousContext#getResponseListeners()
  */
 public ResponseListener<?>[] getResponseListeners() {
   return (ResponseListener<?>[])
       responseListeners.toArray(new ResponseListener[responseListeners.size()]);
 }