/**
   * Remove a PropertyChangeListener from the listener list. This removes a PropertyChangeListener
   * that was registered for all properties. If <code>listener</code> was added more than once to
   * the same event source, it will be notified one less time after being removed. If <code>listener
   * </code> is null, or was never added, no exception is thrown and no action is taken.
   *
   * @param listener The PropertyChangeListener to be removed
   */
  public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
    if (listener == null) {
      return;
    }

    if (listener instanceof PropertyChangeListenerProxy) {
      PropertyChangeListenerProxy proxy = (PropertyChangeListenerProxy) listener;
      // Call two argument remove method.
      removePropertyChangeListener(
          proxy.getPropertyName(), (PropertyChangeListener) proxy.getListener());
    } else {
      if (listeners == null) {
        return;
      }
      listeners.remove(listener);
    }
  }
  /**
   * Add a PropertyChangeListener to the listener list. The listener is registered for all
   * properties. The same listener object may be added more than once, and will be called as many
   * times as it is added. If <code>listener</code> is null, no exception is thrown and no action is
   * taken.
   *
   * @param listener The PropertyChangeListener to be added
   */
  public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
    if (listener == null) {
      return;
    }

    if (listener instanceof PropertyChangeListenerProxy) {
      PropertyChangeListenerProxy proxy = (PropertyChangeListenerProxy) listener;
      // Call two argument add method.
      addPropertyChangeListener(
          proxy.getPropertyName(), (PropertyChangeListener) proxy.getListener());
    } else {
      if (listeners == null) {
        listeners = new EventListenerAggregate(PropertyChangeListener.class);
      }
      listeners.add(listener);
    }
  }