/**
   * If this object has changed, as indicated by the <code>hasChanged</code> method, then notify all
   * of its observers and then call the <code>clearChanged</code> method to indicate that this
   * object has no longer changed.
   *
   * <p>Each observer has its <code>update</code> method called with two arguments: this observable
   * object and the <code>arg</code> argument.
   *
   * @param notification any object.
   * @see java.util.Observable#clearChanged()
   * @see java.util.Observable#hasChanged()
   * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
   */
  private void notifyListeners(Notification notification) {
    /*
     * a temporary array buffer, used as a snapshot of the state of
     * current Listeners.
     */
    Object[] arrLocal;

    synchronized (this) {
      /* We don't want the Observer doing callbacks into
       * arbitrary code while holding its own Monitor.
       * The code where we extract each Observable from
       * the Vector and store the state of the Observer
       * needs synchronization, but notifying observers
       * does not (should not).  The worst result of any
       * potential race-condition here is that:
       * 1) a newly-added Observer will miss a
       *   notification in progress
       * 2) a recently unregistered Observer will be
       *   wrongly notified when it doesn't care
       */
      if (!changed) return;
      arrLocal = listeners.toArray();
      clearChanged();
    }

    for (int i = arrLocal.length - 1; i >= 0; i--)
      ((RuntimeModelListener) arrLocal[i]).update(this, notification);
  }