/* JTree.java 
   Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
 
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., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 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 javax.swing;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.FocusListener;
import java.beans.PropertyChangeListener;
import java.io.Serializable;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Locale;
import java.util.Vector;

import javax.accessibility.Accessible;
import javax.accessibility.AccessibleAction;
import javax.accessibility.AccessibleComponent;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.accessibility.AccessibleSelection;
import javax.accessibility.AccessibleState;
import javax.accessibility.AccessibleStateSet;
import javax.accessibility.AccessibleText;
import javax.accessibility.AccessibleValue;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeExpansionListener;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.event.TreeWillExpandListener;
import javax.swing.plaf.TreeUI;
import javax.swing.text.Position;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.DefaultTreeSelectionModel;
import javax.swing.tree.ExpandVetoException;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

public class JTree extends JComponent implements Scrollable, Accessible
{

  /**
   * This class implements accessibility support for the JTree class. It 
   * provides an implementation of the Java Accessibility API appropriate 
   * to tree user-interface elements.
   */
  protected class AccessibleJTree extends JComponent.AccessibleJComponent
      implements AccessibleSelection, TreeSelectionListener, TreeModelListener,
      TreeExpansionListener
  {
    
    /**
     * This class implements accessibility support for the JTree child. It provides 
     * an implementation of the Java Accessibility API appropriate to tree nodes.
     */
    protected class AccessibleJTreeNode extends AccessibleContext 
       implements Accessible, AccessibleComponent, AccessibleSelection, 
       AccessibleAction
    {
      
      private JTree tree;
      private TreePath tp;
      private Accessible acc;
      private AccessibleStateSet states;
      private Vector selectionList;
      private Vector actionList;
      private TreeModel mod;
      private Cursor cursor;
      
      /**
       * Constructs an AccessibleJTreeNode
       * 
       * @param t - the current tree
       * @param p - the current path to be dealt with
       * @param ap - the accessible object to use
       */
      public AccessibleJTreeNode(JTree t, TreePath p, Accessible ap)
      {
        states = new AccessibleStateSet();
        selectionList = new Vector();
        actionList = new Vector();
        mod = tree.getModel();
        cursor = JTree.this.getCursor();
                
        tree = t;
        tp = p;
        acc = ap;
        
        // Add all the children of this path that may already be
        // selected to the selection list.
        TreePath[] selected = tree.getSelectionPaths();
        for (int i = 0; i < selected.length; i++)
          {
            TreePath sel = selected[i];
            if ((sel.getParentPath()).equals(tp))
              selectionList.add(sel);
          }
        
        // Add all the actions available for a node to 
        // the action list.
        actionList.add("EXPAND");
        actionList.add("COLLAPSE");
        actionList.add("EDIT");
        actionList.add("SELECT");
        actionList.add("DESELECT");
      }      
      
      /**
       * Adds the specified selected item in the object to the object's
       * selection.
       * 
       * @param i - the i-th child of this node.
       */
      public void addAccessibleSelection(int i)
      {
        if (mod != null)
          {
            Object child = mod.getChild(tp.getLastPathComponent(), i);
            if (child != null)
              {
                if (!states.contains(AccessibleState.MULTISELECTABLE))
                  clearAccessibleSelection();
                selectionList.add(child);                  
                tree.addSelectionPath(tp.pathByAddingChild(child));
              }
          }
      }
      
      /**
       * Adds the specified focus listener to receive focus events 
       * from this component.
       * 
       * @param l - the new focus listener
       */
      public void addFocusListener(FocusListener l)
      {
        tree.addFocusListener(l);
      }
      
      /**
       * Add a PropertyChangeListener to the listener list.
       * 
       * @param l - the new property change listener
       */
      public void addPropertyChangeListener(PropertyChangeListener l)
      {
        // Nothing to do here.
      }
      
      /**
       * Clears the selection in the object, so that nothing in the 
       * object is selected.
       */
      public void clearAccessibleSelection()
      {
        selectionList.clear();
      }
      
      /**
       * Checks whether the specified point is within this object's 
       * bounds, where the point's x and y coordinates are defined to be 
       * relative to the coordinate system of the object. 
       * 
       * @param p - the point to check
       * @return true if p is in the bounds
       */
      public boolean contains(Point p)
      {
        return getBounds().contains(p);
      }
      
      /**
       * Perform the specified Action on the tree node.
       * 
       * @param i - the i-th action to perform
       * @return true if the the action was performed; else false.
       */
      public boolean doAccessibleAction(int i)
      {
        if (i >= actionList.size() || i < 0)
          return false;
        
        if (actionList.get(i).equals("EXPAND"))
          tree.expandPath(tp);
        else if (actionList.get(i).equals("COLLAPSE"))
          tree.collapsePath(tp);
        else if (actionList.get(i).equals("SELECT"))
          tree.addSelectionPath(tp);
        else if (actionList.get(i).equals("DESELECT"))
          tree.removeSelectionPath(tp);
        else if (actionList.get(i).equals("EDIT"))
          tree.startEditingAtPath(tp);
        else
          return false;
        return true;
      }
      
      /**
       * Get the AccessibleAction associated with this object.
       * 
       * @return the action
       */
      public AccessibleAction getAccessibleAction()
      {
        return this;
      }
      
      /**
       * Returns the number of accessible actions available in this tree node.
       * 
       * @return the number of actions
       */
      public int getAccessibleActionCount()
      {
        return actionList.size();
      }
      
      /**
       * Return a description of the specified action of the tree node.
       * 
       * @param i - the i-th action's description
       * @return a description of the action
       */
      public String getAccessibleActionDescription(int i)
      {
        if (i < 0 || i >= actionList.size())
          return (actionList.get(i)).toString();
        return super.getAccessibleDescription();
      }
      
      /**
       * Returns the Accessible child, if one exists, contained at the 
       * local coordinate Point.
       * 
       * @param p - the point of the accessible
       * @return the accessible at point p if it exists
       */
      public Accessible getAccessibleAt(Point p)
      {
        TreePath acc = tree.getClosestPathForLocation(p.x, p.y);
        if (acc != null)
          return new AccessibleJTreeNode(tree, acc, this);
        return null;
      }
      
      /**
       * Return the specified Accessible child of the object.
       * 
       * @param i - the i-th child of the current path
       * @return the child if it exists
       */
      public Accessible getAccessibleChild(int i)
      {
        if (mod != null)
          {
            Object child = mod.getChild(tp.getLastPathComponent(), i);
            if (child != null)
              return new AccessibleJTreeNode(tree, tp.pathByAddingChild(child),
                                             acc);
          }
        return null;
      }
      
      /**
       * Returns the number of accessible children in the object.
       * 
       * @return the number of children the current node has
       */
      public int getAccessibleChildrenCount()
      {
        TreeModel mod = getModel();
        if (mod != null)
          return mod.getChildCount(tp.getLastPathComponent());
        return 0;
      }
      
      /**
       * Get the AccessibleComponent associated with this object.
       * 
       * @return the accessible component if it is supported.
       */
      public AccessibleComponent getAccessibleComponent()
      {
        return this;
      }
      
      /**
       * Get the AccessibleContext associated with this tree node.
       * 
       * @return an instance of this class
       */
      public AccessibleContext getAccessibleContext()
      {
        return this;
      }
      
      /**
       * Get the accessible description of this object.
       * 
       * @return the accessible description
       */
      public String getAccessibleDescription()
      {
        return super.getAccessibleDescription();
      }
      
      /**
       * Get the index of this object in its accessible parent.
       * 
       * @return the index of this in the parent.
       */
      public int getAccessibleIndexInParent()
      {
        AccessibleContext parent = getAccessibleParent().getAccessibleContext();
        if (parent != null)
          for (int i = 0; i < parent.getAccessibleChildrenCount(); i++)
            {
              if ((parent.getAccessibleChild(i)).equals(this))
                return i;
            }
        return -1;
      }
      
      /**
       * Get the accessible name of this object.
       * 
       * @return the accessible name
       */
      public String getAccessibleName()
      {
        return super.getAccessibleName();
      }
      
      /**
       * Get the Accessible parent of this object.
       * 
       * @return the accessible parent if it exists.
       */
      public Accessible getAccessibleParent()
      {
        return super.getAccessibleParent();
      }
      
      /**
       * Get the role of this object.
       * 
       * @return the accessible role
       */
      public AccessibleRole getAccessibleRole()
      {
        return AccessibleJTree.this.getAccessibleRole();
      }
      
      /**
       * Get the AccessibleSelection associated with this object if one exists.
       * 
       * @return the accessible selection for this.
       */
      public AccessibleSelection getAccessibleSelection()
      {
        return this;
      }
      
      /**
       * Returns an Accessible representing the specified selected item 
       * in the object.
       * 
       * @return the accessible representing a certain selected item.
       */
      public Accessible getAccessibleSelection(int i)
      {
        if (i > 0 && i < getAccessibleSelectionCount())
            return new AccessibleJTreeNode(tree, 
                  tp.pathByAddingChild(selectionList.get(i)), acc);
        return null;
      }
      
      /**
       * Returns the number of items currently selected.
       * 
       * @return the number of items selected.
       */
      public int getAccessibleSelectionCount()
      {
        return selectionList.size();
      }
      
      /**
       * Get the state set of this object.
       * 
       * @return the state set for this object
       */
      public AccessibleStateSet getAccessibleStateSet()
      {
        if (isVisible())
          states.add(AccessibleState.VISIBLE);
        if (tree.isCollapsed(tp))
          states.add(AccessibleState.COLLAPSED);
        if (tree.isEditable())
          states.add(AccessibleState.EDITABLE);
        if (mod != null && 
            !mod.isLeaf(tp.getLastPathComponent()))
          states.add(AccessibleState.EXPANDABLE);
        if (tree.isExpanded(tp))
          states.add(AccessibleState.EXPANDED);
        if (isFocusable())
          states.add(AccessibleState.FOCUSABLE);
        if (hasFocus())
          states.add(AccessibleState.FOCUSED);
        if (tree.getSelectionModel().getSelectionMode() != 
          TreeSelectionModel.SINGLE_TREE_SELECTION)
          states.add(AccessibleState.MULTISELECTABLE);
        if (tree.isOpaque())
          states.add(AccessibleState.OPAQUE);
        if (tree.isPathSelected(tp))
          states.add(AccessibleState.SELECTED);
        if (isShowing())
          states.add(AccessibleState.SHOWING);

        states.add(AccessibleState.SELECTABLE);
        return states;
      }
      
      /**
       * Get the AccessibleText associated with this object if one exists.
       * 
       * @return the accessible text
       */
      public AccessibleText getAccessibleText()
      {
        return super.getAccessibleText();
      }
      
      /**
       * Get the AccessibleValue associated with this object if one exists.
       * 
       * @return the accessible value if it exists
       */
      public AccessibleValue getAccessibleValue()
      {
        return super.getAccessibleValue();
      }
      
      /**
       * Get the background color of this object.
       * 
       * @return the color of the background.
       */
      public Color getBackground()
      {
        return tree.getBackground();
      }
      
      /**
       * Gets the bounds of this object in the form of a Rectangle object.
       * 
       * @return the bounds of the current node.
       */
      public Rectangle getBounds()
      {
        return tree.getPathBounds(tp);
      }
      
      /**
       * Gets the Cursor of this object.
       * 
       * @return the cursor for the current node
       */
      public Cursor getCursor()
      {
        return cursor;
      }
      
      /**
       * Gets the Font of this object.
       * 
       * @return the font for the current node
       */
      public Font getFont()
      {
        return tree.getFont();
      }
      
      /**
       * Gets the FontMetrics of this object.
       * 
       * @param f - the current font.
       * @return the font metrics for the given font.
       */
      public FontMetrics getFontMetrics(Font f)
      {
        return tree.getFontMetrics(f);
      }
      
      /**
       * Get the foreground color of this object.
       * 
       * @return the foreground for this object.
       */
      public Color getForeground()
      {
        return tree.getForeground();
      }
      
      /**
       * Gets the locale of the component.
       * 
       * @return the locale of the component.
       */
      public Locale getLocale()
      {
        return tree.getLocale();
      }
      
      /**
       * Gets the location of the object relative to the 
       * parent in the form of a point specifying the object's 
       * top-left corner in the screen's coordinate space. 
       * 
       * @return the location of the current node.
       */
      public Point getLocation()
      {
        return getLocationInJTree();
      }
      
      /**
       * Returns the location in the tree.
       * 
       * @return the location in the JTree.
       */
      protected Point getLocationInJTree()
      {
        Rectangle bounds = tree.getPathBounds(tp);
        return new Point(bounds.x, bounds.y);
      }
      
      /**
       * Returns the location of the object on the screen.
       * 
       * @return the location of the object on the screen.
       */
      public Point getLocationOnScreen()
      {
        Point loc = getLocation();
        SwingUtilities.convertPointToScreen(loc, tree);
        return loc;
      }
      
      /**
       * Returns the size of this object in the form of a Dimension object.
       * 
       * @return the size of the object
       */
      public Dimension getSize()
      {
        Rectangle b = getBounds();
        return b.getSize();
      }
      
      /**
       * Returns true if the current child of this object is selected.
       * 
       * @param i - the child of the current node
       * @return true if the child is selected.
       */
      public boolean isAccessibleChildSelected(int i)
      {
        Object child = mod.getChild(tp.getLastPathComponent(), i);
        if (child != null)
          return tree.isPathSelected(tp.pathByAddingChild(child));
        return false;
      }
      
      /**
       * Determines if the object is enabled.
       * 
       * @return true if the tree is enabled
       */
      public boolean isEnabled()
      {
        return tree.isEnabled();
      }
      
      /**
       * Returns whether this object can accept focus or not.
       * 
       * @return true, it is always focus traversable
       */
      public boolean isFocusTraversable()
      {
        return true;
      }
      
      /**
       * Determines if the object is showing.
       * 
       * @return true if the object is visible and the
       * parent is visible.
       */
      public boolean isShowing()
      {
        return isVisible() && tree.isShowing();
      }
      
      /**
       * Determines if the object is visible.
       * 
       * @return true if the object is visible.
       */
      public boolean isVisible()
      {
        return tree.isVisible(tp);
      }
      
      /**
       * Removes the specified selected item in the object from the
       * object's selection.
       * 
       * @param i - the specified item to remove
       */
      public void removeAccessibleSelection(int i)
      {
        if (mod != null)
          {
            Object child = mod.getChild(tp.getLastPathComponent(), i);
            if (child != null)
              {
                if (!states.contains(AccessibleState.MULTISELECTABLE))
                  clearAccessibleSelection();
                if (selectionList.contains(child))
                  {
                    selectionList.remove(child);                  
                    tree.removeSelectionPath(tp.pathByAddingChild(child));
                  }
              }
          }
      }
      
      /**
       * Removes the specified focus listener so it no longer receives focus 
       * events from this component.
       * 
       * @param l - the focus listener to remove
       */
      public void removeFocusListener(FocusListener l)
      {
        tree.removeFocusListener(l);
      }
      
      /**
       * Remove a PropertyChangeListener from the listener list.
       * 
       * @param l - the property change listener to remove.
       */
      public void removePropertyChangeListener(PropertyChangeListener l)
      {
        // Nothing to do here.
      }
      
      /**
       * Requests focus for this object.
       */
      public void requestFocus()
      {
        tree.requestFocus();
      }
      
      /**
       * Causes every selected item in the object to be selected if the object 
       * supports multiple selections.
       */
      public void selectAllAccessibleSelection()
      {
        Object parent = tp.getLastPathComponent();
        if (mod != null)
          {
            for (int i = 0; i < mod.getChildCount(parent); i++)
              {
                Object child = mod.getChild(parent, i);
                if (child != null)
                  {
                    if (!states.contains(AccessibleState.MULTISELECTABLE))
                      clearAccessibleSelection();
                    if (selectionList.contains(child))
                      {
                        selectionList.add(child);
                        tree.addSelectionPath(tp.pathByAddingChild(child));
                      }
                  }
              }
          }
      }
      
      /**
       * Set the accessible description of this object.
       * 
       * @param s - the string to set the accessible description to.
       */
      public void setAccessibleDescription(String s)
      {
        super.setAccessibleDescription(s);
      }
      
      /**
       * Set the localized accessible name of this object.
       * 
       * @param s - the string to set the accessible name to.
       */
      public void setAccessibleName(String s)
      {
        super.setAccessibleName(s);
      }
      
      /**
       * Set the background color of this object.
       * 
       * @param c - the color to set the background to.
       */
      public void setBackground(Color c)
      {
        // Nothing to do here.
      }
      
      /**
       * Sets the bounds of this object in the form of a Rectangle object.
       * 
       * @param r - the bounds to set the object o
       */
      public void setBounds(Rectangle r)
      {
        // Nothing to do here.
      }
      
      /**
       * Sets the Cursor of this object.
       * 
       * @param c - the new cursor
       */
      public void setCursor(Cursor c)
      {
        cursor = c;
      }
      
      /**
       * Sets the enabled state of the object.
       * 
       * @param b - boolean to enable or disable object
       */
      public void setEnabled(boolean b)
      {
         // Nothing to do here.
      }
      
      /**
       * Sets the Font of this object.
       * 
       * @param f - the new font.
       */
      public void setFont(Font f)
      {
         // Nothing to do here.
      }
      
      /**
       * Sets the foreground color of this object.
       * 
       * @param c - the new foreground color.
       */
      public void setForeground(Color c)
      {
        // Nothing to do here.
      }
      
      /**
       * Sets the location of the object relative to the parent.
       * 
       * @param p - the new location for the object.
       */
      public void setLocation(Point p)
      {
        // Nothing to do here.
      }
      
      /**
       * Resizes this object so that it has width and height.
       * 
       * @param d - the new size for the object.
       */
      public void setSize(Dimension d)
      {
        // Nothing to do here.
      }
      
      /**
       * Sets the visible state of the object.
       * 
       * @param b - sets the objects visibility.
       */
      public void setVisible(boolean b)
      {
        // Nothing to do here.
      }
    }
    
    /**
     * Constructor
     */
    public AccessibleJTree()
    {
      // Nothing to do here.
    }
    
    /**
     * Adds the specified selected item in the object to the object's selection.
     * 
     * @param i - the row to add to the tree's selection
     */
    public void addAccessibleSelection(int i)
    {
      addSelectionInterval(i, i);
    }
    
    /**
     * Clears the selection in the object, so that nothing in the object is selected.
     */
    public void clearAccessibleSelection()
    {
      clearSelection();
    }
    
    /**
     * Fire a visible data property change notification.
     */
    public void fireVisibleDataPropertyChange()
    {
      treeDidChange();
    }
    
    /**
     * Returns the Accessible child, if one exists, contained at the local 
     * coordinate Point.
     * 
     * @param p - the point of the accessible to get.
     * @return the accessible at point p.
     */
    public Accessible getAccessibleAt(Point p)
    {
      TreePath tp = getClosestPathForLocation(p.x, p.y);
      if (tp != null)
        return new AccessibleJTreeNode(JTree.this, tp, null);
      return null;
    }
    
    /**
     * Return the nth Accessible child of the object.
     * 
     * @param i - the accessible child to get
     * @return the i-th child
     */
    public Accessible getAccessibleChild(int i)
    {
      return null;
    }
    
    /**
     * Returns the number of top-level children nodes of this JTree.
     * 
     * @return the number of top-level children
     */
    public int getAccessibleChildrenCount()
    {
      TreeModel model = getModel();
      if (model != null)
        return model.getChildCount(model.getRoot());
      return 0;
    }
    
    /**
     * Get the index of this object in its accessible parent.
     * 
     * @return the index of this object.
     */
    public int getAccessibleIndexInParent()
    {
      return 0;
    }
    
    /**
     * Get the role of this object.
     * 
     * @return the role of this object
     */
    public AccessibleRole getAccessibleRole()
    {
      return AccessibleRole.TREE;
    }
    
    /**
     * Get the AccessibleSelection associated with this object.
     * 
     * @return the accessible selection of the tree
     */
    public AccessibleSelection getAccessibleSelection()
    {
      TreeModel mod = getModel();
      if (mod != null)
        return (new AccessibleJTreeNode(JTree.this, 
                  new TreePath(mod.getRoot()), null)).getAccessibleSelection();
      return null;
    }
    
    /**
     * Returns an Accessible representing the specified selected item in the object.
     * 
     * @return the i-th accessible in the selection
     */
    public Accessible getAccessibleSelection(int i)
    {
      TreeModel mod = getModel();
      if (mod != null)
        return (new AccessibleJTreeNode(JTree.this, 
                  new TreePath(mod.getRoot()), null)).getAccessibleSelection(i);
      return null;
    }
    
    /**
     * Returns the number of items currently selected.
     * 
     * @return the number of selected accessibles.
     */
    public int getAccessibleSelectionCount()
    {
      return getSelectionCount();
    }
    
    /**
     * Returns true if the current child of this object is selected.
     * 
     * @param i - the child of this object
     * @return true if the i-th child is selected.
     */
    public boolean isAccessibleChildSelected(int i)
    {
      // Nothing to do here.
      return false;
    }
    
    /**
     * Removes the specified selected item in the object from the object's
     * selection.
     * 
     * @param i - the i-th selected item to remove
     */
    public void removeAccessibleSelection(int i)
    {
      removeSelectionInterval(i, i);
    }
    
    /**
     * Causes every selected item in the object to be selected if the object
     * supports multiple selections.
     */
    public void selectAllAccessibleSelection()
    {
      if (getSelectionModel().getSelectionMode() != 
        TreeSelectionModel.SINGLE_TREE_SELECTION)
      addSelectionInterval(0, getVisibleRowCount());
    }
    
    /**
     * Tree Collapsed notification
     * 
     * @param e - the event
     */
    public void treeCollapsed(TreeExpansionEvent e)
    {
      fireTreeCollapsed(e.getPath());
    }
   
    /**
     * Tree Model Expansion notification.
     * 
     * @param e - the event
     */
    public void treeExpanded(TreeExpansionEvent e)
    {
      fireTreeExpanded(e.getPath());
    }
    
    /**
     * Tree Model Node change notification.
     * 
     * @param e - the event
     */
    public void treeNodesChanged(TreeModelEvent e)
    {
      // Nothing to do here.
    }
    
    /**
     * Tree Model Node change notification.
     * 
     * @param e - the event
     */
    public void treeNodesInserted(TreeModelEvent e)
    {
      // Nothing to do here.
    }
    
    /**
     * Tree Model Node change notification.
     * 
     * @param e - the event
     */
    public void treeNodesRemoved(TreeModelEvent e)
    {
      // Nothing to do here.
    }
    
    /**
     * Tree Model structure change change notification.
     * 
     * @param e - the event
     */
    public void treeStructureChanged(TreeModelEvent e)
    {
      // Nothing to do here.
    }
    
    /**
     * Tree Selection Listener value change method.
     * 
     * @param e - the event
     */
    public void valueChanged(TreeSelectionEvent e)
    {
      fireValueChanged(e);
    }
  }
  
  public static class DynamicUtilTreeNode extends DefaultMutableTreeNode
  {
    protected Object childValue;

    protected boolean loadedChildren;

    /**
     * Currently not set or used by this class. It might be set and used in
     * later versions of this class.
     */
    protected boolean hasChildren;

    public DynamicUtilTreeNode(Object value, Object children)
    {
      super(value);
      childValue = children;
      loadedChildren = false;
    }

    public int getChildCount()
    {
      loadChildren();
      return super.getChildCount();
    }

    protected void loadChildren()
    {
      if (!loadedChildren)
        {
          createChildren(this, childValue);
          loadedChildren = true;
        }
    }

    public Enumeration children()
    {
      loadChildren();
      return super.children();
    }

    /**
     * Returns the child node at position <code>pos</code>. Subclassed
     * here to load the children if necessary.
     * 
     * @param pos the position of the child node to fetch
     * 
     * @return the childnode at the specified position
     */
    public TreeNode getChildAt(int pos)
    {
      loadChildren();
      return super.getChildAt(pos);
    }

    public boolean isLeaf()
    {
      return childValue == null || !(childValue instanceof Hashtable
          || childValue instanceof Vector 
          || childValue.getClass().isArray());
    }

    public static void createChildren(DefaultMutableTreeNode parent,
                                      Object children)
    {
      if (children instanceof Hashtable)
        {
          Hashtable tab = (Hashtable) children;
          Enumeration e = tab.keys();
          while (e.hasMoreElements())
            {
              Object key = e.nextElement();
              Object val = tab.get(key);
              parent.add(new DynamicUtilTreeNode(key, val));
            }
        }
      else if (children instanceof Vector)
        {
          Iterator i = ((Vector) children).iterator();
          while (i.hasNext())
            {
              Object n = i.next();
              parent.add(new DynamicUtilTreeNode(n, n));
            }
        }
      else if (children != null && children.getClass().isArray())
        {
          Object[] arr = (Object[]) children;
          for (int i = 0; i < arr.length; ++i)
            parent.add(new DynamicUtilTreeNode(arr[i], arr[i]));
        }
    }
  }

  /**
   * Listens to the model of the JTree and updates the property 
   * <code>expandedState</code> if nodes are removed or changed.
   */
  protected class TreeModelHandler implements TreeModelListener
  {

    /**
     * Creates a new instance of TreeModelHandler.
     */
    protected TreeModelHandler()
    {
      // Nothing to do here.
    }

    /**
     * Notifies when a node has changed in some ways. This does not include
     * that a node has changed its location or changed it's children. It
     * only means that some attributes of the node have changed that might
     * affect its presentation.
     * 
     * This method is called after the actual change occured.
     * 
     * @param ev the TreeModelEvent describing the change
     */
    public void treeNodesChanged(TreeModelEvent ev)
    {
      // Nothing to do here.
    }

    /**
     * Notifies when a node is inserted into the tree.
     * 
     * This method is called after the actual change occured.
     * 
     * @param ev the TreeModelEvent describing the change
     */
    public void treeNodesInserted(TreeModelEvent ev)
    {
      // nothing to do here
    }

    /**
     * Notifies when a node is removed from the tree.
     * 
     * This method is called after the actual change occured.
     *
     * @param ev the TreeModelEvent describing the change
	 */
    public void treeNodesRemoved(TreeModelEvent ev)
    {
      // TODO: The API docs suggest that this method should do something
      // but I cannot really see what has to be done here ...
    }

    /**
     * Notifies when the structure of the tree is changed.
     * 
     * This method is called after the actual change occured.
     * 
     * @param ev the TreeModelEvent describing the change
     */
    public void treeStructureChanged(TreeModelEvent ev)
    {
      // Set state of new path.
      TreePath path = ev.getTreePath();
      setExpandedState(path, isExpanded(path));
    }
  }

  /**
   * This redirects TreeSelectionEvents and rewrites the source of it to be
   * this JTree. This is typically done when the tree model generates an
   * event, but the JTree object associated with that model should be listed
   * as the actual source of the event.
   */
  protected class TreeSelectionRedirector implements TreeSelectionListener,
                                                     Serializable
  {
    /** The serial version UID. */
    private static final long serialVersionUID = -3505069663646241664L;

    /**
     * Creates a new instance of TreeSelectionRedirector
     */
    protected TreeSelectionRedirector()
    {
      // Nothing to do here.
    }

    /**
     * Notifies when the tree selection changes.
     * 
     * @param ev the TreeSelectionEvent that describes the change
     */
    public void valueChanged(TreeSelectionEvent ev)
    {
      TreeSelectionEvent rewritten = 
        (TreeSelectionEvent) ev.cloneWithSource(JTree.this);
      fireValueChanged(rewritten);

      // Only repaint the changed nodes.
      TreePath[] changed = ev.getPaths();
      for (int i = 0; i < changed.length; i++)
        {
          repaint(getPathBounds(changed[i]));
        }
    }
  }

  /**
   * A TreeModel that does not allow anything to be selected.
   */
  protected static class EmptySelectionModel extends DefaultTreeSelectionModel
  {
    /** The serial version UID. */
    private static final long serialVersionUID = -5815023306225701477L;

    /**
     * The shared instance of this model.
     */
    protected static final EmptySelectionModel sharedInstance =
      new EmptySelectionModel();

    /**
     * Creates a new instance of EmptySelectionModel.
     */
    protected EmptySelectionModel()
    {
      // Nothing to do here.
    }

    /**
     * Returns the shared instance of EmptySelectionModel.
     * 
     * @return the shared instance of EmptySelectionModel
     */
    public static EmptySelectionModel sharedInstance()
    {
      return sharedInstance;
    }

    /**
     * This catches attempts to set a selection and sets nothing instead.
     * 
     * @param paths not used here
     */
    public void setSelectionPaths(TreePath[] paths)
    {
      // We don't allow selections in this class.
    }

    /**
     * This catches attempts to add something to the selection.
     * 
     * @param paths not used here
     */
    public void addSelectionPaths(TreePath[] paths)
    {
      // We don't allow selections in this class.
    }

    /**
     * This catches attempts to remove something from the selection.
     * 
     * @param paths not used here
     */
    public void removeSelectionPaths(TreePath[] paths)
    {
      // We don't allow selections in this class.
    }
  }

  private static final long serialVersionUID = 7559816092864483649L;

  public static final String CELL_EDITOR_PROPERTY = "cellEditor";

  public static final String CELL_RENDERER_PROPERTY = "cellRenderer";

  public static final String EDITABLE_PROPERTY = "editable";

  public static final String INVOKES_STOP_CELL_EDITING_PROPERTY =
    "invokesStopCellEditing";

  public static final String LARGE_MODEL_PROPERTY = "largeModel";

  public static final String ROOT_VISIBLE_PROPERTY = "rootVisible";

  public static final String ROW_HEIGHT_PROPERTY = "rowHeight";

  public static final String SCROLLS_ON_EXPAND_PROPERTY = "scrollsOnExpand";

  public static final String SELECTION_MODEL_PROPERTY = "selectionModel";

  public static final String SHOWS_ROOT_HANDLES_PROPERTY = "showsRootHandles";

  public static final String TOGGLE_CLICK_COUNT_PROPERTY = "toggleClickCount";

  public static final String TREE_MODEL_PROPERTY = "model";

  public static final String VISIBLE_ROW_COUNT_PROPERTY = "visibleRowCount";

  /** @since 1.3 */
  public static final String ANCHOR_SELECTION_PATH_PROPERTY =
    "anchorSelectionPath";

	/** @since 1.3 */
  public static final String LEAD_SELECTION_PATH_PROPERTY = "leadSelectionPath";

  /** @since 1.3 */
  public static final String EXPANDS_SELECTED_PATHS_PROPERTY =
    "expandsSelectedPaths";

  private static final Object EXPANDED = Boolean.TRUE;

  private static final Object COLLAPSED = Boolean.FALSE;

  private boolean dragEnabled;

  private boolean expandsSelectedPaths;

  private TreePath anchorSelectionPath;

  /**
   * This contains the state of all nodes in the tree. Al/ entries map the
   * TreePath of a note to to its state. Valid states are EXPANDED and
   * COLLAPSED. Nodes not in this Hashtable are assumed state COLLAPSED.
   */
  private Hashtable nodeStates = new Hashtable();

  protected transient TreeCellEditor cellEditor;

  protected transient TreeCellRenderer cellRenderer;

  protected boolean editable;

  protected boolean invokesStopCellEditing;

  protected boolean largeModel;

  protected boolean rootVisible;

  protected int rowHeight;

  protected boolean scrollsOnExpand;

  protected transient TreeSelectionModel selectionModel;

  protected boolean showsRootHandles;

  protected int toggleClickCount;

  protected transient TreeModel treeModel;

  protected int visibleRowCount;

  /**
   * Handles TreeModelEvents to update the expandedState.
   */
  protected transient TreeModelListener treeModelListener;

  /**
   * Redirects TreeSelectionEvents so that the source is this JTree.
   */
  protected TreeSelectionRedirector selectionRedirector =
    new TreeSelectionRedirector();

  /**
   * Indicates if the rowHeight property has been set by a client
   * program or by the UI.
   *
   * @see #setUIProperty(String, Object)
   * @see LookAndFeel#installProperty(JComponent, String, Object)
   */
  private boolean clientRowHeightSet = false;

  /**
   * Indicates if the scrollsOnExpand property has been set by a client
   * program or by the UI.
   *
   * @see #setUIProperty(String, Object)
   * @see LookAndFeel#installProperty(JComponent, String, Object)
   */
  private boolean clientScrollsOnExpandSet = false;

  /**
   * Indicates if the showsRootHandles property has been set by a client
   * program or by the UI.
   *
   * @see #setUIProperty(String, Object)
   * @see LookAndFeel#installProperty(JComponent, String, Object)
   */
  private boolean clientShowsRootHandlesSet = false;

  /**
   * Creates a new <code>JTree</code> object.
   */
  public JTree()
  {
    this(getDefaultTreeModel());
  }

  /**
   * Creates a new <code>JTree</code> object.
   * 
   * @param value the initial nodes in the tree
   */
  public JTree(Hashtable value)
  {
    this(createTreeModel(value));
  }

  /**
   * Creates a new <code>JTree</code> object.
   * 
   * @param value the initial nodes in the tree
   */
  public JTree(Object[] value)
  {
    this(createTreeModel(value));
  }

  /**
   * Creates a new <code>JTree</code> object.
   * 
   * @param model the model to use
   */
  public JTree(TreeModel model)
  {
    setRootVisible(true);
    setSelectionModel(new EmptySelectionModel());
    selectionModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
    
    // The root node appears expanded by default.
    nodeStates = new Hashtable();

    // The cell renderer gets set by the UI.
    cellRenderer = null;

    // Install the UI before installing the model. This way we avoid double
    // initialization of lots of UI and model stuff inside the UI and related
    // classes. The necessary UI updates are performed via property change
    // events to the UI.
    updateUI();
    setModel(model);
  }

  /**
   * Creates a new <code>JTree</code> object.
   * 
   * @param root the root node
   */
  public JTree(TreeNode root)
  {
    this(root, false);
  }

  /**
   * Creates a new <code>JTree</code> object.
   * 
   * @param root the root node
   * @param asksAllowChildren if false, all nodes without children are leaf
   *        nodes. If true, only nodes that do not allow children are leaf
   *        nodes.
   */
  public JTree(TreeNode root, boolean asksAllowChildren)
  {
    this(new DefaultTreeModel(root, asksAllowChildren));
  }

  /**
   * Creates a new <code>JTree</code> object.
   * 
   * @param value the initial nodes in the tree
   */
  public JTree(Vector value)
  {
    this(createTreeModel(value));
  }

  public int getRowForPath(TreePath path)
  {
    TreeUI ui = getUI();

    if (ui != null)
      return ui.getRowForPath(this, path);

    return -1;
  }

  public TreePath getPathForRow(int row)
  {
    TreeUI ui = getUI();
    return ui != null ? ui.getPathForRow(this, row) : null;
  }
  
  /**
   * Get the pathes that are displayes between the two given rows.
   * 
   * @param index0 the starting row, inclusive
   * @param index1 the ending row, inclusive
   * 
   * @return the array of the tree pathes
   */
  protected TreePath[] getPathBetweenRows(int index0, int index1)
  {
    TreeUI ui = getUI();

    if (ui == null)
      return null;

    int minIndex = Math.min(index0, index1);
    int maxIndex = Math.max(index0, index1);
    TreePath[] paths = new TreePath[maxIndex - minIndex + 1];

    for (int i = minIndex; i <= maxIndex; ++i)
      paths[i - minIndex] = ui.getPathForRow(this, i);

    return paths;
  }

  /**
   * Creates a new <code>TreeModel</code> object.
   * 
   * @param value the values stored in the model
   */
  protected static TreeModel createTreeModel(Object value)
  {
    return new DefaultTreeModel(new DynamicUtilTreeNode(value, value));
  }

  /**
   * Return the UI associated with this <code>JTree</code> object.
   * 
   * @return the associated <code>TreeUI</code> object
   */
  public TreeUI getUI()
  {
    return (TreeUI) ui;
  }

  /**
   * Sets the UI associated with this <code>JTree</code> object.
   * 
   * @param ui the <code>TreeUI</code> to associate
   */
  public void setUI(TreeUI ui)
  {
    super.setUI(ui);
  }

  /**
   * This method resets the UI used to the Look and Feel defaults..
   */
  public void updateUI()
  {
    setUI((TreeUI) UIManager.getUI(this));
  }

  /**
   * This method returns the String ID of the UI class of Separator.
   * 
   * @return The UI class' String ID.
   */
  public String getUIClassID()
  {
    return "TreeUI";
  }

  /**
   * Gets the AccessibleContext associated with this
   * <code>JTree</code>.
   * 
   * @return the associated context
   */
  public AccessibleContext getAccessibleContext()
  {
    return new AccessibleJTree();
  }

  /**
   * Returns the preferred viewport size.
   * 
   * @return the preferred size
   */
  public Dimension getPreferredScrollableViewportSize()
  {
    return getPreferredSize();
  }
  
  /**
   * Return the preferred scrolling amount (in pixels) for the given scrolling
   * direction and orientation. This method handles a partially exposed row by
   * returning the distance required to completely expose the item.
   * 
   * @param visibleRect the currently visible part of the component.
   * @param orientation the scrolling orientation
   * @param direction the scrolling direction (negative - up, positive -down).
   *          The values greater than one means that more mouse wheel or similar
   *          events were generated, and hence it is better to scroll the longer
   *          distance.
   * @author Audrius Meskauskas (audriusa@bioinformatics.org)
   */
  public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation,
                                        int direction)
  {
    int delta;

    // Round so that the top would start from the row boundary
    if (orientation == SwingConstants.VERTICAL)
      {
        // One pixel down, otherwise picks another row too high.
        int row = getClosestRowForLocation(visibleRect.x, visibleRect.y + 1);
        row = row + direction;
        if (row < 0)
          row = 0;

        Rectangle newTop = getRowBounds(row);
        delta = newTop.y - visibleRect.y;
      }
    else
      delta = direction * rowHeight == 0 ? 20 : rowHeight;
    return delta;
  }

  public int getScrollableBlockIncrement(Rectangle visibleRect,
                                         int orientation, int direction)
  {
    return getScrollableUnitIncrement(visibleRect, orientation, direction);
  }

  public boolean getScrollableTracksViewportHeight()
  {
    if (getParent() instanceof JViewport)
      return ((JViewport) getParent()).getHeight() > getPreferredSize().height;
    return false;
  }

  public boolean getScrollableTracksViewportWidth()
  {
    if (getParent() instanceof JViewport)
      return ((JViewport) getParent()).getWidth() > getPreferredSize().width;
    return false;
  }

  /**
   * Adds a <code>TreeExpansionListener</code> object to the tree.
   * 
   * @param listener the listener to add
   */
  public void addTreeExpansionListener(TreeExpansionListener listener)
  {
    listenerList.add(TreeExpansionListener.class, listener);
  }

  /**
   * Removes a <code>TreeExpansionListener</code> object from the tree.
   * 
   * @param listener the listener to remove
   */
  public void removeTreeExpansionListener(TreeExpansionListener listener)
  {
    listenerList.remove(TreeExpansionListener.class, listener);
  }

  /**
   * Returns all added <code>TreeExpansionListener</code> objects.
   * 
   * @return an array of listeners
   */
  public TreeExpansionListener[] getTreeExpansionListeners()
  {
    return (TreeExpansionListener[]) getListeners(TreeExpansionListener.class);
  }

  /**
   * Notifies all listeners that the tree was collapsed.
   * 
   * @param path the path to the node that was collapsed
   */
  public void fireTreeCollapsed(TreePath path)
  {
    TreeExpansionEvent event = new TreeExpansionEvent(this, path);
    TreeExpansionListener[] listeners = getTreeExpansionListeners();

    for (int index = 0; index < listeners.length; ++index)
      listeners[index].treeCollapsed(event);
  }

  /**
   * Notifies all listeners that the tree was expanded.
   * 
   * @param path the path to the node that was expanded
   */
  public void fireTreeExpanded(TreePath path)
  {
    TreeExpansionEvent event = new TreeExpansionEvent(this, path);
    TreeExpansionListener[] listeners = getTreeExpansionListeners();

    for (int index = 0; index < listeners.length; ++index)
      listeners[index].treeExpanded(event);
  }

  /**
   * Adds a <code>TreeSelctionListener</code> object to the tree.
   * 
   * @param listener the listener to add
   */
  public void addTreeSelectionListener(TreeSelectionListener listener)
  {
    listenerList.add(TreeSelectionListener.class, listener);
  }

  /**
   * Removes a <code>TreeSelectionListener</code> object from the tree.
   * 
   * @param listener the listener to remove
   */
  public void removeTreeSelectionListener(TreeSelectionListener listener)
  {
    listenerList.remove(TreeSelectionListener.class, listener);
  }

  /**
   * Returns all added <code>TreeSelectionListener</code> objects.
   * 
   * @return an array of listeners
   */
  public TreeSelectionListener[] getTreeSelectionListeners()
  {
    return (TreeSelectionListener[]) 
    getListeners(TreeSelectionListener.class);
  }

  /**
   * Notifies all listeners when the selection of the tree changed.
   * 
   * @param event the event to send
   */
  protected void fireValueChanged(TreeSelectionEvent event)
  {
    TreeSelectionListener[] listeners = getTreeSelectionListeners();

    for (int index = 0; index < listeners.length; ++index)
      listeners[index].valueChanged(event);
  }

  /**
   * Adds a <code>TreeWillExpandListener</code> object to the tree.
   * 
   * @param listener the listener to add
   */
  public void addTreeWillExpandListener(TreeWillExpandListener listener)
  {
    listenerList.add(TreeWillExpandListener.class, listener);
  }

  /**
   * Removes a <code>TreeWillExpandListener</code> object from the tree.
   * 
   * @param listener the listener to remove
   */
  public void removeTreeWillExpandListener(TreeWillExpandListener listener)
  {
    listenerList.remove(TreeWillExpandListener.class, listener);
  }

  /**
   * Returns all added <code>TreeWillExpandListener</code> objects.
   * 
   * @return an array of listeners
   */
  public TreeWillExpandListener[] getTreeWillExpandListeners()
  {
    return (TreeWillExpandListener[]) 
    getListeners(TreeWillExpandListener.class);
  }

  /**
   * Notifies all listeners that the tree will collapse.
   * 
   * @param path the path to the node that will collapse
   */
  public void fireTreeWillCollapse(TreePath path) throws ExpandVetoException
  {
    TreeExpansionEvent event = new TreeExpansionEvent(this, path);
    TreeWillExpandListener[] listeners = getTreeWillExpandListeners();

    for (int index = 0; index < listeners.length; ++index)
      listeners[index].treeWillCollapse(event);
  }

  /**
   * Notifies all listeners that the tree will expand.
   * 
   * @param path the path to the node that will expand
   */
  public void fireTreeWillExpand(TreePath path) throws ExpandVetoException
  {
    TreeExpansionEvent event = new TreeExpansionEvent(this, path);
    TreeWillExpandListener[] listeners = getTreeWillExpandListeners();

    for (int index = 0; index < listeners.length; ++index)
      listeners[index].treeWillExpand(event);
  }

  /**
   * Returns the model of this <code>JTree</code> object.
   * 
   * @return the associated <code>TreeModel</code>
   */
  public TreeModel getModel()
  {
    return treeModel;
  }

  /**
   * Sets the model to use in <code>JTree</code>.
   * 
   * @param model the <code>TreeModel</code> to use
   */
  public void setModel(TreeModel model)
  {
    if (treeModel == model)
      return;

    // Remove listeners from old model.
    if (treeModel != null && treeModelListener != null)
      treeModel.removeTreeModelListener(treeModelListener);

    // add treeModelListener to the new model
    if (treeModelListener == null)
      treeModelListener = createTreeModelListener();
    if (model != null) // as setModel(null) is allowed
      model.addTreeModelListener(treeModelListener);

    TreeModel oldValue = treeModel;
    treeModel = model;
    clearToggledPaths();

    if (treeModel != null)
      {
        if (treeModelListener == null)
          treeModelListener = createTreeModelListener();
        if (treeModelListener != null)
          treeModel.addTreeModelListener(treeModelListener);
        Object root = treeModel.getRoot();
        if (root != null && !treeModel.isLeaf(root))
          {
            nodeStates.put(new TreePath(root), Boolean.TRUE);
          }
      }

    firePropertyChange(TREE_MODEL_PROPERTY, oldValue, model);
  }

  /**
   * Checks if this <code>JTree</code> object is editable.
   * 
   * @return <code>true</code> if this tree object is editable,
   *         <code>false</code> otherwise
   */
  public boolean isEditable()
  {
    return editable;
  }

  /**
   * Sets the <code>editable</code> property.
   * 
   * @param flag <code>true</code> to make this tree object editable,
   *        <code>false</code> otherwise
   */
  public void setEditable(boolean flag)
  {
    if (editable == flag)
      return;

    boolean oldValue = editable;
    editable = flag;
    firePropertyChange(EDITABLE_PROPERTY, oldValue, editable);
  }

  /**
   * Checks if the root element is visible.
   * 
   * @return <code>true</code> if the root element is visible,
   *         <code>false</code> otherwise
   */
  public boolean isRootVisible()
  {
    return rootVisible;
  }

  public void setRootVisible(boolean flag)
  {
    if (rootVisible == flag)
      return;

    // If the root is currently selected, unselect it
    if (rootVisible && !flag)
      {
        TreeSelectionModel model = getSelectionModel();
        // The root is always shown in the first row
        TreePath rootPath = getPathForRow(0);
        model.removeSelectionPath(rootPath);
      }
    
    boolean oldValue = rootVisible;
    rootVisible = flag;
    firePropertyChange(ROOT_VISIBLE_PROPERTY, oldValue, flag);
    
  }

  public boolean getShowsRootHandles()
  {
    return showsRootHandles;
  }

  public void setShowsRootHandles(boolean flag)
  {
    clientShowsRootHandlesSet = true;

    if (showsRootHandles == flag)
      return;
    
    boolean oldValue = showsRootHandles;
    showsRootHandles = flag;
    firePropertyChange(SHOWS_ROOT_HANDLES_PROPERTY, oldValue, flag);
  }

  public TreeCellEditor getCellEditor()
  {
    return cellEditor;
  }

  public void setCellEditor(TreeCellEditor editor)
  {
    if (cellEditor == editor)
      return;

    TreeCellEditor oldValue = cellEditor;
    cellEditor = editor;
    firePropertyChange(CELL_EDITOR_PROPERTY, oldValue, editor);
  }

  public TreeCellRenderer getCellRenderer()
  {
    return cellRenderer;
  }

  public void setCellRenderer(TreeCellRenderer newRenderer)
  {
    if (cellRenderer == newRenderer)
      return;

    TreeCellRenderer oldValue = cellRenderer;
    cellRenderer = newRenderer;
    firePropertyChange(CELL_RENDERER_PROPERTY, oldValue, newRenderer);
  }

  public TreeSelectionModel getSelectionModel()
  {
    return selectionModel;
  }

  public void setSelectionModel(TreeSelectionModel model)
  {
    if (selectionModel == model)
      return;

    if (selectionModel != null)
      selectionModel.removeTreeSelectionListener(selectionRedirector);

    TreeSelectionModel oldValue = selectionModel;
    selectionModel = model;

    if (selectionModel != null)
      selectionModel.addTreeSelectionListener(selectionRedirector);

    firePropertyChange(SELECTION_MODEL_PROPERTY, oldValue, model);
    revalidate();
    repaint();
  }

  public int getVisibleRowCount()
  {
    return visibleRowCount;
  }

  public void setVisibleRowCount(int rows)
  {
    if (visibleRowCount == rows)
      return;

    int oldValue = visibleRowCount;
    visibleRowCount = rows;
    firePropertyChange(VISIBLE_ROW_COUNT_PROPERTY, oldValue, rows);
  }

  public boolean isLargeModel()
  {
    return largeModel;
  }

  public void setLargeModel(boolean large)
  {
    if (largeModel == large)
      return;

    boolean oldValue = largeModel;
    largeModel = large;
    firePropertyChange(LARGE_MODEL_PROPERTY, oldValue, large);
  }

  public int getRowHeight()
  {
    return rowHeight;
  }

  public void setRowHeight(int height)
  {
    clientRowHeightSet = true;

    if (rowHeight == height)
      return;

    int oldValue = rowHeight;
    rowHeight = height;
    firePropertyChange(ROW_HEIGHT_PROPERTY, oldValue, height);
  }

  public boolean isFixedRowHeight()
  {
    return rowHeight > 0;
  }

  public boolean getInvokesStopCellEditing()
  {
    return invokesStopCellEditing;
  }

  public void setInvokesStopCellEditing(boolean invoke)
  {
    if (invokesStopCellEditing == invoke)
      return;

    boolean oldValue = invokesStopCellEditing;
    invokesStopCellEditing = invoke;
    firePropertyChange(INVOKES_STOP_CELL_EDITING_PROPERTY, 
                       oldValue, invoke);
  }

  /**
   * @since 1.3
   */
  public int getToggleClickCount()
  {
    return toggleClickCount;
  }

  /**
   * @since 1.3
   */
  public void setToggleClickCount(int count)
  {
    if (toggleClickCount == count)
      return;

    int oldValue = toggleClickCount;
    toggleClickCount = count;
    firePropertyChange(TOGGLE_CLICK_COUNT_PROPERTY, oldValue, count);
  }

  public void scrollPathToVisible(TreePath path)
  {
    if (path == null)
      return;
    Rectangle rect = getPathBounds(path);
    scrollRectToVisible(rect);
  }

  public void scrollRowToVisible(int row)
  {
    scrollPathToVisible(getPathForRow(row));
  }

  public boolean getScrollsOnExpand()
  {
    return scrollsOnExpand;
  }

  public void setScrollsOnExpand(boolean scroll)
  {
    clientScrollsOnExpandSet = true;
    if (scrollsOnExpand == scroll)
      return;

    boolean oldValue = scrollsOnExpand;
    scrollsOnExpand = scroll;
    firePropertyChange(SCROLLS_ON_EXPAND_PROPERTY, oldValue, scroll);
  }

  public void setSelectionPath(TreePath path)
  {
    selectionModel.setSelectionPath(path);
  }

  public void setSelectionPaths(TreePath[] paths)
  {
    selectionModel.setSelectionPaths(paths);
  }

  public void setSelectionRow(int row)
  {
    TreePath path = getPathForRow(row);

    if (path != null)
      selectionModel.setSelectionPath(path);
  }

  public void setSelectionRows(int[] rows)
  {
    // Make sure we have an UI so getPathForRow() does not return null.
    if (rows == null || getUI() == null)
      return;

    TreePath[] paths = new TreePath[rows.length];

    for (int i = rows.length - 1; i >= 0; --i)
      paths[i] = getPathForRow(rows[i]);

    setSelectionPaths(paths);
  }

  public void setSelectionInterval(int index0, int index1)
  {
    TreePath[] paths = getPathBetweenRows(index0, index1);

    if (paths != null)
      setSelectionPaths(paths);
  }

  public void addSelectionPath(TreePath path)
  {
    selectionModel.addSelectionPath(path);
  }

  public void addSelectionPaths(TreePath[] paths)
  {
    selectionModel.addSelectionPaths(paths);
  }

  public void addSelectionRow(int row)
  {
    TreePath path = getPathForRow(row);

    if (path != null)
      selectionModel.addSelectionPath(path);
  }

  public void addSelectionRows(int[] rows)
  {
    // Make sure we have an UI so getPathForRow() does not return null.
    if (rows == null || getUI() == null)
      return;

    TreePath[] paths = new TreePath[rows.length];

    for (int i = rows.length - 1; i >= 0; --i)
      paths[i] = getPathForRow(rows[i]);

    addSelectionPaths(paths);
  }
  
  /**
   * Select all rows between the two given indexes, inclusive. The method
   * will not select the inner leaves and braches of the currently collapsed
   * nodes in this interval.
   * 
   * @param index0 the starting row, inclusive
   * @param index1 the ending row, inclusive
   */
  public void addSelectionInterval(int index0, int index1)
  {
    TreePath[] paths = getPathBetweenRows(index0, index1);

    if (paths != null)
      addSelectionPaths(paths);
  }

  public void removeSelectionPath(TreePath path)
  {
    selectionModel.removeSelectionPath(path);
  }

  public void removeSelectionPaths(TreePath[] paths)
  {
    selectionModel.removeSelectionPaths(paths);
  }

  public void removeSelectionRow(int row)
  {
    TreePath path = getPathForRow(row);

    if (path != null)
      selectionModel.removeSelectionPath(path);
  }

  public void removeSelectionRows(int[] rows)
  {
    if (rows == null || getUI() == null)
      return;

    TreePath[] paths = new TreePath[rows.length];

    for (int i = rows.length - 1; i >= 0; --i)
      paths[i] = getPathForRow(rows[i]);

    removeSelectionPaths(paths);
  }

  public void removeSelectionInterval(int index0, int index1)
  {
    TreePath[] paths = getPathBetweenRows(index0, index1);

    if (paths != null)
      removeSelectionPaths(paths);
  }

  public void clearSelection()
  {
    selectionModel.clearSelection();
    setLeadSelectionPath(null);
  }

  public TreePath getLeadSelectionPath()
  {
    if (selectionModel == null)
      return null;
    else
      return selectionModel.getLeadSelectionPath();
  }

  /**
   * @since 1.3
   */
  public void setLeadSelectionPath(TreePath path)
  {
    if (selectionModel != null)
      {
        TreePath oldValue = selectionModel.getLeadSelectionPath();
        if (path.equals(oldValue))
          return;
       
        // Repaint the previous and current rows with the lead selection path.
        if (path != null)
          {
            repaint(getPathBounds(path));
            selectionModel.addSelectionPath(path);
          }
        
        if (oldValue != null)
          repaint(getPathBounds(oldValue));
        
        firePropertyChange(LEAD_SELECTION_PATH_PROPERTY, oldValue, path);
      }
  }

  /**
   * @since 1.3
   */
  public TreePath getAnchorSelectionPath()
  {
    return anchorSelectionPath;
  }

  /**
   * @since 1.3
   */
  public void setAnchorSelectionPath(TreePath path)
  {
    if (anchorSelectionPath == path)
      return;

    TreePath oldValue = anchorSelectionPath;
    anchorSelectionPath = path;
    firePropertyChange(ANCHOR_SELECTION_PATH_PROPERTY, oldValue, path);
  }

  public int getLeadSelectionRow()
  {
    return selectionModel.getLeadSelectionRow();
  }

  public int getMaxSelectionRow()
  {
    return selectionModel.getMaxSelectionRow();
  }

  public int getMinSelectionRow()
  {
    return selectionModel.getMinSelectionRow();
  }

  public int getSelectionCount()
  {
    return selectionModel.getSelectionCount();
  }

  public TreePath getSelectionPath()
  {
    return selectionModel.getSelectionPath();
  }

  public TreePath[] getSelectionPaths()
  {
    return selectionModel.getSelectionPaths();
  }

  public int[] getSelectionRows()
  {
    return selectionModel.getSelectionRows();
  }

  public boolean isPathSelected(TreePath path)
  {
    return selectionModel.isPathSelected(path);
  }

  public boolean isRowSelected(int row)
  {
    return selectionModel.isPathSelected(getPathForRow(row));
  }

  public boolean isSelectionEmpty()
  {
    return selectionModel.isSelectionEmpty();
  }

  /**
   * Return the value of the <code>dragEnabled</code> property.
   * 
   * @return the value
   * 
   * @since 1.4
   */
  public boolean getDragEnabled()
  {
    return dragEnabled;
  }

  /**
   * Set the <code>dragEnabled</code> property.
   * 
   * @param enabled new value
   * 
   * @since 1.4
   */
  public void setDragEnabled(boolean enabled)
  {
    dragEnabled = enabled;
  }

  public int getRowCount()
  {
    TreeUI ui = getUI();

    if (ui != null)
      return ui.getRowCount(this);

    return 0;
  }

  public void collapsePath(TreePath path)
  {
    try
      {
        fireTreeWillCollapse(path);
      }
    catch (ExpandVetoException ev)
      {
        // We do nothing if attempt has been vetoed.
      }
    setExpandedState(path, false);
    fireTreeCollapsed(path);
  }

  public void collapseRow(int row)
  {
    if (row < 0 || row >= getRowCount())
      return;

    TreePath path = getPathForRow(row);

    if (path != null)
      collapsePath(path);
  }

  public void expandPath(TreePath path)
  {
    // Don't expand if path is null
    // or is already expanded.
    if (path == null || isExpanded(path))
      return;

    try
      {
        fireTreeWillExpand(path);
      }
    catch (ExpandVetoException ev)
      {
        // We do nothing if attempt has been vetoed.
      }

    setExpandedState(path, true);
    fireTreeExpanded(path);
  }

  public void expandRow(int row)
  {
    if (row < 0 || row >= getRowCount())
      return;

    TreePath path = getPathForRow(row);

    if (path != null)
      expandPath(path);
  }

  public boolean isCollapsed(TreePath path)
  {
    return !isExpanded(path);
  }

  public boolean isCollapsed(int row)
  {
    if (row < 0 || row >= getRowCount())
      return false;

    TreePath path = getPathForRow(row);

    if (path != null)
      return isCollapsed(path);

    return false;
  }

  public boolean isExpanded(TreePath path)
  {
    if (path == null)
      return false;

    Object state = nodeStates.get(path);

    if ((state == null) || (state != EXPANDED))
      return false;

    TreePath parent = path.getParentPath();

    if (parent != null)
      return isExpanded(parent);

    return true;
  }

  public boolean isExpanded(int row)
  {
    if (row < 0 || row >= getRowCount())
      return false;

    TreePath path = getPathForRow(row);

    if (path != null)
      return isExpanded(path);

    return false;
  }

  /**
   * @since 1.3
   */
  public boolean getExpandsSelectedPaths()
  {
    return expandsSelectedPaths;
  }

  /**
   * @since 1.3
   */
  public void setExpandsSelectedPaths(boolean flag)
  {
    if (expandsSelectedPaths == flag)
      return;

    boolean oldValue = expandsSelectedPaths;
    expandsSelectedPaths = flag;
    firePropertyChange(EXPANDS_SELECTED_PATHS_PROPERTY, oldValue, flag);
  }

  public Rectangle getPathBounds(TreePath path)
  {
    TreeUI ui = getUI();

    if (ui == null)
      return null;

    return ui.getPathBounds(this, path);
  }

  public Rectangle getRowBounds(int row)
  {
    TreePath path = getPathForRow(row);

    if (path != null)
      return getPathBounds(path);

    return null;
  }

  public boolean isEditing()
  {
    TreeUI ui = getUI();

    if (ui != null)
      return ui.isEditing(this);

    return false;
  }

  public boolean stopEditing()
  {
    TreeUI ui = getUI();

    if (isEditing())
      if (ui != null)
        return ui.stopEditing(this);

    return false;
  }

  public void cancelEditing()
  {
    TreeUI ui = getUI();
      
    if (isEditing())
      if (ui != null)
        ui.cancelEditing(this);
  }

  public void startEditingAtPath(TreePath path)
  {
    TreeUI ui = getUI();

    if (ui != null)
      ui.startEditingAtPath(this, path);
  }

  public TreePath getEditingPath()
  {
    TreeUI ui = getUI();

    if (ui != null)
      return ui.getEditingPath(this);

    return null;
  }

  public TreePath getPathForLocation(int x, int y)
  {
    TreePath path = getClosestPathForLocation(x, y);

    if (path != null)
      {
        Rectangle rect = getPathBounds(path);

        if ((rect != null) && rect.contains(x, y))
          return path;
      }

    return null;
  }

  public int getRowForLocation(int x, int y)
  {
    TreePath path = getPathForLocation(x, y);

    if (path != null)
      return getRowForPath(path);

    return -1;
  }

  public TreePath getClosestPathForLocation(int x, int y)
  {
    TreeUI ui = getUI();

    if (ui != null)
      return ui.getClosestPathForLocation(this, x, y);

    return null;
  }

  public int getClosestRowForLocation(int x, int y)
  {
    TreePath path = getClosestPathForLocation(x, y);

    if (path != null)
      return getRowForPath(path);

    return -1;
  }

  public Object getLastSelectedPathComponent()
  {
    TreePath path = getSelectionPath();

    if (path != null)
      return path.getLastPathComponent();

    return null;
  }

  private void doExpandParents(TreePath path, boolean state)
  {
    TreePath parent = path.getParentPath();		

    if (!isExpanded(parent) && parent != null)
      doExpandParents(parent, false);
    
    nodeStates.put(path, state ? EXPANDED : COLLAPSED);
  }

  protected void setExpandedState(TreePath path, boolean state)
  {
    if (path == null)
      return;

    doExpandParents(path, state);
  }

  protected void clearToggledPaths()
  {
    nodeStates.clear();
  }

  protected Enumeration getDescendantToggledPaths(TreePath parent)
  {
    if (parent == null)
      return null;

    Enumeration nodes = nodeStates.keys();
    Vector result = new Vector();

    while (nodes.hasMoreElements())
      {
        TreePath path = (TreePath) nodes.nextElement();

        if (path.isDescendant(parent))
          result.addElement(path);
      }

    return result.elements();
  }

  public boolean hasBeenExpanded(TreePath path)
  {
    if (path == null)
      return false;

    return nodeStates.get(path) != null;
  }

  public boolean isVisible(TreePath path)
  {
    if (path == null)
      return false;

    TreePath parent = path.getParentPath();

    if (parent == null)
      return true; // Is root node.

    return isExpanded(parent);
  }

  public void makeVisible(TreePath path)
  {
    if (path == null)
      return;
    
    expandPath(path.getParentPath());
  }

  public boolean isPathEditable(TreePath path)
  {
    return isEditable();
  }

  /**
   * Creates and returns an instance of {@link TreeModelHandler}.
   * 
   * @return an instance of {@link TreeModelHandler}
   */
  protected TreeModelListener createTreeModelListener()
  {
    return new TreeModelHandler();
  }

  /**
   * Returns a sample TreeModel that can be used in a JTree. This can be used
   * in Bean- or GUI-Builders to show something interesting.
   * 
   * @return a sample TreeModel that can be used in a JTree
   */
  protected static TreeModel getDefaultTreeModel()
  {
    DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root node");
    DefaultMutableTreeNode child1 = new DefaultMutableTreeNode("Child node 1");
    DefaultMutableTreeNode child11 =
      new DefaultMutableTreeNode("Child node 1.1");
    DefaultMutableTreeNode child12 =
      new DefaultMutableTreeNode("Child node 1.2");
    DefaultMutableTreeNode child13 =
      new DefaultMutableTreeNode("Child node 1.3");
    DefaultMutableTreeNode child2 = new DefaultMutableTreeNode("Child node 2");
    DefaultMutableTreeNode child21 =
      new DefaultMutableTreeNode("Child node 2.1");
    DefaultMutableTreeNode child22 =
      new DefaultMutableTreeNode("Child node 2.2");
    DefaultMutableTreeNode child23 =
      new DefaultMutableTreeNode("Child node 2.3");
    DefaultMutableTreeNode child24 =
      new DefaultMutableTreeNode("Child node 2.4");

    DefaultMutableTreeNode child3 = new DefaultMutableTreeNode("Child node 3");
    root.add(child1);
    root.add(child2);
    root.add(child3);
    child1.add(child11);
    child1.add(child12);
    child1.add(child13);
    child2.add(child21);
    child2.add(child22);
    child2.add(child23);
    child2.add(child24);
    return new DefaultTreeModel(root);
  }

  /**
   * Converts the specified value to a String. This is used by the renderers
   * of this JTree and its nodes.
   * 
   * This implementation simply returns <code>value.toString()</code> and
   * ignores all other parameters. Subclass this method to control the
   * conversion.
   * 
   * @param value the value that is converted to a String
   * @param selected indicates if that value is selected or not
   * @param expanded indicates if that value is expanded or not
   * @param leaf indicates if that value is a leaf node or not
   * @param row the row of the node
   * @param hasFocus indicates if that node has focus or not
   */
  public String convertValueToText(Object value, boolean selected,
                                   boolean expanded, boolean leaf, int row, boolean hasFocus)
  {
    return value.toString();
  }

  /**
   * A String representation of this JTree. This is intended to be used for
   * debugging. The returned string may be empty but may not be
   * <code>null</code>.
   * 
   * @return a String representation of this JTree
   */
  protected String paramString()
  {
    // TODO: this is completely legal, but it would possibly be nice
    // to return some more content, like the tree structure, some properties
    // etc ...
    return "";
  }

  /**
   * Returns all TreePath objects which are a descendants of the given path
   * and are exapanded at the moment of the execution of this method. If the
   * state of any node is beeing toggled while this method is executing this
   * change may be left unaccounted.
   * 
   * @param path The parent of this request
   *
   * @return An Enumeration containing TreePath objects
   */
  public Enumeration getExpandedDescendants(TreePath path)
  {
    Enumeration paths = nodeStates.keys();
    Vector relevantPaths = new Vector();
    while (paths.hasMoreElements())
      {
        TreePath nextPath = (TreePath) paths.nextElement();
        if (nodeStates.get(nextPath) == EXPANDED
            && path.isDescendant(nextPath))
          {
            relevantPaths.add(nextPath);
          }
      }
    return relevantPaths.elements();
  }

  /**
   * Returns the next table element (beginning from the row
   * <code>startingRow</code> that starts with <code>prefix</code>.
   * Searching is done in the direction specified by <code>bias</code>.
   * 
   * @param prefix the prefix to search for in the cell values
   * @param startingRow the index of the row where to start searching from
   * @param bias the search direction, either {@link Position.Bias#Forward} or
   *        {@link Position.Bias#Backward}
   * 
   * @return the path to the found element or -1 if no such element has been
   *         found
   * 
   * @throws IllegalArgumentException if prefix is <code>null</code> or
   *         startingRow is not valid
   * 
   * @since 1.4
   */
  public TreePath getNextMatch(String prefix, int startingRow,
                               Position.Bias bias)
  {
    if (prefix == null)
      throw new IllegalArgumentException("The argument 'prefix' must not be"
                                         + " null.");
    if (startingRow < 0)
      throw new IllegalArgumentException("The argument 'startingRow' must not"
                                         + " be less than zero.");

    int size = getRowCount();
    if (startingRow > size)
      throw new IllegalArgumentException("The argument 'startingRow' must not"
                                         + " be greater than the number of"
                                         + " elements in the TreeModel.");

    TreePath foundPath = null;
    if (bias == Position.Bias.Forward)
      {
        for (int i = startingRow; i < size; i++)
          {
            TreePath path = getPathForRow(i);
            Object o = path.getLastPathComponent();
            // FIXME: in the following call to convertValueToText the
            // last argument (hasFocus) should be done right.
            String item = convertValueToText(o, isRowSelected(i),
                                             isExpanded(i), treeModel.isLeaf(o),
                                             i, false);
            if (item.startsWith(prefix))
              {
                foundPath = path;
                break;
              }
          }
      }
    else
      {
        for (int i = startingRow; i >= 0; i--)
          {
            TreePath path = getPathForRow(i);
            Object o = path.getLastPathComponent();
            // FIXME: in the following call to convertValueToText the
            // last argument (hasFocus) should be done right.
            String item = convertValueToText(o, isRowSelected(i),
                                             isExpanded(i), treeModel.isLeaf(o), i, false);
            if (item.startsWith(prefix))
              {
                foundPath = path;
                break;
              }
          }
      }
    return foundPath;
  }

  /**
   * Removes any paths in the current set of selected paths that are
   * descendants of <code>path</code>. If <code>includePath</code> is set
   * to <code>true</code> and <code>path</code> itself is selected, then
   * it will be removed too.
   * 
   * @param path the path from which selected descendants are to be removed
   * @param includeSelected if <code>true</code> then <code>path</code> itself
   *        will also be remove if it's selected
   * 
   * @return <code>true</code> if something has been removed,
   *         <code>false</code> otherwise
   * 
   * @since 1.3
   */
  protected boolean removeDescendantSelectedPaths(TreePath path,
                                                  boolean includeSelected)
  {
    boolean removedSomething = false;
    TreePath[] selected = getSelectionPaths();
    for (int index = 0; index < selected.length; index++)
      {
        if ((selected[index] == path && includeSelected)
            || (selected[index].isDescendant(path)))
          {
            removeSelectionPath(selected[index]);
            removedSomething = true;
          }
      }
    return removedSomething;
  }
  
  /**
   * Removes any descendants of the TreePaths in toRemove that have been 
   * expanded.
   * 
   * @param toRemove - Enumeration of TreePaths that need to be removed from
   * cache of toggled tree paths.
   */
  protected void removeDescendantToggledPaths(Enumeration toRemove)
  {
    while (toRemove.hasMoreElements())
      {
        TreePath current = (TreePath) toRemove.nextElement();
        Enumeration descendants = getDescendantToggledPaths(current);
        
        while (descendants.hasMoreElements())
          {
            TreePath currentDes = (TreePath) descendants.nextElement();
            if (isExpanded(currentDes))
                nodeStates.remove(currentDes);
          }
      }
  }

  /**
   * <p>
   * Sent when the tree has changed enough that we need to resize the bounds,
   * but not enough that we need to remove the expanded node set (e.g nodes were
   * expanded or collapsed, or nodes were inserted into the tree). You should
   * never have to invoke this, the UI will invoke this as it needs to.
   * </p>
   * <p>
   * If the tree uses {@link DefaultTreeModel}, you must call
   * {@link DefaultTreeModel#reload(TreeNode)} or
   * {@link DefaultTreeModel#reload()} after adding or removing nodes. Following
   * the official Java 1.5 API standard, just calling treeDidChange, repaint()
   * or revalidate() does <i>not</i> update the tree appearance properly.
   * 
   * @see DefaultTreeModel#reload()
   */
  public void treeDidChange()
  {
    repaint();
  }

  /**
   * Helper method for
   * {@link LookAndFeel#installProperty(JComponent, String, Object)}.
   * 
   * @param propertyName the name of the property
   * @param value the value of the property
   *
   * @throws IllegalArgumentException if the specified property cannot be set
   *         by this method
   * @throws ClassCastException if the property value does not match the
   *         property type
   * @throws NullPointerException if <code>c</code> or
   *         <code>propertyValue</code> is <code>null</code>
   */
  void setUIProperty(String propertyName, Object value)
  {
    if (propertyName.equals("rowHeight"))
      {
        if (! clientRowHeightSet)
          {
            setRowHeight(((Integer) value).intValue());
            clientRowHeightSet = false;
          }
      }
    else if (propertyName.equals("scrollsOnExpand"))
      {
        if (! clientScrollsOnExpandSet)
          {
            setScrollsOnExpand(((Boolean) value).booleanValue());
            clientScrollsOnExpandSet = false;
          }
      }
    else if (propertyName.equals("showsRootHandles"))
      {
        if (! clientShowsRootHandlesSet)
          {
            setShowsRootHandles(((Boolean) value).booleanValue());
            clientShowsRootHandlesSet = false;
          }
      }
    else
      {
        super.setUIProperty(propertyName, value);
      }
  }
}
