gt: 	    LOG.error("Invalid event:" + event.getEventType());
context: // $Id: ArgoEventPump.java 132 2010-09-26 23:32:33Z marcusvnac $
  // Copyright (c) 1996-2008 The Regents of the University of California. All
  // Rights Reserved. Permission to use, copy, modify, and distribute this
  // software and its documentation without fee, and without a written
  // agreement is hereby granted, provided that the above copyright notice
  // and this paragraph appear in all copies.  This software program and
  // documentation are copyrighted by The Regents of the University of
  // California. The software program and documentation are supplied "AS
  // IS", without any accompanying services from The Regents. The Regents
  // does not warrant that the operation of the program will be
  // uninterrupted or error-free. The end-user understands that the program
  // was developed for research purposes and is advised not to rely
  // exclusively on the program for any reason.  IN NO EVENT SHALL THE
  // UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
  // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
  // ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
  // THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
  // SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY
  // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
  // PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
  // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
  // UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  
  package org.argouml.application.events;
  
  import java.util.ArrayList;
  import java.util.List;
  
  import javax.swing.SwingUtilities;
  
  //#if defined(LOGGING)
  //@#$LPS-LOGGING:GranularityType:Import
  import org.apache.log4j.Logger;
  //#endif
  import org.argouml.application.api.ArgoEventListener;
  
  /**
   * ArgoEventPump is an event dispatcher which handles events that are global
   * in nature for the entire application.
   * <p>
   * TODO: DiagramAppearance and Notation events are not application-wide and will
   * be moved from here to someplace more specific in the future so that they can
   * be managed on a per-project or per-diagram basis.
   */
  public final class ArgoEventPump {
      //#if defined(LOGGING)
      //@#$LPS-LOGGING:GranularityType:Field
      /**
       * Logger.
       */
      private static final Logger LOG = Logger.getLogger(ArgoEventPump.class);
      //#endif
      /**
       * <code>listeners</code> contains the list of register listeners.
       *
       * It is a list of {@link Pair}.
       */
      private List<Pair> listeners;
  
      /**
       * The singleton.
       */
      static final ArgoEventPump SINGLETON = new ArgoEventPump();
  
      /**
       * @return the singleton
       */
      public static ArgoEventPump getInstance() {
          return SINGLETON;
      }
  
      /**
       * Constructor.
       */
      private ArgoEventPump() {
      }
  
      /**
       * @param listener The listener to be added.
       */
      public static void addListener(ArgoEventListener listener) {
          SINGLETON.doAddListener(ArgoEventTypes.ANY_EVENT, listener);
      }
  
      /**
       * @param event the event-type to what the listener will listen
       * @param listener the listener to be added
       */
      public static void addListener(int event, ArgoEventListener listener) {
          SINGLETON.doAddListener(event, listener);
      }
  
      /**
       * @param listener the listener to be removed
       */
      public static void removeListener(ArgoEventListener listener) {
          SINGLETON.doRemoveListener(ArgoEventTypes.ANY_EVENT, listener);
      }
  
      /**
       * @param event the event to which the listener will not listen any more
       * @param listener the listener to be removed
       */
      public static void removeListener(int event, ArgoEventListener listener) {
          SINGLETON.doRemoveListener(event, listener);
      }
  
      /**
       * @param event the event to what the listener will listen (?)
       * @param listener the listener to be added
       */
      protected void doAddListener(int event, ArgoEventListener listener) {
          if (listeners == null) {
              listeners = new ArrayList<Pair>();
          }
          synchronized (listeners) {
              listeners.add(new Pair(event, listener));
          }
      }
  
      /**
       * Removes a listener, eventtype pair from the listener list.
       *
       * TODO: replace the listener implementation with a EventListenerList
       * for better performance
       *
       * @param event the event to which the listener will not listen any more
       * @param listener the listener to be removed
       */
      protected void doRemoveListener(int event, ArgoEventListener listener) {
          if (listeners == null) {
              return;
          }
          synchronized (listeners) {
              List<Pair> removeList = new ArrayList<Pair>();
              if (event == ArgoEventTypes.ANY_EVENT) {
                  // TODO: This is a linear search of a list that contain many
                  // thousands of items (one for every Fig in the entire project)
                  for (Pair p : listeners) {
                      if (p.listener == listener) {
                          removeList.add(p);
                      }
                  }
              } else {
                  Pair test = new Pair(event, listener);
                  // TODO: This is a linear search of a list that contain many
                  // thousands of items (one for every Fig in the entire project)
                  for (Pair p : listeners) {
                      if (p.equals(test)) {
                          removeList.add(p);
                      }
                  }
              }
              listeners.removeAll(removeList);
          }
      }
  
      /**
       * Handle firing a notation event.
       * <p>
       * TODO: This needs to be managed on a per-diagram or per-project basis.
       *
       * @param event The event to be fired.
       * @param listener The listener.
       */
      private void handleFireNotationEvent(
          final ArgoNotationEvent event,
          final ArgoNotationEventListener listener) {
         
          // Notation events are likely to cause GEF/Swing operations, so we
          // dispatch them on the Swing event thread as a convenience so that 
          // the receiving notationChanged() methods don't need to deal with it
          if (SwingUtilities.isEventDispatchThread()) {
              fireNotationEventInternal(event, listener);
          } else {
              SwingUtilities.invokeLater(new Runnable() {
                  public void run() {
                      fireNotationEventInternal(event, listener);
                  }
              });
          }
      }
  
      private void fireNotationEventInternal(ArgoNotationEvent event,
              ArgoNotationEventListener listener) {
          switch (event.getEventType()) {
  	case ArgoEventTypes.NOTATION_CHANGED :
  	    listener.notationChanged(event);
  	    /* Remark: The code in 
  	     * ProjectSettings.init() currently presumes
  	     * that nobody is using this event. */
  	    break;
  
  	case ArgoEventTypes.NOTATION_ADDED :
  	    listener.notationAdded(event);
  	    break;
  
  	case ArgoEventTypes.NOTATION_REMOVED :
  	    listener.notationRemoved(event);
  	    break;
  
  	case ArgoEventTypes.NOTATION_PROVIDER_ADDED :
  	    listener.notationProviderAdded(event);
  	    break;
  
  	case ArgoEventTypes.NOTATION_PROVIDER_REMOVED :
  	    listener.notationProviderRemoved(event);
  	    break;
  
  	default :
  	    //#if defined(LOGGING)
  	    //@#$LPS-LOGGING:GranularityType:Statement
  	    //@#$LPS-LOGGING:Localization:NestedStatement
  