/* BasicTreeUI.java --
 Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.

 This file is part of GNU Classpath.

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

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

 You should have received a copy of the GNU General Public License
 along with GNU Classpath; see the file COPYING.  If not, write to the
 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 02110-1301 USA.

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

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


package javax.swing.plaf.basic;

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.Point;
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.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.JTextField;
import javax.swing.JTree;
import javax.swing.KeyStroke;
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.InputMapUIResource;
import javax.swing.plaf.TreeUI;
import javax.swing.text.Caret;
import javax.swing.tree.AbstractLayoutCache;
import javax.swing.tree.DefaultTreeCellEditor;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.FixedHeightLayoutCache;
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;

/**
 * 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)
 */
public class BasicTreeUI extends TreeUI
{
  /** 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.
   */
  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;
  
  /** The action listener for the editor's Timer. */
  Timer editorTimer = new EditorUpdateTimer();

  /** The new value of the node after editing. */
  Object newVal;

  /** The action bound to KeyStrokes. */
  TreeAction action;
  
  /** 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;
  
  /** Default row height, if none was set. */
  int rowHeight = 20;

  /** Listeners */
  private PropertyChangeListener propertyChangeListener;
  private FocusListener focusListener;
  private TreeSelectionListener treeSelectionListener;
  private MouseListener mouseListener;
  private KeyListener keyListener;
  private PropertyChangeListener selectionModelPropertyChangeListener;
  private ComponentListener componentListener;
  CellEditorListener cellEditorListener;
  private TreeExpansionListener treeExpansionListener;
  private TreeModelListener treeModelListener;

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

    propertyChangeListener = createPropertyChangeListener();
    focusListener = createFocusListener();
    treeSelectionListener = createTreeSelectionListener();
    mouseListener = createMouseListener();
    keyListener = createKeyListener();
    selectionModelPropertyChangeListener = createSelectionModelPropertyChangeListener();
    componentListener = createComponentListener();
    cellEditorListener = createCellEditorListener();
    treeExpansionListener = createTreeExpansionListener();
    treeModelListener = createTreeModelListener();

    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 UIManager.getColor("Tree.hash");
  }

  /**
   * Sets the Hash color.
   * 
   * @param color
   *          the <code>Color</code> to set the Hash to.
   */
  protected void setHashColor(Color color)
  {
    // FIXME: Putting something in the UIDefaults map is certainly wrong.
    UIManager.put("Tree.hash", 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 = this.rowHeight;
    treeState.setRowHeight(rowHeight);
  }

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

  /**
   * Sets the TreeCellRenderer to <code>tcr</code>. This invokes
   * <code>updateRenderer</code>.
   * 
   * @param tcr
   *          is the new TreeCellRenderer.
   */
  protected void setCellRenderer(TreeCellRenderer tcr)
  {
    currentCellRenderer = tcr;
    updateRenderer();
  }

  /**
   * 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)
  {
    tree.setModel(model);
    treeModel = tree.getModel();
  }

  /**
   * 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)
  {
    tree.setShowsRootHandles(newValue);
  }

  /**
   * 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)
  {
    Rectangle bounds = null;
    int row = -1;
    Object cell = null;
    if (path != null)
      {
        row = getRowForPath(tree, path);
        cell = path.getLastPathComponent();
        bounds = new Rectangle(0, row * getRowHeight(), 0, 0);
      }
    return nodeDimensions.getNodeDimensions(cell, row,
                                            getLevel(cell),
                                            tree.isExpanded(path),
                                            bounds);
  }

  /**
   * 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)
  {
    if (treeModel != null && currentVisiblePath != null)
      {
        Object[] nodes = currentVisiblePath.getPath();
        if (row < nodes.length)
          return new TreePath(getPathToRoot(nodes[row], 0));
      }
    return null;
  }

  /**
   * 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)
  {
    int row = 0;
    Object dest = path.getLastPathComponent();
    int rowCount = getRowCount(tree);
    if (currentVisiblePath != null)
      {
        Object[] nodes = currentVisiblePath.getPath();
        while (row < rowCount)
          {
            if (dest.equals(nodes[row]))
              return row;
            row++;          
          }
      }
    return -1;
  }

  /**
   * 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)
  {
    if (currentVisiblePath != null)
      return currentVisiblePath.getPathCount();
    return 0;
  }

  /**
   * 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)
  {
    int row = Math.round(y / getRowHeight());
    TreePath path = getPathForRow(tree, row);

    // no row is visible at this node
    while (row > 0 && path == null)
      {
        --row;
        path = getPathForRow(tree, row);
      }

    return path;
  }

  /**
   * 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(true, false, false);
    return !isEditing(tree);
  }

  /**
   * Cancels the current editing session.
   * 
   * @param tree
   *          is the tree to cancel the editing session on.
   */
  public void cancelEditing(JTree tree)
  {
    if (isEditing(tree))
      completeEditing(false, true, false);
  }

  /**
   * 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()
  {
    // TODO: Implement this properly.
  }

  /**
   * Invoked from installUI after all the defaults/listeners have been
   * installed.
   */
  protected void completeUIInstall()
  {
    // TODO: Implement this properly.
  }

  /**
   * Invoked from uninstallUI after all the defaults/listeners have been
   * uninstalled.
   */
  protected void completeUIUninstall()
  {
    // TODO: Implement this properly.
  }

  /**
   * 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.
   * 
   * @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 FixedHeightLayoutCache();
  }

  /**
   * 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()
  {
    if (currentCellRenderer != null)
      return new DefaultTreeCellEditor(tree,
                                       (DefaultTreeCellRenderer) currentCellRenderer,
                                       cellEditor);
    return new DefaultTreeCellEditor(tree,
                                     (DefaultTreeCellRenderer) createDefaultCellRenderer(),
                                     cellEditor);
  }

  /**
   * 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()
  {
    action = null;
    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)
      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)
      {
        if(tree.getCellRenderer() == null)
          {  
            if(currentCellRenderer == null) 
              currentCellRenderer = createDefaultCellRenderer();                
            tree.setCellRenderer(currentCellRenderer);
          }
      }
  }

  /**
   * Resets the treeState instance based on the tree we're providing the look
   * and feel for.
   */
  protected void configureLayoutCache()
  {
    treeState = createLayoutCache();
  }

  /**
   * 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()
  {
    int maxWidth = 0;
    boolean isLeaf = false;
    if (currentVisiblePath != null)
      {
        Object[] path = currentVisiblePath.getPath();
        for (int i = 0; i < path.length; i++)
          {
            TreePath curr = new TreePath(getPathToRoot(path[i], 0));
            Rectangle bounds = getPathBounds(tree, curr);
            if (treeModel != null)
              isLeaf = treeModel.isLeaf(path[i]);
            if (!isLeaf && hasControlIcons())
              bounds.width += getCurrentControlIcon(curr).getIconWidth();
            maxWidth = Math.max(maxWidth, bounds.x + bounds.width);
          }
        preferredSize = new Dimension(maxWidth, (getRowHeight() * path.length));
      }
    else preferredSize = new Dimension(0, 0);
    validCachedPreferredSize = true;
  }

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

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

  /**
   * Install all defaults for the tree.
   */
  protected void installDefaults()
  {
    LookAndFeel.installColorsAndFont(tree, "Tree.background",
                                     "Tree.foreground", "Tree.font");
    tree.setOpaque(true);

    rightChildIndent = UIManager.getInt("Tree.rightChildIndent");
    leftChildIndent = UIManager.getInt("Tree.leftChildIndent");
    setRowHeight(UIManager.getInt("Tree.rowHeight"));
    tree.setRowHeight(getRowHeight());
    tree.requestFocusInWindow(false);
    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) UIManager.get("Tree.focusInputMap");
    InputMapUIResource parentInputMap = new InputMapUIResource();
    ActionMap parentActionMap = new ActionMapUIResource();
    action = new TreeAction();
    Object keys[] = focusInputMap.allKeys();

    for (int i = 0; i < keys.length; i++)
      {
        parentInputMap.put(
                           KeyStroke.getKeyStroke(
                                                  ((KeyStroke) keys[i]).getKeyCode(),
                                                  convertModifiers(((KeyStroke) keys[i]).getModifiers())),
                           (String) focusInputMap.get((KeyStroke) keys[i]));

        parentInputMap.put(
                           KeyStroke.getKeyStroke(
                                                  ((KeyStroke) keys[i]).getKeyCode(),
                                                  ((KeyStroke) keys[i]).getModifiers()),
                           (String) focusInputMap.get((KeyStroke) keys[i]));

        parentActionMap.put(
                            (String) focusInputMap.get((KeyStroke) keys[i]),
                            new ActionListenerProxy(
                                                    action,
                                                    (String) focusInputMap.get((KeyStroke) keys[i])));

      }

    parentInputMap.setParent(tree.getInputMap(
                                              JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).getParent());
    parentActionMap.setParent(tree.getActionMap().getParent());
    tree.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).setParent(
                                                                              parentInputMap);
    tree.getActionMap().setParent(parentActionMap);
  }

  /**
   * 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()
  {
    tree.addPropertyChangeListener(propertyChangeListener);
    tree.addFocusListener(focusListener);
    tree.addTreeSelectionListener(treeSelectionListener);
    tree.addMouseListener(mouseListener);
    tree.addKeyListener(keyListener);
    tree.addPropertyChangeListener(selectionModelPropertyChangeListener);
    tree.addComponentListener(componentListener);
    tree.addTreeExpansionListener(treeExpansionListener);
    if (treeModel != null)
      treeModel.addTreeModelListener(treeModelListener);
  }

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

    installComponents();
    installKeyboardActions();
    installListeners();
    
    setCellEditor(createDefaultCellEditor());
    createdCellEditor = true;
    isEditing = false;

    TreeModel mod = tree.getModel();
    setModel(mod);
    if (mod != null)
      {
        TreePath path = new TreePath(mod.getRoot());
        if (!tree.isExpanded(path))
          toggleExpandState(path);
      }
    treeSelectionModel = tree.getSelectionModel();

    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)
  {
    prepareForUIUninstall();
    uninstallDefaults();
    uninstallKeyboardActions();
    uninstallListeners();
    tree = null;
    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;
    if (currentVisiblePath == null)
      updateCurrentVisiblePath();

    Rectangle clip = g.getClipBounds();
    Insets insets = tree.getInsets();

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

        paintVerticalPartOfLeg(g, clip, insets, currentVisiblePath);
        for (int i = startIndex; i <= endIndex; i++)
          {
            Object curr = currentVisiblePath.getPathComponent(i);
            boolean isLeaf = treeModel.isLeaf(curr);
            TreePath path = new TreePath(getPathToRoot(curr, 0));

            boolean isExpanded = tree.isExpanded(path);
            Rectangle bounds = getPathBounds(tree, path);
            paintHorizontalPartOfLeg(g, clip, insets, bounds, path, i,
                                     isExpanded, false, isLeaf);
            paintRow(g, clip, insets, bounds, path, i, isExpanded, false,
                     isLeaf);
          }
      }
  }

  /**
   * 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()
  {
    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)
  {
    // FIXME: checkConsistancy not implemented, c not used 
    if(!validCachedPreferredSize) 
      updateCachedPreferredSize();
    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)
  {
    Dimension min = getPreferredMinSize(); 
    if (min == null)
      return new Dimension();
    return min;
  }

  /**
   * 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)
  {
    if (c instanceof JTree)
      return ((JTree) c).getPreferredSize();
    return new Dimension();
  }

  /**
   * 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)
  {
    if (messageStop)
      {
        getCellEditor().stopCellEditing();
        stopEditingInCompleteEditing = true;
      }

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

    if (messageTree)
      treeModel.valueForPathChanged(tree.getLeadSelectionPath(), newVal);
  }

  /**
   * 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)
  {
    int x;
    int y;
    if (event == null)
      {
        Rectangle bounds = getPathBounds(tree, path);
        x = bounds.x;
        y = bounds.y;
      }
    else
      {
        x = event.getX();
        y = event.getY();
      }

    updateCellEditor();
    TreeCellEditor ed = getCellEditor();
    if (ed != null && ed.shouldSelectCell(event) && ed.isCellEditable(event))
      {
        editingPath = path;
        editingRow = tree.getRowForPath(editingPath);

        Object val = editingPath.getLastPathComponent();
        cellEditor.addCellEditorListener(cellEditorListener);
        stopEditingInCompleteEditing = false;
        boolean expanded = tree.isExpanded(editingPath);
        isEditing = true;
        editingComponent = ed.getTreeCellEditorComponent(tree, val, true,
                                                         expanded,
                                                         isLeaf(editingRow),
                                                         editingRow);
        editingComponent.getParent().setVisible(true);
        editingComponent.getParent().validate();
        tree.add(editingComponent.getParent());
        editingComponent.getParent().validate();
        validCachedPreferredSize = false;
        tree.revalidate();
        ((JTextField) editingComponent).requestFocusInWindow(false);
        editorTimer.start();
        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))
      toggleExpandState(path);
  }

  /**
   * 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;
    int row = getRowForPath(tree, path);
    
    if (!isLeaf(row))
      {
        Rectangle bounds = getPathBounds(tree, path);

        if (hasControlIcons() && (mouseX < bounds.x) 
            && (mouseX > (bounds.x - getCurrentControlIcon(path).getIconWidth() - gap)))
          cntlClick = true;
      }
    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)
  {
    if (tree.isExpanded(path))
      tree.collapsePath(path);
    else
      tree.expandPath(path);
    updateCurrentVisiblePath();
  }

  /**
   * Returning true signifies a mouse event on the node should toggle the
   * selection of only the row under the mouse.
   * 
   * @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);
  }

  /**
   * Returning true signifies a mouse event on the node should select from the
   * anchor point.
   * 
   * @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.CONTIGUOUS_TREE_SELECTION);
  }

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

  /**
   * 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 if the even specified a toggle event the row is expanded/collapsed.
   * 
   * @param path
   *          is the path selected for an event
   * @param event
   *          is the MouseEvent performed on the path.
   */
  protected void selectPathForEvent(TreePath path, MouseEvent event)
  {
    if (isToggleSelectionEvent(event))
      {
        if (tree.isPathSelected(path))
          tree.removeSelectionPath(path);
        else
          {
            tree.addSelectionPath(path);
            tree.setAnchorSelectionPath(path);
          }
      }
    else if (isMultiSelectEvent(event))
      {
        TreePath anchor = tree.getAnchorSelectionPath();
        if (anchor != null)
          {
            int aRow = getRowForPath(tree, anchor);
            tree.addSelectionInterval(aRow, getRowForPath(tree, path));
          }
        else
          tree.addSelectionPath(path);
      }
    else
      tree.addSelectionPath(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);
  }

  /**
   * This class implements the actions that we want to happen when specific keys
   * are pressed for the JTree. The actionPerformed method is called when a key
   * that has been registered for the JTree is received.
   */
  class TreeAction
    extends AbstractAction
  {

    /**
     * What to do when this action is called.
     * 
     * @param e
     *          the ActionEvent that caused this action.
     */
    public void actionPerformed(ActionEvent e)
    {
      TreePath lead = tree.getLeadSelectionPath();

      if (e.getActionCommand().equals("selectPreviousChangeLead")
          || e.getActionCommand().equals("selectPreviousExtendSelection")
          || e.getActionCommand().equals("selectPrevious")
          || e.getActionCommand().equals("selectNext")
          || e.getActionCommand().equals("selectNextExtendSelection")
          || e.getActionCommand().equals("selectNextChangeLead"))
        (new TreeIncrementAction(0, "")).actionPerformed(e);
      else if (e.getActionCommand().equals("selectParent")
               || e.getActionCommand().equals("selectChild"))
        (new TreeTraverseAction(0, "")).actionPerformed(e);
      else if (e.getActionCommand().equals("selectAll"))
        {
          TreePath[] paths = new TreePath[tree.getVisibleRowCount()];

          Object curr = getNextVisibleNode(treeModel.getRoot());
          int i = 0;
          while (curr != null && i < paths.length)
            {
              paths[i] = new TreePath(getPathToRoot(curr, 0));
              i++;
            }

          tree.addSelectionPaths(paths);
        }
      else if (e.getActionCommand().equals("startEditing"))
        tree.startEditingAtPath(lead);
      else if (e.getActionCommand().equals("toggle"))
        {
          if (tree.isEditing())
              tree.stopEditing();
          else
            {
              Object last = lead.getLastPathComponent();
              TreePath path = new TreePath(getPathToRoot(last, 0));
              if (!treeModel.isLeaf(last))
                toggleExpandState(path);
            }
        }
      else if (e.getActionCommand().equals("clearSelection"))
        tree.clearSelection();

      if (tree.isEditing() && !e.getActionCommand().equals("startEditing"))
        tree.cancelEditing();

      tree.scrollPathToVisible(lead);
    }
  }

  /**
   * This class is used to mimic the behaviour of the JDK when registering
   * keyboard actions. It is the same as the private class used in JComponent
   * for the same reason. This class receives an action event and dispatches it
   * to the true receiver after altering the actionCommand property of the
   * event.
   */
  private static class ActionListenerProxy
    extends AbstractAction
  {
    ActionListener target;

    String bindingCommandName;

    public ActionListenerProxy(ActionListener li, String cmd)
    {
      target = li;
      bindingCommandName = cmd;
    }

    public void actionPerformed(ActionEvent e)
    {
      ActionEvent derivedEvent = new ActionEvent(e.getSource(), e.getID(),
                                                 bindingCommandName,
                                                 e.getModifiers());

      target.actionPerformed(derivedEvent);
    }
  }

  /**
   * The timer that updates the editor component.
   */
  private class EditorUpdateTimer
    extends Timer
    implements ActionListener
  {
    /**
     * Creates a new EditorUpdateTimer object with a default delay of 0.3
     * seconds.
     */
    public EditorUpdateTimer()
    {
      super(300, null);
      addActionListener(this);
    }

    /**
     * Lets the caret blink and repaints the table.
     */
    public void actionPerformed(ActionEvent ev)
    {
      Caret c = ((JTextField) editingComponent).getCaret();
      if (c != null)
        c.setVisible(!c.isVisible());
      tree.repaint();
    }

    /**
     * Updates the blink delay according to the current caret.
     */
    public void update()
    {
      stop();
      Caret c = ((JTextField) editingComponent).getCaret();
      if (c != null)
        {
          setDelay(c.getBlinkRate());
          if (((JTextField) editingComponent).isEditable())
            start();
          else
            c.setVisible(false);
        }
    }
  }

  /**
   * 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)
    {
      // TODO: What should be done here, if anything?
    }

    /**
     * Creates, if necessary, and starts a Timer to check if needed to resize the
     * bounds
     */
    protected void startTimer()
    {
      // TODO: Implement this properly.
    }

    /**
     * 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()
    {
      return null;
    }

    /**
     * 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)
    {
      // TODO: Implement this properly.
    }
  }

  /**
   * 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)
    {
      editingPath = null;
      editingRow = -1;
      stopEditingInCompleteEditing = false;
      if (editingComponent != null)
        {
          tree.remove(editingComponent.getParent());
          editingComponent = null;
        }
      if (cellEditor != null)
        {
          newVal = ((JTextField) getCellEditor().getCellEditorValue()).getText();
          completeEditing(false, false, true);
          if (cellEditor instanceof DefaultTreeCellEditor)
            tree.removeTreeSelectionListener((DefaultTreeCellEditor) cellEditor);
          cellEditor.removeCellEditorListener(cellEditorListener);
          setCellEditor(null);
          createdCellEditor = false;
        }
      isEditing = false;
      tree.requestFocusInWindow(false);
      editorTimer.stop();
      validCachedPreferredSize = false;
      tree.revalidate();
      tree.repaint();
    }

    /**
     * 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)
    {
      editingPath = null;
      editingRow = -1;
      stopEditingInCompleteEditing = false;
      if (editingComponent != null)
        tree.remove(editingComponent.getParent());
      editingComponent = null;
      if (cellEditor != null)
        {
          if (cellEditor instanceof DefaultTreeCellEditor)
            tree.removeTreeSelectionListener((DefaultTreeCellEditor) cellEditor);
          cellEditor.removeCellEditorListener(cellEditorListener);
          setCellEditor(null);
          createdCellEditor = false;
        }
      tree.requestFocusInWindow(false);
      editorTimer.stop();
      isEditing = false;
      validCachedPreferredSize = false;
      tree.revalidate();
      tree.repaint();
    }
  }// 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.
     * 
     * @param e
     *          is the focus event that is activated
     */
    public void focusGained(FocusEvent e)
    {
      // TODO: Implement this properly.
    }

    /**
     * Invoked when focus is deactivated on the tree we're in, redraws the lead
     * row. Invoked when a component loses the keyboard focus.
     * 
     * @param e
     *          is the focus event that is deactivated
     */
    public void focusLost(FocusEvent e)
    {
      // TODO: Implement this properly.
    }
  }

  /**
   * 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)
    {
      // TODO: What should be done here, if anything?
    }

    /**
     * Invoked when a key has been pressed.
     * 
     * @param e
     *          the key pressed
     */
    public void keyPressed(KeyEvent e)
    {
      // TODO: What should be done here, if anything?
    }

    /**
     * Invoked when a key has been released
     * 
     * @param e
     *          the key released
     */
    public void keyReleased(KeyEvent e)
    {
      // TODO: What should be done here, if anything?
    }
  }

  /**
   * 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)
    {
      Point click = e.getPoint();
      TreePath path = getClosestPathForLocation(tree, click.x, click.y);

      if (path != null)
        {
          Rectangle bounds = getPathBounds(tree, path);
          int row = getRowForPath(tree, path);
          boolean cntlClick = isLocationInExpandControl(path, click.x, click.y);

          boolean isLeaf = isLeaf(row);
          
          TreeCellRenderer tcr = getCellRenderer();
          Icon icon;
          if (isLeaf)
            icon = UIManager.getIcon("Tree.leafIcon");
          else if (tree.isExpanded(path))
            icon = UIManager.getIcon("Tree.openIcon");
          else
            icon = UIManager.getIcon("Tree.closedIcon");
          
          if (tcr instanceof DefaultTreeCellRenderer)
            {
             Icon tmp = ((DefaultTreeCellRenderer) tcr).getIcon();
             if (tmp != null)
               icon = tmp;
            }
          
          // add gap*2 for the space before and after the text
          if (icon != null)
            bounds.width += icon.getIconWidth() + gap*2;

          boolean inBounds = bounds.contains(click.x, click.y);
          if ((inBounds || cntlClick) && tree.isVisible(path))
            {
              if (inBounds)
                {
                  selectPath(tree, path);
                  if (e.getClickCount() == 2 && !isLeaf(row))
                      toggleExpandState(path);
                }
              
              if (cntlClick)
                {
                  handleExpandControlClick(path, click.x, click.y);
                  if (cellEditor != null)
                    cellEditor.cancelCellEditing();
                  tree.scrollPathToVisible(path);
                }
              else if (tree.isEditable())
                startEditing(path, e);
            }
        }
    }

    /**
     * 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)
    {
      // 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)
    {
      // 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)
    {
      // 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)
    {
      // 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)
    {
      // 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)
    {
      // 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)
    {
      // 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)
    {
      // 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)
    {
      // 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)
    {
      // TODO: What should be done here, if anything?
    }

    /**
     * Removes event from the source
     */
    protected void removeFromSource()
    {
      // 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)
        {
          size.x = getRowX(row, depth);
          size.width = SwingUtilities.computeStringWidth(fm, s);
          size.height = fm.getHeight();
        }
      return size;
    }

    /**
     * Returns the amount to indent the given row
     * 
     * @return amount to indent the given row.
     */
    protected int getRowX(int row, int depth)
    {
      if (row == 0)
        return 0;
      return depth * rightChildIndent;
    }
  }// NodeDimensionsHandler

  /**
   * PropertyChangeListener for the tree. Updates the appropriate varaible, 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)
    {
      if ((event.getPropertyName()).equals("rootVisible"))
        {
          validCachedPreferredSize = false;
          updateCurrentVisiblePath();
          tree.revalidate();
          tree.repaint();
        }
    }
  }

  /**
   * 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)
    {
      // TODO: What should be done here, if anything?
    }
  }

  /**
   * ActionListener that invokes cancelEditing when action performed.
   */
  public class TreeCancelEditingAction
    extends AbstractAction
  {

    /**
     * Constructor
     */
    public TreeCancelEditingAction(String name)
    {
      // TODO: Implement this properly.
    }

    /**
     * Invoked when an action occurs.
     * 
     * @param e
     *          event that occured
     */
    public void actionPerformed(ActionEvent e)
    {
      // TODO: Implement this properly.
    }

    /**
     * Returns true if the action is enabled.
     * 
     * @return true if the action is enabled, false otherwise
     */
    public boolean isEnabled()
    {
      // TODO: Implement this properly.
      return false;
    }
  }

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

    /** direction is either home or end */
    protected int direction;

    /**
     * Constructor
     * 
     * @param direction -
     *          it is home or end
     * @param name
     *          is the name of the direction
     */
    public TreeHomeAction(int direction, String name)
    {
      // TODO: Implement this properly
    }

    /**
     * Invoked when an action occurs.
     * 
     * @param e
     *          is the event that occured
     */
    public void actionPerformed(ActionEvent e)
    {
      // TODO: Implement this properly
    }

    /**
     * Returns true if the action is enabled.
     * 
     * @return true if the action is enabled.
     */
    public boolean isEnabled()
    {
      // TODO: Implement this properly
      return false;
    }
  }

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

    /**
     * Constructor
     * 
     * @param direction
     *          up or down
     * @param name
     *          is the name of the direction
     */
    public TreeIncrementAction(int direction, String name)
    {
      // TODO: Implement this properly
    }

    /**
     * Invoked when an action occurs.
     * 
     * @param e
     *          is the event that occured
     */
    public void actionPerformed(ActionEvent e)
    {
      Object last = tree.getLeadSelectionPath().getLastPathComponent();

      if (e.getActionCommand().equals("selectPreviousChangeLead"))
        {
          Object prev = getPreviousVisibleNode(last);
          
          if (prev != null)
            {
              TreePath newPath = new TreePath(getPathToRoot(prev, 0));
              selectPath(tree, newPath);
              tree.setLeadSelectionPath(newPath);
            }
        }
      else if (e.getActionCommand().equals("selectPreviousExtendSelection"))
        {
          Object prev = getPreviousVisibleNode(last);
          if (prev != null)
            {
              TreePath newPath = new TreePath(getPathToRoot(prev, 0));
              tree.addSelectionPath(newPath);
              tree.setLeadSelectionPath(newPath);
            }
        }
      else if (e.getActionCommand().equals("selectPrevious"))
        {
          Object prev = getPreviousVisibleNode(last);
          
          if (prev != null)
            {
              TreePath newPath = new TreePath(getPathToRoot(prev, 0));
              selectPath(tree, newPath);
            }
        }
      else if (e.getActionCommand().equals("selectNext"))
        {
          Object next = getNextVisibleNode(last);
          
          if (next != null)
            {
              TreePath newPath = new TreePath(getPathToRoot(next, 0));
              selectPath(tree, newPath);
            }
        }
      else if (e.getActionCommand().equals("selectNextExtendSelection"))
        {
          Object next = getNextVisibleNode(last);
          if (next != null)
            {
              TreePath newPath = new TreePath(getPathToRoot(next, 0));
              tree.addSelectionPath(newPath);
              tree.setLeadSelectionPath(newPath);
            }
        }
      else if (e.getActionCommand().equals("selectNextChangeLead"))
        {
          Object next = getNextVisibleNode(last);
          if (next != null)
            {
              TreePath newPath = new TreePath(getPathToRoot(next, 0));
              selectPath(tree, newPath);
              tree.setLeadSelectionPath(newPath);
            }
        }
    }

    /**
     * Returns true if the action is enabled.
     * 
     * @return true if the action is enabled.
     */
    public boolean isEnabled()
    {
      // TODO: Implement this properly
      return false;
    }
  }

  /**
   * 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;
      updateCurrentVisiblePath();
      tree.revalidate();
      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;
      updateCurrentVisiblePath();
      tree.revalidate();
      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;
      updateCurrentVisiblePath();
      tree.revalidate();
      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()));
      updateCurrentVisiblePath();
      validCachedPreferredSize = false;
      tree.revalidate();
      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;
    }

    /**
     * Invoked when an action occurs.
     * 
     * @param e
     *          is the event that occured
     */
    public void actionPerformed(ActionEvent e)
    {
      // TODO: Implement this properly.
    }

    /**
     * Returns true if the action is enabled.
     * 
     * @return true if the action is enabled.
     */
    public boolean isEnabled()
    {
      return false;
    }
  }// 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();
    }
  }// TreeSelectionHandler

  /**
   * For the first selected row expandedness will be toggled.
   */
  public class TreeToggleAction extends AbstractAction
  {
    /**
     * Constructor
     * 
     * @param name
     *          is the name of <code>Action</code> field
     */
    public TreeToggleAction(String name)
    {
      // Nothing to do here.
    }

    /**
     * Invoked when an action occurs.
     * 
     * @param e
     *          the event that occured
     */
    public void actionPerformed(ActionEvent e)
    {
      // TODO: Implement this properly.
    }

    /**
     * Returns true if the action is enabled.
     * 
     * @return true if the action is enabled, false otherwise
     */
    public boolean isEnabled()
    {
      return false;
    }
  } // 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;
    }

    /**
     * Invoked when an action occurs.
     * 
     * @param e
     *          the event that occured
     */
    public void actionPerformed(ActionEvent e)
    {
      Object last = tree.getLeadSelectionPath().getLastPathComponent();

      if (e.getActionCommand().equals("selectParent"))
        {
          TreePath path = new TreePath(getPathToRoot(last, 0));
          Object p = getParent(treeModel.getRoot(), last);

          if (!treeModel.isLeaf(last))
            toggleExpandState(path);
          else if (p != null)
            selectPath(tree, new TreePath(getPathToRoot(p, 0)));
        }
      else if (e.getActionCommand().equals("selectChild"))
        {
          TreePath path = new TreePath(getPathToRoot(last, 0));

          if (!treeModel.isLeaf(last))
            toggleExpandState(path);
          else
            {
              Object next = getNextVisibleNode(last);

              if (next != null)
                selectPath(tree, new TreePath(getPathToRoot(next, 0)));
            }
        }
    }

    /**
     * Returns true if the action is enabled.
     * 
     * @return true if the action is enabled, false otherwise
     */
    public boolean isEnabled()
    {
      // TODO: Implement this properly
      return false;
    }
  }

  /**
   * 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 (tree.isExpanded(path))
      return expandedIcon;
    return collapsedIcon;
  }

  /**
   * 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;
  }
  
  /**
   * Get previous visible node in the tree. Package private for use in inner
   * classes.
   * 
   * @param node -
   *          current node
   * @return the next visible node in the JTree. Return null if there are no
   *         more.
   */
  Object getPreviousVisibleNode(Object node)
  {
    if (currentVisiblePath != null)
      {
        Object[] nodes = currentVisiblePath.getPath();
        int i = 0;
        while (i < nodes.length && !node.equals(nodes[i]))
          i++;
        // return the next node
        if (i-1 >= 0)
          return nodes[i-1];
      }
    return null;
  }

  /**
   * Returns the next node in the tree Package private for use in inner classes.
   * 
   * @param curr - 
   *          current node
   * @return the next node in the tree
   */
  Object getNextNode(Object curr)
  {
    if (!treeModel.isLeaf(curr) && treeModel.getChildCount(curr) > 0)
      return treeModel.getChild(curr, 0);

    Object node = curr;
    Object sibling = null;
    do
      {
        sibling = getNextSibling(node);
        node = getParent(treeModel.getRoot(), node);
      }
    while (sibling == null && node != null);
    
    return sibling;
  }

  /**
   * Returns the previous node in the tree Package private for use in inner
   * classes.
   * 
   * @param node
   *          current node
   * @return the previous node in the tree
   */
  Object getPreviousNode(Object node)
  {
    Object parent = getParent(treeModel.getRoot(), node);
    if (parent == null)
      return null;

    Object sibling = getPreviousSibling(node);

    if (sibling == null)
      return parent;

    int size = 0;
    if (!treeModel.isLeaf(sibling))
      size = treeModel.getChildCount(sibling);
    while (size > 0)
      {
        sibling = treeModel.getChild(sibling, size - 1);
        if (!treeModel.isLeaf(sibling))
          size = treeModel.getChildCount(sibling);
        else
          size = 0;
      }

    return sibling;
  }

  /**
   * Returns the next sibling in the tree Package private for use in inner
   * classes.
   * 
   * @param node - 
   *          current node
   * @return the next sibling in the tree
   */
  Object getNextSibling(Object node)
  {
    Object parent = getParent(treeModel.getRoot(), node);
    if (parent == null)
      return null;

    int index = treeModel.getIndexOfChild(parent, node) + 1;

    int size = 0;
    if (!treeModel.isLeaf(parent))
      size = treeModel.getChildCount(parent);
    if (index == 0 || index >= size)
      return null;

    return treeModel.getChild(parent, index);
  }
  
  /**
   * Returns the previous sibling in the tree Package private for use in inner
   * classes.
   * 
   * @param node -
   *          current node
   * @return the previous sibling in the tree
   */
  Object getPreviousSibling(Object node)
  {
    Object parent = getParent(treeModel.getRoot(), node);
    if (parent == null)
      return null;

    int index = treeModel.getIndexOfChild(parent, node) - 1;

    int size = 0;
    if (!treeModel.isLeaf(parent))
      size = treeModel.getChildCount(parent);
    if (index < 0 || index >= size)
      return null;

    return treeModel.getChild(parent, index);
  }

  /**
   * 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)
      {
        if (tree.getSelectionModel().getSelectionMode() == 
                          TreeSelectionModel.SINGLE_TREE_SELECTION)
          {
            tree.getSelectionModel().clearSelection();
            tree.addSelectionPath(path);
            tree.setLeadSelectionPath(path);
          }
        else if (tree.getSelectionModel().getSelectionMode() == 
                  TreeSelectionModel.CONTIGUOUS_TREE_SELECTION)
          {
            // TODO
          }
        else
          {
            tree.addSelectionPath(path);
            tree.setLeadSelectionPath(path);
            tree.getSelectionModel().setSelectionMode
                      (TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
          }
      }
  }

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

  /**
   * Returns the level of the node in the tree.
   * 
   * @param node -
   *          current node
   * @return the number of the level
   */
  int getLevel(Object node)
  {
    int count = -1;

    Object current = node;

    if (treeModel != null)
      {
        Object root = treeModel.getRoot();
        if (!tree.isRootVisible() && tree.isExpanded(new TreePath(root)))
          count--;
        
        do
          {
            current = getParent(root, current);
            count++;
          }
        while (current != null);
      }
    return count;
  }

  /**
   * 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 - rightChildIndent + iconW/2;
        if (x + iconW > bounds.x)
          x = bounds.x - rightChildIndent - 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 - gap - 2,
                          bounds.x);
  }
  
  /**
   * 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)
  {
    int max = tree.getVisibleRowCount();
    for (int i = 0; i < max; i++)
      {
        Object curr = path.getPathComponent(i);
        TreePath currPath = new TreePath(getPathToRoot(curr, 0));
        int numChild = treeModel.getChildCount(curr);
        if (numChild > 0 && tree.isExpanded(currPath))
          {
            Rectangle bounds = getPathBounds(tree, currPath);
            Rectangle lastChildBounds = getPathBounds(tree, 
                                        new TreePath(getPathToRoot(
                                        treeModel.getChild(curr, numChild - 1), 
                                        0)));
            paintVerticalLine(g, tree, bounds.x + gap + 2, bounds.y + 
                              bounds.height - 2, lastChildBounds.y + 
                              lastChildBounds.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();
    
    if (tree.isVisible(path))
      {
        if (!validCachedPreferredSize)
          updateCachedPreferredSize();
        
        
        paintExpandControl(g, clipBounds, insets, bounds, path, row, isExpanded, hasBeenExpanded, isLeaf);
        
        if (row != 0)
          bounds.x += gap;
        bounds.width = preferredSize.width + bounds.x;
        
        if (editingComponent != null && editingPath != null && isEditing(tree)
            && node.equals(editingPath.getLastPathComponent()))
          {    
            rendererPane.paintComponent(g, editingComponent.getParent(), null,
                                        bounds);
          }
        else
          {
            TreeCellRenderer dtcr = tree.getCellRenderer();
            if (dtcr == null)
              dtcr = createDefaultCellRenderer();
            
            Component c = dtcr.getTreeCellRendererComponent(tree, node,
                                     selected, isExpanded, isLeaf, row, tree.hasFocus());
            rendererPane.paintComponent(g, c, c.getParent(), bounds);
          }
      }
  }

  /**
   * Prepares for the UI to uninstall.
   */
  protected void prepareForUIUninstall()
  {
    // TODO: Implement this properly.
  }
  
  /**
   * 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 && getLevel(node) != 0 && hasControlIcons());
  }
  
  /**
   * Updates the cached current TreePath of all visible
   * nodes in the tree.
   */
  void updateCurrentVisiblePath()
  {
    if (treeModel == null)
      return;

    Object next = treeModel.getRoot();
    TreePath rootPath = new TreePath(next);
    Rectangle bounds = getPathBounds(tree, rootPath);
    
    // If root is not a valid size to be visible, or is
    // not visible and the tree is expanded, then the next node acts
    // as the root
    if ((bounds.width == 0 && bounds.height == 0) || (!isRootVisible()
        && tree.isExpanded(new TreePath(next))))
      {
        next = getNextNode(next);
        rootPath = new TreePath(next);
      }
    
    Object root = next;
    TreePath current = null;
    while (next != null)
      {
        if (current == null)
          current = rootPath;
        else
          current = current.pathByAddingChild(next);
        
        do
          {
            TreePath path = new TreePath(getPathToRoot(next, 0));
            if ((tree.isVisible(path) && tree.isExpanded(path))
                || treeModel.isLeaf(next))
              next = getNextNode(next);
            else
              {
                Object pNext = next;
                next = getNextSibling(pNext);
                // if no next sibling, check parent's next sibling.
                if (next == null)
                  {
                    Object parent = getParent(root, pNext);
                    while (next == null && parent != null)
                      {
                        next = getNextSibling(parent);
                        if (next == null)
                          parent = getParent(root, parent);
                      }
                  }
              }
          }
        while (next != null && 
            !tree.isVisible(new TreePath(getPathToRoot(next, 0))));
      }

    currentVisiblePath = current;
    tree.setVisibleRowCount(getRowCount(tree));

    if (tree.getSelectionModel() != null && tree.getSelectionCount() == 0 &&
        currentVisiblePath != null)
      selectPath(tree, new TreePath(getPathToRoot(currentVisiblePath.
                                                  getPathComponent(0), 0)));
  }
  
  /**
   * Get next visible node in the currentVisiblePath. Package private for use in
   * inner classes.
   * 
   * @param node
   *          current node
   * @return the next visible node in the JTree. Return null if there are no
   *         more.
   */
  Object getNextVisibleNode(Object node)
  {
    if (currentVisiblePath != null)
      {
        Object[] nodes = currentVisiblePath.getPath();
        int i = 0;
        while (i < nodes.length && !node.equals(nodes[i]))
          i++;
        // return the next node
        if (i+1 < nodes.length)
          return nodes[i+1];
      }
    return null;
  }
} // BasicTreeUI
