/* 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)
    {
      if (ev != null)
        {
          TreePath parent = ev.getTreePath();
          Object[] children = ev.getChildren();
          TreeSelectionModel sm = getSelectionModel();
          if (children != null)
            {
              TreePath path;
              Vector toRemove = new Vector();
              // Collect items that we must remove.
              for (int i = children.length - 1; i >= 0; i--)
                {
                  path = parent.pathByAddingChild(children[i]);
                  if (nodeStates.containsKey(path))
                    toRemove.add(path);
                  // Clear selection while we are at it.
                  if (sm != null)
                    removeDescendantSelectedPaths(path, true);
                }
              if (toRemove.size() > 0)
                removeDescendantToggledPaths(toRemove.elements());
              TreeModel model = getModel();
              if (model == null || model.isLeaf(parent.getLastPathComponent()))
                nodeStates.remove(parent);
            }
        }
    }

    /**
     * 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)
    {
      if (ev != null)
        {
          TreePath parent = ev.getTreePath();
          if (parent != null)
            {
              if (parent.getPathCount() == 1)
                {
                  // We have a new root, clear everything.
                  clearToggledPaths();
                  Object root = treeModel.getRoot();
                  if (root != null && treeModel.isLeaf(root))
                    nodeStates.put(parent, Boolean.TRUE);
                }
              else if (nodeStates.containsKey(parent))
                {
                  Vector toRemove = new Vector();
                  boolean expanded = isExpanded(parent);
                  toRemove.add(parent);
                  removeDescendantToggledPaths(toRemove.elements());
                  if (expanded)
                    {
                      TreeModel model = getModel();
                      if (model != null
                          || model.isLeaf(parent.getLastPathComponent()))
                        collapsePath(parent);
                      else
                        nodeStates.put(parent, Boolean.TRUE);
                    }
                }
              removeDescendantSelectedPaths(parent, false);
            }
        }
    }
  }

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

  /**
   * 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.
   *
   * This is package private to avoid accessor methods.
   */
  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 DefaultTreeSelectionModel() );

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

    // Round so that the top would start from the row boundary
    if (orientation == SwingConstants.VERTICAL)
      {
        int row = getClosestRowForLocation(0, visibleRect.y);
        if (row != -1)
          {
            Rectangle b = getRowBounds(row);
            if (b.y != visibleRect.y)
              {
                if (direction < 0)
                  delta = Math.max(0, visibleRect.y - b.y);
                else
                  delta = b.y + b.height - visibleRect.y;
              }
            else
              {
                if (direction < 0)
                  {
                    if (row != 0)
                      {
                        b = getRowBounds(row - 1);
                        delta = b.height;
                      }
                  }
                else
                  delta = b.height;
              }
          }
      }
    else
      // The RI always  returns 4 for HORIZONTAL scrolling.
      delta = 4;
    return delta;
  }

  public int getScrollableBlockIncrement(Rectangle visibleRect,
                                         int orientation, int direction)
  {
    int block;
    if (orientation == SwingConstants.VERTICAL)
      block = visibleRect.height;
    else
      block = visibleRect.width;
    return block;
  }

  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( model == null )
      model = EmptySelectionModel.sharedInstance();

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

    TreeSelectionModel oldValue = selectionModel;
    selectionModel = model;

    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)
  {
    clearSelectionPathStates();
    selectionModel.setSelectionPath(path);
  }

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

  /**
   * This method, and all calls to it, should be removed once the
   * DefaultTreeModel fires events properly.  Maintenance of the nodeStates
   * table should really be done in the TreeModelHandler.
   */
  private void clearSelectionPathStates()
  {
    TreePath[] oldPaths = selectionModel.getSelectionPaths();
    if (oldPaths != null)
      for (int i = 0; i < oldPaths.length; i++)
        nodeStates.remove(oldPaths[i]);
  }

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

    if (path != null)
      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)
  {
    clearSelectionPathStates();
    selectionModel.removeSelectionPath(path);
  }

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

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

    if (path != null)
      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 == oldValue || path != null && 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);
  }

  /**
   * Returns <code>true</code> when the specified row is selected,
   * <code>false</code> otherwise. This call is delegated to the
   * {@link TreeSelectionModel#isRowSelected(int)} method.
   *
   * @param row the row to check
   *
   * @return <code>true</code> when the specified row is selected,
   *         <code>false</code> otherwise
   */
  public boolean isRowSelected(int row)
  {
    return selectionModel.isRowSelected(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<TreePath> 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<TreePath> 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<TreePath> toRemove)
  {
    while (toRemove.hasMoreElements())
      {
        TreePath current = 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);
      }
  }
}
