/* 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);
      JTree.this.repaint();
    }
  }

  /**
   * 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 = new Object();

  private static final Object COLLAPSED = new Object();

  private boolean dragEnabled;

  private boolean expandsSelectedPaths;

  private TreePath anchorSelectionPath;

  private TreePath leadSelectionPath;

  /**
   * 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();

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

  /**
   * 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)
  {
    updateUI();
    setRootVisible(true);
    setModel(model);
    setSelectionModel(new EmptySelectionModel());
  }

  /**
   * 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;
  }

  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 new Dimension (getPreferredSize().width, getVisibleRowCount()*getRowHeight());
  }

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

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

  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;

    // 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;

    firePropertyChange(TREE_MODEL_PROPERTY, oldValue, model);
    updateUI();
  }

  /**
   * 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;

    boolean oldValue = rootVisible;
    rootVisible = flag;
    firePropertyChange(ROOT_VISIBLE_PROPERTY, oldValue, flag);
  }

  public boolean getShowsRootHandles()
  {
    return showsRootHandles;
  }

  public void setShowsRootHandles(boolean flag)
  {
    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)
  {
    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;
    
    Object[] oPath = path.getPath();
    TreePath temp = new TreePath(oPath[0]);
    boolean stop = false;
    int i = 1;
    while (!stop)
      {
        while (isVisible(temp))
          if (i < oPath.length)
            temp = temp.pathByAddingChild(oPath[i++]);
          else
            {
              stop = true;
              break;
            }
        makeVisible(temp);
      }
    Rectangle rect = getPathBounds(path);
    scrollRectToVisible(rect);
    revalidate();
    repaint();
  }

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

  public boolean getScrollsOnExpand()
  {
    return scrollsOnExpand;
  }

  public void setScrollsOnExpand(boolean scroll)
  {
    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);
  }

  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()
  {
    return leadSelectionPath;
  }

  /**
   * @since 1.3
   */
  public void setLeadSelectionPath(TreePath path)
  {
    if (leadSelectionPath == path)
      return;
    
    TreePath oldValue = leadSelectionPath;
    leadSelectionPath = path;
    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
    if (path == null)
      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 (ui != null)
      return ui.stopEditing(this);

    return false;
  }

  public void cancelEditing()
  {
    TreeUI ui = getUI();

    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
   */
  public 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);
          }
      }
  }

  /**
   * 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. 
   */
  public void treeDidChange()
  {
    repaint();
  }
}
