/* BasicTreeUI.java --
 Copyright (C) 2002, 2004, 2005, 2006, 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.plaf.basic;

import gnu.classpath.NotImplementedException;
import gnu.javax.swing.tree.GnuPath;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Label;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Enumeration;
import java.util.Hashtable;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.CellRendererPane;
import javax.swing.Icon;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.MouseInputListener;
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.plaf.ActionMapUIResource;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.TreeUI;
import javax.swing.tree.AbstractLayoutCache;
import javax.swing.tree.DefaultTreeCellEditor;
import javax.swing.tree.DefaultTreeCellRenderer;
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;
import javax.swing.tree.VariableHeightLayoutCache;

/**
 * A delegate providing the user interface for <code>JTree</code> according to
 * the Basic look and feel.
 * 
 * @see javax.swing.JTree
 * @author Lillian Angel (langel@redhat.com)
 * @author Sascha Brawer (brawer@dandelis.ch)
 * @author Audrius Meskauskas (audriusa@bioinformatics.org)
 */
public class BasicTreeUI
    extends TreeUI
{
  /**
   * The tree cell editing may be started by the single mouse click on the
   * selected cell. To separate it from the double mouse click, the editing
   * session starts after this time (in ms) after that single click, and only no
   * other clicks were performed during that time.
   */
  static int WAIT_TILL_EDITING = 900;

  /** Collapse Icon for the tree. */
  protected transient Icon collapsedIcon;

  /** Expanded Icon for the tree. */
  protected transient Icon expandedIcon;

  /** Distance between left margin and where vertical dashes will be drawn. */
  protected int leftChildIndent;

  /**
   * Distance between leftChildIndent and where cell contents will be drawn.
   */
  protected int rightChildIndent;

  /**
   * Total fistance that will be indented. The sum of leftChildIndent and
   * rightChildIndent .
   */
  protected int totalChildIndent;

  /** Index of the row that was last selected. */
  protected int lastSelectedRow;

  /** Component that we're going to be drawing onto. */
  protected JTree tree;

  /** Renderer that is being used to do the actual cell drawing. */
  protected transient TreeCellRenderer currentCellRenderer;

  /**
   * Set to true if the renderer that is currently in the tree was created by
   * this instance.
   */
  protected boolean createdRenderer;

  /** Editor for the tree. */
  protected transient TreeCellEditor cellEditor;

  /**
   * Set to true if editor that is currently in the tree was created by this
   * instance.
   */
  protected boolean createdCellEditor;

  /**
   * Set to false when editing and shouldSelectCall() returns true meaning the
   * node should be selected before editing, used in completeEditing.
   * GNU Classpath editing is implemented differently, so this value is not
   * actually read anywhere. However it is always set correctly to maintain 
   * interoperability with the derived classes that read this field.
   */
  protected boolean stopEditingInCompleteEditing;

  /** Used to paint the TreeCellRenderer. */
  protected CellRendererPane rendererPane;

  /** Size needed to completely display all the nodes. */
  protected Dimension preferredSize;

  /** Minimum size needed to completely display all the nodes. */
  protected Dimension preferredMinSize;

  /** Is the preferredSize valid? */
  protected boolean validCachedPreferredSize;

  /** Object responsible for handling sizing and expanded issues. */
  protected AbstractLayoutCache treeState;

  /** Used for minimizing the drawing of vertical lines. */
  protected Hashtable drawingCache;

  /**
   * True if doing optimizations for a largeModel. Subclasses that don't support
   * this may wish to override createLayoutCache to not return a
   * FixedHeightLayoutCache instance.
   */
  protected boolean largeModel;

  /** Responsible for telling the TreeState the size needed for a node. */
  protected AbstractLayoutCache.NodeDimensions nodeDimensions;

  /** Used to determine what to display. */
  protected TreeModel treeModel;

  /** Model maintaining the selection. */
  protected TreeSelectionModel treeSelectionModel;

  /**
   * How much the depth should be offset to properly calculate x locations. This
   * is based on whether or not the root is visible, and if the root handles are
   * visible.
   */
  protected int depthOffset;

  /**
   * When editing, this will be the Component that is doing the actual editing.
   */
  protected Component editingComponent;

  /** Path that is being edited. */
  protected TreePath editingPath;

  /**
   * Row that is being edited. Should only be referenced if editingComponent is
   * null.
   */
  protected int editingRow;

  /** Set to true if the editor has a different size than the renderer. */
  protected boolean editorHasDifferentSize;

  /** Boolean to keep track of editing. */
  boolean isEditing;

  /** The current path of the visible nodes in the tree. */
  TreePath currentVisiblePath;

  /** The gap between the icon and text. */
  int gap = 4;

  /** The max height of the nodes in the tree. */
  int maxHeight;
  
  /** The hash color. */
  Color hashColor;

  /** Listeners */
  PropertyChangeListener propertyChangeListener;

  FocusListener focusListener;

  TreeSelectionListener treeSelectionListener;

  MouseListener mouseListener;

  KeyListener keyListener;

  PropertyChangeListener selectionModelPropertyChangeListener;

  ComponentListener componentListener;

  CellEditorListener cellEditorListener;

  TreeExpansionListener treeExpansionListener;

  TreeModelListener treeModelListener;

  /**
   * This timer fires the editing action after about 1200 ms if not reset during
   * that time. It handles the editing start with the single mouse click (and
   * not the double mouse click) on the selected tree node.
   */
  Timer startEditTimer;
  
  /**
   * The zero size icon, used for expand controls, if they are not visible.
   */
  static Icon nullIcon;

  /**
   * The special value of the mouse event is sent indicating that this is not
   * just the mouse click, but the mouse click on the selected node. Sending
   * such event forces to start the cell editing session.
   */
  static final MouseEvent EDIT = new MouseEvent(new Label(), 7, 7, 7, 7, 7, 7,
                                                false);

  /**
   * Creates a new BasicTreeUI object.
   */
  public BasicTreeUI()
  {
    validCachedPreferredSize = false;
    drawingCache = new Hashtable();
    nodeDimensions = createNodeDimensions();
    configureLayoutCache();

    editingRow = - 1;
    lastSelectedRow = - 1;
  }

  /**
   * Returns an instance of the UI delegate for the specified component.
   * 
   * @param c the <code>JComponent</code> for which we need a UI delegate for.
   * @return the <code>ComponentUI</code> for c.
   */
  public static ComponentUI createUI(JComponent c)
  {
    return new BasicTreeUI();
  }

  /**
   * Returns the Hash color.
   * 
   * @return the <code>Color</code> of the Hash.
   */
  protected Color getHashColor()
  {
    return hashColor;
  }

  /**
   * Sets the Hash color.
   * 
   * @param color the <code>Color</code> to set the Hash to.
   */
  protected void setHashColor(Color color)
  {
    hashColor = color;
  }

  /**
   * Sets the left child's indent value.
   * 
   * @param newAmount is the new indent value for the left child.
   */
  public void setLeftChildIndent(int newAmount)
  {
    leftChildIndent = newAmount;
  }

  /**
   * Returns the indent value for the left child.
   * 
   * @return the indent value for the left child.
   */
  public int getLeftChildIndent()
  {
    return leftChildIndent;
  }

  /**
   * Sets the right child's indent value.
   * 
   * @param newAmount is the new indent value for the right child.
   */
  public void setRightChildIndent(int newAmount)
  {
    rightChildIndent = newAmount;
  }

  /**
   * Returns the indent value for the right child.
   * 
   * @return the indent value for the right child.
   */
  public int getRightChildIndent()
  {
    return rightChildIndent;
  }

  /**
   * Sets the expanded icon.
   * 
   * @param newG is the new expanded icon.
   */
  public void setExpandedIcon(Icon newG)
  {
    expandedIcon = newG;
  }

  /**
   * Returns the current expanded icon.
   * 
   * @return the current expanded icon.
   */
  public Icon getExpandedIcon()
  {
    return expandedIcon;
  }

  /**
   * Sets the collapsed icon.
   * 
   * @param newG is the new collapsed icon.
   */
  public void setCollapsedIcon(Icon newG)
  {
    collapsedIcon = newG;
  }

  /**
   * Returns the current collapsed icon.
   * 
   * @return the current collapsed icon.
   */
  public Icon getCollapsedIcon()
  {
    return collapsedIcon;
  }

  /**
   * Updates the componentListener, if necessary.
   * 
   * @param largeModel sets this.largeModel to it.
   */
  protected void setLargeModel(boolean largeModel)
  {
    if (largeModel != this.largeModel)
      {
        tree.removeComponentListener(componentListener);
        this.largeModel = largeModel;
        tree.addComponentListener(componentListener);
      }
  }

  /**
   * Returns true if largeModel is set
   * 
   * @return true if largeModel is set, otherwise false.
   */
  protected boolean isLargeModel()
  {
    return largeModel;
  }

  /**
   * Sets the row height.
   * 
   * @param rowHeight is the height to set this.rowHeight to.
   */
  protected void setRowHeight(int rowHeight)
  {
    if (rowHeight == 0)
      rowHeight = getMaxHeight(tree);
    treeState.setRowHeight(rowHeight);
  }

  /**
   * Returns the current row height.
   * 
   * @return current row height.
   */
  protected int getRowHeight()
  {
    return tree.getRowHeight();
  }

  /**
   * Sets the TreeCellRenderer to <code>tcr</code>. This invokes
   * <code>updateRenderer</code>.
   * 
   * @param tcr is the new TreeCellRenderer.
   */
  protected void setCellRenderer(TreeCellRenderer tcr)
  {
    // Finish editing before changing the renderer.
    completeEditing();

    // The renderer is set in updateRenderer.
    updateRenderer();

    // Refresh the layout if necessary.
    if (treeState != null)
      {
	treeState.invalidateSizes();
	updateSize();
      }
  }

  /**
   * Return currentCellRenderer, which will either be the trees renderer, or
   * defaultCellRenderer, which ever was not null.
   * 
   * @return the current Cell Renderer
   */
  protected TreeCellRenderer getCellRenderer()
  {
    if (currentCellRenderer != null)
      return currentCellRenderer;

    return createDefaultCellRenderer();
  }

  /**
   * Sets the tree's model.
   * 
   * @param model to set the treeModel to.
   */
  protected void setModel(TreeModel model)
  {
    completeEditing();

    if (treeModel != null && treeModelListener != null)
      treeModel.removeTreeModelListener(treeModelListener);

    treeModel = tree.getModel();

    if (treeModel != null && treeModelListener != null)
      treeModel.addTreeModelListener(treeModelListener);

    if (treeState != null)
      {
        treeState.setModel(treeModel);
        updateLayoutCacheExpandedNodes();
        updateSize();
      }
  }

  /**
   * Returns the tree's model
   * 
   * @return treeModel
   */
  protected TreeModel getModel()
  {
    return treeModel;
  }

  /**
   * Sets the root to being visible.
   * 
   * @param newValue sets the visibility of the root
   */
  protected void setRootVisible(boolean newValue)
  {
    tree.setRootVisible(newValue);
  }

  /**
   * Returns true if the root is visible.
   * 
   * @return true if the root is visible.
   */
  protected boolean isRootVisible()
  {
    return tree.isRootVisible();
  }

  /**
   * Determines whether the node handles are to be displayed.
   * 
   * @param newValue sets whether or not node handles should be displayed.
   */
  protected void setShowsRootHandles(boolean newValue)
  {
    completeEditing();
    updateDepthOffset();
    if (treeState != null)
      {
        treeState.invalidateSizes();
        updateSize();
      }
  }

  /**
   * Returns true if the node handles are to be displayed.
   * 
   * @return true if the node handles are to be displayed.
   */
  protected boolean getShowsRootHandles()
  {
    return tree.getShowsRootHandles();
  }

  /**
   * Sets the cell editor.
   * 
   * @param editor to set the cellEditor to.
   */
  protected void setCellEditor(TreeCellEditor editor)
  {
    cellEditor = editor;
    createdCellEditor = true;
  }

  /**
   * Returns the <code>TreeCellEditor</code> for this tree.
   * 
   * @return the cellEditor for this tree.
   */
  protected TreeCellEditor getCellEditor()
  {
    return cellEditor;
  }

  /**
   * Configures the receiver to allow, or not allow, editing.
   * 
   * @param newValue sets the receiver to allow editing if true.
   */
  protected void setEditable(boolean newValue)
  {
    tree.setEditable(newValue);
  }

  /**
   * Returns true if the receiver allows editing.
   * 
   * @return true if the receiver allows editing.
   */
  protected boolean isEditable()
  {
    return tree.isEditable();
  }

  /**
   * Resets the selection model. The appropriate listeners are installed on the
   * model.
   * 
   * @param newLSM resets the selection model.
   */
  protected void setSelectionModel(TreeSelectionModel newLSM)
  {
    if (newLSM != null)
      {
        treeSelectionModel = newLSM;
        tree.setSelectionModel(treeSelectionModel);
      }
  }

  /**
   * Returns the current selection model.
   * 
   * @return the current selection model.
   */
  protected TreeSelectionModel getSelectionModel()
  {
    return treeSelectionModel;
  }

  /**
   * Returns the Rectangle enclosing the label portion that the last item in
   * path will be drawn to. Will return null if any component in path is
   * currently valid.
   * 
   * @param tree is the current tree the path will be drawn to.
   * @param path is the current path the tree to draw to.
   * @return the Rectangle enclosing the label portion that the last item in the
   *         path will be drawn to.
   */
  public Rectangle getPathBounds(JTree tree, TreePath path)
  {
    return treeState.getBounds(path, new Rectangle());
  }

  /**
   * Returns the max height of all the nodes in the tree.
   * 
   * @param tree - the current tree
   * @return the max height.
   */
  int getMaxHeight(JTree tree)
  {
    if (maxHeight != 0)
      return maxHeight;

    Icon e = UIManager.getIcon("Tree.openIcon");
    Icon c = UIManager.getIcon("Tree.closedIcon");
    Icon l = UIManager.getIcon("Tree.leafIcon");
    int rc = getRowCount(tree);
    int iconHeight = 0;

    for (int row = 0; row < rc; row++)
      {
        if (isLeaf(row))
          iconHeight = l.getIconHeight();
        else if (tree.isExpanded(row))
          iconHeight = e.getIconHeight();
        else
          iconHeight = c.getIconHeight();

        maxHeight = Math.max(maxHeight, iconHeight + gap);
      }
     
    treeState.setRowHeight(maxHeight);
    return maxHeight;
  }
  
  /**
   * Get the tree node icon.
   */
  Icon getNodeIcon(TreePath path)
  {
    Object node = path.getLastPathComponent();
    if (treeModel.isLeaf(node))
      return UIManager.getIcon("Tree.leafIcon");
    else if (treeState.getExpandedState(path))
      return UIManager.getIcon("Tree.openIcon");
    else
      return UIManager.getIcon("Tree.closedIcon");
  }

  /**
   * Returns the path for passed in row. If row is not visible null is returned.
   * 
   * @param tree is the current tree to return path for.
   * @param row is the row number of the row to return.
   * @return the path for passed in row. If row is not visible null is returned.
   */
  public TreePath getPathForRow(JTree tree, int row)
  {
    return treeState.getPathForRow(row);
  }

  /**
   * Returns the row that the last item identified in path is visible at. Will
   * return -1 if any of the elments in the path are not currently visible.
   * 
   * @param tree is the current tree to return the row for.
   * @param path is the path used to find the row.
   * @return the row that the last item identified in path is visible at. Will
   *         return -1 if any of the elments in the path are not currently
   *         visible.
   */
  public int getRowForPath(JTree tree, TreePath path)
  {
    return treeState.getRowForPath(path);
  }

  /**
   * Returns the number of rows that are being displayed.
   * 
   * @param tree is the current tree to return the number of rows for.
   * @return the number of rows being displayed.
   */
  public int getRowCount(JTree tree)
  {
    return treeState.getRowCount();
  }

  /**
   * Returns the path to the node that is closest to x,y. If there is nothing
   * currently visible this will return null, otherwise it'll always return a
   * valid path. If you need to test if the returned object is exactly at x,y
   * you should get the bounds for the returned path and test x,y against that.
   * 
   * @param tree the tree to search for the closest path
   * @param x is the x coordinate of the location to search
   * @param y is the y coordinate of the location to search
   * @return the tree path closes to x,y.
   */
  public TreePath getClosestPathForLocation(JTree tree, int x, int y)
  {
    return treeState.getPathClosestTo(x, y);
  }

  /**
   * Returns true if the tree is being edited. The item that is being edited can
   * be returned by getEditingPath().
   * 
   * @param tree is the tree to check for editing.
   * @return true if the tree is being edited.
   */
  public boolean isEditing(JTree tree)
  {
    return isEditing;
  }

  /**
   * Stops the current editing session. This has no effect if the tree is not
   * being edited. Returns true if the editor allows the editing session to
   * stop.
   * 
   * @param tree is the tree to stop the editing on
   * @return true if the editor allows the editing session to stop.
   */
  public boolean stopEditing(JTree tree)
  {
    if (isEditing(tree))
      {
        completeEditing(false, false, true);
        finish();
      }
    return ! isEditing(tree);
  }

  /**
   * Cancels the current editing session.
   * 
   * @param tree is the tree to cancel the editing session on.
   */
  public void cancelEditing(JTree tree)
  {
    // There is no need to send the cancel message to the editor,
    // as the cancellation event itself arrives from it. This would
    // only be necessary when cancelling the editing programatically.
    completeEditing(false, false, false);
    finish();
  }

  /**
   * Selects the last item in path and tries to edit it. Editing will fail if
   * the CellEditor won't allow it for the selected item.
   * 
   * @param tree is the tree to edit on.
   * @param path is the path in tree to edit on.
   */
  public void startEditingAtPath(JTree tree, TreePath path)
  {
    startEditing(path, null);
  }

  /**
   * Returns the path to the element that is being editted.
   * 
   * @param tree is the tree to get the editing path from.
   * @return the path that is being edited.
   */
  public TreePath getEditingPath(JTree tree)
  {
    return editingPath;
  }

  /**
   * Invoked after the tree instance variable has been set, but before any
   * default/listeners have been installed.
   */
  protected void prepareForUIInstall()
  {
    lastSelectedRow = -1;
    preferredSize = new Dimension();
    largeModel = tree.isLargeModel();
    preferredSize = new Dimension();
    setModel(tree.getModel());
  }

  /**
   * Invoked from installUI after all the defaults/listeners have been
   * installed.
   */
  protected void completeUIInstall()
  {
    setShowsRootHandles(tree.getShowsRootHandles());
    updateRenderer();
    updateDepthOffset();
    setSelectionModel(tree.getSelectionModel());
    configureLayoutCache();
    treeState.setRootVisible(tree.isRootVisible()); 
    treeSelectionModel.setRowMapper(treeState);
    updateSize();
  }

  /**
   * Invoked from uninstallUI after all the defaults/listeners have been
   * uninstalled.
   */
  protected void completeUIUninstall()
  {
    tree = null;
  }

  /**
   * Installs the subcomponents of the tree, which is the renderer pane.
   */
  protected void installComponents()
  {
    currentCellRenderer = createDefaultCellRenderer();
    rendererPane = createCellRendererPane();
    createdRenderer = true;
    setCellRenderer(currentCellRenderer);
  }

  /**
   * Creates an instance of NodeDimensions that is able to determine the size of
   * a given node in the tree. The node dimensions must be created before
   * configuring the layout cache.
   * 
   * @return the NodeDimensions of a given node in the tree
   */
  protected AbstractLayoutCache.NodeDimensions createNodeDimensions()
  {
    return new NodeDimensionsHandler();
  }

  /**
   * Creates a listener that is reponsible for the updates the UI based on how
   * the tree changes.
   * 
   * @return the PropertyChangeListener that is reposnsible for the updates
   */
  protected PropertyChangeListener createPropertyChangeListener()
  {
    return new PropertyChangeHandler();
  }

  /**
   * Creates the listener responsible for updating the selection based on mouse
   * events.
   * 
   * @return the MouseListener responsible for updating.
   */
  protected MouseListener createMouseListener()
  {
    return new MouseHandler();
  }

  /**
   * Creates the listener that is responsible for updating the display when
   * focus is lost/grained.
   * 
   * @return the FocusListener responsible for updating.
   */
  protected FocusListener createFocusListener()
  {
    return new FocusHandler();
  }

  /**
   * Creates the listener reponsible for getting key events from the tree.
   * 
   * @return the KeyListener responsible for getting key events.
   */
  protected KeyListener createKeyListener()
  {
    return new KeyHandler();
  }

  /**
   * Creates the listener responsible for getting property change events from
   * the selection model.
   * 
   * @returns the PropertyChangeListener reponsible for getting property change
   *          events from the selection model.
   */
  protected PropertyChangeListener createSelectionModelPropertyChangeListener()
  {
    return new SelectionModelPropertyChangeHandler();
  }

  /**
   * Creates the listener that updates the display based on selection change
   * methods.
   * 
   * @return the TreeSelectionListener responsible for updating.
   */
  protected TreeSelectionListener createTreeSelectionListener()
  {
    return new TreeSelectionHandler();
  }

  /**
   * Creates a listener to handle events from the current editor
   * 
   * @return the CellEditorListener that handles events from the current editor
   */
  protected CellEditorListener createCellEditorListener()
  {
    return new CellEditorHandler();
  }

  /**
   * Creates and returns a new ComponentHandler. This is used for the large
   * model to mark the validCachedPreferredSize as invalid when the component
   * moves.
   * 
   * @return a new ComponentHandler.
   */
  protected ComponentListener createComponentListener()
  {
    return new ComponentHandler();
  }

  /**
   * Creates and returns the object responsible for updating the treestate when
   * a nodes expanded state changes.
   * 
   * @return the TreeExpansionListener responsible for updating the treestate
   */
  protected TreeExpansionListener createTreeExpansionListener()
  {
    return new TreeExpansionHandler();
  }

  /**
   * Creates the object responsible for managing what is expanded, as well as
   * the size of nodes.
   * 
   * @return the object responsible for managing what is expanded.
   */
  protected AbstractLayoutCache createLayoutCache()
  {
    return new VariableHeightLayoutCache();
  }

  /**
   * Returns the renderer pane that renderer components are placed in.
   * 
   * @return the rendererpane that render components are placed in.
   */
  protected CellRendererPane createCellRendererPane()
  {
    return new CellRendererPane();
  }

  /**
   * Creates a default cell editor.
   * 
   * @return the default cell editor.
   */
  protected TreeCellEditor createDefaultCellEditor()
  {
    DefaultTreeCellEditor ed;
    if (currentCellRenderer != null
        && currentCellRenderer instanceof DefaultTreeCellRenderer)
      ed = new DefaultTreeCellEditor(tree,
                                (DefaultTreeCellRenderer) currentCellRenderer);
    else
      ed = new DefaultTreeCellEditor(tree, null);
    return ed;
  }

  /**
   * Returns the default cell renderer that is used to do the stamping of each
   * node.
   * 
   * @return the default cell renderer that is used to do the stamping of each
   *         node.
   */
  protected TreeCellRenderer createDefaultCellRenderer()
  {
    return new DefaultTreeCellRenderer();
  }

  /**
   * Returns a listener that can update the tree when the model changes.
   * 
   * @return a listener that can update the tree when the model changes.
   */
  protected TreeModelListener createTreeModelListener()
  {
    return new TreeModelHandler();
  }

  /**
   * Uninstall all registered listeners
   */
  protected void uninstallListeners()
  {
    tree.removePropertyChangeListener(propertyChangeListener);
    tree.removeFocusListener(focusListener);
    tree.removeTreeSelectionListener(treeSelectionListener);
    tree.removeMouseListener(mouseListener);
    tree.removeKeyListener(keyListener);
    tree.removePropertyChangeListener(selectionModelPropertyChangeListener);
    tree.removeComponentListener(componentListener);
    tree.removeTreeExpansionListener(treeExpansionListener);

    TreeCellEditor tce = tree.getCellEditor();
    if (tce != null)
      tce.removeCellEditorListener(cellEditorListener);
    if (treeModel != null)
      treeModel.removeTreeModelListener(treeModelListener);
  }

  /**
   * Uninstall all keyboard actions.
   */
  protected void uninstallKeyboardActions()
  {
    tree.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).setParent(
                                                                              null);
    tree.getActionMap().setParent(null);
  }

  /**
   * Uninstall the rendererPane.
   */
  protected void uninstallComponents()
  {
    currentCellRenderer = null;
    rendererPane = null;
    createdRenderer = false;
    setCellRenderer(currentCellRenderer);
  }

  /**
   * The vertical element of legs between nodes starts at the bottom of the
   * parent node by default. This method makes the leg start below that.
   * 
   * @return the vertical leg buffer
   */
  protected int getVerticalLegBuffer()
  {
    return getRowHeight() / 2;
  }

  /**
   * The horizontal element of legs between nodes starts at the right of the
   * left-hand side of the child node by default. This method makes the leg end
   * before that.
   * 
   * @return the horizontal leg buffer
   */
  protected int getHorizontalLegBuffer()
  {
    return rightChildIndent / 2;
  }

  /**
   * Make all the nodes that are expanded in JTree expanded in LayoutCache. This
   * invokes updateExpandedDescendants with the root path.
   */
  protected void updateLayoutCacheExpandedNodes()
  {
    if (treeModel != null && treeModel.getRoot() != null)
      updateExpandedDescendants(new TreePath(treeModel.getRoot()));
  }

  /**
   * Updates the expanded state of all the descendants of the <code>path</code>
   * by getting the expanded descendants from the tree and forwarding to the
   * tree state.
   * 
   * @param path the path used to update the expanded states
   */
  protected void updateExpandedDescendants(TreePath path)
  {
    Enumeration expanded = tree.getExpandedDescendants(path);
    while (expanded.hasMoreElements())
      treeState.setExpandedState((TreePath) expanded.nextElement(), true);
  }

  /**
   * Returns a path to the last child of <code>parent</code>
   * 
   * @param parent is the topmost path to specified
   * @return a path to the last child of parent
   */
  protected TreePath getLastChildPath(TreePath parent)
  {
    return (TreePath) parent.getLastPathComponent();
  }

  /**
   * Updates how much each depth should be offset by.
   */
  protected void updateDepthOffset()
  {
    depthOffset += getVerticalLegBuffer();
  }

  /**
   * Updates the cellEditor based on editability of the JTree that we're
   * contained in. If the tree is editable but doesn't have a cellEditor, a
   * basic one will be used.
   */
  protected void updateCellEditor()
  {
    if (tree.isEditable() && cellEditor == null)
      setCellEditor(createDefaultCellEditor());
    createdCellEditor = true;
  }

  /**
   * Messaged from the tree we're in when the renderer has changed.
   */
  protected void updateRenderer()
  {
    if (tree != null)
      {
	TreeCellRenderer rend = tree.getCellRenderer();
	if (rend != null)
	  {
	    createdRenderer = false;
	    currentCellRenderer = rend;
	    if (createdCellEditor)
	      tree.setCellEditor(null);
	  }
	else
	  {
	    tree.setCellRenderer(createDefaultCellRenderer());
	    createdRenderer = true;
	  }
      }
    else
      {
	currentCellRenderer = null;
	createdRenderer = false;
      }

    updateCellEditor();
  }

  /**
   * Resets the treeState instance based on the tree we're providing the look
   * and feel for. The node dimensions handler is required and must be created
   * in advance.
   */
  protected void configureLayoutCache()
  {
    treeState = createLayoutCache();
    treeState.setNodeDimensions(nodeDimensions);
  }

  /**
   * Marks the cached size as being invalid, and messages the tree with
   * <code>treeDidChange</code>.
   */
  protected void updateSize()
  {
    preferredSize = null;
    updateCachedPreferredSize();
    tree.treeDidChange();
  }

  /**
   * Updates the <code>preferredSize</code> instance variable, which is
   * returned from <code>getPreferredSize()</code>.
   */
  protected void updateCachedPreferredSize()
  {
    validCachedPreferredSize = false;
  }

  /**
   * Messaged from the VisibleTreeNode after it has been expanded.
   * 
   * @param path is the path that has been expanded.
   */
  protected void pathWasExpanded(TreePath path)
  {
    validCachedPreferredSize = false;
    treeState.setExpandedState(path, true);
    tree.repaint();
  }

  /**
   * Messaged from the VisibleTreeNode after it has collapsed
   */
  protected void pathWasCollapsed(TreePath path)
  {
    validCachedPreferredSize = false;
    treeState.setExpandedState(path, false);
    tree.repaint();
  }

  /**
   * Install all defaults for the tree.
   */
  protected void installDefaults()
  {
    LookAndFeel.installColorsAndFont(tree, "Tree.background",
                                     "Tree.foreground", "Tree.font");
    
    hashColor = UIManager.getColor("Tree.hash");
    if (hashColor == null)
      hashColor = Color.black;
    
    tree.setOpaque(true);

    rightChildIndent = UIManager.getInt("Tree.rightChildIndent");
    leftChildIndent = UIManager.getInt("Tree.leftChildIndent");
    totalChildIndent = rightChildIndent + leftChildIndent;
    setRowHeight(UIManager.getInt("Tree.rowHeight"));
    tree.setRowHeight(getRowHeight());
    tree.setScrollsOnExpand(UIManager.getBoolean("Tree.scrollsOnExpand"));
    setExpandedIcon(UIManager.getIcon("Tree.expandedIcon"));
    setCollapsedIcon(UIManager.getIcon("Tree.collapsedIcon"));
  }

  /**
   * Install all keyboard actions for this
   */
  protected void installKeyboardActions()
  {
    InputMap focusInputMap =
      (InputMap) SharedUIDefaults.get("Tree.focusInputMap");
    SwingUtilities.replaceUIInputMap(tree, JComponent.WHEN_FOCUSED,
                                     focusInputMap);
    InputMap ancestorInputMap =
      (InputMap) SharedUIDefaults.get("Tree.ancestorInputMap");
    SwingUtilities.replaceUIInputMap(tree,
                                 JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
                                 ancestorInputMap);

    SwingUtilities.replaceUIActionMap(tree, getActionMap());
  }

  /**
   * Creates and returns the shared action map for JTrees.
   *
   * @return the shared action map for JTrees
   */
  private ActionMap getActionMap()
  {
    ActionMap am = (ActionMap) UIManager.get("Tree.actionMap");
    if (am == null)
      {
        am = createDefaultActions();
        UIManager.getLookAndFeelDefaults().put("Tree.actionMap", am);
      }
    return am;
  }

  /**
   * Creates the default actions when there are none specified by the L&F.
   *
   * @return the default actions
   */
  private ActionMap createDefaultActions()
  {
    ActionMapUIResource am = new ActionMapUIResource();
    Action action;

    // TreeHomeAction.
    action = new TreeHomeAction(-1, "selectFirst");
    am.put(action.getValue(Action.NAME), action);
    action = new TreeHomeAction(-1, "selectFirstChangeLead");
    am.put(action.getValue(Action.NAME), action);
    action = new TreeHomeAction(-1, "selectFirstExtendSelection");
    am.put(action.getValue(Action.NAME), action);
    action = new TreeHomeAction(1, "selectLast");
    am.put(action.getValue(Action.NAME), action);
    action = new TreeHomeAction(1, "selectLastChangeLead");
    am.put(action.getValue(Action.NAME), action);
    action = new TreeHomeAction(1, "selectLastExtendSelection");
    am.put(action.getValue(Action.NAME), action);

    // TreeIncrementAction.
    action = new TreeIncrementAction(-1, "selectPrevious");
    am.put(action.getValue(Action.NAME), action);
    action = new TreeIncrementAction(-1, "selectPreviousExtendSelection");
    am.put(action.getValue(Action.NAME), action);
    action = new TreeIncrementAction(-1, "selectPreviousChangeLead");
    am.put(action.getValue(Action.NAME), action);
    action = new TreeIncrementAction(1, "selectNext");
    am.put(action.getValue(Action.NAME), action);
    action = new TreeIncrementAction(1, "selectNextExtendSelection");
    am.put(action.getValue(Action.NAME), action);
    action = new TreeIncrementAction(1, "selectNextChangeLead");
    am.put(action.getValue(Action.NAME), action);

    // TreeTraverseAction.
    action = new TreeTraverseAction(-1, "selectParent");
    am.put(action.getValue(Action.NAME), action);
    action = new TreeTraverseAction(1, "selectChild");
    am.put(action.getValue(Action.NAME), action);
    
    // TreeToggleAction.
    action = new TreeToggleAction("toggleAndAnchor");
    am.put(action.getValue(Action.NAME), action);

    // TreePageAction.
    action = new TreePageAction(-1, "scrollUpChangeSelection");
    am.put(action.getValue(Action.NAME), action);
    action = new TreePageAction(-1, "scrollUpExtendSelection");
    am.put(action.getValue(Action.NAME), action);
    action = new TreePageAction(-1, "scrollUpChangeLead");
    am.put(action.getValue(Action.NAME), action);
    action = new TreePageAction(1, "scrollDownChangeSelection");
    am.put(action.getValue(Action.NAME), action);
    action = new TreePageAction(1, "scrollDownExtendSelection");
    am.put(action.getValue(Action.NAME), action);
    action = new TreePageAction(1, "scrollDownChangeLead");
    am.put(action.getValue(Action.NAME), action);
    
    // Tree editing actions
    action = new TreeStartEditingAction("startEditing");
    am.put(action.getValue(Action.NAME), action);
    action = new TreeCancelEditingAction("cancel");
    am.put(action.getValue(Action.NAME), action);
    

    return am;
  }

  /**
   * Converts the modifiers.
   * 
   * @param mod - modifier to convert
   * @returns the new modifier
   */
  private int convertModifiers(int mod)
  {
    if ((mod & KeyEvent.SHIFT_DOWN_MASK) != 0)
      {
        mod |= KeyEvent.SHIFT_MASK;
        mod &= ~ KeyEvent.SHIFT_DOWN_MASK;
      }
    if ((mod & KeyEvent.CTRL_DOWN_MASK) != 0)
      {
        mod |= KeyEvent.CTRL_MASK;
        mod &= ~ KeyEvent.CTRL_DOWN_MASK;
      }
    if ((mod & KeyEvent.META_DOWN_MASK) != 0)
      {
        mod |= KeyEvent.META_MASK;
        mod &= ~ KeyEvent.META_DOWN_MASK;
      }
    if ((mod & KeyEvent.ALT_DOWN_MASK) != 0)
      {
        mod |= KeyEvent.ALT_MASK;
        mod &= ~ KeyEvent.ALT_DOWN_MASK;
      }
    if ((mod & KeyEvent.ALT_GRAPH_DOWN_MASK) != 0)
      {
        mod |= KeyEvent.ALT_GRAPH_MASK;
        mod &= ~ KeyEvent.ALT_GRAPH_DOWN_MASK;
      }
    return mod;
  }

  /**
   * Install all listeners for this
   */
  protected void installListeners()
  {
    propertyChangeListener = createPropertyChangeListener();
    tree.addPropertyChangeListener(propertyChangeListener);

    focusListener = createFocusListener();
    tree.addFocusListener(focusListener);

    treeSelectionListener = createTreeSelectionListener();
    tree.addTreeSelectionListener(treeSelectionListener);

    mouseListener = createMouseListener();
    tree.addMouseListener(mouseListener);

    keyListener = createKeyListener();
    tree.addKeyListener(keyListener);

    selectionModelPropertyChangeListener =
      createSelectionModelPropertyChangeListener();
    if (treeSelectionModel != null
        && selectionModelPropertyChangeListener != null)
      {
        treeSelectionModel.addPropertyChangeListener(
            selectionModelPropertyChangeListener);
      }

    componentListener = createComponentListener();
    tree.addComponentListener(componentListener);

    treeExpansionListener = createTreeExpansionListener();
    tree.addTreeExpansionListener(treeExpansionListener);

    treeModelListener = createTreeModelListener();
    if (treeModel != null)
      treeModel.addTreeModelListener(treeModelListener);

    cellEditorListener = createCellEditorListener();
  }

  /**
   * Install the UI for the component
   * 
   * @param c the component to install UI for
   */
  public void installUI(JComponent c)
  {
    tree = (JTree) c;

    prepareForUIInstall();
    installDefaults();
    installComponents();
    installKeyboardActions();
    installListeners();
    completeUIInstall();
  }
  
  /**
   * Uninstall the defaults for the tree
   */
  protected void uninstallDefaults()
  {
    tree.setFont(null);
    tree.setForeground(null);
    tree.setBackground(null);
  }

  /**
   * Uninstall the UI for the component
   * 
   * @param c the component to uninstall UI for
   */
  public void uninstallUI(JComponent c)
  {
    completeEditing();

    prepareForUIUninstall();
    uninstallDefaults();
    uninstallKeyboardActions();
    uninstallListeners();
    uninstallComponents();
    completeUIUninstall();
  }

  /**
   * Paints the specified component appropriate for the look and feel. This
   * method is invoked from the ComponentUI.update method when the specified
   * component is being painted. Subclasses should override this method and use
   * the specified Graphics object to render the content of the component.
   * 
   * @param g the Graphics context in which to paint
   * @param c the component being painted; this argument is often ignored, but
   *          might be used if the UI object is stateless and shared by multiple
   *          components
   */
  public void paint(Graphics g, JComponent c)
  {
    JTree tree = (JTree) c;
    
    int rows = treeState.getRowCount();
    
    if (rows == 0)
      // There is nothing to do if the tree is empty.
      return;

    Rectangle clip = g.getClipBounds();

    Insets insets = tree.getInsets();

    if (clip != null && treeModel != null)
      {
        int startIndex = tree.getClosestRowForLocation(clip.x, clip.y);
        int endIndex = tree.getClosestRowForLocation(clip.x + clip.width,
                                                     clip.y + clip.height);

        // Also paint dashes to the invisible nodes below.
        // These should be painted first, otherwise they may cover
        // the control icons.
        if (endIndex < rows)
          for (int i = endIndex + 1; i < rows; i++)
            {
              TreePath path = treeState.getPathForRow(i);
              if (isLastChild(path))
                paintVerticalPartOfLeg(g, clip, insets, path);
            }

        // The two loops are required to ensure that the lines are not
        // painted over the other tree components.

        int n = endIndex - startIndex + 1;
        Rectangle[] bounds = new Rectangle[n];
        boolean[] isLeaf = new boolean[n];
        boolean[] isExpanded = new boolean[n];
        TreePath[] path = new TreePath[n];
        int k;

        k = 0;
        for (int i = startIndex; i <= endIndex; i++, k++)
          {
            path[k] = treeState.getPathForRow(i);
            isLeaf[k] = treeModel.isLeaf(path[k].getLastPathComponent());
            isExpanded[k] = tree.isExpanded(path[k]);
            bounds[k] = getPathBounds(tree, path[k]);

            paintHorizontalPartOfLeg(g, clip, insets, bounds[k], path[k], i,
                                     isExpanded[k], false, isLeaf[k]);
            if (isLastChild(path[k]))
              paintVerticalPartOfLeg(g, clip, insets, path[k]);
          }

        k = 0;
        for (int i = startIndex; i <= endIndex; i++, k++)
          {
            paintRow(g, clip, insets, bounds[k], path[k], i, isExpanded[k],
                     false, isLeaf[k]);
          }
      }
  }

  /**
   * Check if the path is referring to the last child of some parent.
   */
  private boolean isLastChild(TreePath path)
  {
    if (path instanceof GnuPath)
      {
        // Except the seldom case when the layout cache is changed, this
        // optimized code will be executed.
        return ((GnuPath) path).isLastChild;
      }
    else
      {
        // Non optimized general case.
        TreePath parent = path.getParentPath();
        if (parent == null)
          return false;
        int childCount = treeState.getVisibleChildCount(parent);
        int p = treeModel.getIndexOfChild(parent, path.getLastPathComponent());
        return p == childCount - 1;
      }
  }

  /**
   * Ensures that the rows identified by beginRow through endRow are visible.
   * 
   * @param beginRow is the first row
   * @param endRow is the last row
   */
  protected void ensureRowsAreVisible(int beginRow, int endRow)
  {
    if (beginRow < endRow)
      {
        int temp = endRow;
        endRow = beginRow;
        beginRow = temp;
      }

    for (int i = beginRow; i < endRow; i++)
      {
        TreePath path = getPathForRow(tree, i);
        if (! tree.isVisible(path))
          tree.makeVisible(path);
      }
  }

  /**
   * Sets the preferred minimum size.
   * 
   * @param newSize is the new preferred minimum size.
   */
  public void setPreferredMinSize(Dimension newSize)
  {
    preferredMinSize = newSize;
  }

  /**
   * Gets the preferred minimum size.
   * 
   * @returns the preferred minimum size.
   */
  public Dimension getPreferredMinSize()
  {
    if (preferredMinSize == null)
      return getPreferredSize(tree);
    else
      return preferredMinSize;
  }

  /**
   * Returns the preferred size to properly display the tree, this is a cover
   * method for getPreferredSize(c, false).
   * 
   * @param c the component whose preferred size is being queried; this argument
   *          is often ignored but might be used if the UI object is stateless
   *          and shared by multiple components
   * @return the preferred size
   */
  public Dimension getPreferredSize(JComponent c)
  {
    return getPreferredSize(c, false);
  }

  /**
   * Returns the preferred size to represent the tree in c. If checkConsistancy
   * is true, checkConsistancy is messaged first.
   * 
   * @param c the component whose preferred size is being queried.
   * @param checkConsistancy if true must check consistancy
   * @return the preferred size
   */
  public Dimension getPreferredSize(JComponent c, boolean checkConsistancy)
  {
    if (! validCachedPreferredSize)
      {
        Rectangle size = tree.getBounds();
        // Add the scrollbar dimensions to the preferred size.
        preferredSize = new Dimension(treeState.getPreferredWidth(size),
                                      treeState.getPreferredHeight());
        validCachedPreferredSize = true;
      }
    return preferredSize;
  }

  /**
   * Returns the minimum size for this component. Which will be the min
   * preferred size or (0,0).
   * 
   * @param c the component whose min size is being queried.
   * @returns the preferred size or null
   */
  public Dimension getMinimumSize(JComponent c)
  {
    return preferredMinSize = getPreferredSize(c);
  }

  /**
   * Returns the maximum size for the component, which will be the preferred
   * size if the instance is currently in JTree or (0,0).
   * 
   * @param c the component whose preferred size is being queried
   * @return the max size or null
   */
  public Dimension getMaximumSize(JComponent c)
  {
    return getPreferredSize(c);
  }

  /**
   * Messages to stop the editing session. If the UI the receiver is providing
   * the look and feel for returns true from
   * <code>getInvokesStopCellEditing</code>, stopCellEditing will be invoked
   * on the current editor. Then completeEditing will be messaged with false,
   * true, false to cancel any lingering editing.
   */
  protected void completeEditing()
  {
    completeEditing(false, true, false);
  }

  /**
   * Stops the editing session. If messageStop is true, the editor is messaged
   * with stopEditing, if messageCancel is true the editor is messaged with
   * cancelEditing. If messageTree is true, the treeModel is messaged with
   * valueForPathChanged.
   * 
   * @param messageStop message to stop editing
   * @param messageCancel message to cancel editing
   * @param messageTree message to treeModel
   */
  protected void completeEditing(boolean messageStop, boolean messageCancel,
                                 boolean messageTree)
  {
    // Make no attempt to complete the non existing editing session.
    if (!isEditing(tree))
      return;
    
    if (messageStop)
      {
        getCellEditor().stopCellEditing();
        stopEditingInCompleteEditing = true;
      }

    if (messageCancel)
      {
        getCellEditor().cancelCellEditing();
        stopEditingInCompleteEditing = true;
      }

    if (messageTree)
      {
        TreeCellEditor editor = getCellEditor();
        if (editor != null)
          {
            Object value = editor.getCellEditorValue();
            treeModel.valueForPathChanged(tree.getLeadSelectionPath(), value);
          }
      }
  }

  /**
   * Will start editing for node if there is a cellEditor and shouldSelectCall
   * returns true. This assumes that path is valid and visible.
   * 
   * @param path is the path to start editing
   * @param event is the MouseEvent performed on the path
   * @return true if successful
   */
  protected boolean startEditing(TreePath path, MouseEvent event)
  {
    updateCellEditor();
    TreeCellEditor ed = getCellEditor();

    if (ed != null && (event == EDIT || ed.shouldSelectCell(event))
        && ed.isCellEditable(event))
      {
        Rectangle bounds = getPathBounds(tree, path);

        // Extend the right boundary till the tree width.
        bounds.width = tree.getWidth() - bounds.x;

        editingPath = path;
        editingRow = tree.getRowForPath(editingPath);

        Object value = editingPath.getLastPathComponent();

        stopEditingInCompleteEditing = false;
        boolean expanded = tree.isExpanded(editingPath);
        isEditing = true;
        editingComponent = ed.getTreeCellEditorComponent(tree, value, true,
                                                         expanded,
                                                         isLeaf(editingRow),
                                                         editingRow);

        // Remove all previous components (if still present). Only one
        // container with the editing component inside is allowed in the tree.
        tree.removeAll();

        // The editing component must be added to its container. We add the
        // container, not the editing component itself.
        Component container = editingComponent.getParent();
        container.setBounds(bounds);
        tree.add(container);
        editingComponent.requestFocus();

        return true;
      }
    return false;
  }

  /**
   * If the <code>mouseX</code> and <code>mouseY</code> are in the expand or
   * collapse region of the row, this will toggle the row.
   * 
   * @param path the path we are concerned with
   * @param mouseX is the cursor's x position
   * @param mouseY is the cursor's y position
   */
  protected void checkForClickInExpandControl(TreePath path, int mouseX,
                                              int mouseY)
  {
    if (isLocationInExpandControl(path, mouseX, mouseY))
      handleExpandControlClick(path, mouseX, mouseY);
  }

  /**
   * Returns true if the <code>mouseX</code> and <code>mouseY</code> fall in
   * the area of row that is used to expand/collpse the node and the node at row
   * does not represent a leaf.
   * 
   * @param path the path we are concerned with
   * @param mouseX is the cursor's x position
   * @param mouseY is the cursor's y position
   * @return true if the <code>mouseX</code> and <code>mouseY</code> fall in
   *         the area of row that is used to expand/collpse the node and the
   *         node at row does not represent a leaf.
   */
  protected boolean isLocationInExpandControl(TreePath path, int mouseX,
                                              int mouseY)
  {
    boolean cntlClick = false;
    if (! treeModel.isLeaf(path.getLastPathComponent()))
      {
        int width;
        Icon expandedIcon = getExpandedIcon();
        if (expandedIcon != null)
          width = expandedIcon.getIconWidth();
        else
          // Only guessing. This is the width of
          // the tree control icon in Metal L&F.
          width = 18;

        Insets i = tree.getInsets();
        
        int depth;
        if (isRootVisible())
          depth = path.getPathCount()-1;
        else
          depth = path.getPathCount()-2;
        
        int left = getRowX(tree.getRowForPath(path), depth)
                   - width + i.left;
        cntlClick = mouseX >= left && mouseX <= left + width;
      }
    return cntlClick;
  }

  /**
   * Messaged when the user clicks the particular row, this invokes
   * toggleExpandState.
   * 
   * @param path the path we are concerned with
   * @param mouseX is the cursor's x position
   * @param mouseY is the cursor's y position
   */
  protected void handleExpandControlClick(TreePath path, int mouseX, int mouseY)
  {
    toggleExpandState(path);
  }

  /**
   * Expands path if it is not expanded, or collapses row if it is expanded. If
   * expanding a path and JTree scroll on expand, ensureRowsAreVisible is
   * invoked to scroll as many of the children to visible as possible (tries to
   * scroll to last visible descendant of path).
   * 
   * @param path the path we are concerned with
   */
  protected void toggleExpandState(TreePath path)
  {
    // tree.isExpanded(path) would do the same, but treeState knows faster.
    if (treeState.isExpanded(path))
      tree.collapsePath(path);
    else
      tree.expandPath(path);
  }

  /**
   * Returning true signifies a mouse event on the node should toggle the
   * selection of only the row under the mouse. The BasisTreeUI treats the
   * event as "toggle selection event" if the CTRL button was pressed while
   * clicking. The event is not counted as toggle event if the associated
   * tree does not support the multiple selection.
   * 
   * @param event is the MouseEvent performed on the row.
   * @return true signifies a mouse event on the node should toggle the
   *         selection of only the row under the mouse.
   */
  protected boolean isToggleSelectionEvent(MouseEvent event)
  {
    return 
      (tree.getSelectionModel().getSelectionMode() != 
        TreeSelectionModel.SINGLE_TREE_SELECTION) &&
      ((event.getModifiersEx() & InputEvent.CTRL_DOWN_MASK) != 0);  
  }

  /**
   * Returning true signifies a mouse event on the node should select from the
   * anchor point. The BasisTreeUI treats the event as "multiple selection
   * event" if the SHIFT button was pressed while clicking. The event is not
   * counted as multiple selection event if the associated tree does not support
   * the multiple selection.
   * 
   * @param event is the MouseEvent performed on the node.
   * @return true signifies a mouse event on the node should select from the
   *         anchor point.
   */
  protected boolean isMultiSelectEvent(MouseEvent event)
  {
    return 
      (tree.getSelectionModel().getSelectionMode() != 
        TreeSelectionModel.SINGLE_TREE_SELECTION) &&
      ((event.getModifiersEx() & InputEvent.SHIFT_DOWN_MASK) != 0);  
  }

  /**
   * Returning true indicates the row under the mouse should be toggled based on
   * the event. This is invoked after checkForClickInExpandControl, implying the
   * location is not in the expand (toggle) control.
   * 
   * @param event is the MouseEvent performed on the row.
   * @return true indicates the row under the mouse should be toggled based on
   *         the event.
   */
  protected boolean isToggleEvent(MouseEvent event)
  {
    boolean toggle = false;
    if (SwingUtilities.isLeftMouseButton(event))
      {
        int clickCount = tree.getToggleClickCount();
        if (clickCount > 0 && event.getClickCount() == clickCount)
          toggle = true;
      }
    return toggle;
  }

  /**
   * Messaged to update the selection based on a MouseEvent over a particular
   * row. If the even is a toggle selection event, the row is either selected,
   * or deselected. If the event identifies a multi selection event, the
   * selection is updated from the anchor point. Otherwise, the row is selected,
   * and the previous selection is cleared.</p>
   * 
   * @param path is the path selected for an event
   * @param event is the MouseEvent performed on the path.
   * 
   * @see #isToggleSelectionEvent(MouseEvent)
   * @see #isMultiSelectEvent(MouseEvent)
   */
  protected void selectPathForEvent(TreePath path, MouseEvent event)
  {
    if (isToggleSelectionEvent(event))
      {
        // The event selects or unselects the clicked row.
        if (tree.isPathSelected(path))
          tree.removeSelectionPath(path);
        else
          {
            tree.addSelectionPath(path);
            tree.setAnchorSelectionPath(path);
          }
      }
    else if (isMultiSelectEvent(event))
      {
        // The event extends selection form anchor till the clicked row.
        TreePath anchor = tree.getAnchorSelectionPath();
        if (anchor != null)
          {
            int aRow = getRowForPath(tree, anchor);
            tree.addSelectionInterval(aRow, getRowForPath(tree, path));
          }
        else
          tree.addSelectionPath(path);
      }
    else
      {
        // This is an ordinary event that just selects the clicked row.
        tree.setSelectionPath(path);
        if (isToggleEvent(event))
          toggleExpandState(path);
      }
  }

  /**
   * Returns true if the node at <code>row</code> is a leaf.
   * 
   * @param row is the row we are concerned with.
   * @return true if the node at <code>row</code> is a leaf.
   */
  protected boolean isLeaf(int row)
  {
    TreePath pathForRow = getPathForRow(tree, row);
    if (pathForRow == null)
      return true;

    Object node = pathForRow.getLastPathComponent();
    return treeModel.isLeaf(node);
  }
  
  /**
   * The action to start editing at the current lead selection path.
   */
  class TreeStartEditingAction
      extends AbstractAction
  {
    /**
     * Creates the new tree cancel editing action.
     * 
     * @param name the name of the action (used in toString).
     */
    public TreeStartEditingAction(String name)
    {
      super(name);
    }    
    
    /**
     * Start editing at the current lead selection path.
     * 
     * @param e the ActionEvent that caused this action.
     */
    public void actionPerformed(ActionEvent e)
    {
      TreePath lead = tree.getLeadSelectionPath();
      if (!tree.isEditing()) 
        tree.startEditingAtPath(lead);
    }
  }  

  /**
   * Updates the preferred size when scrolling, if necessary.
   */
  public class ComponentHandler
      extends ComponentAdapter
      implements ActionListener
  {
    /**
     * Timer used when inside a scrollpane and the scrollbar is adjusting
     */
    protected Timer timer;

    /** ScrollBar that is being adjusted */
    protected JScrollBar scrollBar;

    /**
     * Constructor
     */
    public ComponentHandler()
    {
      // Nothing to do here.
    }

    /**
     * Invoked when the component's position changes.
     * 
     * @param e the event that occurs when moving the component
     */
    public void componentMoved(ComponentEvent e)
    {
      if (timer == null)
        {
          JScrollPane scrollPane = getScrollPane();
          if (scrollPane == null)
            updateSize();
          else
            {
              // Determine the scrollbar that is adjusting, if any, and
              // start the timer for that. If no scrollbar is adjusting,
              // we simply call updateSize().
              scrollBar = scrollPane.getVerticalScrollBar();
              if (scrollBar == null || !scrollBar.getValueIsAdjusting())
                {
                  // It's not the vertical scrollbar, try the horizontal one.
                  scrollBar = scrollPane.getHorizontalScrollBar();
                  if (scrollBar != null && scrollBar.getValueIsAdjusting())
                    startTimer();
                  else
                    updateSize();
                }
              else
                {
                  startTimer();
                }
            }
        }
    }

    /**
     * Creates, if necessary, and starts a Timer to check if needed to resize
     * the bounds
     */
    protected void startTimer()
    {
      if (timer == null)
        {
          timer = new Timer(200, this);
          timer.setRepeats(true);
        }
      timer.start();
    }

    /**
     * Returns the JScrollPane housing the JTree, or null if one isn't found.
     * 
     * @return JScrollPane housing the JTree, or null if one isn't found.
     */
    protected JScrollPane getScrollPane()
    {
      JScrollPane found = null;
      Component p = tree.getParent();
      while (p != null && !(p instanceof JScrollPane))
        p = p.getParent();
      if (p instanceof JScrollPane)
        found = (JScrollPane) p;
      return found;
    }

    /**
     * Public as a result of Timer. If the scrollBar is null, or not adjusting,
     * this stops the timer and updates the sizing.
     * 
     * @param ae is the action performed
     */
    public void actionPerformed(ActionEvent ae)
    {
      if (scrollBar == null || !scrollBar.getValueIsAdjusting())
        {
          if (timer != null)
            timer.stop();
          updateSize();
          timer = null;
          scrollBar = null;
        }
    }
  }

  /**
   * Listener responsible for getting cell editing events and updating the tree
   * accordingly.
   */
  public class CellEditorHandler
      implements CellEditorListener
  {
    /**
     * Constructor
     */
    public CellEditorHandler()
    {
      // Nothing to do here.
    }

    /**
     * Messaged when editing has stopped in the tree. Tells the listeners
     * editing has stopped.
     * 
     * @param e is the notification event
     */
    public void editingStopped(ChangeEvent e)
    {
      stopEditing(tree);
    }

    /**
     * Messaged when editing has been canceled in the tree. This tells the
     * listeners the editor has canceled editing.
     * 
     * @param e is the notification event
     */
    public void editingCanceled(ChangeEvent e)
    {
      cancelEditing(tree);
    }
  } // CellEditorHandler

  /**
   * Repaints the lead selection row when focus is lost/grained.
   */
  public class FocusHandler
      implements FocusListener
  {
    /**
     * Constructor
     */
    public FocusHandler()
    {
      // Nothing to do here.
    }

    /**
     * Invoked when focus is activated on the tree we're in, redraws the lead
     * row. Invoked when a component gains the keyboard focus. The method
     * repaints the lead row that is shown differently when the tree is in
     * focus.
     * 
     * @param e is the focus event that is activated
     */
    public void focusGained(FocusEvent e)
    {
      repaintLeadRow();
    }

    /**
     * Invoked when focus is deactivated on the tree we're in, redraws the lead
     * row. Invoked when a component loses the keyboard focus. The method
     * repaints the lead row that is shown differently when the tree is in
     * focus.
     * 
     * @param e is the focus event that is deactivated
     */
    public void focusLost(FocusEvent e)
    {
      repaintLeadRow();
    }

    /**
     * Repaint the lead row.
     */
    void repaintLeadRow()
    {
      TreePath lead = tree.getLeadSelectionPath();
      if (lead != null)
        tree.repaint(tree.getPathBounds(lead));
    }
  }

  /**
   * This is used to get multiple key down events to appropriately genereate
   * events.
   */
  public class KeyHandler
      extends KeyAdapter
  {
    /** Key code that is being generated for. */
    protected Action repeatKeyAction;

    /** Set to true while keyPressed is active */
    protected boolean isKeyDown;

    /**
     * Constructor
     */
    public KeyHandler()
    {
      // Nothing to do here.
    }

    /**
     * Invoked when a key has been typed. Moves the keyboard focus to the first
     * element whose first letter matches the alphanumeric key pressed by the
     * user. Subsequent same key presses move the keyboard focus to the next
     * object that starts with the same letter.
     * 
     * @param e the key typed
     */
    public void keyTyped(KeyEvent e)
    {
      char typed = Character.toLowerCase(e.getKeyChar());
      for (int row = tree.getLeadSelectionRow() + 1;
        row < tree.getRowCount(); row++)
        {
           if (checkMatch(row, typed))
             {
               tree.setSelectionRow(row);
               tree.scrollRowToVisible(row);
               return;
             }
        }
      
      // Not found below, search above:
      for (int row = 0; row < tree.getLeadSelectionRow(); row++)
        {
           if (checkMatch(row, typed))
             {
               tree.setSelectionRow(row);
               tree.scrollRowToVisible(row);               
               return;
             }
        }
    }
    
    /**
     * Check if the given tree row starts with this character
     * 
     * @param row the tree row
     * @param typed the typed char, must be converted to lowercase
     * @return true if the given tree row starts with this character
     */
    boolean checkMatch(int row, char typed)
    {
      TreePath path = treeState.getPathForRow(row);
      String node = path.getLastPathComponent().toString();
      if (node.length() > 0)
        {
          char x = node.charAt(0);
          if (typed == Character.toLowerCase(x))
            return true;
        }
      return false;
    }

    /**
     * Invoked when a key has been pressed.
     * 
     * @param e the key pressed
     */
    public void keyPressed(KeyEvent e)
    {
      // Nothing to do here.
    }

    /**
     * Invoked when a key has been released
     * 
     * @param e the key released
     */
    public void keyReleased(KeyEvent e)
    {
      // Nothing to do here.
    }
  }

  /**
   * MouseListener is responsible for updating the selection based on mouse
   * events.
   */
  public class MouseHandler
      extends MouseAdapter
      implements MouseMotionListener
  {
    /**
     * Constructor
     */
    public MouseHandler()
    {
      // Nothing to do here.
    }

    /**
     * Invoked when a mouse button has been pressed on a component.
     * 
     * @param e is the mouse event that occured
     */
    public void mousePressed(MouseEvent e)
    {
      // Any mouse click cancels the previous waiting edit action, initiated
      // by the single click on the selected node.
      if (startEditTimer != null)
        {
          startEditTimer.stop();
          startEditTimer = null;
        }

      if (tree != null && tree.isEnabled())
        {
          // Always end the current editing session if clicked on the
          // tree and outside the bounds of the editing component.
          if (isEditing(tree))
            if (!stopEditing(tree))
            // Return if we have failed to cancel the editing session.
              return;
 
          int x = e.getX();
          int y = e.getY();
          TreePath path = getClosestPathForLocation(tree, x, y);

          if (path != null)
            {
              Rectangle bounds = getPathBounds(tree, path);
              if (SwingUtilities.isLeftMouseButton(e))
                checkForClickInExpandControl(path, x, y);

              if (x > bounds.x && x <= (bounds.x + bounds.width))
                {
                  TreePath currentLead = tree.getLeadSelectionPath();
                  if (currentLead != null && currentLead.equals(path)
                      && e.getClickCount() == 1 && tree.isEditable())
                    {
                      // Schedule the editing session.
                      final TreePath editPath = path;
                      
                      // The code below handles the required click-pause-click
                      // functionality which must be present in the tree UI. 
                      // If the next click comes after the
                      // time longer than the double click interval AND
                      // the same node stays focused for the WAIT_TILL_EDITING
                      // duration, the timer starts the editing session.
                      if (startEditTimer != null)
                        startEditTimer.stop();

                      startEditTimer = new Timer(WAIT_TILL_EDITING,
                         new ActionListener()
                           {
                              public void actionPerformed(ActionEvent e)
                                {
                                   startEditing(editPath, EDIT);
                                }
                            });
                      
                      startEditTimer.setRepeats(false);
                      startEditTimer.start();
                    }
                  else
                    {
                      if (e.getClickCount() == 2)
                        toggleExpandState(path);
                      else
                        selectPathForEvent(path, e);
                    }
                }
            }
        }

      // We need to request the focus.
      tree.requestFocusInWindow();
    }

    /**
     * Invoked when a mouse button is pressed on a component and then dragged.
     * MOUSE_DRAGGED events will continue to be delivered to the component where
     * the drag originated until the mouse button is released (regardless of
     * whether the mouse position is within the bounds of the component).
     * 
     * @param e is the mouse event that occured
     */
    public void mouseDragged(MouseEvent e)
    throws NotImplementedException
    {
      // TODO: What should be done here, if anything?
    }

    /**
     * Invoked when the mouse button has been moved on a component (with no
     * buttons no down).
     * 
     * @param e the mouse event that occured
     */
    public void mouseMoved(MouseEvent e)
    throws NotImplementedException
    {
      // TODO: What should be done here, if anything?
    }

    /**
     * Invoked when a mouse button has been released on a component.
     * 
     * @param e is the mouse event that occured
     */
    public void mouseReleased(MouseEvent e)
    throws NotImplementedException
    {
      // TODO: What should be done here, if anything?
    }
  }

  /**
   * MouseInputHandler handles passing all mouse events, including mouse motion
   * events, until the mouse is released to the destination it is constructed
   * with.
   */
  public class MouseInputHandler
      implements MouseInputListener
  {
    /** Source that events are coming from */
    protected Component source;

    /** Destination that receives all events. */
    protected Component destination;

    /**
     * Constructor
     * 
     * @param source that events are coming from
     * @param destination that receives all events
     * @param e is the event received
     */
    public MouseInputHandler(Component source, Component destination,
                             MouseEvent e)
    {
      this.source = source;
      this.destination = destination;
    }

    /**
     * Invoked when the mouse button has been clicked (pressed and released) on
     * a component.
     * 
     * @param e mouse event that occured
     */
    public void mouseClicked(MouseEvent e)
    throws NotImplementedException
    {
      // TODO: What should be done here, if anything?
    }

    /**
     * Invoked when a mouse button has been pressed on a component.
     * 
     * @param e mouse event that occured
     */
    public void mousePressed(MouseEvent e)
    throws NotImplementedException
    {
      // TODO: What should be done here, if anything?
    }

    /**
     * Invoked when a mouse button has been released on a component.
     * 
     * @param e mouse event that occured
     */
    public void mouseReleased(MouseEvent e)
    throws NotImplementedException
    {
      // TODO: What should be done here, if anything?
    }

    /**
     * Invoked when the mouse enters a component.
     * 
     * @param e mouse event that occured
     */
    public void mouseEntered(MouseEvent e)
    throws NotImplementedException
    {
      // TODO: What should be done here, if anything?
    }

    /**
     * Invoked when the mouse exits a component.
     * 
     * @param e mouse event that occured
     */
    public void mouseExited(MouseEvent e)
    throws NotImplementedException
    {
      // TODO: What should be done here, if anything?
    }

    /**
     * Invoked when a mouse button is pressed on a component and then dragged.
     * MOUSE_DRAGGED events will continue to be delivered to the component where
     * the drag originated until the mouse button is released (regardless of
     * whether the mouse position is within the bounds of the component).
     * 
     * @param e mouse event that occured
     */
    public void mouseDragged(MouseEvent e)
    throws NotImplementedException
    {
      // TODO: What should be done here, if anything?
    }

    /**
     * Invoked when the mouse cursor has been moved onto a component but no
     * buttons have been pushed.
     * 
     * @param e mouse event that occured
     */
    public void mouseMoved(MouseEvent e)
    throws NotImplementedException
    {
      // TODO: What should be done here, if anything?
    }

    /**
     * Removes event from the source
     */
    protected void removeFromSource()
    throws NotImplementedException
    {
      // TODO: Implement this properly.
    }
  }

  /**
   * Class responsible for getting size of node, method is forwarded to
   * BasicTreeUI method. X location does not include insets, that is handled in
   * getPathBounds.
   */
  public class NodeDimensionsHandler
      extends AbstractLayoutCache.NodeDimensions
  {
    /**
     * Constructor
     */
    public NodeDimensionsHandler()
    {
      // Nothing to do here.
    }

    /**
     * Returns, by reference in bounds, the size and x origin to place value at.
     * The calling method is responsible for determining the Y location. If
     * bounds is null, a newly created Rectangle should be returned, otherwise
     * the value should be placed in bounds and returned.
     * 
     * @param cell the value to be represented
     * @param row row being queried
     * @param depth the depth of the row
     * @param expanded true if row is expanded
     * @param size a Rectangle containing the size needed to represent value
     * @return containing the node dimensions, or null if node has no dimension
     */
    public Rectangle getNodeDimensions(Object cell, int row, int depth,
                                       boolean expanded, Rectangle size)
    {
      if (size == null || cell == null)
        return null;

      String s = cell.toString();
      Font f = tree.getFont();
      FontMetrics fm = tree.getToolkit().getFontMetrics(f);

      if (s != null)
        {
          TreePath path = treeState.getPathForRow(row);
          size.x = getRowX(row, depth);
          size.width = SwingUtilities.computeStringWidth(fm, s);
          size.width = size.width + getCurrentControlIcon(path).getIconWidth()
                       + gap + getNodeIcon(path).getIconWidth();
          size.height = getMaxHeight(tree);
          size.y = size.height * row;
        }

      return size;
    }

    /**
     * Returns the amount to indent the given row
     * 
     * @return amount to indent the given row.
     */
    protected int getRowX(int row, int depth)
    {
      return BasicTreeUI.this.getRowX(row, depth);
    }
  } // NodeDimensionsHandler

  /**
   * PropertyChangeListener for the tree. Updates the appropriate variable, or
   * TreeState, based on what changes.
   */
  public class PropertyChangeHandler
      implements PropertyChangeListener
  {

    /**
     * Constructor
     */
    public PropertyChangeHandler()
    {
      // Nothing to do here.
    }

    /**
     * This method gets called when a bound property is changed.
     * 
     * @param event A PropertyChangeEvent object describing the event source and
     *          the property that has changed.
     */
    public void propertyChange(PropertyChangeEvent event)
    {
      String property = event.getPropertyName();
      if (property.equals(JTree.ROOT_VISIBLE_PROPERTY))
        {
          validCachedPreferredSize = false;
          treeState.setRootVisible(tree.isRootVisible());
          tree.repaint();
        }
      else if (property.equals(JTree.SELECTION_MODEL_PROPERTY))
        {
          treeSelectionModel = tree.getSelectionModel();
          treeSelectionModel.setRowMapper(treeState);
        }
      else if (property.equals(JTree.TREE_MODEL_PROPERTY))
        {
          setModel(tree.getModel());
        }
      else if (property.equals(JTree.CELL_RENDERER_PROPERTY))
        {
          setCellRenderer(tree.getCellRenderer());
          // Update layout.
          if (treeState != null)
            treeState.invalidateSizes();
        }
    }
  }

  /**
   * Listener on the TreeSelectionModel, resets the row selection if any of the
   * properties of the model change.
   */
  public class SelectionModelPropertyChangeHandler
      implements PropertyChangeListener
  {

    /**
     * Constructor
     */
    public SelectionModelPropertyChangeHandler()
    {
      // Nothing to do here.
    }

    /**
     * This method gets called when a bound property is changed.
     * 
     * @param event A PropertyChangeEvent object describing the event source and
     *          the property that has changed.
     */
    public void propertyChange(PropertyChangeEvent event)
    throws NotImplementedException
    {
      // TODO: What should be done here, if anything?
    }
  }

  /**
   * The action to cancel editing on this tree.
   */
  public class TreeCancelEditingAction
      extends AbstractAction
  {
    /**
     * Creates the new tree cancel editing action.
     * 
     * @param name the name of the action (used in toString).
     */
    public TreeCancelEditingAction(String name)
    {
      super(name);
    }

    /**
     * Invoked when an action occurs, cancels the cell editing (if the
     * tree cell is being edited). 
     * 
     * @param e event that occured
     */
    public void actionPerformed(ActionEvent e)
    {
      if (isEnabled() && tree.isEditing())
        tree.cancelEditing();
    }
  }

  /**
   * Updates the TreeState in response to nodes expanding/collapsing.
   */
  public class TreeExpansionHandler
      implements TreeExpansionListener
  {

    /**
     * Constructor
     */
    public TreeExpansionHandler()
    {
      // Nothing to do here.
    }

    /**
     * Called whenever an item in the tree has been expanded.
     * 
     * @param event is the event that occured
     */
    public void treeExpanded(TreeExpansionEvent event)
    {
      validCachedPreferredSize = false;
      treeState.setExpandedState(event.getPath(), true);
      // The maximal cell height may change
      maxHeight = 0;
      tree.revalidate();
      tree.repaint();
    }

    /**
     * Called whenever an item in the tree has been collapsed.
     * 
     * @param event is the event that occured
     */
    public void treeCollapsed(TreeExpansionEvent event)
    {
      validCachedPreferredSize = false;
      treeState.setExpandedState(event.getPath(), false);
      // The maximal cell height may change
      maxHeight = 0;
      tree.revalidate();
      tree.repaint();
    }
  } // TreeExpansionHandler

  /**
   * TreeHomeAction is used to handle end/home actions. Scrolls either the first
   * or last cell to be visible based on direction.
   */
  public class TreeHomeAction
      extends AbstractAction
  {

    /** The direction, either home or end */
    protected int direction;

    /**
     * Creates a new TreeHomeAction instance.
     * 
     * @param dir the direction to go to, <code>-1</code> for home,
     *        <code>1</code> for end
     * @param name the name of the action
     */
    public TreeHomeAction(int dir, String name)
    {
      direction = dir;
      putValue(Action.NAME, name);
    }

    /**
     * Invoked when an action occurs.
     * 
     * @param e is the event that occured
     */
    public void actionPerformed(ActionEvent e)
    {
      if (tree != null)
        {
          String command = (String) getValue(Action.NAME);
          if (command.equals("selectFirst"))
            {
              ensureRowsAreVisible(0, 0);
              tree.setSelectionInterval(0, 0);
            }
          if (command.equals("selectFirstChangeLead"))
            {
              ensureRowsAreVisible(0, 0);
              tree.setLeadSelectionPath(getPathForRow(tree, 0));
            }
          if (command.equals("selectFirstExtendSelection"))
            {
              ensureRowsAreVisible(0, 0);
              TreePath anchorPath = tree.getAnchorSelectionPath();
              if (anchorPath == null)
                tree.setSelectionInterval(0, 0);
              else
                {
                  int anchorRow = getRowForPath(tree, anchorPath);
                  tree.setSelectionInterval(0, anchorRow);
                  tree.setAnchorSelectionPath(anchorPath);
                  tree.setLeadSelectionPath(getPathForRow(tree, 0));
                }
            }
          else if (command.equals("selectLast"))
            {
              int end = getRowCount(tree) - 1;
              ensureRowsAreVisible(end, end);
              tree.setSelectionInterval(end, end);
            }
          else if (command.equals("selectLastChangeLead"))
            {
              int end = getRowCount(tree) - 1;
              ensureRowsAreVisible(end, end);
              tree.setLeadSelectionPath(getPathForRow(tree, end));
            }
          else if (command.equals("selectLastExtendSelection"))
            {
              int end = getRowCount(tree) - 1;
              ensureRowsAreVisible(end, end);
              TreePath anchorPath = tree.getAnchorSelectionPath();
              if (anchorPath == null)
                tree.setSelectionInterval(end, end);
              else
                {
                  int anchorRow = getRowForPath(tree, anchorPath);
                  tree.setSelectionInterval(end, anchorRow);
                  tree.setAnchorSelectionPath(anchorPath);
                  tree.setLeadSelectionPath(getPathForRow(tree, end));
                }
            }
        }

      // Ensure that the lead path is visible after the increment action.
      tree.scrollPathToVisible(tree.getLeadSelectionPath());
    }

    /**
     * Returns true if the action is enabled.
     * 
     * @return true if the action is enabled.
     */
    public boolean isEnabled()
    {
      return (tree != null) && tree.isEnabled();
    }
  }

  /**
   * TreeIncrementAction is used to handle up/down actions. Selection is moved
   * up or down based on direction.
   */
  public class TreeIncrementAction
    extends AbstractAction
  {

    /**
     * Specifies the direction to adjust the selection by.
     */
    protected int direction;

    /**
     * Creates a new TreeIncrementAction.
     * 
     * @param dir up or down, <code>-1</code> for up, <code>1</code> for down
     * @param name is the name of the direction
     */
    public TreeIncrementAction(int dir, String name)
    {
      direction = dir;
      putValue(Action.NAME, name);
    }

    /**
     * Invoked when an action occurs.
     * 
     * @param e is the event that occured
     */
    public void actionPerformed(ActionEvent e)
    {
      TreePath currentPath = tree.getLeadSelectionPath();
      int currentRow;

      if (currentPath != null)
        currentRow = treeState.getRowForPath(currentPath);
      else
        currentRow = 0;

      int rows = treeState.getRowCount();

      int nextRow = currentRow + 1;
      int prevRow = currentRow - 1;
      boolean hasNext = nextRow < rows;
      boolean hasPrev = prevRow >= 0 && rows > 0;
      TreePath newPath;
      String command = (String) getValue(Action.NAME);

      if (command.equals("selectPreviousChangeLead") && hasPrev)
        {
          newPath = treeState.getPathForRow(prevRow);
          tree.setSelectionPath(newPath);
          tree.setAnchorSelectionPath(newPath);
          tree.setLeadSelectionPath(newPath);
        }
      else if (command.equals("selectPreviousExtendSelection") && hasPrev)
        {
          newPath = treeState.getPathForRow(prevRow);

          // If the new path is already selected, the selection shrinks,
          // unselecting the previously current path.
          if (tree.isPathSelected(newPath))
            tree.getSelectionModel().removeSelectionPath(currentPath);

          // This must be called in any case because it updates the model
          // lead selection index.
          tree.addSelectionPath(newPath);
          tree.setLeadSelectionPath(newPath);
        }
      else if (command.equals("selectPrevious") && hasPrev)
        {
          newPath = treeState.getPathForRow(prevRow);
          tree.setSelectionPath(newPath);
        }
      else if (command.equals("selectNext") && hasNext)
        {
          newPath = treeState.getPathForRow(nextRow);
          tree.setSelectionPath(newPath);
        }
      else if (command.equals("selectNextExtendSelection") && hasNext)
        {
          newPath = treeState.getPathForRow(nextRow);

          // If the new path is already selected, the selection shrinks,
          // unselecting the previously current path.
          if (tree.isPathSelected(newPath))
            tree.getSelectionModel().removeSelectionPath(currentPath);

          // This must be called in any case because it updates the model
          // lead selection index.
          tree.addSelectionPath(newPath);

          tree.setLeadSelectionPath(newPath);
        }
      else if (command.equals("selectNextChangeLead") && hasNext)
        {
          newPath = treeState.getPathForRow(nextRow);
          tree.setSelectionPath(newPath);
          tree.setAnchorSelectionPath(newPath);
          tree.setLeadSelectionPath(newPath);
        }
      
      // Ensure that the lead path is visible after the increment action.
      tree.scrollPathToVisible(tree.getLeadSelectionPath());
    }

    /**
     * Returns true if the action is enabled.
     * 
     * @return true if the action is enabled.
     */
    public boolean isEnabled()
    {
      return (tree != null) && tree.isEnabled();
    }
  }

  /**
   * Forwards all TreeModel events to the TreeState.
   */
  public class TreeModelHandler
      implements TreeModelListener
  {
    /**
     * Constructor
     */
    public TreeModelHandler()
    {
      // Nothing to do here.
    }

    /**
     * Invoked after a node (or a set of siblings) has changed in some way. The
     * node(s) have not changed locations in the tree or altered their children
     * arrays, but other attributes have changed and may affect presentation.
     * Example: the name of a file has changed, but it is in the same location
     * in the file system. To indicate the root has changed, childIndices and
     * children will be null. Use e.getPath() to get the parent of the changed
     * node(s). e.getChildIndices() returns the index(es) of the changed
     * node(s).
     * 
     * @param e is the event that occured
     */
    public void treeNodesChanged(TreeModelEvent e)
    {
      validCachedPreferredSize = false;
      treeState.treeNodesChanged(e);
      tree.repaint();
    }

    /**
     * Invoked after nodes have been inserted into the tree. Use e.getPath() to
     * get the parent of the new node(s). e.getChildIndices() returns the
     * index(es) of the new node(s) in ascending order.
     * 
     * @param e is the event that occured
     */
    public void treeNodesInserted(TreeModelEvent e)
    {
      validCachedPreferredSize = false;
      treeState.treeNodesInserted(e);
      tree.repaint();
    }

    /**
     * Invoked after nodes have been removed from the tree. Note that if a
     * subtree is removed from the tree, this method may only be invoked once
     * for the root of the removed subtree, not once for each individual set of
     * siblings removed. Use e.getPath() to get the former parent of the deleted
     * node(s). e.getChildIndices() returns, in ascending order, the index(es)
     * the node(s) had before being deleted.
     * 
     * @param e is the event that occured
     */
    public void treeNodesRemoved(TreeModelEvent e)
    {
      validCachedPreferredSize = false;
      treeState.treeNodesRemoved(e);
      tree.repaint();
    }

    /**
     * Invoked after the tree has drastically changed structure from a given
     * node down. If the path returned by e.getPath() is of length one and the
     * first element does not identify the current root node the first element
     * should become the new root of the tree. Use e.getPath() to get the path
     * to the node. e.getChildIndices() returns null.
     * 
     * @param e is the event that occured
     */
    public void treeStructureChanged(TreeModelEvent e)
    {
      if (e.getPath().length == 1
          && ! e.getPath()[0].equals(treeModel.getRoot()))
        tree.expandPath(new TreePath(treeModel.getRoot()));
      validCachedPreferredSize = false;
      treeState.treeStructureChanged(e);
      tree.repaint();
    }
  } // TreeModelHandler

  /**
   * TreePageAction handles page up and page down events.
   */
  public class TreePageAction
      extends AbstractAction
  {
    /** Specifies the direction to adjust the selection by. */
    protected int direction;

    /**
     * Constructor
     * 
     * @param direction up or down
     * @param name is the name of the direction
     */
    public TreePageAction(int direction, String name)
    {
      this.direction = direction;
      putValue(Action.NAME, name);
    }

    /**
     * Invoked when an action occurs.
     * 
     * @param e is the event that occured
     */
    public void actionPerformed(ActionEvent e)
    {
      String command = (String) getValue(Action.NAME);
      boolean extendSelection = command.equals("scrollUpExtendSelection")
                                || command.equals("scrollDownExtendSelection");
      boolean changeSelection = command.equals("scrollUpChangeSelection")
                                || command.equals("scrollDownChangeSelection");

      // Disable change lead, unless we are in discontinuous mode.
      if (!extendSelection && !changeSelection
          && tree.getSelectionModel().getSelectionMode() !=
            TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION)
        {
          changeSelection = true;
        }

      int rowCount = getRowCount(tree);
      if (rowCount > 0 && treeSelectionModel != null)
        {
          Dimension maxSize = tree.getSize();
          TreePath lead = tree.getLeadSelectionPath();
          TreePath newPath = null;
          Rectangle visible = tree.getVisibleRect();
          if (direction == -1) // The RI handles -1 as up.
            {
              newPath = getClosestPathForLocation(tree, visible.x, visible.y);
              if (newPath.equals(lead)) // Corner case, adjust one page up.
                {
                  visible.y = Math.max(0, visible.y - visible.height);
                  newPath = getClosestPathForLocation(tree, visible.x,
                                                      visible.y);
                }
            }
          else // +1 is down.
            {
              visible.y = Math.min(maxSize.height,
                                   visible.y + visible.height - 1);
              newPath = getClosestPathForLocation(tree, visible.x, visible.y);
              if (newPath.equals(lead)) // Corner case, adjust one page down.
                {
                  visible.y = Math.min(maxSize.height,
                                       visible.y + visible.height - 1);
                  newPath = getClosestPathForLocation(tree, visible.x,
                                                      visible.y);
                }
            }

          // Determine new visible rect.
          Rectangle newVisible = getPathBounds(tree, newPath);
          newVisible.x = visible.x;
          newVisible.width = visible.width;
          if (direction == -1)
            {
              newVisible.height = visible.height;
            }
          else
            {
              newVisible.y -= visible.height - newVisible.height;
              newVisible.height = visible.height;
            }

          if (extendSelection)
            {
              // Extend selection.
              TreePath anchorPath = tree.getAnchorSelectionPath();
              if (anchorPath == null)
                {
                  tree.setSelectionPath(newPath);
                }
              else
                {
                  int newIndex = getRowForPath(tree, newPath);
                  int anchorIndex = getRowForPath(tree, anchorPath);
                  tree.setSelectionInterval(Math.min(anchorIndex, newIndex),
                                            Math.max(anchorIndex, newIndex));
                  tree.setAnchorSelectionPath(anchorPath);
                  tree.setLeadSelectionPath(newPath);
                }
            }
          else if (changeSelection)
            {
              tree.setSelectionPath(newPath);
            }
          else // Change lead.
            {
              tree.setLeadSelectionPath(newPath);
            }

          tree.scrollRectToVisible(newVisible);
        }
    }

    /**
     * Returns true if the action is enabled.
     * 
     * @return true if the action is enabled.
     */
    public boolean isEnabled()
    {
      return (tree != null) && tree.isEnabled();
    }
  } // TreePageAction

  /**
   * Listens for changes in the selection model and updates the display
   * accordingly.
   */
  public class TreeSelectionHandler
      implements TreeSelectionListener
  {
    /**
     * Constructor
     */
    public TreeSelectionHandler()
    {
      // Nothing to do here.
    }

    /**
     * Messaged when the selection changes in the tree we're displaying for.
     * Stops editing, messages super and displays the changed paths.
     * 
     * @param event the event that characterizes the change.
     */
    public void valueChanged(TreeSelectionEvent event)
    {
      if (tree.isEditing())
        tree.cancelEditing();

      TreePath op = event.getOldLeadSelectionPath();
      TreePath np = event.getNewLeadSelectionPath();
      
      // Repaint of the changed lead selection path.
      if (op != np)
        {
          Rectangle o = treeState.getBounds(event.getOldLeadSelectionPath(), 
                                           new Rectangle());
          Rectangle n = treeState.getBounds(event.getNewLeadSelectionPath(), 
                                           new Rectangle());
          
          if (o != null)
            tree.repaint(o);
          if (n != null)
            tree.repaint(n);
        }
    }
  } // TreeSelectionHandler

  /**
   * For the first selected row expandedness will be toggled.
   */
  public class TreeToggleAction
      extends AbstractAction
  {
    /**
     * Creates a new TreeToggleAction.
     * 
     * @param name is the name of <code>Action</code> field
     */
    public TreeToggleAction(String name)
    {
      putValue(Action.NAME, name);
    }

    /**
     * Invoked when an action occurs.
     * 
     * @param e the event that occured
     */
    public void actionPerformed(ActionEvent e)
    {
      int selected = tree.getLeadSelectionRow();
      if (selected != -1 && isLeaf(selected))
        {
          TreePath anchorPath = tree.getAnchorSelectionPath();
          TreePath leadPath = tree.getLeadSelectionPath();
          toggleExpandState(getPathForRow(tree, selected));
          // Need to do this, so that the toggling doesn't mess up the lead
          // and anchor.
          tree.setLeadSelectionPath(leadPath);
          tree.setAnchorSelectionPath(anchorPath);

          // Ensure that the lead path is visible after the increment action.
          tree.scrollPathToVisible(tree.getLeadSelectionPath());
        }
    }

    /**
     * Returns true if the action is enabled.
     * 
     * @return true if the action is enabled, false otherwise
     */
    public boolean isEnabled()
    {
      return (tree != null) && tree.isEnabled();
    }
  } // TreeToggleAction

  /**
   * TreeTraverseAction is the action used for left/right keys. Will toggle the
   * expandedness of a node, as well as potentially incrementing the selection.
   */
  public class TreeTraverseAction
      extends AbstractAction
  {
    /**
     * Determines direction to traverse, 1 means expand, -1 means collapse.
     */
    protected int direction;

    /**
     * Constructor
     * 
     * @param direction to traverse
     * @param name is the name of the direction
     */
    public TreeTraverseAction(int direction, String name)
    {
      this.direction = direction;
      putValue(Action.NAME, name);
    }

    /**
     * Invoked when an action occurs.
     * 
     * @param e the event that occured
     */
    public void actionPerformed(ActionEvent e)
    {
      TreePath current = tree.getLeadSelectionPath();
      if (current == null)
        return;

      String command = (String) getValue(Action.NAME);
      if (command.equals("selectParent"))
        {
          if (current == null)
            return;

          if (tree.isExpanded(current))
            {
              tree.collapsePath(current);
            }
          else
            {
              // If the node is not expanded (also, if it is a leaf node),
              // we just select the parent. We do not select the root if it
              // is not visible.
              TreePath parent = current.getParentPath();
              if (parent != null && 
                  ! (parent.getPathCount() == 1 && ! tree.isRootVisible()))
                tree.setSelectionPath(parent);
            }
        }
      else if (command.equals("selectChild"))
        {
          Object node = current.getLastPathComponent();
          int nc = treeModel.getChildCount(node);
          if (nc == 0 || treeState.isExpanded(current))
            {
              // If the node is leaf or it is already expanded,
              // we just select the next row.
              int nextRow = tree.getLeadSelectionRow() + 1;
              if (nextRow <= tree.getRowCount())
                tree.setSelectionRow(nextRow);
            }
          else
            {
              tree.expandPath(current);
            }
        }
      
      // Ensure that the lead path is visible after the increment action.
      tree.scrollPathToVisible(tree.getLeadSelectionPath());
    }

    /**
     * Returns true if the action is enabled.
     * 
     * @return true if the action is enabled, false otherwise
     */
    public boolean isEnabled()
    {
      return (tree != null) && tree.isEnabled();
    }
  }

  /**
   * Returns true if the LookAndFeel implements the control icons. Package
   * private for use in inner classes.
   * 
   * @returns true if there are control icons
   */
  boolean hasControlIcons()
  {
    if (expandedIcon != null || collapsedIcon != null)
      return true;
    return false;
  }

  /**
   * Returns control icon. It is null if the LookAndFeel does not implements the
   * control icons. Package private for use in inner classes.
   * 
   * @return control icon if it exists.
   */
  Icon getCurrentControlIcon(TreePath path)
  {
    if (hasControlIcons())
      {
        if (tree.isExpanded(path))
          return expandedIcon;
        else
          return collapsedIcon;
      }
    else
      {
        if (nullIcon == null)
          nullIcon = new Icon()
          {
            public int getIconHeight()
            {
              return 0;
            }

            public int getIconWidth()
            {
              return 0;
            }

            public void paintIcon(Component c, Graphics g, int x, int y)
            {
              // No action here.
            }
          };
        return nullIcon;
      }
  }

  /**
   * Returns the parent of the current node
   * 
   * @param root is the root of the tree
   * @param node is the current node
   * @return is the parent of the current node
   */
  Object getParent(Object root, Object node)
  {
    if (root == null || node == null || root.equals(node))
      return null;

    if (node instanceof TreeNode)
      return ((TreeNode) node).getParent();
    return findNode(root, node);
  }

  /**
   * Recursively checks the tree for the specified node, starting at the root.
   * 
   * @param root is starting node to start searching at.
   * @param node is the node to search for
   * @return the parent node of node
   */
  private Object findNode(Object root, Object node)
  {
    if (! treeModel.isLeaf(root) && ! root.equals(node))
      {
        int size = treeModel.getChildCount(root);
        for (int j = 0; j < size; j++)
          {
            Object child = treeModel.getChild(root, j);
            if (node.equals(child))
              return root;

            Object n = findNode(child, node);
            if (n != null)
              return n;
          }
      }
    return null;
  }

  /**
   * Selects the specified path in the tree depending on modes. Package private
   * for use in inner classes.
   * 
   * @param tree is the tree we are selecting the path in
   * @param path is the path we are selecting
   */
  void selectPath(JTree tree, TreePath path)
  {
    if (path != null)
      {
        tree.setSelectionPath(path);
        tree.setLeadSelectionPath(path);        
        tree.makeVisible(path);
        tree.scrollPathToVisible(path);
      }
  }

  /**
   * Returns the path from node to the root. Package private for use in inner
   * classes.
   * 
   * @param node the node to get the path to
   * @param depth the depth of the tree to return a path for
   * @return an array of tree nodes that represent the path to node.
   */
  Object[] getPathToRoot(Object node, int depth)
  {
    if (node == null)
      {
        if (depth == 0)
          return null;

        return new Object[depth];
      }

    Object[] path = getPathToRoot(getParent(treeModel.getRoot(), node),
                                  depth + 1);
    path[path.length - depth - 1] = node;
    return path;
  }

  /**
   * Draws a vertical line using the given graphic context
   * 
   * @param g is the graphic context
   * @param c is the component the new line will belong to
   * @param x is the horizonal position
   * @param top specifies the top of the line
   * @param bottom specifies the bottom of the line
   */
  protected void paintVerticalLine(Graphics g, JComponent c, int x, int top,
                                   int bottom)
  {
    // FIXME: Check if drawing a dashed line or not.
    g.setColor(getHashColor());
    g.drawLine(x, top, x, bottom);
  }

  /**
   * Draws a horizontal line using the given graphic context
   * 
   * @param g is the graphic context
   * @param c is the component the new line will belong to
   * @param y is the vertical position
   * @param left specifies the left point of the line
   * @param right specifies the right point of the line
   */
  protected void paintHorizontalLine(Graphics g, JComponent c, int y, int left,
                                     int right)
  {
    // FIXME: Check if drawing a dashed line or not.
    g.setColor(getHashColor());
    g.drawLine(left, y, right, y);
  }

  /**
   * Draws an icon at around a specific position
   * 
   * @param c is the component the new line will belong to
   * @param g is the graphic context
   * @param icon is the icon which will be drawn
   * @param x is the center position in x-direction
   * @param y is the center position in y-direction
   */
  protected void drawCentered(Component c, Graphics g, Icon icon, int x, int y)
  {
    x -= icon.getIconWidth() / 2;
    y -= icon.getIconHeight() / 2;

    if (x < 0)
      x = 0;
    if (y < 0)
      y = 0;

    icon.paintIcon(c, g, x, y);
  }

  /**
   * Draws a dashed horizontal line.
   * 
   * @param g - the graphics configuration.
   * @param y - the y location to start drawing at
   * @param x1 - the x location to start drawing at
   * @param x2 - the x location to finish drawing at
   */
  protected void drawDashedHorizontalLine(Graphics g, int y, int x1, int x2)
  {
    g.setColor(getHashColor());
    for (int i = x1; i < x2; i += 2)
      g.drawLine(i, y, i + 1, y);
  }

  /**
   * Draws a dashed vertical line.
   * 
   * @param g - the graphics configuration.
   * @param x - the x location to start drawing at
   * @param y1 - the y location to start drawing at
   * @param y2 - the y location to finish drawing at
   */
  protected void drawDashedVerticalLine(Graphics g, int x, int y1, int y2)
  {
    g.setColor(getHashColor());
    for (int i = y1; i < y2; i += 2)
      g.drawLine(x, i, x, i + 1);
  }

  /**
   * Paints the expand (toggle) part of a row. The receiver should NOT modify
   * clipBounds, or insets.
   * 
   * @param g - the graphics configuration
   * @param clipBounds -
   * @param insets -
   * @param bounds - bounds of expand control
   * @param path - path to draw control for
   * @param row - row to draw control for
   * @param isExpanded - is the row expanded
   * @param hasBeenExpanded - has the row already been expanded
   * @param isLeaf - is the path a leaf
   */
  protected void paintExpandControl(Graphics g, Rectangle clipBounds,
                                    Insets insets, Rectangle bounds,
                                    TreePath path, int row, boolean isExpanded,
                                    boolean hasBeenExpanded, boolean isLeaf)
  {
    if (shouldPaintExpandControl(path, row, isExpanded, hasBeenExpanded, isLeaf))
      {
        Icon icon = getCurrentControlIcon(path);
        int iconW = icon.getIconWidth();
        int x = bounds.x - iconW - gap;
        icon.paintIcon(tree, g, x, bounds.y + bounds.height / 2
                                   - icon.getIconHeight() / 2);
      }
  }

  /**
   * Paints the horizontal part of the leg. The receiver should NOT modify
   * clipBounds, or insets. NOTE: parentRow can be -1 if the root is not
   * visible.
   * 
   * @param g - the graphics configuration
   * @param clipBounds -
   * @param insets -
   * @param bounds - bounds of the cell
   * @param path - path to draw leg for
   * @param row - row to start drawing at
   * @param isExpanded - is the row expanded
   * @param hasBeenExpanded - has the row already been expanded
   * @param isLeaf - is the path a leaf
   */
  protected void paintHorizontalPartOfLeg(Graphics g, Rectangle clipBounds,
                                          Insets insets, Rectangle bounds,
                                          TreePath path, int row,
                                          boolean isExpanded,
                                          boolean hasBeenExpanded,
                                          boolean isLeaf)
  {
    if (row != 0)
      {
        paintHorizontalLine(g, tree, bounds.y + bounds.height / 2,
                            bounds.x - leftChildIndent - gap, bounds.x - gap);
      }
  }

  /**
   * Paints the vertical part of the leg. The receiver should NOT modify
   * clipBounds, insets.
   * 
   * @param g - the graphics configuration.
   * @param clipBounds -
   * @param insets -
   * @param path - the path to draw the vertical part for.
   */
  protected void paintVerticalPartOfLeg(Graphics g, Rectangle clipBounds,
                                        Insets insets, TreePath path)
  {
    Rectangle bounds = getPathBounds(tree, path);
    TreePath parent = path.getParentPath();
    
    boolean paintLine;
    if (isRootVisible())
      paintLine = parent != null;
    else
      paintLine = parent != null && parent.getPathCount() > 1;
    if (paintLine)
      {
        Rectangle parentBounds = getPathBounds(tree, parent);
        paintVerticalLine(g, tree, parentBounds.x + 2 * gap, 
                          parentBounds.y + parentBounds.height / 2,
                          bounds.y + bounds.height / 2);
      }
  }

  /**
   * Paints the renderer part of a row. The receiver should NOT modify
   * clipBounds, or insets.
   * 
   * @param g - the graphics configuration
   * @param clipBounds -
   * @param insets -
   * @param bounds - bounds of expand control
   * @param path - path to draw control for
   * @param row - row to draw control for
   * @param isExpanded - is the row expanded
   * @param hasBeenExpanded - has the row already been expanded
   * @param isLeaf - is the path a leaf
   */
  protected void paintRow(Graphics g, Rectangle clipBounds, Insets insets,
                          Rectangle bounds, TreePath path, int row,
                          boolean isExpanded, boolean hasBeenExpanded,
                          boolean isLeaf)
  {
    boolean selected = tree.isPathSelected(path);
    boolean hasIcons = false;
    Object node = path.getLastPathComponent();

    paintExpandControl(g, clipBounds, insets, bounds, path, row, isExpanded,
                       hasBeenExpanded, isLeaf);

    TreeCellRenderer dtcr = currentCellRenderer;

    boolean focused = false;
    if (treeSelectionModel != null)
      focused = treeSelectionModel.getLeadSelectionRow() == row
                && tree.isFocusOwner();

    Component c = dtcr.getTreeCellRendererComponent(tree, node, selected,
                                                    isExpanded, isLeaf, row,
                                                    focused);

    rendererPane.paintComponent(g, c, c.getParent(), bounds);
  }

  /**
   * Prepares for the UI to uninstall.
   */
  protected void prepareForUIUninstall()
  {
    // Nothing to do here yet.
  }

  /**
   * Returns true if the expand (toggle) control should be drawn for the
   * specified row.
   * 
   * @param path - current path to check for.
   * @param row - current row to check for.
   * @param isExpanded - true if the path is expanded
   * @param hasBeenExpanded - true if the path has been expanded already
   * @param isLeaf - true if the row is a lead
   */
  protected boolean shouldPaintExpandControl(TreePath path, int row,
                                             boolean isExpanded,
                                             boolean hasBeenExpanded,
                                             boolean isLeaf)
  {
    Object node = path.getLastPathComponent();
    return ! isLeaf && hasControlIcons();
  }

  /**
   * Finish the editing session.
   */
  void finish()
  {
    treeState.invalidatePathBounds(treeState.getPathForRow(editingRow));
    editingPath = null;
    editingRow = - 1;
    stopEditingInCompleteEditing = false;
    isEditing = false;
    Rectangle bounds = editingComponent.getParent().getBounds();
    tree.removeAll();
    validCachedPreferredSize = false;
    // Repaint the region, where was the editing component.
    tree.repaint(bounds);
    editingComponent = null;
    tree.requestFocus();
  }
  
  /**
   * Returns the amount to indent the given row
   * 
   * @return amount to indent the given row.
   */
  protected int getRowX(int row, int depth)
  {
    return depth * totalChildIndent;
  }
} // BasicTreeUI
