/* AWTEventMulticaster.java -- allows multicast chaining of listeners
   Copyright (C) 1999, 2000, 2002 Free Software Foundation

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.awt;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.HierarchyBoundsListener;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.awt.event.InputMethodEvent;
import java.awt.event.InputMethodListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.event.TextEvent;
import java.awt.event.TextListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
import java.awt.event.WindowListener;
import java.awt.event.WindowStateListener;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.EventListener;

/**
 * This class is used to implement a chain of event handlers.  Dispatching
 * using this class is thread safe.  Here is a quick example of how to
 * add and delete listeners using this class.  For this example, we will
 * assume are firing <code>AdjustmentEvent</code>'s.  However, this
 * same approach is useful for all events in the <code>java.awt.event</code>
 * package, and more if this class is subclassed.
 *
 * <p><code>
 * AdjustmentListener al;
 * public void addAdjustmentListener(AdjustmentListener listener)
 * {
 *   al = AWTEventMulticaster.add(al, listener);
 * }
 * public void removeAdjustmentListener(AdjustmentListener listener)
 * {
 *   al = AWTEventMulticaster.remove(al, listener);
 * }
 * </code>
 *
 * <p>When it come time to process an event, simply call <code>al</code>,
 * assuming it is not <code>null</code>, and all listeners in the chain will
 * be fired.
 *
 * <p>The first time <code>add</code> is called it is passed
 * <code>null</code> and <code>listener</code> as its arguments.  This
 * starts building the chain.  This class returns <code>listener</code>
 * which becomes the new <code>al</code>.  The next time, <code>add</code>
 * is called with <code>al</code> and <code>listener</code> and the
 * new listener is then chained to the old.
 *
 * @author Bryce McKinlay
 * @author Aaron M. Renn <arenn@urbanophile.com>
 * @author Eric Blake <ebb9@email.byu.edu>
 * @since 1.1
 * @status updated to 1.4
 */
public class AWTEventMulticaster
  implements ComponentListener, ContainerListener, FocusListener, KeyListener,
             MouseListener, MouseMotionListener, WindowListener,
             WindowFocusListener, WindowStateListener, ActionListener,
             ItemListener, AdjustmentListener, TextListener,
             InputMethodListener, HierarchyListener, HierarchyBoundsListener,
             MouseWheelListener
{
  /**
   * A variable in the event chain.
   */
  protected final EventListener a;

  /**
   * A variable in the event chain.
   */
  protected final EventListener b;

  /**
   * Initializes a new instance of <code>AWTEventMulticaster</code> with
   * the specified event listener parameters. The parameters should not be
   * null, although it is not required to enforce this with a
   * NullPointerException.
   *
   * @param a the "a" listener object
   * @param b the "b" listener object
   */
  protected AWTEventMulticaster(EventListener a, EventListener b)
  {
    this.a = a;
    this.b = b;
  }

  /**
   * Removes one instance of the specified listener from this multicaster
   * chain. This descends recursively if either child is a multicaster, and
   * returns a multicaster chain with the old listener removed.
   *
   * @param oldl the object to remove from this multicaster
   * @return the resulting multicaster with the specified listener removed
   */
  protected EventListener remove(EventListener oldl)
  {
    // If oldl is an immediate child, return the other child.
    if (a == oldl)
      return b;
    if (b == oldl)
      return a;
    // If a and/or b are Multicaster's, search them recursively.
    if (a instanceof AWTEventMulticaster)
      {
        EventListener newa = ((AWTEventMulticaster) a).remove(oldl);
        if (newa != a)
          return new AWTEventMulticaster(newa, b);
      }
    if (b instanceof AWTEventMulticaster)
      {
        EventListener newb = ((AWTEventMulticaster) b).remove(oldl);
        if (newb != b)
          return new AWTEventMulticaster(a, newb);
      }
    // oldl was not found.
    return this;
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   */
  public void componentResized(ComponentEvent e)
  {
    ((ComponentListener) a).componentResized(e);
    ((ComponentListener) b).componentResized(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   */
  public void componentMoved(ComponentEvent e)
  {
    ((ComponentListener) a).componentMoved(e);
    ((ComponentListener) b).componentMoved(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   */
  public void componentShown(ComponentEvent e)
  {
    ((ComponentListener) a).componentShown(e);
    ((ComponentListener) b).componentShown(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   */
  public void componentHidden(ComponentEvent e)
  {
    ((ComponentListener) a).componentHidden(e);
    ((ComponentListener) b).componentHidden(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   */
  public void componentAdded(ContainerEvent e)
  {
    ((ContainerListener) a).componentAdded(e);
    ((ContainerListener) b).componentAdded(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   */
  public void componentRemoved(ContainerEvent e)
  {
    ((ContainerListener) a).componentRemoved(e);
    ((ContainerListener) b).componentRemoved(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   */
  public void focusGained(FocusEvent e)
  {
    ((FocusListener) a).focusGained(e);
    ((FocusListener) b).focusGained(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   */
  public void focusLost(FocusEvent e)
  {
    ((FocusListener) a).focusLost(e);
    ((FocusListener) b).focusLost(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   */
  public void keyTyped(KeyEvent e)
  {
    ((KeyListener) a).keyTyped(e);
    ((KeyListener) b).keyTyped(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   */
  public void keyPressed(KeyEvent e)
  {
    ((KeyListener) a).keyPressed(e);
    ((KeyListener) b).keyPressed(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   */
  public void keyReleased(KeyEvent e)
  {
    ((KeyListener) a).keyReleased(e);
    ((KeyListener) b).keyReleased(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   */
  public void mouseClicked(MouseEvent e)
  {
    ((MouseListener) a).mouseClicked(e);
    ((MouseListener) b).mouseClicked(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   */
  public void mousePressed(MouseEvent e)
  {
    ((MouseListener) a).mousePressed(e);
    ((MouseListener) b).mousePressed(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   */
  public void mouseReleased(MouseEvent e)
  {
    ((MouseListener) a).mouseReleased(e);
    ((MouseListener) b).mouseReleased(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   */
  public void mouseEntered(MouseEvent e)
  {
    ((MouseListener) a).mouseEntered(e);
    ((MouseListener) b).mouseEntered(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   */
  public void mouseExited(MouseEvent e)
  {
    ((MouseListener) a).mouseExited(e);
    ((MouseListener) b).mouseExited(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   */
  public void mouseDragged(MouseEvent e)
  {
    ((MouseMotionListener) a).mouseDragged(e);
    ((MouseMotionListener) b).mouseDragged(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   */
  public void mouseMoved(MouseEvent e)
  {
    ((MouseMotionListener) a).mouseMoved(e);
    ((MouseMotionListener) b).mouseMoved(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   */
  public void windowOpened(WindowEvent e)
  {
    ((WindowListener) a).windowOpened(e);
    ((WindowListener) b).windowOpened(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   */
  public void windowClosing(WindowEvent e)
  {
    ((WindowListener) a).windowClosing(e);
    ((WindowListener) b).windowClosing(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   */
  public void windowClosed(WindowEvent e)
  {
    ((WindowListener) a).windowClosed(e);
    ((WindowListener) b).windowClosed(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   */
  public void windowIconified(WindowEvent e)
  {
    ((WindowListener) a).windowIconified(e);
    ((WindowListener) b).windowIconified(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   */
  public void windowDeiconified(WindowEvent e)
  {
    ((WindowListener) a).windowDeiconified(e);
    ((WindowListener) b).windowDeiconified(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   */
  public void windowActivated(WindowEvent e)
  {
    ((WindowListener) a).windowActivated(e);
    ((WindowListener) b).windowActivated(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   */
  public void windowDeactivated(WindowEvent e)
  {
    ((WindowListener) a).windowDeactivated(e);
    ((WindowListener) b).windowDeactivated(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   * @since 1.4
   */
  public void windowStateChanged(WindowEvent e)
  {
    ((WindowStateListener) a).windowStateChanged(e);
    ((WindowStateListener) b).windowStateChanged(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   * @since 1.4
   */
  public void windowGainedFocus(WindowEvent e)
  {
    ((WindowFocusListener) a).windowGainedFocus(e);
    ((WindowFocusListener) b).windowGainedFocus(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   * @since 1.4
   */
  public void windowLostFocus(WindowEvent e)
  {
    ((WindowFocusListener) a).windowLostFocus(e);
    ((WindowFocusListener) b).windowLostFocus(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   */
  public void actionPerformed(ActionEvent e)
  {
    ((ActionListener) a).actionPerformed(e);
    ((ActionListener) b).actionPerformed(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   */
  public void itemStateChanged(ItemEvent e)
  {
    ((ItemListener) a).itemStateChanged(e);
    ((ItemListener) b).itemStateChanged(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   */
  public void adjustmentValueChanged(AdjustmentEvent e)
  {
    ((AdjustmentListener) a).adjustmentValueChanged(e);
    ((AdjustmentListener) b).adjustmentValueChanged(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   */
  public void textValueChanged(TextEvent e)
  {
    ((TextListener) a).textValueChanged(e);
    ((TextListener) b).textValueChanged(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   * @since 1.2
   */
  public void inputMethodTextChanged(InputMethodEvent e)
  {
    ((InputMethodListener) a).inputMethodTextChanged(e);
    ((InputMethodListener) b).inputMethodTextChanged(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   * @since 1.2
   */
  public void caretPositionChanged(InputMethodEvent e)
  {
    ((InputMethodListener) a).caretPositionChanged(e);
    ((InputMethodListener) b).caretPositionChanged(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   * @since 1.3
   */
  public void hierarchyChanged(HierarchyEvent e)
  {
    ((HierarchyListener) a).hierarchyChanged(e);
    ((HierarchyListener) b).hierarchyChanged(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   * @since 1.3
   */
  public void ancestorMoved(HierarchyEvent e)
  {
    ((HierarchyBoundsListener) a).ancestorMoved(e);
    ((HierarchyBoundsListener) b).ancestorMoved(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   * @since 1.3
   */
  public void ancestorResized(HierarchyEvent e)
  {
    ((HierarchyBoundsListener) a).ancestorResized(e);
    ((HierarchyBoundsListener) b).ancestorResized(e);
  }

  /**
   * Handles this event by dispatching it to the "a" and "b" listener
   * instances.
   *
   * @param event the event to handle
   * @since 1.4
   */
  public void mouseWheelMoved(MouseWheelEvent e)
  {
    ((MouseWheelListener) a).mouseWheelMoved(e);
    ((MouseWheelListener) b).mouseWheelMoved(e);
  }

  /**
   * Chain <code>ComponentListener</code> a and b.
   *
   * @param a the "a" listener, may be null
   * @param b the "b" listener, may be null
   * @return latest entry in the chain
   */
  public static ComponentListener add(ComponentListener a, ComponentListener b)
  {
    return (ComponentListener) addInternal(a, b);
  }

  /**
   * Chain <code>ContainerListener</code> a and b.
   *
   * @param a the "a" listener, may be null
   * @param b the "b" listener, may be null
   * @return latest entry in the chain
   */
  public static ContainerListener add(ContainerListener a, ContainerListener b)
  {
    return (ContainerListener) addInternal(a, b);
  }

  /**
   * Chain <code>FocusListener</code> a and b.
   *
   * @param a the "a" listener, may be null
   * @param b the "b" listener, may be null
   * @return latest entry in the chain
   */
  public static FocusListener add(FocusListener a, FocusListener b)
  {
    return (FocusListener) addInternal(a, b);
  }

  /**
   * Chain <code>KeyListener</code> a and b.
   *
   * @param a the "a" listener, may be null
   * @param b the "b" listener, may be null
   * @return latest entry in the chain
   */
  public static KeyListener add(KeyListener a, KeyListener b)
  {
    return (KeyListener) addInternal(a, b);
  }

  /**
   * Chain <code>MouseListener</code> a and b.
   *
   * @param a the "a" listener, may be null
   * @param b the "b" listener, may be null
   * @return latest entry in the chain
   */
  public static MouseListener add(MouseListener a, MouseListener b)
  {
    return (MouseListener) addInternal(a, b);
  }

  /**
   * Chain <code>MouseMotionListener</code> a and b.
   *
   * @param a the "a" listener, may be null
   * @param b the "b" listener, may be null
   * @return latest entry in the chain
   */
  public static MouseMotionListener add(MouseMotionListener a,
                                        MouseMotionListener b)
  {
    return (MouseMotionListener) addInternal(a, b);
  }

  /**
   * Chain <code>WindowListener</code> a and b.
   *
   * @param a the "a" listener, may be null
   * @param b the "b" listener, may be null 
   * @return latest entry in the chain
   */
  public static WindowListener add(WindowListener a, WindowListener b)
  {
    return (WindowListener) addInternal(a, b);
  }

  /**
   * Chain <code>WindowStateListener</code> a and b.
   *
   * @param a the "a" listener, may be null
   * @param b the "b" listener, may be null 
   * @return latest entry in the chain
   * @since 1.4
   */
  public static WindowStateListener add(WindowStateListener a,
                                        WindowStateListener b)
  {
    return (WindowStateListener) addInternal(a, b);
  }

  /**
   * Chain <code>WindowFocusListener</code> a and b.
   *
   * @param a the "a" listener, may be null
   * @param b the "b" listener, may be null 
   * @return latest entry in the chain
   * @since 1.4
   */
  public static WindowFocusListener add(WindowFocusListener a,
                                        WindowFocusListener b)
  {
    return (WindowFocusListener) addInternal(a, b);
  }

  /**
   * Chain <code>ActionListener</code> a and b.
   *
   * @param a the "a" listener, may be null
   * @param b the "b" listener, may be null
   * @return latest entry in the chain
   */
  public static ActionListener add(ActionListener a, ActionListener b)
  {
    return (ActionListener) addInternal(a, b);
  }

  /**
   * Chain <code>ItemListener</code> a and b.
   *
   * @param a the "a" listener, may be null
   * @param b the "b" listener, may be null
   * @return latest entry in the chain
   */
  public static ItemListener add(ItemListener a, ItemListener b)
  {
    return (ItemListener) addInternal(a, b);
  }

  /**
   * Chain <code>AdjustmentListener</code> a and b.
   *
   * @param a the "a" listener, may be null
   * @param b the "b" listener, may be null
   * @return latest entry in the chain
   */
  public static AdjustmentListener add(AdjustmentListener a,
                                       AdjustmentListener b)
  {
    return (AdjustmentListener) addInternal(a, b);
  }

  /**
   * Chain <code>AdjustmentListener</code> a and b.
   *
   * @param a the "a" listener, may be null
   * @param b the "b" listener, may be null
   * @return latest entry in the chain
   */
  public static TextListener add(TextListener a, TextListener b)
  {
    return (TextListener) addInternal(a, b);
  }

  /**
   * Chain <code>InputMethodListener</code> a and b.
   *
   * @param a the "a" listener, may be null
   * @param b the "b" listener, may be null
   * @return latest entry in the chain
   * @since 1.2
   */
  public static InputMethodListener add(InputMethodListener a,
                                        InputMethodListener b)
  {
    return (InputMethodListener) addInternal(a, b);
  }

  /**
   * Chain <code>HierarchyListener</code> a and b.
   *
   * @param a the "a" listener, may be null
   * @param b the "b" listener, may be null
   * @return latest entry in the chain
   * @since 1.3
   */
  public static HierarchyListener add(HierarchyListener a, HierarchyListener b)
  {
    return (HierarchyListener) addInternal(a, b);
  }

  /**
   * Chain <code>HierarchyBoundsListener</code> a and b.
   *
   * @param a the "a" listener, may be null
   * @param b the "b" listener, may be null
   * @return latest entry in the chain
   * @since 1.3
   */
  public static HierarchyBoundsListener add(HierarchyBoundsListener a,
                                            HierarchyBoundsListener b)
  {
    return (HierarchyBoundsListener) addInternal(a, b);
  }

  /**
   * Chain <code>MouseWheelListener</code> a and b.
   *
   * @param a the "a" listener, may be null
   * @param b the "b" listener, may be null
   * @return latest entry in the chain
   * @since 1.4
   */
  public static MouseWheelListener add(MouseWheelListener a,
                                       MouseWheelListener b)
  {
    return (MouseWheelListener) addInternal(a, b);
  }

  /**
   * Removes the listener <code>oldl</code> from the listener <code>l</code>.
   *
   * @param l the listener chain to reduce
   * @param oldl the listener to remove
   * @return the resulting listener chain
   */
  public static ComponentListener remove(ComponentListener l,
                                         ComponentListener oldl)
  {
    return (ComponentListener) removeInternal(l, oldl);
  }

  /**
   * Removes the listener <code>oldl</code> from the listener <code>l</code>.
   *
   * @param l the listener chain to reduce
   * @param oldl the listener to remove
   * @return the resulting listener chain
   */
  public static ContainerListener remove(ContainerListener l,
                                         ContainerListener oldl)
  {
    return (ContainerListener) removeInternal(l, oldl);
  }

  /**
   * Removes the listener <code>oldl</code> from the listener <code>l</code>.
   *
   * @param l the listener chain to reduce
   * @param oldl the listener to remove
   * @return the resulting listener chain
   */
  public static FocusListener remove(FocusListener l, FocusListener oldl)
  {
    return (FocusListener) removeInternal(l, oldl);
  }

  /**
   * Removes the listener <code>oldl</code> from the listener <code>l</code>.
   *
   * @param l the listener chain to reduce
   * @param oldl the listener to remove
   * @return the resulting listener chain
   */
  public static KeyListener remove(KeyListener l, KeyListener oldl)
  {
    return (KeyListener) removeInternal(l, oldl);
  }

  /**
   * Removes the listener <code>oldl</code> from the listener <code>l</code>.
   *
   * @param l the listener chain to reduce
   * @param oldl the listener to remove
   * @return the resulting listener chain
   */
  public static MouseListener remove(MouseListener l, MouseListener oldl)
  {
    return (MouseListener) removeInternal(l, oldl);
  }

  /**
   * Removes the listener <code>oldl</code> from the listener <code>l</code>.
   *
   * @param l the listener chain to reduce
   * @param oldl the listener to remove
   * @return the resulting listener chain
   */
  public static MouseMotionListener remove(MouseMotionListener l,
                                           MouseMotionListener oldl)
  {
    return (MouseMotionListener) removeInternal(l, oldl);
  }

  /**
   * Removes the listener <code>oldl</code> from the listener <code>l</code>.
   *
   * @param l the listener chain to reduce
   * @param oldl the listener to remove
   * @return the resulting listener chain
   */
  public static WindowListener remove(WindowListener l, WindowListener oldl)
  {
    return (WindowListener) removeInternal(l, oldl);
  }

  /**
   * Removes the listener <code>oldl</code> from the listener <code>l</code>.
   *
   * @param l the listener chain to reduce
   * @param oldl the listener to remove
   * @return the resulting listener chain
   * @since 1.4
   */
  public static WindowStateListener remove(WindowStateListener l,
                                           WindowStateListener oldl)
  {
    return (WindowStateListener) removeInternal(l, oldl);
  }

  /**
   * Removes the listener <code>oldl</code> from the listener <code>l</code>.
   *
   * @param l the listener chain to reduce
   * @param oldl the listener to remove
   * @return the resulting listener chain
   * @since 1.4
   */
  public static WindowFocusListener remove(WindowFocusListener l,
                                           WindowFocusListener oldl)
  {
    return (WindowFocusListener) removeInternal(l, oldl);
  }

  /**
   * Removes the listener <code>oldl</code> from the listener <code>l</code>.
   *
   * @param l the listener chain to reduce
   * @param oldl the listener to remove
   * @return the resulting listener chain
   */
  public static ActionListener remove(ActionListener l, ActionListener oldl)
  {
    return (ActionListener) removeInternal(l, oldl);
  }

  /**
   * Removes the listener <code>oldl</code> from the listener <code>l</code>.
   *
   * @param l the listener chain to reduce
   * @param oldl the listener to remove
   * @return the resulting listener chain
   */
  public static ItemListener remove(ItemListener l, ItemListener oldl)
  {
    return (ItemListener) removeInternal(l, oldl);
  }

  /**
   * Removes the listener <code>oldl</code> from the listener <code>l</code>.
   *
   * @param l the listener chain to reduce
   * @param oldl the listener to remove
   * @return the resulting listener chain
   */
  public static AdjustmentListener remove(AdjustmentListener l,
                                          AdjustmentListener oldl)
  {
    return (AdjustmentListener) removeInternal(l, oldl);
  }

  /**
   * Removes the listener <code>oldl</code> from the listener <code>l</code>.
   *
   * @param l the listener chain to reduce
   * @param oldl the listener to remove
   * @return the resulting listener chain
   */
  public static TextListener remove(TextListener l, TextListener oldl)
  {
    return (TextListener) removeInternal(l, oldl);
  }

  /**
   * Removes the listener <code>oldl</code> from the listener <code>l</code>.
   *
   * @param l the listener chain to reduce
   * @param oldl the listener to remove
   * @return the resulting listener chain
   * @since 1.2
   */
  public static InputMethodListener remove(InputMethodListener l,
                                           InputMethodListener oldl)
  {
    return (InputMethodListener) removeInternal(l, oldl);
  }

  /**
   * Removes the listener <code>oldl</code> from the listener <code>l</code>.
   *
   * @param l the listener chain to reduce
   * @param oldl the listener to remove
   * @return the resulting listener chain
   * @since 1.3
   */
  public static HierarchyListener remove(HierarchyListener l,
                                         HierarchyListener oldl)
  {
    return (HierarchyListener) removeInternal(l, oldl);
  }

  /**
   * Removes the listener <code>oldl</code> from the listener <code>l</code>.
   *
   * @param l the listener chain to reduce
   * @param oldl the listener to remove
   * @return the resulting listener chain
   * @since 1.3
   */
  public static HierarchyBoundsListener remove(HierarchyBoundsListener l,
                                               HierarchyBoundsListener oldl)
  {
    return (HierarchyBoundsListener) removeInternal(l, oldl);
  }

  /**
   * Removes the listener <code>oldl</code> from the listener <code>l</code>.
   *
   * @param l the listener chain to reduce
   * @param oldl the listener to remove
   * @return the resulting listener chain
   * @since 1.4
   */
  public static MouseWheelListener remove(MouseWheelListener l,
                                          MouseWheelListener oldl)
  {
    return (MouseWheelListener) removeInternal(l, oldl);
  }

  /**
   * Chain <code>EventListener</code> a and b.
   *
   * @param a the "a" listener, may be null
   * @param b the "b" listener, may be null 
   * @return latest entry in the chain
   */
  protected static EventListener addInternal(EventListener a, EventListener b)
  {
    if (a == null)
      return b;
    if (b == null)
      return a;
    return new AWTEventMulticaster(a, b);
  }

  /**
   * Removes the listener <code>oldl</code> from the listener <code>l</code>.
   *
   * @param l the listener chain to reduce
   * @param oldl the listener to remove
   * @return the resulting listener chain
   */
  protected static EventListener removeInternal(EventListener l,
                                                EventListener oldl)
  {
    if (l == oldl)
      return null;
    if (l instanceof AWTEventMulticaster)
      return ((AWTEventMulticaster) l).remove(oldl);
    return l;
  }

  /**
   * Saves all Serializable listeners to a serialization stream.
   *
   * @param s the stream to save to
   * @param k a prefix stream put before each serializable listener
   * @throws IOException if serialization fails
   */
  protected void saveInternal(ObjectOutputStream s, String k)
    throws IOException
  {
    // This is not documented by Sun, but I think it is correct.
    if (a instanceof AWTEventMulticaster)
      ((AWTEventMulticaster) a).saveInternal(s, k);
    else if (a instanceof Serializable)
      {
        s.writeObject(k);
        s.writeObject(a);
      }
    if (b instanceof AWTEventMulticaster)
      ((AWTEventMulticaster) b).saveInternal(s, k);
    else if (b instanceof Serializable)
      {
        s.writeObject(k);
        s.writeObject(b);
      }
  }

  /**
   * Saves a Serializable listener chain to a serialization stream.
   *
   * @param s the stream to save to
   * @param k a prefix stream put before each serializable listener
   * @param l the listener chain to save
   * @throws IOException if serialization fails
   */
  protected static void save(ObjectOutputStream s, String k, EventListener l)
    throws IOException
  {
    // This is not documented by Sun, but I think it is correct.
    if (l instanceof AWTEventMulticaster)
      ((AWTEventMulticaster) l).saveInternal(s, k);
    else if (l instanceof Serializable)
      {
        s.writeObject(k);
        s.writeObject(l);
      }
  }

  /**
   * Returns an array of all chained listeners of the specified type in the
   * given chain. A null listener returns an empty array, and a listener
   * which is not an AWTEventMulticaster returns an array of one element. If
   * no listeners in the chain are of the specified type, an empty array is
   * returned.
   *
   * @param l the listener chain to convert to an array
   * @param type the type of listeners to collect
   * @return an array of the listeners of that type in the chain
   * @throws ClassCastException if type is not assignable from EventListener
   * @throws NullPointerException if type is null
   * @throws IllegalArgumentException if type is Void.TYPE
   * @since 1.4
   */
  public static EventListener[] getListeners(EventListener l, Class type)
  {
    ArrayList list = new ArrayList();
    if (l instanceof AWTEventMulticaster)
      ((AWTEventMulticaster) l).getListeners(list, type);
    else if (type.isInstance(l))
      list.add(l);
    EventListener[] r = (EventListener[]) Array.newInstance(type, list.size());
    list.toArray(r);
    return r;
  }

  /**
   * Collects all instances of the given type in the chain into the list.
   *
   * @param l the list to collect into
   * @param type the type of listeners to collect
   * @throws NullPointerException if type is null
   * @see #getListeners(EventListener, Class)
   */
  private void getListeners(ArrayList l, Class type)
  {
    if (a instanceof AWTEventMulticaster)
      ((AWTEventMulticaster) a).getListeners(l, type);
    else if (type.isInstance(a))
      l.add(a);
    if (b instanceof AWTEventMulticaster)
      ((AWTEventMulticaster) b).getListeners(l, type);
    else if (type.isInstance(b))
      l.add(b);
  }
} // class AWTEventMulticaster
