/*
 * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package javax.swing.plaf.basic;

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.datatransfer.*;
import java.awt.dnd.*;
import java.beans.*;
import java.io.*;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.TooManyListenersException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import javax.swing.plaf.ActionMapUIResource;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.TreeUI;
import javax.swing.tree.*;
import javax.swing.text.Position;
import javax.swing.plaf.basic.DragRecognitionSupport.BeforeDrag;
import sun.swing.SwingUtilities2;

import sun.swing.DefaultLookup;
import sun.swing.UIAction;

/**
 * The basic L&F for a hierarchical data structure.
 * <p>
 *
 * @author Scott Violet
 * @author Shannon Hickey (drag and drop)
 */

public class BasicTreeUI extends TreeUI
{
    private static final StringBuilder BASELINE_COMPONENT_KEY =
        new StringBuilder("Tree.baselineComponent");

    // Old actions forward to an instance of this.
    static private final Actions SHARED_ACTION = new Actions();

    transient protected Icon        collapsedIcon;
    transient protected Icon        expandedIcon;

    /**
      * Color used to draw hash marks.  If <code>null</code> no hash marks
      * will be drawn.
      */
    private Color hashColor;

    /** Distance between left margin and where vertical dashes will be
      * drawn. */
    protected int               leftChildIndent;
    /** Distance to add to leftChildIndent to determine where cell
      * contents will be drawn. */
    protected int               rightChildIndent;
    /** Total distance that will be indented.  The sum of leftChildIndent
      * and rightChildIndent. */
    protected int               totalChildIndent;

    /** Minimum preferred size. */
    protected Dimension         preferredMinSize;

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

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

    /** Renderer that is being used to do the actual cell drawing. */
    transient protected 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. */
    transient protected 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 shouldSelectCell() 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;

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

    /** Object responsible for handling sizing and expanded issues. */
    // WARNING: Be careful with the bounds held by treeState. They are
    // always in terms of left-to-right. They get mapped to right-to-left
    // by the various methods of this class.
    protected AbstractLayoutCache  treeState;


    /** Used for minimizing the drawing of vertical lines. */
    protected Hashtable<TreePath,Boolean> 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;

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

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

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

    // Following 4 ivars are only valid when editing.

    /** 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 not null. */
    protected int               editingRow;

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

    /** Row correspondin to lead path. */
    private int                 leadRow;
    /** If true, the property change event for LEAD_SELECTION_PATH_PROPERTY,
     * or ANCHOR_SELECTION_PATH_PROPERTY will not generate a repaint. */
    private boolean             ignoreLAChange;

    /** Indicates the orientation. */
    private boolean             leftToRight;

    // Cached listeners
    private PropertyChangeListener propertyChangeListener;
    private PropertyChangeListener selectionModelPropertyChangeListener;
    private MouseListener mouseListener;
    private FocusListener focusListener;
    private KeyListener keyListener;
    /** Used for large models, listens for moved/resized events and
     * updates the validCachedPreferredSize bit accordingly. */
    private ComponentListener   componentListener;
    /** Listens for CellEditor events. */
    private CellEditorListener  cellEditorListener;
    /** Updates the display when the selection changes. */
    private TreeSelectionListener treeSelectionListener;
    /** Is responsible for updating the display based on model events. */
    private TreeModelListener treeModelListener;
    /** Updates the treestate as the nodes expand. */
    private TreeExpansionListener treeExpansionListener;

    /** UI property indicating whether to paint lines */
    private boolean paintLines = true;

    /** UI property for painting dashed lines */
    private boolean lineTypeDashed;

    /**
     * The time factor to treate the series of typed alphanumeric key
     * as prefix for first letter navigation.
     */
    private long timeFactor = 1000L;

    private Handler handler;

    /**
     * A temporary variable for communication between startEditingOnRelease
     * and startEditing.
     */
    private MouseEvent releaseEvent;

    public static ComponentUI createUI(JComponent x) {
        return new BasicTreeUI();
    }


    static void loadActionMap(LazyActionMap map) {
        map.put(new Actions(Actions.SELECT_PREVIOUS));
        map.put(new Actions(Actions.SELECT_PREVIOUS_CHANGE_LEAD));
        map.put(new Actions(Actions.SELECT_PREVIOUS_EXTEND_SELECTION));

        map.put(new Actions(Actions.SELECT_NEXT));
        map.put(new Actions(Actions.SELECT_NEXT_CHANGE_LEAD));
        map.put(new Actions(Actions.SELECT_NEXT_EXTEND_SELECTION));

        map.put(new Actions(Actions.SELECT_CHILD));
        map.put(new Actions(Actions.SELECT_CHILD_CHANGE_LEAD));

        map.put(new Actions(Actions.SELECT_PARENT));
        map.put(new Actions(Actions.SELECT_PARENT_CHANGE_LEAD));

        map.put(new Actions(Actions.SCROLL_UP_CHANGE_SELECTION));
        map.put(new Actions(Actions.SCROLL_UP_CHANGE_LEAD));
        map.put(new Actions(Actions.SCROLL_UP_EXTEND_SELECTION));

        map.put(new Actions(Actions.SCROLL_DOWN_CHANGE_SELECTION));
        map.put(new Actions(Actions.SCROLL_DOWN_EXTEND_SELECTION));
        map.put(new Actions(Actions.SCROLL_DOWN_CHANGE_LEAD));

        map.put(new Actions(Actions.SELECT_FIRST));
        map.put(new Actions(Actions.SELECT_FIRST_CHANGE_LEAD));
        map.put(new Actions(Actions.SELECT_FIRST_EXTEND_SELECTION));

        map.put(new Actions(Actions.SELECT_LAST));
        map.put(new Actions(Actions.SELECT_LAST_CHANGE_LEAD));
        map.put(new Actions(Actions.SELECT_LAST_EXTEND_SELECTION));

        map.put(new Actions(Actions.TOGGLE));

        map.put(new Actions(Actions.CANCEL_EDITING));

        map.put(new Actions(Actions.START_EDITING));

        map.put(new Actions(Actions.SELECT_ALL));

        map.put(new Actions(Actions.CLEAR_SELECTION));

        map.put(new Actions(Actions.SCROLL_LEFT));
        map.put(new Actions(Actions.SCROLL_RIGHT));

        map.put(new Actions(Actions.SCROLL_LEFT_EXTEND_SELECTION));
        map.put(new Actions(Actions.SCROLL_RIGHT_EXTEND_SELECTION));

        map.put(new Actions(Actions.SCROLL_RIGHT_CHANGE_LEAD));
        map.put(new Actions(Actions.SCROLL_LEFT_CHANGE_LEAD));

        map.put(new Actions(Actions.EXPAND));
        map.put(new Actions(Actions.COLLAPSE));
        map.put(new Actions(Actions.MOVE_SELECTION_TO_PARENT));

        map.put(new Actions(Actions.ADD_TO_SELECTION));
        map.put(new Actions(Actions.TOGGLE_AND_ANCHOR));
        map.put(new Actions(Actions.EXTEND_TO));
        map.put(new Actions(Actions.MOVE_SELECTION_TO));

        map.put(TransferHandler.getCutAction());
        map.put(TransferHandler.getCopyAction());
        map.put(TransferHandler.getPasteAction());
    }


    public BasicTreeUI() {
        super();
    }

    protected Color getHashColor() {
        return hashColor;
    }

    protected void setHashColor(Color color) {
        hashColor = color;
    }

    public void setLeftChildIndent(int newAmount) {
        leftChildIndent = newAmount;
        totalChildIndent = leftChildIndent + rightChildIndent;
        if(treeState != null)
            treeState.invalidateSizes();
        updateSize();
    }

    public int getLeftChildIndent() {
        return leftChildIndent;
    }

    public void setRightChildIndent(int newAmount) {
        rightChildIndent = newAmount;
        totalChildIndent = leftChildIndent + rightChildIndent;
        if(treeState != null)
            treeState.invalidateSizes();
        updateSize();
    }

    public int getRightChildIndent() {
        return rightChildIndent;
    }

    public void setExpandedIcon(Icon newG) {
        expandedIcon = newG;
    }

    public Icon getExpandedIcon() {
        return expandedIcon;
    }

    public void setCollapsedIcon(Icon newG) {
        collapsedIcon = newG;
    }

    public Icon getCollapsedIcon() {
        return collapsedIcon;
    }

    //
    // Methods for configuring the behavior of the tree. None of them
    // push the value to the JTree instance. You should really only
    // call these methods on the JTree.
    //

    /**
     * Updates the componentListener, if necessary.
     */
    protected void setLargeModel(boolean largeModel) {
        if(getRowHeight() < 1)
            largeModel = false;
        if(this.largeModel != largeModel) {
            completeEditing();
            this.largeModel = largeModel;
            treeState = createLayoutCache();
            configureLayoutCache();
            updateLayoutCacheExpandedNodesIfNecessary();
            updateSize();
        }
    }

    protected boolean isLargeModel() {
        return largeModel;
    }

    /**
     * Sets the row height, this is forwarded to the treeState.
     */
    protected void setRowHeight(int rowHeight) {
        completeEditing();
        if(treeState != null) {
            setLargeModel(tree.isLargeModel());
            treeState.setRowHeight(rowHeight);
            updateSize();
        }
    }

    protected int getRowHeight() {
        return (tree == null) ? -1 : tree.getRowHeight();
    }

    /**
     * Sets the TreeCellRenderer to <code>tcr</code>. This invokes
     * <code>updateRenderer</code>.
     */
    protected void setCellRenderer(TreeCellRenderer tcr) {
        completeEditing();
        updateRenderer();
        if(treeState != null) {
            treeState.invalidateSizes();
            updateSize();
        }
    }

    /**
     * Return currentCellRenderer, which will either be the trees
     * renderer, or defaultCellRenderer, which ever wasn't null.
     */
    protected TreeCellRenderer getCellRenderer() {
        return currentCellRenderer;
    }

    /**
     * Sets the TreeModel.
     */
    protected void setModel(TreeModel model) {
        completeEditing();
        if(treeModel != null && treeModelListener != null)
            treeModel.removeTreeModelListener(treeModelListener);
        treeModel = model;
        if(treeModel != null) {
            if(treeModelListener != null)
                treeModel.addTreeModelListener(treeModelListener);
        }
        if(treeState != null) {
            treeState.setModel(model);
            updateLayoutCacheExpandedNodesIfNecessary();
            updateSize();
        }
    }

    protected TreeModel getModel() {
        return treeModel;
    }

    /**
     * Sets the root to being visible.
     */
    protected void setRootVisible(boolean newValue) {
        completeEditing();
        updateDepthOffset();
        if(treeState != null) {
            treeState.setRootVisible(newValue);
            treeState.invalidateSizes();
            updateSize();
        }
    }

    protected boolean isRootVisible() {
        return (tree != null) ? tree.isRootVisible() : false;
    }

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

    protected boolean getShowsRootHandles() {
        return (tree != null) ? tree.getShowsRootHandles() : false;
    }

    /**
     * Sets the cell editor.
     */
    protected void setCellEditor(TreeCellEditor editor) {
        updateCellEditor();
    }

    protected TreeCellEditor getCellEditor() {
        return (tree != null) ? tree.getCellEditor() : null;
    }

    /**
     * Configures the receiver to allow, or not allow, editing.
     */
    protected void setEditable(boolean newValue) {
        updateCellEditor();
    }

    protected boolean isEditable() {
        return (tree != null) ? tree.isEditable() : false;
    }

    /**
     * Resets the selection model. The appropriate listener are installed
     * on the model.
     */
    protected void setSelectionModel(TreeSelectionModel newLSM) {
        completeEditing();
        if(selectionModelPropertyChangeListener != null &&
           treeSelectionModel != null)
            treeSelectionModel.removePropertyChangeListener
                              (selectionModelPropertyChangeListener);
        if(treeSelectionListener != null && treeSelectionModel != null)
            treeSelectionModel.removeTreeSelectionListener
                               (treeSelectionListener);
        treeSelectionModel = newLSM;
        if(treeSelectionModel != null) {
            if(selectionModelPropertyChangeListener != null)
                treeSelectionModel.addPropertyChangeListener
                              (selectionModelPropertyChangeListener);
            if(treeSelectionListener != null)
                treeSelectionModel.addTreeSelectionListener
                                   (treeSelectionListener);
            if(treeState != null)
                treeState.setSelectionModel(treeSelectionModel);
        }
        else if(treeState != null)
            treeState.setSelectionModel(null);
        if(tree != null)
            tree.repaint();
    }

    protected TreeSelectionModel getSelectionModel() {
        return treeSelectionModel;
    }

    //
    // TreeUI methods
    //

    /**
      * Returns the Rectangle enclosing the label portion that the
      * last item in path will be drawn into.  Will return null if
      * any component in path is currently valid.
      */
    public Rectangle getPathBounds(JTree tree, TreePath path) {
        if(tree != null && treeState != null) {
            return getPathBounds(path, tree.getInsets(), new Rectangle());
        }
        return null;
    }

    private Rectangle getPathBounds(TreePath path, Insets insets,
                                    Rectangle bounds) {
        bounds = treeState.getBounds(path, bounds);
        if (bounds != null) {
            if (leftToRight) {
                bounds.x += insets.left;
            } else {
                bounds.x = tree.getWidth() - (bounds.x + bounds.width) -
                        insets.right;
            }
            bounds.y += insets.top;
        }
        return bounds;
    }

    /**
      * Returns the path for passed in row.  If row is not visible
      * null is returned.
      */
    public TreePath getPathForRow(JTree tree, int row) {
        return (treeState != null) ? treeState.getPathForRow(row) : null;
    }

    /**
      * Returns the row that the last item identified in path is visible
      * at.  Will return -1 if any of the elements in path are not
      * currently visible.
      */
    public int getRowForPath(JTree tree, TreePath path) {
        return (treeState != null) ? treeState.getRowForPath(path) : -1;
    }

    /**
      * Returns the number of rows that are being displayed.
      */
    public int getRowCount(JTree tree) {
        return (treeState != null) ? treeState.getRowCount() : 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.
      */
    public TreePath getClosestPathForLocation(JTree tree, int x, int y) {
        if(tree != null && treeState != null) {
            // TreeState doesn't care about the x location, hence it isn't
            // adjusted
            y -= tree.getInsets().top;
            return treeState.getPathClosestTo(x, y);
        }
        return null;
    }

    /**
      * Returns true if the tree is being edited.  The item that is being
      * edited can be returned by getEditingPath().
      */
    public boolean isEditing(JTree tree) {
        return (editingComponent != null);
    }

    /**
      * Stops the current editing session.  This has no effect if the
      * tree isn't being edited.  Returns true if the editor allows the
      * editing session to stop.
      */
    public boolean stopEditing(JTree tree) {
        if(editingComponent != null && cellEditor.stopCellEditing()) {
            completeEditing(false, false, true);
            return true;
        }
        return false;
    }

    /**
      * Cancels the current editing session.
      */
    public void cancelEditing(JTree tree) {
        if(editingComponent != null) {
            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.
      */
    public void startEditingAtPath(JTree tree, TreePath path) {
        tree.scrollPathToVisible(path);
        if(path != null && tree.isVisible(path))
            startEditing(path, null);
    }

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

    //
    // Install methods
    //

    public void installUI(JComponent c) {
        if ( c == null ) {
            throw new NullPointerException( "null component passed to BasicTreeUI.installUI()" );
        }

        tree = (JTree)c;

        prepareForUIInstall();

        // Boilerplate install block
        installDefaults();
        installKeyboardActions();
        installComponents();
        installListeners();

        completeUIInstall();
    }

    /**
     * Invoked after the <code>tree</code> instance variable has been
     * set, but before any defaults/listeners have been installed.
     */
    protected void prepareForUIInstall() {
        drawingCache = new Hashtable<TreePath,Boolean>(7);

        // Data member initializations
        leftToRight = BasicGraphicsUtils.isLeftToRight(tree);
        stopEditingInCompleteEditing = true;
        lastSelectedRow = -1;
        leadRow = -1;
        preferredSize = new Dimension();

        largeModel = tree.isLargeModel();
        if(getRowHeight() <= 0)
            largeModel = false;
        setModel(tree.getModel());
    }

    /**
     * Invoked from installUI after all the defaults/listeners have been
     * installed.
     */
    protected void completeUIInstall() {
        // Custom install code

        this.setShowsRootHandles(tree.getShowsRootHandles());

        updateRenderer();

        updateDepthOffset();

        setSelectionModel(tree.getSelectionModel());

        // Create, if necessary, the TreeState instance.
        treeState = createLayoutCache();
        configureLayoutCache();

        updateSize();
    }

    protected void installDefaults() {
        if(tree.getBackground() == null ||
           tree.getBackground() instanceof UIResource) {
            tree.setBackground(UIManager.getColor("Tree.background"));
        }
        if(getHashColor() == null || getHashColor() instanceof UIResource) {
            setHashColor(UIManager.getColor("Tree.hash"));
        }
        if (tree.getFont() == null || tree.getFont() instanceof UIResource)
            tree.setFont( UIManager.getFont("Tree.font") );
        // JTree's original row height is 16.  To correctly display the
        // contents on Linux we should have set it to 18, Windows 19 and
        // Solaris 20.  As these values vary so much it's too hard to
        // be backward compatable and try to update the row height, we're
        // therefor NOT going to adjust the row height based on font.  If the
        // developer changes the font, it's there responsibility to update
        // the row height.

        setExpandedIcon( (Icon)UIManager.get( "Tree.expandedIcon" ) );
        setCollapsedIcon( (Icon)UIManager.get( "Tree.collapsedIcon" ) );

        setLeftChildIndent(((Integer)UIManager.get("Tree.leftChildIndent")).
                           intValue());
        setRightChildIndent(((Integer)UIManager.get("Tree.rightChildIndent")).
                           intValue());

        LookAndFeel.installProperty(tree, "rowHeight",
                                    UIManager.get("Tree.rowHeight"));

        largeModel = (tree.isLargeModel() && tree.getRowHeight() > 0);

        Object scrollsOnExpand = UIManager.get("Tree.scrollsOnExpand");
        if (scrollsOnExpand != null) {
            LookAndFeel.installProperty(tree, "scrollsOnExpand", scrollsOnExpand);
        }

        paintLines = UIManager.getBoolean("Tree.paintLines");
        lineTypeDashed = UIManager.getBoolean("Tree.lineTypeDashed");

        Long l = (Long)UIManager.get("Tree.timeFactor");
        timeFactor = (l!=null) ? l.longValue() : 1000L;

        Object showsRootHandles = UIManager.get("Tree.showsRootHandles");
        if (showsRootHandles != null) {
            LookAndFeel.installProperty(tree,
                    JTree.SHOWS_ROOT_HANDLES_PROPERTY, showsRootHandles);
        }
    }

    protected void installListeners() {
        if ( (propertyChangeListener = createPropertyChangeListener())
             != null ) {
            tree.addPropertyChangeListener(propertyChangeListener);
        }
        if ( (mouseListener = createMouseListener()) != null ) {
            tree.addMouseListener(mouseListener);
            if (mouseListener instanceof MouseMotionListener) {
                tree.addMouseMotionListener((MouseMotionListener)mouseListener);
            }
        }
        if ((focusListener = createFocusListener()) != null ) {
            tree.addFocusListener(focusListener);
        }
        if ((keyListener = createKeyListener()) != null) {
            tree.addKeyListener(keyListener);
        }
        if((treeExpansionListener = createTreeExpansionListener()) != null) {
            tree.addTreeExpansionListener(treeExpansionListener);
        }
        if((treeModelListener = createTreeModelListener()) != null &&
           treeModel != null) {
            treeModel.addTreeModelListener(treeModelListener);
        }
        if((selectionModelPropertyChangeListener =
            createSelectionModelPropertyChangeListener()) != null &&
           treeSelectionModel != null) {
            treeSelectionModel.addPropertyChangeListener
                (selectionModelPropertyChangeListener);
        }
        if((treeSelectionListener = createTreeSelectionListener()) != null &&
           treeSelectionModel != null) {
            treeSelectionModel.addTreeSelectionListener(treeSelectionListener);
        }

        TransferHandler th = tree.getTransferHandler();
        if (th == null || th instanceof UIResource) {
            tree.setTransferHandler(defaultTransferHandler);
            // default TransferHandler doesn't support drop
            // so we don't want drop handling
            if (tree.getDropTarget() instanceof UIResource) {
                tree.setDropTarget(null);
            }
        }

        LookAndFeel.installProperty(tree, "opaque", Boolean.TRUE);
    }

    protected void installKeyboardActions() {
        InputMap km = getInputMap(JComponent.
                                  WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);

        SwingUtilities.replaceUIInputMap(tree, JComponent.
                                         WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
                                         km);
        km = getInputMap(JComponent.WHEN_FOCUSED);
        SwingUtilities.replaceUIInputMap(tree, JComponent.WHEN_FOCUSED, km);

        LazyActionMap.installLazyActionMap(tree, BasicTreeUI.class,
                                           "Tree.actionMap");
    }

    InputMap getInputMap(int condition) {
        if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) {
            return (InputMap)DefaultLookup.get(tree, this,
                                               "Tree.ancestorInputMap");
        }
        else if (condition == JComponent.WHEN_FOCUSED) {
            InputMap keyMap = (InputMap)DefaultLookup.get(tree, this,
                                                      "Tree.focusInputMap");
            InputMap rtlKeyMap;

            if (tree.getComponentOrientation().isLeftToRight() ||
                  ((rtlKeyMap = (InputMap)DefaultLookup.get(tree, this,
                  "Tree.focusInputMap.RightToLeft")) == null)) {
                return keyMap;
            } else {
                rtlKeyMap.setParent(keyMap);
                return rtlKeyMap;
            }
        }
        return null;
    }

    /**
     * Intalls the subcomponents of the tree, which is the renderer pane.
     */
    protected void installComponents() {
        if ((rendererPane = createCellRendererPane()) != null) {
            tree.add( rendererPane );
        }
    }

    //
    // Create methods.
    //

    /**
     * Creates an instance of NodeDimensions that is able to determine
     * the size of a given node in the tree.
     */
    protected AbstractLayoutCache.NodeDimensions createNodeDimensions() {
        return new NodeDimensionsHandler();
    }

    /**
     * Creates a listener that is responsible that updates the UI based on
     * how the tree changes.
     */
    protected PropertyChangeListener createPropertyChangeListener() {
        return getHandler();
    }

    private Handler getHandler() {
        if (handler == null) {
            handler = new Handler();
        }
        return handler;
    }

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

    /**
     * Creates a listener that is responsible for updating the display
     * when focus is lost/gained.
     */
    protected FocusListener createFocusListener() {
        return getHandler();
    }

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

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

    /**
     * Creates the listener that updates the display based on selection change
     * methods.
     */
    protected TreeSelectionListener createTreeSelectionListener() {
        return getHandler();
    }

    /**
     * Creates a listener to handle events from the current editor.
     */
    protected CellEditorListener createCellEditorListener() {
        return getHandler();
    }

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

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

    /**
     * Creates the object responsible for managing what is expanded, as
     * well as the size of nodes.
     */
    protected AbstractLayoutCache createLayoutCache() {
        if(isLargeModel() && getRowHeight() > 0) {
            return new FixedHeightLayoutCache();
        }
        return new VariableHeightLayoutCache();
    }

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

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

            return editor;
        }
        return new DefaultTreeCellEditor(tree, null);
    }

    /**
      * Returns 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.
     */
    protected TreeModelListener createTreeModelListener() {
        return getHandler();
    }

    //
    // Uninstall methods
    //

    public void uninstallUI(JComponent c) {
        completeEditing();

        prepareForUIUninstall();

        uninstallDefaults();
        uninstallListeners();
        uninstallKeyboardActions();
        uninstallComponents();

        completeUIUninstall();
    }

    protected void prepareForUIUninstall() {
    }

    protected void completeUIUninstall() {
        if(createdRenderer) {
            tree.setCellRenderer(null);
        }
        if(createdCellEditor) {
            tree.setCellEditor(null);
        }
        cellEditor = null;
        currentCellRenderer = null;
        rendererPane = null;
        componentListener = null;
        propertyChangeListener = null;
        mouseListener = null;
        focusListener = null;
        keyListener = null;
        setSelectionModel(null);
        treeState = null;
        drawingCache = null;
        selectionModelPropertyChangeListener = null;
        tree = null;
        treeModel = null;
        treeSelectionModel = null;
        treeSelectionListener = null;
        treeExpansionListener = null;
    }

    protected void uninstallDefaults() {
        if (tree.getTransferHandler() instanceof UIResource) {
            tree.setTransferHandler(null);
        }
    }

    protected void uninstallListeners() {
        if(componentListener != null) {
            tree.removeComponentListener(componentListener);
        }
        if (propertyChangeListener != null) {
            tree.removePropertyChangeListener(propertyChangeListener);
        }
        if (mouseListener != null) {
            tree.removeMouseListener(mouseListener);
            if (mouseListener instanceof MouseMotionListener) {
                tree.removeMouseMotionListener((MouseMotionListener)mouseListener);
            }
        }
        if (focusListener != null) {
            tree.removeFocusListener(focusListener);
        }
        if (keyListener != null) {
            tree.removeKeyListener(keyListener);
        }
        if(treeExpansionListener != null) {
            tree.removeTreeExpansionListener(treeExpansionListener);
        }
        if(treeModel != null && treeModelListener != null) {
            treeModel.removeTreeModelListener(treeModelListener);
        }
        if(selectionModelPropertyChangeListener != null &&
           treeSelectionModel != null) {
            treeSelectionModel.removePropertyChangeListener
                (selectionModelPropertyChangeListener);
        }
        if(treeSelectionListener != null && treeSelectionModel != null) {
            treeSelectionModel.removeTreeSelectionListener
                               (treeSelectionListener);
        }
        handler = null;
    }

    protected void uninstallKeyboardActions() {
        SwingUtilities.replaceUIActionMap(tree, null);
        SwingUtilities.replaceUIInputMap(tree, JComponent.
                                         WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
                                         null);
        SwingUtilities.replaceUIInputMap(tree, JComponent.WHEN_FOCUSED, null);
    }

    /**
     * Uninstalls the renderer pane.
     */
    protected void uninstallComponents() {
        if(rendererPane != null) {
            tree.remove(rendererPane);
        }
    }

    /**
     * Recomputes the right margin, and invalidates any tree states
     */
    private void redoTheLayout() {
        if (treeState != null) {
            treeState.invalidateSizes();
        }
    }

    /**
     * Returns the baseline.
     *
     * @throws NullPointerException {@inheritDoc}
     * @throws IllegalArgumentException {@inheritDoc}
     * @see javax.swing.JComponent#getBaseline(int, int)
     * @since 1.6
     */
    public int getBaseline(JComponent c, int width, int height) {
        super.getBaseline(c, width, height);
        UIDefaults lafDefaults = UIManager.getLookAndFeelDefaults();
        Component renderer = (Component)lafDefaults.get(
                BASELINE_COMPONENT_KEY);
        if (renderer == null) {
            TreeCellRenderer tcr = createDefaultCellRenderer();
            renderer = tcr.getTreeCellRendererComponent(
                    tree, "a", false, false, false, -1, false);
            lafDefaults.put(BASELINE_COMPONENT_KEY, renderer);
        }
        int rowHeight = tree.getRowHeight();
        int baseline;
        if (rowHeight > 0) {
            baseline = renderer.getBaseline(Integer.MAX_VALUE, rowHeight);
        }
        else {
            Dimension pref = renderer.getPreferredSize();
            baseline = renderer.getBaseline(pref.width, pref.height);
        }
        return baseline + tree.getInsets().top;
    }

    /**
     * Returns an enum indicating how the baseline of the component
     * changes as the size changes.
     *
     * @throws NullPointerException {@inheritDoc}
     * @see javax.swing.JComponent#getBaseline(int, int)
     * @since 1.6
     */
    public Component.BaselineResizeBehavior getBaselineResizeBehavior(
            JComponent c) {
        super.getBaselineResizeBehavior(c);
        return Component.BaselineResizeBehavior.CONSTANT_ASCENT;
    }

    //
    // Painting routines.
    //

    public void paint(Graphics g, JComponent c) {
        if (tree != c) {
            throw new InternalError("incorrect component");
        }

        // Should never happen if installed for a UI
        if(treeState == null) {
            return;
        }

        Rectangle        paintBounds = g.getClipBounds();
        Insets           insets = tree.getInsets();
        TreePath         initialPath = getClosestPathForLocation
                                       (tree, 0, paintBounds.y);
        Enumeration      paintingEnumerator = treeState.getVisiblePathsFrom
                                              (initialPath);
        int              row = treeState.getRowForPath(initialPath);
        int              endY = paintBounds.y + paintBounds.height;

        drawingCache.clear();

        if(initialPath != null && paintingEnumerator != null) {
            TreePath   parentPath = initialPath;

            // Draw the lines, knobs, and rows

            // Find each parent and have them draw a line to their last child
            parentPath = parentPath.getParentPath();
            while(parentPath != null) {
                paintVerticalPartOfLeg(g, paintBounds, insets, parentPath);
                drawingCache.put(parentPath, Boolean.TRUE);
                parentPath = parentPath.getParentPath();
            }

            boolean         done = false;
            // Information for the node being rendered.
            boolean         isExpanded;
            boolean         hasBeenExpanded;
            boolean         isLeaf;
            Rectangle       boundsBuffer = new Rectangle();
            Rectangle       bounds;
            TreePath        path;
            boolean         rootVisible = isRootVisible();

            while(!done && paintingEnumerator.hasMoreElements()) {
                path = (TreePath)paintingEnumerator.nextElement();
                if(path != null) {
                    isLeaf = treeModel.isLeaf(path.getLastPathComponent());
                    if(isLeaf)
                        isExpanded = hasBeenExpanded = false;
                    else {
                        isExpanded = treeState.getExpandedState(path);
                        hasBeenExpanded = tree.hasBeenExpanded(path);
                    }
                    bounds = getPathBounds(path, insets, boundsBuffer);
                    if(bounds == null)
                        // This will only happen if the model changes out
                        // from under us (usually in another thread).
                        // Swing isn't multithreaded, but I'll put this
                        // check in anyway.
                        return;
                    // See if the vertical line to the parent has been drawn.
                    parentPath = path.getParentPath();
                    if(parentPath != null) {
                        if(drawingCache.get(parentPath) == null) {
                            paintVerticalPartOfLeg(g, paintBounds,
                                                   insets, parentPath);
                            drawingCache.put(parentPath, Boolean.TRUE);
                        }
                        paintHorizontalPartOfLeg(g, paintBounds, insets,
                                                 bounds, path, row,
                                                 isExpanded,
                                                 hasBeenExpanded, isLeaf);
                    }
                    else if(rootVisible && row == 0) {
                        paintHorizontalPartOfLeg(g, paintBounds, insets,
                                                 bounds, path, row,
                                                 isExpanded,
                                                 hasBeenExpanded, isLeaf);
                    }
                    if(shouldPaintExpandControl(path, row, isExpanded,
                                                hasBeenExpanded, isLeaf)) {
                        paintExpandControl(g, paintBounds, insets, bounds,
                                           path, row, isExpanded,
                                           hasBeenExpanded, isLeaf);
                    }
                    paintRow(g, paintBounds, insets, bounds, path,
                                 row, isExpanded, hasBeenExpanded, isLeaf);
                    if((bounds.y + bounds.height) >= endY)
                        done = true;
                }
                else {
                    done = true;
                }
                row++;
            }
        }

        paintDropLine(g);

        // Empty out the renderer pane, allowing renderers to be gc'ed.
        rendererPane.removeAll();

        drawingCache.clear();
    }

    private boolean isDropLine(JTree.DropLocation loc) {
        return loc != null && loc.getPath() != null && loc.getChildIndex() != -1;
    }

    private void paintDropLine(Graphics g) {
        JTree.DropLocation loc = tree.getDropLocation();
        if (!isDropLine(loc)) {
            return;
        }

        Color c = UIManager.getColor("Tree.dropLineColor");
        if (c != null) {
            g.setColor(c);
            Rectangle rect = getDropLineRect(loc);
            g.fillRect(rect.x, rect.y, rect.width, rect.height);
        }
    }

    private Rectangle getDropLineRect(JTree.DropLocation loc) {
        Rectangle rect;
        TreePath path = loc.getPath();
        int index = loc.getChildIndex();
        boolean ltr = leftToRight;

        Insets insets = tree.getInsets();

        if (tree.getRowCount() == 0) {
            rect = new Rectangle(insets.left,
                                 insets.top,
                                 tree.getWidth() - insets.left - insets.right,
                                 0);
        } else {
            TreeModel model = getModel();
            Object root = model.getRoot();

            if (path.getLastPathComponent() == root
                    && index >= model.getChildCount(root)) {

                rect = tree.getRowBounds(tree.getRowCount() - 1);
                rect.y = rect.y + rect.height;
                Rectangle xRect;

                if (!tree.isRootVisible()) {
                    xRect = tree.getRowBounds(0);
                } else if (model.getChildCount(root) == 0){
                    xRect = tree.getRowBounds(0);
                    xRect.x += totalChildIndent;
                    xRect.width -= totalChildIndent + totalChildIndent;
                } else {
                    TreePath lastChildPath = path.pathByAddingChild(
                        model.getChild(root, model.getChildCount(root) - 1));
                    xRect = tree.getPathBounds(lastChildPath);
                }

                rect.x = xRect.x;
                rect.width = xRect.width;
            } else {
                rect = tree.getPathBounds(path.pathByAddingChild(
                    model.getChild(path.getLastPathComponent(), index)));
            }
        }

        if (rect.y != 0) {
            rect.y--;
        }

        if (!ltr) {
            rect.x = rect.x + rect.width - 100;
        }

        rect.width = 100;
        rect.height = 2;

        return rect;
    }

    /**
     * Paints the horizontal part of the leg. The receiver should
     * NOT modify <code>clipBounds</code>, or <code>insets</code>.<p>
     * NOTE: <code>parentRow</code> can be -1 if the root is not visible.
     */
    protected void paintHorizontalPartOfLeg(Graphics g, Rectangle clipBounds,
                                            Insets insets, Rectangle bounds,
                                            TreePath path, int row,
                                            boolean isExpanded,
                                            boolean hasBeenExpanded, boolean
                                            isLeaf) {
        if (!paintLines) {
            return;
        }

        // Don't paint the legs for the root'ish node if the
        int depth = path.getPathCount() - 1;
        if((depth == 0 || (depth == 1 && !isRootVisible())) &&
           !getShowsRootHandles()) {
            return;
        }

        int clipLeft = clipBounds.x;
        int clipRight = clipBounds.x + clipBounds.width;
        int clipTop = clipBounds.y;
        int clipBottom = clipBounds.y + clipBounds.height;
        int lineY = bounds.y + bounds.height / 2;

        if (leftToRight) {
            int leftX = bounds.x - getRightChildIndent();
            int nodeX = bounds.x - getHorizontalLegBuffer();

            if(lineY >= clipTop
                    && lineY < clipBottom
                    && nodeX >= clipLeft
                    && leftX < clipRight
                    && leftX < nodeX) {

                g.setColor(getHashColor());
                paintHorizontalLine(g, tree, lineY, leftX, nodeX - 1);
            }
        } else {
            int nodeX = bounds.x + bounds.width + getHorizontalLegBuffer();
            int rightX = bounds.x + bounds.width + getRightChildIndent();

            if(lineY >= clipTop
                    && lineY < clipBottom
                    && rightX >= clipLeft
                    && nodeX < clipRight
                    && nodeX < rightX) {

                g.setColor(getHashColor());
                paintHorizontalLine(g, tree, lineY, nodeX, rightX - 1);
            }
        }
    }

    /**
     * Paints the vertical part of the leg. The receiver should
     * NOT modify <code>clipBounds</code>, <code>insets</code>.<p>
     */
    protected void paintVerticalPartOfLeg(Graphics g, Rectangle clipBounds,
                                          Insets insets, TreePath path) {
        if (!paintLines) {
            return;
        }

        int depth = path.getPathCount() - 1;
        if (depth == 0 && !getShowsRootHandles() && !isRootVisible()) {
            return;
        }
        int lineX = getRowX(-1, depth + 1);
        if (leftToRight) {
            lineX = lineX - getRightChildIndent() + insets.left;
        }
        else {
            lineX = tree.getWidth() - lineX - insets.right +
                    getRightChildIndent() - 1;
        }
        int clipLeft = clipBounds.x;
        int clipRight = clipBounds.x + (clipBounds.width - 1);

        if (lineX >= clipLeft && lineX <= clipRight) {
            int clipTop = clipBounds.y;
            int clipBottom = clipBounds.y + clipBounds.height;
            Rectangle parentBounds = getPathBounds(tree, path);
            Rectangle lastChildBounds = getPathBounds(tree,
                                                     getLastChildPath(path));

            if(lastChildBounds == null)
                // This shouldn't happen, but if the model is modified
                // in another thread it is possible for this to happen.
                // Swing isn't multithreaded, but I'll add this check in
                // anyway.
                return;

            int       top;

            if(parentBounds == null) {
                top = Math.max(insets.top + getVerticalLegBuffer(),
                               clipTop);
            }
            else
                top = Math.max(parentBounds.y + parentBounds.height +
                               getVerticalLegBuffer(), clipTop);
            if(depth == 0 && !isRootVisible()) {
                TreeModel      model = getModel();

                if(model != null) {
                    Object        root = model.getRoot();

                    if(model.getChildCount(root) > 0) {
                        parentBounds = getPathBounds(tree, path.
                                  pathByAddingChild(model.getChild(root, 0)));
                        if(parentBounds != null)
                            top = Math.max(insets.top + getVerticalLegBuffer(),
                                           parentBounds.y +
                                           parentBounds.height / 2);
                    }
                }
            }

            int bottom = Math.min(lastChildBounds.y +
                                  (lastChildBounds.height / 2), clipBottom);

            if (top <= bottom) {
                g.setColor(getHashColor());
                paintVerticalLine(g, tree, lineX, top, bottom);
            }
        }
    }

    /**
     * Paints the expand (toggle) part of a row. The receiver should
     * NOT modify <code>clipBounds</code>, or <code>insets</code>.
     */
    protected void paintExpandControl(Graphics g,
                                      Rectangle clipBounds, Insets insets,
                                      Rectangle bounds, TreePath path,
                                      int row, boolean isExpanded,
                                      boolean hasBeenExpanded,
                                      boolean isLeaf) {
        Object       value = path.getLastPathComponent();

        // Draw icons if not a leaf and either hasn't been loaded,
        // or the model child count is > 0.
        if (!isLeaf && (!hasBeenExpanded ||
                        treeModel.getChildCount(value) > 0)) {
            int middleXOfKnob;
            if (leftToRight) {
                middleXOfKnob = bounds.x - getRightChildIndent() + 1;
            } else {
                middleXOfKnob = bounds.x + bounds.width + getRightChildIndent() - 1;
            }
            int middleYOfKnob = bounds.y + (bounds.height / 2);

            if (isExpanded) {
                Icon expandedIcon = getExpandedIcon();
                if(expandedIcon != null)
                  drawCentered(tree, g, expandedIcon, middleXOfKnob,
                               middleYOfKnob );
            }
            else {
                Icon collapsedIcon = getCollapsedIcon();
                if(collapsedIcon != null)
                  drawCentered(tree, g, collapsedIcon, middleXOfKnob,
                               middleYOfKnob);
            }
        }
    }

    /**
     * Paints the renderer part of a row. The receiver should
     * NOT modify <code>clipBounds</code>, or <code>insets</code>.
     */
    protected void paintRow(Graphics g, Rectangle clipBounds,
                            Insets insets, Rectangle bounds, TreePath path,
                            int row, boolean isExpanded,
                            boolean hasBeenExpanded, boolean isLeaf) {
        // Don't paint the renderer if editing this row.
        if(editingComponent != null && editingRow == row)
            return;

        int leadIndex;

        if(tree.hasFocus()) {
            leadIndex = getLeadSelectionRow();
        }
        else
            leadIndex = -1;

        Component component;

        component = currentCellRenderer.getTreeCellRendererComponent
                      (tree, path.getLastPathComponent(),
                       tree.isRowSelected(row), isExpanded, isLeaf, row,
                       (leadIndex == row));

        rendererPane.paintComponent(g, component, tree, bounds.x, bounds.y,
                                    bounds.width, bounds.height, true);
    }

    /**
     * Returns true if the expand (toggle) control should be drawn for
     * the specified row.
     */
    protected boolean shouldPaintExpandControl(TreePath path, int row,
                                               boolean isExpanded,
                                               boolean hasBeenExpanded,
                                               boolean isLeaf) {
        if(isLeaf)
            return false;

        int              depth = path.getPathCount() - 1;

        if((depth == 0 || (depth == 1 && !isRootVisible())) &&
           !getShowsRootHandles())
            return false;
        return true;
    }

    /**
     * Paints a vertical line.
     */
    protected void paintVerticalLine(Graphics g, JComponent c, int x, int top,
                                    int bottom) {
        if (lineTypeDashed) {
            drawDashedVerticalLine(g, x, top, bottom);
        } else {
            g.drawLine(x, top, x, bottom);
        }
    }

    /**
     * Paints a horizontal line.
     */
    protected void paintHorizontalLine(Graphics g, JComponent c, int y,
                                      int left, int right) {
        if (lineTypeDashed) {
            drawDashedHorizontalLine(g, y, left, right);
        } else {
            g.drawLine(left, y, right, y);
        }
    }

    /**
     * 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.
     */
    protected int getVerticalLegBuffer() {
        return 0;
    }

    /**
     * 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.
     */
    protected int getHorizontalLegBuffer() {
        return 0;
    }

    private int findCenteredX(int x, int iconWidth) {
        return leftToRight
               ? x - (int)Math.ceil(iconWidth / 2.0)
               : x - (int)Math.floor(iconWidth / 2.0);
    }

    //
    // Generic painting methods
    //

    // Draws the icon centered at (x,y)
    protected void drawCentered(Component c, Graphics graphics, Icon icon,
                                int x, int y) {
        icon.paintIcon(c, graphics,
                      findCenteredX(x, icon.getIconWidth()),
                      y - icon.getIconHeight() / 2);
    }

    // This method is slow -- revisit when Java2D is ready.
    // assumes x1 <= x2
    protected void drawDashedHorizontalLine(Graphics g, int y, int x1, int x2){
        // Drawing only even coordinates helps join line segments so they
        // appear as one line.  This can be defeated by translating the
        // Graphics by an odd amount.
        x1 += (x1 % 2);

        for (int x = x1; x <= x2; x+=2) {
            g.drawLine(x, y, x, y);
        }
    }

    // This method is slow -- revisit when Java2D is ready.
    // assumes y1 <= y2
    protected void drawDashedVerticalLine(Graphics g, int x, int y1, int y2) {
        // Drawing only even coordinates helps join line segments so they
        // appear as one line.  This can be defeated by translating the
        // Graphics by an odd amount.
        y1 += (y1 % 2);

        for (int y = y1; y <= y2; y+=2) {
            g.drawLine(x, y, x, y);
        }
    }

    //
    // Various local methods
    //

    /**
     * Returns the location, along the x-axis, to render a particular row
     * at. The return value does not include any Insets specified on the JTree.
     * This does not check for the validity of the row or depth, it is assumed
     * to be correct and will not throw an Exception if the row or depth
     * doesn't match that of the tree.
     *
     * @param row Row to return x location for
     * @param depth Depth of the row
     * @return amount to indent the given row.
     * @since 1.5
     */
    protected int getRowX(int row, int depth) {
        return totalChildIndent * (depth + depthOffset);
    }

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

    private void updateLayoutCacheExpandedNodesIfNecessary() {
        if (treeModel != null && treeModel.getRoot() != null) {
            TreePath rootPath = new TreePath(treeModel.getRoot());
            if (tree.isExpanded(rootPath)) {
                updateLayoutCacheExpandedNodes();
            } else {
                treeState.setExpandedState(rootPath, false);
            }
        }
    }

    /**
     * Updates the expanded state of all the descendants of <code>path</code>
     * by getting the expanded descendants from the tree and forwarding
     * to the tree state.
     */
    protected void updateExpandedDescendants(TreePath path) {
        completeEditing();
        if(treeState != null) {
            treeState.setExpandedState(path, true);

            Enumeration   descendants = tree.getExpandedDescendants(path);

            if(descendants != null) {
                while(descendants.hasMoreElements()) {
                    path = (TreePath)descendants.nextElement();
                    treeState.setExpandedState(path, true);
                }
            }
            updateLeadRow();
            updateSize();
        }
    }

    /**
     * Returns a path to the last child of <code>parent</code>.
     */
    protected TreePath getLastChildPath(TreePath parent) {
        if(treeModel != null) {
            int         childCount = treeModel.getChildCount
                (parent.getLastPathComponent());

            if(childCount > 0)
                return parent.pathByAddingChild(treeModel.getChild
                           (parent.getLastPathComponent(), childCount - 1));
        }
        return null;
    }

    /**
     * Updates how much each depth should be offset by.
     */
    protected void updateDepthOffset() {
        if(isRootVisible()) {
            if(getShowsRootHandles())
                depthOffset = 1;
            else
                depthOffset = 0;
        }
        else if(!getShowsRootHandles())
            depthOffset = -1;
        else
            depthOffset = 0;
    }

    /**
      * Updates the cellEditor based on the 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() {
        TreeCellEditor        newEditor;

        completeEditing();
        if(tree == null)
            newEditor = null;
        else {
            if(tree.isEditable()) {
                newEditor = tree.getCellEditor();
                if(newEditor == null) {
                    newEditor = createDefaultCellEditor();
                    if(newEditor != null) {
                        tree.setCellEditor(newEditor);
                        createdCellEditor = true;
                    }
                }
            }
            else
                newEditor = null;
        }
        if(newEditor != cellEditor) {
            if(cellEditor != null && cellEditorListener != null)
                cellEditor.removeCellEditorListener(cellEditorListener);
            cellEditor = newEditor;
            if(cellEditorListener == null)
                cellEditorListener = createCellEditorListener();
            if(newEditor != null && cellEditorListener != null)
                newEditor.addCellEditorListener(cellEditorListener);
            createdCellEditor = false;
        }
    }

    /**
      * Messaged from the tree we're in when the renderer has changed.
      */
    protected void updateRenderer() {
        if(tree != null) {
            TreeCellRenderer      newCellRenderer;

            newCellRenderer = tree.getCellRenderer();
            if(newCellRenderer == null) {
                tree.setCellRenderer(createDefaultCellRenderer());
                createdRenderer = true;
            }
            else {
                createdRenderer = false;
                currentCellRenderer = newCellRenderer;
                if(createdCellEditor) {
                    tree.setCellEditor(null);
                }
            }
        }
        else {
            createdRenderer = false;
            currentCellRenderer = null;
        }
        updateCellEditor();
    }

    /**
     * Resets the TreeState instance based on the tree we're providing the
     * look and feel for.
     */
    protected void configureLayoutCache() {
        if(treeState != null && tree != null) {
            if(nodeDimensions == null)
                nodeDimensions = createNodeDimensions();
            treeState.setNodeDimensions(nodeDimensions);
            treeState.setRootVisible(tree.isRootVisible());
            treeState.setRowHeight(tree.getRowHeight());
            treeState.setSelectionModel(getSelectionModel());
            // Only do this if necessary, may loss state if call with
            // same model as it currently has.
            if(treeState.getModel() != tree.getModel())
                treeState.setModel(tree.getModel());
            updateLayoutCacheExpandedNodesIfNecessary();
            // Create a listener to update preferred size when bounds
            // changes, if necessary.
            if(isLargeModel()) {
                if(componentListener == null) {
                    componentListener = createComponentListener();
                    if(componentListener != null)
                        tree.addComponentListener(componentListener);
                }
            }
            else if(componentListener != null) {
                tree.removeComponentListener(componentListener);
                componentListener = null;
            }
        }
        else if(componentListener != null) {
            tree.removeComponentListener(componentListener);
            componentListener = null;
        }
    }

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

    private void updateSize0() {
        validCachedPreferredSize = false;
        tree.revalidate();
    }

    /**
     * Updates the <code>preferredSize</code> instance variable,
     * which is returned from <code>getPreferredSize()</code>.<p>
     * For left to right orientations, the size is determined from the
     * current AbstractLayoutCache. For RTL orientations, the preferred size
     * becomes the width minus the minimum x position.
     */
    protected void updateCachedPreferredSize() {
        if(treeState != null) {
            Insets               i = tree.getInsets();

            if(isLargeModel()) {
                Rectangle            visRect = tree.getVisibleRect();

                if (visRect.x == 0 && visRect.y == 0 &&
                        visRect.width == 0 && visRect.height == 0 &&
                        tree.getVisibleRowCount() > 0) {
                    // The tree doesn't have a valid bounds yet. Calculate
                    // based on visible row count.
                    visRect.width = 1;
                    visRect.height = tree.getRowHeight() *
                            tree.getVisibleRowCount();
                } else {
                    visRect.x -= i.left;
                    visRect.y -= i.top;
                }
                preferredSize.width = treeState.getPreferredWidth(visRect);
            }
            else {
                preferredSize.width = treeState.getPreferredWidth(null);
            }
            preferredSize.height = treeState.getPreferredHeight();
            preferredSize.width += i.left + i.right;
            preferredSize.height += i.top + i.bottom;
        }
        validCachedPreferredSize = true;
    }

    /**
      * Messaged from the VisibleTreeNode after it has been expanded.
      */
    protected void pathWasExpanded(TreePath path) {
        if(tree != null) {
            tree.fireTreeExpanded(path);
        }
    }

    /**
      * Messaged from the VisibleTreeNode after it has collapsed.
      */
    protected void pathWasCollapsed(TreePath path) {
        if(tree != null) {
            tree.fireTreeCollapsed(path);
        }
    }

    /**
      * Ensures that the rows identified by beginRow through endRow are
      * visible.
      */
    protected void ensureRowsAreVisible(int beginRow, int endRow) {
        if(tree != null && beginRow >= 0 && endRow < getRowCount(tree)) {
            boolean scrollVert = DefaultLookup.getBoolean(tree, this,
                              "Tree.scrollsHorizontallyAndVertically", false);
            if(beginRow == endRow) {
                Rectangle     scrollBounds = getPathBounds(tree, getPathForRow
                                                           (tree, beginRow));

                if(scrollBounds != null) {
                    if (!scrollVert) {
                        scrollBounds.x = tree.getVisibleRect().x;
                        scrollBounds.width = 1;
                    }
                    tree.scrollRectToVisible(scrollBounds);
                }
            }
            else {
                Rectangle   beginRect = getPathBounds(tree, getPathForRow
                                                      (tree, beginRow));
                Rectangle   visRect = tree.getVisibleRect();
                Rectangle   testRect = beginRect;
                int         beginY = beginRect.y;
                int         maxY = beginY + visRect.height;

                for(int counter = beginRow + 1; counter <= endRow; counter++) {
                    testRect = getPathBounds(tree,
                                             getPathForRow(tree, counter));
                    if((testRect.y + testRect.height) > maxY)
                        counter = endRow;
                }
                tree.scrollRectToVisible(new Rectangle(visRect.x, beginY, 1,
                                                  testRect.y + testRect.height-
                                                  beginY));
            }
        }
    }

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

    /** Returns the minimum preferred size.
      */
    public Dimension getPreferredMinSize() {
        if(preferredMinSize == null)
            return null;
        return new Dimension(preferredMinSize);
    }

    /** Returns the preferred size to properly display the tree,
      * this is a cover method for getPreferredSize(c, false).
      */
    public Dimension getPreferredSize(JComponent c) {
        return getPreferredSize(c, true);
    }

    /** Returns the preferred size to represent the tree in
      * <I>c</I>.  If <I>checkConsistancy</I> is true
      * <b>checkConsistancy</b> is messaged first.
      */
    public Dimension getPreferredSize(JComponent c,
                                      boolean checkConsistancy) {
        Dimension       pSize = this.getPreferredMinSize();

        if(!validCachedPreferredSize)
            updateCachedPreferredSize();
        if(tree != null) {
            if(pSize != null)
                return new Dimension(Math.max(pSize.width,
                                              preferredSize.width),
                              Math.max(pSize.height, preferredSize.height));
            return new Dimension(preferredSize.width, preferredSize.height);
        }
        else if(pSize != null)
            return pSize;
        else
            return new Dimension(0, 0);
    }

    /**
      * Returns the minimum size for this component.  Which will be
      * the min preferred size or 0, 0.
      */
    public Dimension getMinimumSize(JComponent c) {
        if(this.getPreferredMinSize() != null)
            return this.getPreferredMinSize();
        return new Dimension(0, 0);
    }

    /**
      * Returns the maximum size for this component, which will be the
      * preferred size if the instance is currently in a JTree, or 0, 0.
      */
    public Dimension getMaximumSize(JComponent c) {
        if(tree != null)
            return getPreferredSize(tree);
        if(this.getPreferredMinSize() != null)
            return this.getPreferredMinSize();
        return new Dimension(0, 0);
    }


    /**
     * 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
     * invoked on the current editor. Then completeEditing will
     * be messaged with false, true, false to cancel any lingering
     * editing.
     */
    protected void completeEditing() {
        /* If should invoke stopCellEditing, try that */
        if(tree.getInvokesStopCellEditing() &&
           stopEditingInCompleteEditing && editingComponent != null) {
            cellEditor.stopCellEditing();
        }
        /* Invoke cancelCellEditing, this will do nothing if stopCellEditing
           was successful. */
        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.
      */
    protected void completeEditing(boolean messageStop,
                                   boolean messageCancel,
                                   boolean messageTree) {
        if(stopEditingInCompleteEditing && editingComponent != null) {
            Component             oldComponent = editingComponent;
            TreePath              oldPath = editingPath;
            TreeCellEditor        oldEditor = cellEditor;
            Object                newValue = oldEditor.getCellEditorValue();
            Rectangle             editingBounds = getPathBounds(tree,
                                                                editingPath);
            boolean               requestFocus = (tree != null &&
                                   (tree.hasFocus() || SwingUtilities.
                                    findFocusOwner(editingComponent) != null));

            editingComponent = null;
            editingPath = null;
            if(messageStop)
                oldEditor.stopCellEditing();
            else if(messageCancel)
                oldEditor.cancelCellEditing();
            tree.remove(oldComponent);
            if(editorHasDifferentSize) {
                treeState.invalidatePathBounds(oldPath);
                updateSize();
            }
            else {
                editingBounds.x = 0;
                editingBounds.width = tree.getSize().width;
                tree.repaint(editingBounds);
            }
            if(requestFocus)
                tree.requestFocus();
            if(messageTree)
                treeModel.valueForPathChanged(oldPath, newValue);
        }
    }

    // cover method for startEditing that allows us to pass extra
    // information into that method via a class variable
    private boolean startEditingOnRelease(TreePath path,
                                          MouseEvent event,
                                          MouseEvent releaseEvent) {
        this.releaseEvent = releaseEvent;
        try {
            return startEditing(path, event);
        } finally {
            this.releaseEvent = null;
        }
    }

    /**
      * Will start editing for node if there is a cellEditor and
      * shouldSelectCell returns true.<p>
      * This assumes that path is valid and visible.
      */
    protected boolean startEditing(TreePath path, MouseEvent event) {
        if (isEditing(tree) && tree.getInvokesStopCellEditing() &&
                               !stopEditing(tree)) {
            return false;
        }
        completeEditing();
        if(cellEditor != null && tree.isPathEditable(path)) {
            int           row = getRowForPath(tree, path);

            if(cellEditor.isCellEditable(event)) {
                editingComponent = cellEditor.getTreeCellEditorComponent
                      (tree, path.getLastPathComponent(),
                       tree.isPathSelected(path), tree.isExpanded(path),
                       treeModel.isLeaf(path.getLastPathComponent()), row);
                Rectangle           nodeBounds = getPathBounds(tree, path);

                editingRow = row;

                Dimension editorSize = editingComponent.getPreferredSize();

                // Only allow odd heights if explicitly set.
                if(editorSize.height != nodeBounds.height &&
                   getRowHeight() > 0)
                    editorSize.height = getRowHeight();

                if(editorSize.width != nodeBounds.width ||
                   editorSize.height != nodeBounds.height) {
                    // Editor wants different width or height, invalidate
                    // treeState and relayout.
                    editorHasDifferentSize = true;
                    treeState.invalidatePathBounds(path);
                    updateSize();
                    // To make sure x/y are updated correctly, fetch
                    // the bounds again.
                    nodeBounds = getPathBounds(tree, path);
                }
                else
                    editorHasDifferentSize = false;
                tree.add(editingComponent);
                editingComponent.setBounds(nodeBounds.x, nodeBounds.y,
                                           nodeBounds.width,
                                           nodeBounds.height);
                editingPath = path;
                if (editingComponent instanceof JComponent) {
                    ((JComponent)editingComponent).revalidate();
                } else {
                    editingComponent.validate();
                }
                editingComponent.repaint();
                if(cellEditor.shouldSelectCell(event)) {
                    stopEditingInCompleteEditing = false;
                    tree.setSelectionRow(row);
                    stopEditingInCompleteEditing = true;
                }

                Component focusedComponent = SwingUtilities2.
                                 compositeRequestFocus(editingComponent);
                boolean selectAll = true;

                if(event != null) {
                    /* Find the component that will get forwarded all the
                       mouse events until mouseReleased. */
                    Point          componentPoint = SwingUtilities.convertPoint
                        (tree, new Point(event.getX(), event.getY()),
                         editingComponent);

                    /* Create an instance of BasicTreeMouseListener to handle
                       passing the mouse/motion events to the necessary
                       component. */
                    // We really want similar behavior to getMouseEventTarget,
                    // but it is package private.
                    Component activeComponent = SwingUtilities.
                                    getDeepestComponentAt(editingComponent,
                                       componentPoint.x, componentPoint.y);
                    if (activeComponent != null) {
                        MouseInputHandler handler =
                            new MouseInputHandler(tree, activeComponent,
                                                  event, focusedComponent);

                        if (releaseEvent != null) {
                            handler.mouseReleased(releaseEvent);
                        }

                        selectAll = false;
                    }
                }
                if (selectAll && focusedComponent instanceof JTextField) {
                    ((JTextField)focusedComponent).selectAll();
                }
                return true;
            }
            else
                editingComponent = null;
        }
        return false;
    }

    //
    // Following are primarily for handling mouse events.
    //

    /**
     * If the <code>mouseX</code> and <code>mouseY</code> are in the
     * expand/collapse region of the <code>row</code>, this will toggle
     * the row.
     */
    protected void checkForClickInExpandControl(TreePath path,
                                                int mouseX, int mouseY) {
      if (isLocationInExpandControl(path, mouseX, mouseY)) {
          handleExpandControlClick(path, mouseX, mouseY);
        }
    }

    /**
     * Returns true if <code>mouseX</code> and <code>mouseY</code> fall
     * in the area of row that is used to expand/collapse the node and
     * the node at <code>row</code> does not represent a leaf.
     */
    protected boolean isLocationInExpandControl(TreePath path,
                                                int mouseX, int mouseY) {
        if(path != null && !treeModel.isLeaf(path.getLastPathComponent())){
            int                     boxWidth;
            Insets                  i = tree.getInsets();

            if(getExpandedIcon() != null)
                boxWidth = getExpandedIcon().getIconWidth();
            else
                boxWidth = 8;

            int boxLeftX = getRowX(tree.getRowForPath(path),
                                   path.getPathCount() - 1);

            if (leftToRight) {
                boxLeftX = boxLeftX + i.left - getRightChildIndent() + 1;
            } else {
                boxLeftX = tree.getWidth() - boxLeftX - i.right + getRightChildIndent() - 1;
            }

            boxLeftX = findCenteredX(boxLeftX, boxWidth);

            return (mouseX >= boxLeftX && mouseX < (boxLeftX + boxWidth));
        }
        return false;
    }

    /**
     * Messaged when the user clicks the particular row, this invokes
     * toggleExpandState.
     */
    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 scrolls 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).
     */
    protected void toggleExpandState(TreePath path) {
        if(!tree.isExpanded(path)) {
            int       row = getRowForPath(tree, path);

            tree.expandPath(path);
            updateSize();
            if(row != -1) {
                if(tree.getScrollsOnExpand())
                    ensureRowsAreVisible(row, row + treeState.
                                         getVisibleChildCount(path));
                else
                    ensureRowsAreVisible(row, row);
            }
        }
        else {
            tree.collapsePath(path);
            updateSize();
        }
    }

    /**
     * Returning true signifies a mouse event on the node should toggle
     * the selection of only the row under mouse.
     */
    protected boolean isToggleSelectionEvent(MouseEvent event) {
        return (SwingUtilities.isLeftMouseButton(event) &&
                BasicGraphicsUtils.isMenuShortcutKeyDown(event));
    }

    /**
     * Returning true signifies a mouse event on the node should select
     * from the anchor point.
     */
    protected boolean isMultiSelectEvent(MouseEvent event) {
        return (SwingUtilities.isLeftMouseButton(event) &&
                event.isShiftDown());
    }

    /**
     * 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
     */
    protected boolean isToggleEvent(MouseEvent event) {
        if(!SwingUtilities.isLeftMouseButton(event)) {
            return false;
        }
        int           clickCount = tree.getToggleClickCount();

        if(clickCount <= 0) {
            return false;
        }
        return ((event.getClickCount() % clickCount) == 0);
    }

    /**
     * Messaged to update the selection based on a MouseEvent over a
     * particular row. If the event 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 event
     * specified a toggle event the row is expanded/collapsed.
     */
    protected void selectPathForEvent(TreePath path, MouseEvent event) {
        /* Adjust from the anchor point. */
        if(isMultiSelectEvent(event)) {
            TreePath    anchor = getAnchorSelectionPath();
            int         anchorRow = (anchor == null) ? -1 :
                                    getRowForPath(tree, anchor);

            if(anchorRow == -1 || tree.getSelectionModel().
                      getSelectionMode() == TreeSelectionModel.
                      SINGLE_TREE_SELECTION) {
                tree.setSelectionPath(path);
            }
            else {
                int          row = getRowForPath(tree, path);
                TreePath     lastAnchorPath = anchor;

                if (isToggleSelectionEvent(event)) {
                    if (tree.isRowSelected(anchorRow)) {
                        tree.addSelectionInterval(anchorRow, row);
                    } else {
                        tree.removeSelectionInterval(anchorRow, row);
                        tree.addSelectionInterval(row, row);
                    }
                } else if(row < anchorRow) {
                    tree.setSelectionInterval(row, anchorRow);
                } else {
                    tree.setSelectionInterval(anchorRow, row);
                }
                lastSelectedRow = row;
                setAnchorSelectionPath(lastAnchorPath);
                setLeadSelectionPath(path);
            }
        }

        // Should this event toggle the selection of this row?
        /* Control toggles just this node. */
        else if(isToggleSelectionEvent(event)) {
            if(tree.isPathSelected(path))
                tree.removeSelectionPath(path);
            else
                tree.addSelectionPath(path);
            lastSelectedRow = getRowForPath(tree, path);
            setAnchorSelectionPath(path);
            setLeadSelectionPath(path);
        }

        /* Otherwise set the selection to just this interval. */
        else if(SwingUtilities.isLeftMouseButton(event)) {
            tree.setSelectionPath(path);
            if(isToggleEvent(event)) {
                toggleExpandState(path);
            }
        }
    }

    /**
     * @return true if the node at <code>row</code> is a leaf.
     */
    protected boolean isLeaf(int row) {
        TreePath          path = getPathForRow(tree, row);

        if(path != null)
            return treeModel.isLeaf(path.getLastPathComponent());
        // Have to return something here...
        return true;
    }

    //
    // The following selection methods (lead/anchor) are covers for the
    // methods in JTree.
    //
    private void setAnchorSelectionPath(TreePath newPath) {
        ignoreLAChange = true;
        try {
            tree.setAnchorSelectionPath(newPath);
        } finally{
            ignoreLAChange = false;
        }
    }

    private TreePath getAnchorSelectionPath() {
        return tree.getAnchorSelectionPath();
    }

    private void setLeadSelectionPath(TreePath newPath) {
        setLeadSelectionPath(newPath, false);
    }

    private void setLeadSelectionPath(TreePath newPath, boolean repaint) {
        Rectangle       bounds = repaint ?
                            getPathBounds(tree, getLeadSelectionPath()) : null;

        ignoreLAChange = true;
        try {
            tree.setLeadSelectionPath(newPath);
        } finally {
            ignoreLAChange = false;
        }
        leadRow = getRowForPath(tree, newPath);

        if (repaint) {
            if (bounds != null) {
                tree.repaint(getRepaintPathBounds(bounds));
            }
            bounds = getPathBounds(tree, newPath);
            if (bounds != null) {
                tree.repaint(getRepaintPathBounds(bounds));
            }
        }
    }

    private Rectangle getRepaintPathBounds(Rectangle bounds) {
        if (UIManager.getBoolean("Tree.repaintWholeRow")) {
           bounds.x = 0;
           bounds.width = tree.getWidth();
        }
        return bounds;
    }

    private TreePath getLeadSelectionPath() {
        return tree.getLeadSelectionPath();
    }

    private void updateLeadRow() {
        leadRow = getRowForPath(tree, getLeadSelectionPath());
    }

    private int getLeadSelectionRow() {
        return leadRow;
    }

    /**
     * Extends the selection from the anchor to make <code>newLead</code>
     * the lead of the selection. This does not scroll.
     */
    private void extendSelection(TreePath newLead) {
        TreePath           aPath = getAnchorSelectionPath();
        int                aRow = (aPath == null) ? -1 :
                                  getRowForPath(tree, aPath);
        int                newIndex = getRowForPath(tree, newLead);

        if(aRow == -1) {
            tree.setSelectionRow(newIndex);
        }
        else {
            if(aRow < newIndex) {
                tree.setSelectionInterval(aRow, newIndex);
            }
            else {
                tree.setSelectionInterval(newIndex, aRow);
            }
            setAnchorSelectionPath(aPath);
            setLeadSelectionPath(newLead);
        }
    }

    /**
     * Invokes <code>repaint</code> on the JTree for the passed in TreePath,
     * <code>path</code>.
     */
    private void repaintPath(TreePath path) {
        if (path != null) {
            Rectangle bounds = getPathBounds(tree, path);
            if (bounds != null) {
                tree.repaint(bounds.x, bounds.y, bounds.width, bounds.height);
            }
        }
    }

    /**
     * Updates the TreeState in response to nodes expanding/collapsing.
     */
    public class TreeExpansionHandler implements TreeExpansionListener {
        // NOTE: This class exists only for backward compatability. All
        // its functionality has been moved into Handler. If you need to add
        // new functionality add it to the Handler, but make sure this
        // class calls into the Handler.

        /**
         * Called whenever an item in the tree has been expanded.
         */
        public void treeExpanded(TreeExpansionEvent event) {
            getHandler().treeExpanded(event);
        }

        /**
         * Called whenever an item in the tree has been collapsed.
         */
        public void treeCollapsed(TreeExpansionEvent event) {
            getHandler().treeCollapsed(event);
        }
    } // BasicTreeUI.TreeExpansionHandler


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

        public void componentMoved(ComponentEvent e) {
            if(timer == null) {
                JScrollPane   scrollPane = getScrollPane();

                if(scrollPane == null)
                    updateSize();
                else {
                    scrollBar = scrollPane.getVerticalScrollBar();
                    if(scrollBar == null ||
                        !scrollBar.getValueIsAdjusting()) {
                        // Try the horizontal scrollbar.
                        if((scrollBar = scrollPane.getHorizontalScrollBar())
                            != null && scrollBar.getValueIsAdjusting())
                            startTimer();
                        else
                            updateSize();
                    }
                    else
                        startTimer();
                }
            }
        }

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

        /**
         * Returns the JScrollPane housing the JTree, or null if one isn't
         * found.
         */
        protected JScrollPane getScrollPane() {
            Component       c = tree.getParent();

            while(c != null && !(c instanceof JScrollPane))
                c = c.getParent();
            if(c instanceof JScrollPane)
                return (JScrollPane)c;
            return null;
        }

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


    /**
     * Forwards all TreeModel events to the TreeState.
     */
    public class TreeModelHandler implements TreeModelListener {

        // NOTE: This class exists only for backward compatability. All
        // its functionality has been moved into Handler. If you need to add
        // new functionality add it to the Handler, but make sure this
        // class calls into the Handler.

        public void treeNodesChanged(TreeModelEvent e) {
            getHandler().treeNodesChanged(e);
        }

        public void treeNodesInserted(TreeModelEvent e) {
            getHandler().treeNodesInserted(e);
        }

        public void treeNodesRemoved(TreeModelEvent e) {
            getHandler().treeNodesRemoved(e);
        }

        public void treeStructureChanged(TreeModelEvent e) {
            getHandler().treeStructureChanged(e);
        }
    } // End of BasicTreeUI.TreeModelHandler


    /**
     * Listens for changes in the selection model and updates the display
     * accordingly.
     */
    public class TreeSelectionHandler implements TreeSelectionListener {

        // NOTE: This class exists only for backward compatability. All
        // its functionality has been moved into Handler. If you need to add
        // new functionality add it to the Handler, but make sure this
        // class calls into the Handler.

        /**
         * Messaged when the selection changes in the tree we're displaying
         * for.  Stops editing, messages super and displays the changed paths.
         */
        public void valueChanged(TreeSelectionEvent event) {
            getHandler().valueChanged(event);
        }
    }// End of BasicTreeUI.TreeSelectionHandler


    /**
     * Listener responsible for getting cell editing events and updating
     * the tree accordingly.
     */
    public class CellEditorHandler implements CellEditorListener {

        // NOTE: This class exists only for backward compatability. All
        // its functionality has been moved into Handler. If you need to add
        // new functionality add it to the Handler, but make sure this
        // class calls into the Handler.

        /** Messaged when editing has stopped in the tree. */
        public void editingStopped(ChangeEvent e) {
            getHandler().editingStopped(e);
        }

        /** Messaged when editing has been canceled in the tree. */
        public void editingCanceled(ChangeEvent e) {
            getHandler().editingCanceled(e);
        }
    } // BasicTreeUI.CellEditorHandler


    /**
     * This is used to get mutliple key down events to appropriately generate
     * events.
     */
    public class KeyHandler extends KeyAdapter {

        // NOTE: This class exists only for backward compatability. All
        // its functionality has been moved into Handler. If you need to add
        // new functionality add it to the Handler, but make sure this
        // class calls into the Handler.

        // Also note these fields aren't use anymore, nor does Handler have
        // the old functionality. This behavior worked around an old bug
        // in JComponent that has long since been fixed.

        /** Key code that is being generated for. */
        protected Action              repeatKeyAction;

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

        /**
         * 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.
         */
        public void keyTyped(KeyEvent e) {
            getHandler().keyTyped(e);
        }

        public void keyPressed(KeyEvent e) {
            getHandler().keyPressed(e);
        }

        public void keyReleased(KeyEvent e) {
            getHandler().keyReleased(e);
        }
    } // End of BasicTreeUI.KeyHandler


    /**
     * Repaints the lead selection row when focus is lost/gained.
     */
    public class FocusHandler implements FocusListener {
        // NOTE: This class exists only for backward compatability. All
        // its functionality has been moved into Handler. If you need to add
        // new functionality add it to the Handler, but make sure this
        // class calls into the Handler.

        /**
         * Invoked when focus is activated on the tree we're in, redraws the
         * lead row.
         */
        public void focusGained(FocusEvent e) {
            getHandler().focusGained(e);
        }

        /**
         * Invoked when focus is activated on the tree we're in, redraws the
         * lead row.
         */
        public void focusLost(FocusEvent e) {
            getHandler().focusLost(e);
        }
    } // End of class BasicTreeUI.FocusHandler


    /**
     * Class responsible for getting size of node, method is forwarded
     * to BasicTreeUI method. X location does not include insets, that is
     * handled in getPathBounds.
     */
    // This returns locations that don't include any Insets.
    public class NodeDimensionsHandler extends
                 AbstractLayoutCache.NodeDimensions {
        /**
         * Responsible for getting the size of a particular node.
         */
        public Rectangle getNodeDimensions(Object value, int row,
                                           int depth, boolean expanded,
                                           Rectangle size) {
            // Return size of editing component, if editing and asking
            // for editing row.
            if(editingComponent != null && editingRow == row) {
                Dimension        prefSize = editingComponent.
                                              getPreferredSize();
                int              rh = getRowHeight();

                if(rh > 0 && rh != prefSize.height)
                    prefSize.height = rh;
                if(size != null) {
                    size.x = getRowX(row, depth);
                    size.width = prefSize.width;
                    size.height = prefSize.height;
                }
                else {
                    size = new Rectangle(getRowX(row, depth), 0,
                                         prefSize.width, prefSize.height);
                }
                return size;
            }
            // Not editing, use renderer.
            if(currentCellRenderer != null) {
                Component          aComponent;

                aComponent = currentCellRenderer.getTreeCellRendererComponent
                    (tree, value, tree.isRowSelected(row),
                     expanded, treeModel.isLeaf(value), row,
                     false);
                if(tree != null) {
                    // Only ever removed when UI changes, this is OK!
                    rendererPane.add(aComponent);
                    aComponent.validate();
                }
                Dimension        prefSize = aComponent.getPreferredSize();

                if(size != null) {
                    size.x = getRowX(row, depth);
                    size.width = prefSize.width;
                    size.height = prefSize.height;
                }
                else {
                    size = new Rectangle(getRowX(row, depth), 0,
                                         prefSize.width, prefSize.height);
                }
                return size;
            }
            return null;
        }

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

    } // End of class BasicTreeUI.NodeDimensionsHandler


    /**
     * TreeMouseListener is responsible for updating the selection
     * based on mouse events.
     */
    public class MouseHandler extends MouseAdapter implements MouseMotionListener
 {
        // NOTE: This class exists only for backward compatability. All
        // its functionality has been moved into Handler. If you need to add
        // new functionality add it to the Handler, but make sure this
        // class calls into the Handler.

        /**
         * Invoked when a mouse button has been pressed on a component.
         */
        public void mousePressed(MouseEvent e) {
            getHandler().mousePressed(e);
        }

        public void mouseDragged(MouseEvent e) {
            getHandler().mouseDragged(e);
        }

        /**
         * Invoked when the mouse button has been moved on a component
         * (with no buttons no down).
         * @since 1.4
         */
        public void mouseMoved(MouseEvent e) {
            getHandler().mouseMoved(e);
        }

        public void mouseReleased(MouseEvent e) {
            getHandler().mouseReleased(e);
        }
    } // End of BasicTreeUI.MouseHandler


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

        // NOTE: This class exists only for backward compatability. All
        // its functionality has been moved into Handler. If you need to add
        // new functionality add it to the Handler, but make sure this
        // class calls into the Handler.

        public void propertyChange(PropertyChangeEvent event) {
            getHandler().propertyChange(event);
        }
    } // End of BasicTreeUI.PropertyChangeHandler


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

        // NOTE: This class exists only for backward compatability. All
        // its functionality has been moved into Handler. If you need to add
        // new functionality add it to the Handler, but make sure this
        // class calls into the Handler.

        public void propertyChange(PropertyChangeEvent event) {
            getHandler().propertyChange(event);
        }
    } // End of BasicTreeUI.SelectionModelPropertyChangeHandler


    /**
     * <code>TreeTraverseAction</code> 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;
        /** True if the selection is reset, false means only the lead path
         * changes. */
        private boolean changeSelection;

        public TreeTraverseAction(int direction, String name) {
            this(direction, name, true);
        }

        private TreeTraverseAction(int direction, String name,
                                   boolean changeSelection) {
            this.direction = direction;
            this.changeSelection = changeSelection;
        }

        public void actionPerformed(ActionEvent e) {
            if (tree != null) {
                SHARED_ACTION.traverse(tree, BasicTreeUI.this, direction,
                                       changeSelection);
            }
        }

        public boolean isEnabled() { return (tree != null &&
                                             tree.isEnabled()); }
    } // BasicTreeUI.TreeTraverseAction


    /** TreePageAction handles page up and page down events.
      */
    public class TreePageAction extends AbstractAction {
        /** Specifies the direction to adjust the selection by. */
        protected int         direction;
        /** True indicates should set selection from anchor path. */
        private boolean       addToSelection;
        private boolean       changeSelection;

        public TreePageAction(int direction, String name) {
            this(direction, name, false, true);
        }

        private TreePageAction(int direction, String name,
                               boolean addToSelection,
                               boolean changeSelection) {
            this.direction = direction;
            this.addToSelection = addToSelection;
            this.changeSelection = changeSelection;
        }

        public void actionPerformed(ActionEvent e) {
            if (tree != null) {
                SHARED_ACTION.page(tree, BasicTreeUI.this, direction,
                                   addToSelection, changeSelection);
            }
        }

        public boolean isEnabled() { return (tree != null &&
                                             tree.isEnabled()); }

    } // BasicTreeUI.TreePageAction


    /** 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;
        /** If true the new item is added to the selection, if false the
         * selection is reset. */
        private boolean       addToSelection;
        private boolean       changeSelection;

        public TreeIncrementAction(int direction, String name) {
            this(direction, name, false, true);
        }

        private TreeIncrementAction(int direction, String name,
                                   boolean addToSelection,
                                    boolean changeSelection) {
            this.direction = direction;
            this.addToSelection = addToSelection;
            this.changeSelection = changeSelection;
        }

        public void actionPerformed(ActionEvent e) {
            if (tree != null) {
                SHARED_ACTION.increment(tree, BasicTreeUI.this, direction,
                                        addToSelection, changeSelection);
            }
        }

        public boolean isEnabled() { return (tree != null &&
                                             tree.isEnabled()); }

    } // End of class BasicTreeUI.TreeIncrementAction

    /**
      * 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 {
        protected int            direction;
        /** Set to true if append to selection. */
        private boolean          addToSelection;
        private boolean          changeSelection;

        public TreeHomeAction(int direction, String name) {
            this(direction, name, false, true);
        }

        private TreeHomeAction(int direction, String name,
                               boolean addToSelection,
                               boolean changeSelection) {
            this.direction = direction;
            this.changeSelection = changeSelection;
            this.addToSelection = addToSelection;
        }

        public void actionPerformed(ActionEvent e) {
            if (tree != null) {
                SHARED_ACTION.home(tree, BasicTreeUI.this, direction,
                                   addToSelection, changeSelection);
            }
        }

        public boolean isEnabled() { return (tree != null &&
                                             tree.isEnabled()); }

    } // End of class BasicTreeUI.TreeHomeAction


    /**
      * For the first selected row expandedness will be toggled.
      */
    public class TreeToggleAction extends AbstractAction {
        public TreeToggleAction(String name) {
        }

        public void actionPerformed(ActionEvent e) {
            if(tree != null) {
                SHARED_ACTION.toggle(tree, BasicTreeUI.this);
            }
        }

        public boolean isEnabled() { return (tree != null &&
                                             tree.isEnabled()); }

    } // End of class BasicTreeUI.TreeToggleAction


    /**
     * ActionListener that invokes cancelEditing when action performed.
     */
    public class TreeCancelEditingAction extends AbstractAction {
        public TreeCancelEditingAction(String name) {
        }

        public void actionPerformed(ActionEvent e) {
            if(tree != null) {
                SHARED_ACTION.cancelEditing(tree, BasicTreeUI.this);
            }
        }

        public boolean isEnabled() { return (tree != null &&
                                             tree.isEnabled() &&
                                             isEditing(tree)); }
    } // End of class BasicTreeUI.TreeCancelEditingAction


    /**
      * MouseInputHandler handles passing all mouse events,
      * including mouse motion events, until the mouse is released to
      * the destination it is constructed with. It is assumed all the
      * events are currently target at source.
      */
    public class MouseInputHandler extends Object implements
                     MouseInputListener
    {
        /** Source that events are coming from. */
        protected Component        source;
        /** Destination that receives all events. */
        protected Component        destination;
        private Component          focusComponent;
        private boolean            dispatchedEvent;

        public MouseInputHandler(Component source, Component destination,
                                      MouseEvent event){
            this(source, destination, event, null);
        }

        MouseInputHandler(Component source, Component destination,
                          MouseEvent event, Component focusComponent) {
            this.source = source;
            this.destination = destination;
            this.source.addMouseListener(this);
            this.source.addMouseMotionListener(this);

            SwingUtilities2.setSkipClickCount(destination,
                                              event.getClickCount() - 1);

            /* Dispatch the editing event! */
            destination.dispatchEvent(SwingUtilities.convertMouseEvent
                                          (source, event, destination));
            this.focusComponent = focusComponent;
        }

        public void mouseClicked(MouseEvent e) {
            if(destination != null) {
                dispatchedEvent = true;
                destination.dispatchEvent(SwingUtilities.convertMouseEvent
                                          (source, e, destination));
            }
        }

        public void mousePressed(MouseEvent e) {
        }

        public void mouseReleased(MouseEvent e) {
            if(destination != null)
                destination.dispatchEvent(SwingUtilities.convertMouseEvent
                                          (source, e, destination));
            removeFromSource();
        }

        public void mouseEntered(MouseEvent e) {
            if (!SwingUtilities.isLeftMouseButton(e)) {
                removeFromSource();
            }
        }

        public void mouseExited(MouseEvent e) {
            if (!SwingUtilities.isLeftMouseButton(e)) {
                removeFromSource();
            }
        }

        public void mouseDragged(MouseEvent e) {
            if(destination != null) {
                dispatchedEvent = true;
                destination.dispatchEvent(SwingUtilities.convertMouseEvent
                                          (source, e, destination));
            }
        }

        public void mouseMoved(MouseEvent e) {
            removeFromSource();
        }

        protected void removeFromSource() {
            if(source != null) {
                source.removeMouseListener(this);
                source.removeMouseMotionListener(this);
                if (focusComponent != null &&
                      focusComponent == destination && !dispatchedEvent &&
                      (focusComponent instanceof JTextField)) {
                    ((JTextField)focusComponent).selectAll();
                }
            }
            source = destination = null;
        }

    } // End of class BasicTreeUI.MouseInputHandler

    private static final TransferHandler defaultTransferHandler = new TreeTransferHandler();

    static class TreeTransferHandler extends TransferHandler implements UIResource, Comparator<TreePath> {

        private JTree tree;

        /**
         * Create a Transferable to use as the source for a data transfer.
         *
         * @param c  The component holding the data to be transfered.  This
         *  argument is provided to enable sharing of TransferHandlers by
         *  multiple components.
         * @return  The representation of the data to be transfered.
         *
         */
        protected Transferable createTransferable(JComponent c) {
            if (c instanceof JTree) {
                tree = (JTree) c;
                TreePath[] paths = tree.getSelectionPaths();

                if (paths == null || paths.length == 0) {
                    return null;
                }

                StringBuffer plainBuf = new StringBuffer();
                StringBuffer htmlBuf = new StringBuffer();

                htmlBuf.append("<html>\n<body>\n<ul>\n");

                TreeModel model = tree.getModel();
                TreePath lastPath = null;
                TreePath[] displayPaths = getDisplayOrderPaths(paths);

                for (TreePath path : displayPaths) {
                    Object node = path.getLastPathComponent();
                    boolean leaf = model.isLeaf(node);
                    String label = getDisplayString(path, true, leaf);

                    plainBuf.append(label + "\n");
                    htmlBuf.append("  <li>" + label + "\n");
                }

                // remove the last newline
                plainBuf.deleteCharAt(plainBuf.length() - 1);
                htmlBuf.append("</ul>\n</body>\n</html>");

                tree = null;

                return new BasicTransferable(plainBuf.toString(), htmlBuf.toString());
            }

            return null;
        }

        public int compare(TreePath o1, TreePath o2) {
            int row1 = tree.getRowForPath(o1);
            int row2 = tree.getRowForPath(o2);
            return row1 - row2;
        }

        String getDisplayString(TreePath path, boolean selected, boolean leaf) {
            int row = tree.getRowForPath(path);
            boolean hasFocus = tree.getLeadSelectionRow() == row;
            Object node = path.getLastPathComponent();
            return tree.convertValueToText(node, selected, tree.isExpanded(row),
                                           leaf, row, hasFocus);
        }

        /**
         * Selection paths are in selection order.  The conversion to
         * HTML requires display order.  This method resorts the paths
         * to be in the display order.
         */
        TreePath[] getDisplayOrderPaths(TreePath[] paths) {
            // sort the paths to display order rather than selection order
            ArrayList<TreePath> selOrder = new ArrayList<TreePath>();
            for (TreePath path : paths) {
                selOrder.add(path);
            }
            Collections.sort(selOrder, this);
            int n = selOrder.size();
            TreePath[] displayPaths = new TreePath[n];
            for (int i = 0; i < n; i++) {
                displayPaths[i] = selOrder.get(i);
            }
            return displayPaths;
        }

        public int getSourceActions(JComponent c) {
            return COPY;
        }

    }


    private class Handler implements CellEditorListener, FocusListener,
                  KeyListener, MouseListener, MouseMotionListener,
                  PropertyChangeListener, TreeExpansionListener,
                  TreeModelListener, TreeSelectionListener,
                  BeforeDrag {
        //
        // KeyListener
        //
        private String prefix = "";
        private String typedString = "";
        private long lastTime = 0L;

        /**
         * Invoked when a key has been typed.
         *
         * Moves the keyboard focus to the first element whose prefix matches the
         * sequence of alphanumeric keys pressed by the user with delay less
         * than value of <code>timeFactor</code> property (or 1000 milliseconds
         * if it is not defined). Subsequent same key presses move the keyboard
         * focus to the next object that starts with the same letter until another
         * key is pressed, then it is treated as the prefix with appropriate number
         * of the same letters followed by first typed another letter.
         */
        public void keyTyped(KeyEvent e) {
            // handle first letter navigation
            if(tree != null && tree.getRowCount()>0 && tree.hasFocus() &&
               tree.isEnabled()) {
                if (e.isAltDown() || BasicGraphicsUtils.isMenuShortcutKeyDown(e) ||
                    isNavigationKey(e)) {
                    return;
                }
                boolean startingFromSelection = true;

                char c = e.getKeyChar();

                long time = e.getWhen();
                int startingRow = tree.getLeadSelectionRow();
                if (time - lastTime < timeFactor) {
                    typedString += c;
                    if((prefix.length() == 1) && (c == prefix.charAt(0))) {
                        // Subsequent same key presses move the keyboard focus to the next
                        // object that starts with the same letter.
                        startingRow++;
                    } else {
                        prefix = typedString;
                    }
                } else {
                    startingRow++;
                    typedString = "" + c;
                    prefix = typedString;
                }
                lastTime = time;

                if (startingRow < 0 || startingRow >= tree.getRowCount()) {
                    startingFromSelection = false;
                    startingRow = 0;
                }
                TreePath path = tree.getNextMatch(prefix, startingRow,
                                                  Position.Bias.Forward);
                if (path != null) {
                    tree.setSelectionPath(path);
                    int row = getRowForPath(tree, path);
                    ensureRowsAreVisible(row, row);
                } else if (startingFromSelection) {
                    path = tree.getNextMatch(prefix, 0,
                                             Position.Bias.Forward);
                    if (path != null) {
                        tree.setSelectionPath(path);
                        int row = getRowForPath(tree, path);
                        ensureRowsAreVisible(row, row);
                    }
                }
            }
        }

        /**
         * Invoked when a key has been pressed.
         *
         * Checks to see if the key event is a navigation key to prevent
         * dispatching these keys for the first letter navigation.
         */
        public void keyPressed(KeyEvent e) {
            if (tree != null && isNavigationKey(e)) {
                prefix = "";
                typedString = "";
                lastTime = 0L;
            }
        }

        public void keyReleased(KeyEvent e) {
        }

        /**
         * Returns whether or not the supplied key event maps to a key that is used for
         * navigation.  This is used for optimizing key input by only passing non-
         * navigation keys to the first letter navigation mechanism.
         */
        private boolean isNavigationKey(KeyEvent event) {
            InputMap inputMap = tree.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
            KeyStroke key = KeyStroke.getKeyStrokeForEvent(event);

            return inputMap != null && inputMap.get(key) != null;
        }


        //
        // PropertyChangeListener
        //
        public void propertyChange(PropertyChangeEvent event) {
            if (event.getSource() == treeSelectionModel) {
                treeSelectionModel.resetRowSelection();
            }
            else if(event.getSource() == tree) {
                String              changeName = event.getPropertyName();

                if (changeName == JTree.LEAD_SELECTION_PATH_PROPERTY) {
                    if (!ignoreLAChange) {
                        updateLeadRow();
                        repaintPath((TreePath)event.getOldValue());
                        repaintPath((TreePath)event.getNewValue());
                    }
                }
                else if (changeName == JTree.ANCHOR_SELECTION_PATH_PROPERTY) {
                    if (!ignoreLAChange) {
                        repaintPath((TreePath)event.getOldValue());
                        repaintPath((TreePath)event.getNewValue());
                    }
                }
                if(changeName == JTree.CELL_RENDERER_PROPERTY) {
                    setCellRenderer((TreeCellRenderer)event.getNewValue());
                    redoTheLayout();
                }
                else if(changeName == JTree.TREE_MODEL_PROPERTY) {
                    setModel((TreeModel)event.getNewValue());
                }
                else if(changeName == JTree.ROOT_VISIBLE_PROPERTY) {
                    setRootVisible(((Boolean)event.getNewValue()).
                                   booleanValue());
                }
                else if(changeName == JTree.SHOWS_ROOT_HANDLES_PROPERTY) {
                    setShowsRootHandles(((Boolean)event.getNewValue()).
                                        booleanValue());
                }
                else if(changeName == JTree.ROW_HEIGHT_PROPERTY) {
                    setRowHeight(((Integer)event.getNewValue()).
                                 intValue());
                }
                else if(changeName == JTree.CELL_EDITOR_PROPERTY) {
                    setCellEditor((TreeCellEditor)event.getNewValue());
                }
                else if(changeName == JTree.EDITABLE_PROPERTY) {
                    setEditable(((Boolean)event.getNewValue()).booleanValue());
                }
                else if(changeName == JTree.LARGE_MODEL_PROPERTY) {
                    setLargeModel(tree.isLargeModel());
                }
                else if(changeName == JTree.SELECTION_MODEL_PROPERTY) {
                    setSelectionModel(tree.getSelectionModel());
                }
                else if(changeName == "font") {
                    completeEditing();
                    if(treeState != null)
                        treeState.invalidateSizes();
                    updateSize();
                }
                else if (changeName == "componentOrientation") {
                    if (tree != null) {
                        leftToRight = BasicGraphicsUtils.isLeftToRight(tree);
                        redoTheLayout();
                        tree.treeDidChange();

                        InputMap km = getInputMap(JComponent.WHEN_FOCUSED);
                        SwingUtilities.replaceUIInputMap(tree,
                                                JComponent.WHEN_FOCUSED, km);
                    }
                } else if ("dropLocation" == changeName) {
                    JTree.DropLocation oldValue = (JTree.DropLocation)event.getOldValue();
                    repaintDropLocation(oldValue);
                    repaintDropLocation(tree.getDropLocation());
                }
            }
        }

        private void repaintDropLocation(JTree.DropLocation loc) {
            if (loc == null) {
                return;
            }

            Rectangle r;

            if (isDropLine(loc)) {
                r = getDropLineRect(loc);
            } else {
                r = tree.getPathBounds(loc.getPath());
            }

            if (r != null) {
                tree.repaint(r);
            }
        }

        //
        // MouseListener
        //

        // Whether or not the mouse press (which is being considered as part
        // of a drag sequence) also caused the selection change to be fully
        // processed.
        private boolean dragPressDidSelection;

        // Set to true when a drag gesture has been fully recognized and DnD
        // begins. Use this to ignore further mouse events which could be
        // delivered if DnD is cancelled (via ESCAPE for example)
        private boolean dragStarted;

        // The path over which the press occurred and the press event itself
        private TreePath pressedPath;
        private MouseEvent pressedEvent;

        // Used to detect whether the press event causes a selection change.
        // If it does, we won't try to start editing on the release.
        private boolean valueChangedOnPress;

        private boolean isActualPath(TreePath path, int x, int y) {
            if (path == null) {
                return false;
            }

            Rectangle bounds = getPathBounds(tree, path);
            if (y > (bounds.y + bounds.height)) {
                return false;
            }

            return (x >= bounds.x) && (x <= (bounds.x + bounds.width));
        }

        public void mouseClicked(MouseEvent e) {
        }

        public void mouseEntered(MouseEvent e) {
        }

        public void mouseExited(MouseEvent e) {
        }

        /**
         * Invoked when a mouse button has been pressed on a component.
         */
        public void mousePressed(MouseEvent e) {
            if (SwingUtilities2.shouldIgnore(e, tree)) {
                return;
            }

            // if we can't stop any ongoing editing, do nothing
            if (isEditing(tree) && tree.getInvokesStopCellEditing()
                                && !stopEditing(tree)) {
                return;
            }

            completeEditing();

            pressedPath = getClosestPathForLocation(tree, e.getX(), e.getY());

            if (tree.getDragEnabled()) {
                mousePressedDND(e);
            } else {
                SwingUtilities2.adjustFocus(tree);
                handleSelection(e);
            }
        }

        private void mousePressedDND(MouseEvent e) {
            pressedEvent = e;
            boolean grabFocus = true;
            dragStarted = false;
            valueChangedOnPress = false;

            // if we have a valid path and this is a drag initiating event
            if (isActualPath(pressedPath, e.getX(), e.getY()) &&
                    DragRecognitionSupport.mousePressed(e)) {

                dragPressDidSelection = false;

                if (BasicGraphicsUtils.isMenuShortcutKeyDown(e)) {
                    // do nothing for control - will be handled on release
                    // or when drag starts
                    return;
                } else if (!e.isShiftDown() && tree.isPathSelected(pressedPath)) {
                    // clicking on something that's already selected
                    // and need to make it the lead now
                    setAnchorSelectionPath(pressedPath);
                    setLeadSelectionPath(pressedPath, true);
                    return;
                }

                dragPressDidSelection = true;

                // could be a drag initiating event - don't grab focus
                grabFocus = false;
            }

            if (grabFocus) {
                SwingUtilities2.adjustFocus(tree);
            }

            handleSelection(e);
        }

        void handleSelection(MouseEvent e) {
            if(pressedPath != null) {
                Rectangle bounds = getPathBounds(tree, pressedPath);

                if(e.getY() >= (bounds.y + bounds.height)) {
                    return;
                }

                // Preferably checkForClickInExpandControl could take
                // the Event to do this it self!
                if(SwingUtilities.isLeftMouseButton(e)) {
                    checkForClickInExpandControl(pressedPath, e.getX(), e.getY());
                }

                int x = e.getX();

                // Perhaps they clicked the cell itself. If so,
                // select it.
                if (x >= bounds.x && x < (bounds.x + bounds.width)) {
                    if (tree.getDragEnabled() || !startEditing(pressedPath, e)) {
                        selectPathForEvent(pressedPath, e);
                    }
                }
            }
        }

        public void dragStarting(MouseEvent me) {
            dragStarted = true;

            if (BasicGraphicsUtils.isMenuShortcutKeyDown(me)) {
                tree.addSelectionPath(pressedPath);
                setAnchorSelectionPath(pressedPath);
                setLeadSelectionPath(pressedPath, true);
            }

            pressedEvent = null;
            pressedPath = null;
        }

        public void mouseDragged(MouseEvent e) {
            if (SwingUtilities2.shouldIgnore(e, tree)) {
                return;
            }

            if (tree.getDragEnabled()) {
                DragRecognitionSupport.mouseDragged(e, this);
            }
        }

        /**
         * Invoked when the mouse button has been moved on a component
         * (with no buttons no down).
         */
        public void mouseMoved(MouseEvent e) {
        }

        public void mouseReleased(MouseEvent e) {
            if (SwingUtilities2.shouldIgnore(e, tree)) {
                return;
            }

            if (tree.getDragEnabled()) {
                mouseReleasedDND(e);
            }

            pressedEvent = null;
            pressedPath = null;
        }

        private void mouseReleasedDND(MouseEvent e) {
            MouseEvent me = DragRecognitionSupport.mouseReleased(e);
            if (me != null) {
                SwingUtilities2.adjustFocus(tree);
                if (!dragPressDidSelection) {
                    handleSelection(me);
                }
            }

            if (!dragStarted) {

                // Note: We don't give the tree a chance to start editing if the
                // mouse press caused a selection change. Otherwise the default
                // tree cell editor will start editing on EVERY press and
                // release. If it turns out that this affects some editors, we
                // can always parameterize this with a client property. ex:
                //
                // if (pressedPath != null &&
                //         (Boolean.TRUE == tree.getClientProperty("Tree.DnD.canEditOnValueChange") ||
                //          !valueChangedOnPress) && ...
                if (pressedPath != null && !valueChangedOnPress &&
                        isActualPath(pressedPath, pressedEvent.getX(), pressedEvent.getY())) {

                    startEditingOnRelease(pressedPath, pressedEvent, e);
                }
            }
        }

        //
        // FocusListener
        //
        public void focusGained(FocusEvent e) {
            if(tree != null) {
                Rectangle                 pBounds;

                pBounds = getPathBounds(tree, tree.getLeadSelectionPath());
                if(pBounds != null)
                    tree.repaint(getRepaintPathBounds(pBounds));
                pBounds = getPathBounds(tree, getLeadSelectionPath());
                if(pBounds != null)
                    tree.repaint(getRepaintPathBounds(pBounds));
            }
        }

        public void focusLost(FocusEvent e) {
            focusGained(e);
        }

        //
        // CellEditorListener
        //
        public void editingStopped(ChangeEvent e) {
            completeEditing(false, false, true);
        }

        /** Messaged when editing has been canceled in the tree. */
        public void editingCanceled(ChangeEvent e) {
            completeEditing(false, false, false);
        }


        //
        // TreeSelectionListener
        //
        public void valueChanged(TreeSelectionEvent event) {
            valueChangedOnPress = true;

            // Stop editing
            completeEditing();
            // Make sure all the paths are visible, if necessary.
            // PENDING: This should be tweaked when isAdjusting is added
            if(tree.getExpandsSelectedPaths() && treeSelectionModel != null) {
                TreePath[]           paths = treeSelectionModel
                                         .getSelectionPaths();

                if(paths != null) {
                    for(int counter = paths.length - 1; counter >= 0;
                        counter--) {
                        TreePath path = paths[counter].getParentPath();
                        boolean expand = true;

                        while (path != null) {
                            // Indicates this path isn't valid anymore,
                            // we shouldn't attempt to expand it then.
                            if (treeModel.isLeaf(path.getLastPathComponent())){
                                expand = false;
                                path = null;
                            }
                            else {
                                path = path.getParentPath();
                            }
                        }
                        if (expand) {
                            tree.makeVisible(paths[counter]);
                        }
                    }
                }
            }

            TreePath oldLead = getLeadSelectionPath();
            lastSelectedRow = tree.getMinSelectionRow();
            TreePath lead = tree.getSelectionModel().getLeadSelectionPath();
            setAnchorSelectionPath(lead);
            setLeadSelectionPath(lead);

            TreePath[]       changedPaths = event.getPaths();
            Rectangle        nodeBounds;
            Rectangle        visRect = tree.getVisibleRect();
            boolean          paintPaths = true;
            int              nWidth = tree.getWidth();

            if(changedPaths != null) {
                int              counter, maxCounter = changedPaths.length;

                if(maxCounter > 4) {
                    tree.repaint();
                    paintPaths = false;
                }
                else {
                    for (counter = 0; counter < maxCounter; counter++) {
                        nodeBounds = getPathBounds(tree,
                                                   changedPaths[counter]);
                        if(nodeBounds != null &&
                           visRect.intersects(nodeBounds))
                            tree.repaint(0, nodeBounds.y, nWidth,
                                         nodeBounds.height);
                    }
                }
            }
            if(paintPaths) {
                nodeBounds = getPathBounds(tree, oldLead);
                if(nodeBounds != null && visRect.intersects(nodeBounds))
                    tree.repaint(0, nodeBounds.y, nWidth, nodeBounds.height);
                nodeBounds = getPathBounds(tree, lead);
                if(nodeBounds != null && visRect.intersects(nodeBounds))
                    tree.repaint(0, nodeBounds.y, nWidth, nodeBounds.height);
            }
        }


        //
        // TreeExpansionListener
        //
        public void treeExpanded(TreeExpansionEvent event) {
            if(event != null && tree != null) {
                TreePath      path = event.getPath();

                updateExpandedDescendants(path);
            }
        }

        public void treeCollapsed(TreeExpansionEvent event) {
            if(event != null && tree != null) {
                TreePath        path = event.getPath();

                completeEditing();
                if(path != null && tree.isVisible(path)) {
                    treeState.setExpandedState(path, false);
                    updateLeadRow();
                    updateSize();
                }
            }
        }

        //
        // TreeModelListener
        //
        public void treeNodesChanged(TreeModelEvent e) {
            if(treeState != null && e != null) {
                TreePath parentPath = e.getTreePath();
                int[] indices = e.getChildIndices();
                if (indices == null || indices.length == 0) {
                    // The root has changed
                    treeState.treeNodesChanged(e);
                    updateSize();
                }
                else if (treeState.isExpanded(parentPath)) {
                    // Changed nodes are visible
                    // Find the minimum index, we only need paint from there
                    // down.
                    int minIndex = indices[0];
                    for (int i = indices.length - 1; i > 0; i--) {
                        minIndex = Math.min(indices[i], minIndex);
                    }
                    Object minChild = treeModel.getChild(
                            parentPath.getLastPathComponent(), minIndex);
                    TreePath minPath = parentPath.pathByAddingChild(minChild);
                    Rectangle minBounds = getPathBounds(tree, minPath);

                    // Forward to the treestate
                    treeState.treeNodesChanged(e);

                    // Mark preferred size as bogus.
                    updateSize0();

                    // And repaint
                    Rectangle newMinBounds = getPathBounds(tree, minPath);
                    if (indices.length == 1 &&
                            newMinBounds.height == minBounds.height) {
                        tree.repaint(0, minBounds.y, tree.getWidth(),
                                     minBounds.height);
                    }
                    else {
                        tree.repaint(0, minBounds.y, tree.getWidth(),
                                     tree.getHeight() - minBounds.y);
                    }
                }
                else {
                    // Nodes that changed aren't visible.  No need to paint
                    treeState.treeNodesChanged(e);
                }
            }
        }

        public void treeNodesInserted(TreeModelEvent e) {
            if(treeState != null && e != null) {
                treeState.treeNodesInserted(e);

                updateLeadRow();

                TreePath       path = e.getTreePath();

                if(treeState.isExpanded(path)) {
                    updateSize();
                }
                else {
                    // PENDING(sky): Need a method in TreeModelEvent
                    // that can return the count, getChildIndices allocs
                    // a new array!
                    int[]      indices = e.getChildIndices();
                    int        childCount = treeModel.getChildCount
                                            (path.getLastPathComponent());

                    if(indices != null && (childCount - indices.length) == 0)
                        updateSize();
                }
            }
        }

        public void treeNodesRemoved(TreeModelEvent e) {
            if(treeState != null && e != null) {
                treeState.treeNodesRemoved(e);

                updateLeadRow();

                TreePath       path = e.getTreePath();

                if(treeState.isExpanded(path) ||
                   treeModel.getChildCount(path.getLastPathComponent()) == 0)
                    updateSize();
            }
        }

        public void treeStructureChanged(TreeModelEvent e) {
            if(treeState != null && e != null) {
                treeState.treeStructureChanged(e);

                updateLeadRow();

                TreePath       pPath = e.getTreePath();

                if (pPath != null) {
                    pPath = pPath.getParentPath();
                }
                if(pPath == null || treeState.isExpanded(pPath))
                    updateSize();
            }
        }
    }



    private static class Actions extends UIAction {
        private static final String SELECT_PREVIOUS = "selectPrevious";
        private static final String SELECT_PREVIOUS_CHANGE_LEAD =
                             "selectPreviousChangeLead";
        private static final String SELECT_PREVIOUS_EXTEND_SELECTION =
                             "selectPreviousExtendSelection";
        private static final String SELECT_NEXT = "selectNext";
        private static final String SELECT_NEXT_CHANGE_LEAD =
                                    "selectNextChangeLead";
        private static final String SELECT_NEXT_EXTEND_SELECTION =
                                    "selectNextExtendSelection";
        private static final String SELECT_CHILD = "selectChild";
        private static final String SELECT_CHILD_CHANGE_LEAD =
                                    "selectChildChangeLead";
        private static final String SELECT_PARENT = "selectParent";
        private static final String SELECT_PARENT_CHANGE_LEAD =
                                    "selectParentChangeLead";
        private static final String SCROLL_UP_CHANGE_SELECTION =
                                    "scrollUpChangeSelection";
        private static final String SCROLL_UP_CHANGE_LEAD =
                                    "scrollUpChangeLead";
        private static final String SCROLL_UP_EXTEND_SELECTION =
                                    "scrollUpExtendSelection";
        private static final String SCROLL_DOWN_CHANGE_SELECTION =
                                    "scrollDownChangeSelection";
        private static final String SCROLL_DOWN_EXTEND_SELECTION =
                                    "scrollDownExtendSelection";
        private static final String SCROLL_DOWN_CHANGE_LEAD =
                                    "scrollDownChangeLead";
        private static final String SELECT_FIRST = "selectFirst";
        private static final String SELECT_FIRST_CHANGE_LEAD =
                                    "selectFirstChangeLead";
        private static final String SELECT_FIRST_EXTEND_SELECTION =
                                    "selectFirstExtendSelection";
        private static final String SELECT_LAST = "selectLast";
        private static final String SELECT_LAST_CHANGE_LEAD =
                                    "selectLastChangeLead";
        private static final String SELECT_LAST_EXTEND_SELECTION =
                                    "selectLastExtendSelection";
        private static final String TOGGLE = "toggle";
        private static final String CANCEL_EDITING = "cancel";
        private static final String START_EDITING = "startEditing";
        private static final String SELECT_ALL = "selectAll";
        private static final String CLEAR_SELECTION = "clearSelection";
        private static final String SCROLL_LEFT = "scrollLeft";
        private static final String SCROLL_RIGHT = "scrollRight";
        private static final String SCROLL_LEFT_EXTEND_SELECTION =
                                    "scrollLeftExtendSelection";
        private static final String SCROLL_RIGHT_EXTEND_SELECTION =
                                    "scrollRightExtendSelection";
        private static final String SCROLL_RIGHT_CHANGE_LEAD =
                                    "scrollRightChangeLead";
        private static final String SCROLL_LEFT_CHANGE_LEAD =
                                    "scrollLeftChangeLead";
        private static final String EXPAND = "expand";
        private static final String COLLAPSE = "collapse";
        private static final String MOVE_SELECTION_TO_PARENT =
                                    "moveSelectionToParent";

        // add the lead item to the selection without changing lead or anchor
        private static final String ADD_TO_SELECTION = "addToSelection";

        // toggle the selected state of the lead item and move the anchor to it
        private static final String TOGGLE_AND_ANCHOR = "toggleAndAnchor";

        // extend the selection to the lead item
        private static final String EXTEND_TO = "extendTo";

        // move the anchor to the lead and ensure only that item is selected
        private static final String MOVE_SELECTION_TO = "moveSelectionTo";

        Actions() {
            super(null);
        }

        Actions(String key) {
            super(key);
        }

        public boolean isEnabled(Object o) {
            if (o instanceof JTree) {
                if (getName() == CANCEL_EDITING) {
                    return ((JTree)o).isEditing();
                }
            }
            return true;
        }

        public void actionPerformed(ActionEvent e) {
            JTree tree = (JTree)e.getSource();
            BasicTreeUI ui = (BasicTreeUI)BasicLookAndFeel.getUIOfType(
                             tree.getUI(), BasicTreeUI.class);
            if (ui == null) {
                return;
            }
            String key = getName();
            if (key == SELECT_PREVIOUS) {
                increment(tree, ui, -1, false, true);
            }
            else if (key == SELECT_PREVIOUS_CHANGE_LEAD) {
                increment(tree, ui, -1, false, false);
            }
            else if (key == SELECT_PREVIOUS_EXTEND_SELECTION) {
                increment(tree, ui, -1, true, true);
            }
            else if (key == SELECT_NEXT) {
                increment(tree, ui, 1, false, true);
            }
            else if (key == SELECT_NEXT_CHANGE_LEAD) {
                increment(tree, ui, 1, false, false);
            }
            else if (key == SELECT_NEXT_EXTEND_SELECTION) {
                increment(tree, ui, 1, true, true);
            }
            else if (key == SELECT_CHILD) {
                traverse(tree, ui, 1, true);
            }
            else if (key == SELECT_CHILD_CHANGE_LEAD) {
                traverse(tree, ui, 1, false);
            }
            else if (key == SELECT_PARENT) {
                traverse(tree, ui, -1, true);
            }
            else if (key == SELECT_PARENT_CHANGE_LEAD) {
                traverse(tree, ui, -1, false);
            }
            else if (key == SCROLL_UP_CHANGE_SELECTION) {
                page(tree, ui, -1, false, true);
            }
            else if (key == SCROLL_UP_CHANGE_LEAD) {
                page(tree, ui, -1, false, false);
            }
            else if (key == SCROLL_UP_EXTEND_SELECTION) {
                page(tree, ui, -1, true, true);
            }
            else if (key == SCROLL_DOWN_CHANGE_SELECTION) {
                page(tree, ui, 1, false, true);
            }
            else if (key == SCROLL_DOWN_EXTEND_SELECTION) {
                page(tree, ui, 1, true, true);
            }
            else if (key == SCROLL_DOWN_CHANGE_LEAD) {
                page(tree, ui, 1, false, false);
            }
            else if (key == SELECT_FIRST) {
                home(tree, ui, -1, false, true);
            }
            else if (key == SELECT_FIRST_CHANGE_LEAD) {
                home(tree, ui, -1, false, false);
            }
            else if (key == SELECT_FIRST_EXTEND_SELECTION) {
                home(tree, ui, -1, true, true);
            }
            else if (key == SELECT_LAST) {
                home(tree, ui, 1, false, true);
            }
            else if (key == SELECT_LAST_CHANGE_LEAD) {
                home(tree, ui, 1, false, false);
            }
            else if (key == SELECT_LAST_EXTEND_SELECTION) {
                home(tree, ui, 1, true, true);
            }
            else if (key == TOGGLE) {
                toggle(tree, ui);
            }
            else if (key == CANCEL_EDITING) {
                cancelEditing(tree, ui);
            }
            else if (key == START_EDITING) {
                startEditing(tree, ui);
            }
            else if (key == SELECT_ALL) {
                selectAll(tree, ui, true);
            }
            else if (key == CLEAR_SELECTION) {
                selectAll(tree, ui, false);
            }
            else if (key == ADD_TO_SELECTION) {
                if (ui.getRowCount(tree) > 0) {
                    int lead = ui.getLeadSelectionRow();
                    if (!tree.isRowSelected(lead)) {
                        TreePath aPath = ui.getAnchorSelectionPath();
                        tree.addSelectionRow(lead);
                        ui.setAnchorSelectionPath(aPath);
                    }
                }
            }
            else if (key == TOGGLE_AND_ANCHOR) {
                if (ui.getRowCount(tree) > 0) {
                    int lead = ui.getLeadSelectionRow();
                    TreePath lPath = ui.getLeadSelectionPath();
                    if (!tree.isRowSelected(lead)) {
                        tree.addSelectionRow(lead);
                    } else {
                        tree.removeSelectionRow(lead);
                        ui.setLeadSelectionPath(lPath);
                    }
                    ui.setAnchorSelectionPath(lPath);
                }
            }
            else if (key == EXTEND_TO) {
                extendSelection(tree, ui);
            }
            else if (key == MOVE_SELECTION_TO) {
                if (ui.getRowCount(tree) > 0) {
                    int lead = ui.getLeadSelectionRow();
                    tree.setSelectionInterval(lead, lead);
                }
            }
            else if (key == SCROLL_LEFT) {
                scroll(tree, ui, SwingConstants.HORIZONTAL, -10);
            }
            else if (key == SCROLL_RIGHT) {
                scroll(tree, ui, SwingConstants.HORIZONTAL, 10);
            }
            else if (key == SCROLL_LEFT_EXTEND_SELECTION) {
                scrollChangeSelection(tree, ui, -1, true, true);
            }
            else if (key == SCROLL_RIGHT_EXTEND_SELECTION) {
                scrollChangeSelection(tree, ui, 1, true, true);
            }
            else if (key == SCROLL_RIGHT_CHANGE_LEAD) {
                scrollChangeSelection(tree, ui, 1, false, false);
            }
            else if (key == SCROLL_LEFT_CHANGE_LEAD) {
                scrollChangeSelection(tree, ui, -1, false, false);
            }
            else if (key == EXPAND) {
                expand(tree, ui);
            }
            else if (key == COLLAPSE) {
                collapse(tree, ui);
            }
            else if (key == MOVE_SELECTION_TO_PARENT) {
                moveSelectionToParent(tree, ui);
            }
        }

        private void scrollChangeSelection(JTree tree, BasicTreeUI ui,
                           int direction, boolean addToSelection,
                           boolean changeSelection) {
            int           rowCount;

            if((rowCount = ui.getRowCount(tree)) > 0 &&
                ui.treeSelectionModel != null) {
                TreePath          newPath;
                Rectangle         visRect = tree.getVisibleRect();

                if (direction == -1) {
                    newPath = ui.getClosestPathForLocation(tree, visRect.x,
                                                        visRect.y);
                    visRect.x = Math.max(0, visRect.x - visRect.width);
                }
                else {
                    visRect.x = Math.min(Math.max(0, tree.getWidth() -
                                   visRect.width), visRect.x + visRect.width);
                    newPath = ui.getClosestPathForLocation(tree, visRect.x,
                                                 visRect.y + visRect.height);
                }
                // Scroll
                tree.scrollRectToVisible(visRect);
                // select
                if (addToSelection) {
                    ui.extendSelection(newPath);
                }
                else if(changeSelection) {
                    tree.setSelectionPath(newPath);
                }
                else {
                    ui.setLeadSelectionPath(newPath, true);
                }
            }
        }

        private void scroll(JTree component, BasicTreeUI ui, int direction,
                            int amount) {
            Rectangle visRect = component.getVisibleRect();
            Dimension size = component.getSize();
            if (direction == SwingConstants.HORIZONTAL) {
                visRect.x += amount;
                visRect.x = Math.max(0, visRect.x);
                visRect.x = Math.min(Math.max(0, size.width - visRect.width),
                                     visRect.x);
            }
            else {
                visRect.y += amount;
                visRect.y = Math.max(0, visRect.y);
                visRect.y = Math.min(Math.max(0, size.width - visRect.height),
                                     visRect.y);
            }
            component.scrollRectToVisible(visRect);
        }

        private void extendSelection(JTree tree, BasicTreeUI ui) {
            if (ui.getRowCount(tree) > 0) {
                int       lead = ui.getLeadSelectionRow();

                if (lead != -1) {
                    TreePath      leadP = ui.getLeadSelectionPath();
                    TreePath      aPath = ui.getAnchorSelectionPath();
                    int           aRow = ui.getRowForPath(tree, aPath);

                    if(aRow == -1)
                        aRow = 0;
                    tree.setSelectionInterval(aRow, lead);
                    ui.setLeadSelectionPath(leadP);
                    ui.setAnchorSelectionPath(aPath);
                }
            }
        }

        private void selectAll(JTree tree, BasicTreeUI ui, boolean selectAll) {
            int                   rowCount = ui.getRowCount(tree);

            if(rowCount > 0) {
                if(selectAll) {
                    if (tree.getSelectionModel().getSelectionMode() ==
                            TreeSelectionModel.SINGLE_TREE_SELECTION) {

                        int lead = ui.getLeadSelectionRow();
                        if (lead != -1) {
                            tree.setSelectionRow(lead);
                        } else if (tree.getMinSelectionRow() == -1) {
                            tree.setSelectionRow(0);
                            ui.ensureRowsAreVisible(0, 0);
                        }
                        return;
                    }

                    TreePath      lastPath = ui.getLeadSelectionPath();
                    TreePath      aPath = ui.getAnchorSelectionPath();

                    if(lastPath != null && !tree.isVisible(lastPath)) {
                        lastPath = null;
                    }
                    tree.setSelectionInterval(0, rowCount - 1);
                    if(lastPath != null) {
                        ui.setLeadSelectionPath(lastPath);
                    }
                    if(aPath != null && tree.isVisible(aPath)) {
                        ui.setAnchorSelectionPath(aPath);
                    }
                }
                else {
                    TreePath      lastPath = ui.getLeadSelectionPath();
                    TreePath      aPath = ui.getAnchorSelectionPath();

                    tree.clearSelection();
                    ui.setAnchorSelectionPath(aPath);
                    ui.setLeadSelectionPath(lastPath);
                }
            }
        }

        private void startEditing(JTree tree, BasicTreeUI ui) {
            TreePath   lead = ui.getLeadSelectionPath();
            int        editRow = (lead != null) ?
                                     ui.getRowForPath(tree, lead) : -1;

            if(editRow != -1) {
                tree.startEditingAtPath(lead);
            }
        }

        private void cancelEditing(JTree tree, BasicTreeUI ui) {
            tree.cancelEditing();
        }

        private void toggle(JTree tree, BasicTreeUI ui) {
            int            selRow = ui.getLeadSelectionRow();

            if(selRow != -1 && !ui.isLeaf(selRow)) {
                TreePath aPath = ui.getAnchorSelectionPath();
                TreePath lPath = ui.getLeadSelectionPath();

                ui.toggleExpandState(ui.getPathForRow(tree, selRow));
                ui.setAnchorSelectionPath(aPath);
                ui.setLeadSelectionPath(lPath);
            }
        }

        private void expand(JTree tree, BasicTreeUI ui) {
            int selRow = ui.getLeadSelectionRow();
            tree.expandRow(selRow);
        }

        private void collapse(JTree tree, BasicTreeUI ui) {
            int selRow = ui.getLeadSelectionRow();
            tree.collapseRow(selRow);
        }

        private void increment(JTree tree, BasicTreeUI ui, int direction,
                               boolean addToSelection,
                               boolean changeSelection) {

            // disable moving of lead unless in discontiguous mode
            if (!addToSelection && !changeSelection &&
                    tree.getSelectionModel().getSelectionMode() !=
                        TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION) {
                changeSelection = true;
            }

            int              rowCount;

            if(ui.treeSelectionModel != null &&
                  (rowCount = tree.getRowCount()) > 0) {
                int                  selIndex = ui.getLeadSelectionRow();
                int                  newIndex;

                if(selIndex == -1) {
                    if(direction == 1)
                        newIndex = 0;
                    else
                        newIndex = rowCount - 1;
                }
                else
                    /* Aparently people don't like wrapping;( */
                    newIndex = Math.min(rowCount - 1, Math.max
                                        (0, (selIndex + direction)));
                if(addToSelection && ui.treeSelectionModel.
                        getSelectionMode() != TreeSelectionModel.
                        SINGLE_TREE_SELECTION) {
                    ui.extendSelection(tree.getPathForRow(newIndex));
                }
                else if(changeSelection) {
                    tree.setSelectionInterval(newIndex, newIndex);
                }
                else {
                    ui.setLeadSelectionPath(tree.getPathForRow(newIndex),true);
                }
                ui.ensureRowsAreVisible(newIndex, newIndex);
                ui.lastSelectedRow = newIndex;
            }
        }

        private void traverse(JTree tree, BasicTreeUI ui, int direction,
                              boolean changeSelection) {

            // disable moving of lead unless in discontiguous mode
            if (!changeSelection &&
                    tree.getSelectionModel().getSelectionMode() !=
                        TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION) {
                changeSelection = true;
            }

            int                rowCount;

            if((rowCount = tree.getRowCount()) > 0) {
                int               minSelIndex = ui.getLeadSelectionRow();
                int               newIndex;

                if(minSelIndex == -1)
                    newIndex = 0;
                else {
                    /* Try and expand the node, otherwise go to next
                       node. */
                    if(direction == 1) {
                        TreePath minSelPath = ui.getPathForRow(tree, minSelIndex);
                        int childCount = tree.getModel().
                            getChildCount(minSelPath.getLastPathComponent());
                        newIndex = -1;
                        if (!ui.isLeaf(minSelIndex)) {
                            if (!tree.isExpanded(minSelIndex)) {
                                ui.toggleExpandState(minSelPath);
                            }
                            else if (childCount > 0) {
                                newIndex = Math.min(minSelIndex + 1, rowCount - 1);
                            }
                        }
                    }
                    /* Try to collapse node. */
                    else {
                        if(!ui.isLeaf(minSelIndex) &&
                           tree.isExpanded(minSelIndex)) {
                            ui.toggleExpandState(ui.getPathForRow
                                              (tree, minSelIndex));
                            newIndex = -1;
                        }
                        else {
                            TreePath         path = ui.getPathForRow(tree,
                                                                  minSelIndex);

                            if(path != null && path.getPathCount() > 1) {
                                newIndex = ui.getRowForPath(tree, path.
                                                         getParentPath());
                            }
                            else
                                newIndex = -1;
                        }
                    }
                }
                if(newIndex != -1) {
                    if(changeSelection) {
                        tree.setSelectionInterval(newIndex, newIndex);
                    }
                    else {
                        ui.setLeadSelectionPath(ui.getPathForRow(
                                                    tree, newIndex), true);
                    }
                    ui.ensureRowsAreVisible(newIndex, newIndex);
                }
            }
        }

        private void moveSelectionToParent(JTree tree, BasicTreeUI ui) {
            int selRow = ui.getLeadSelectionRow();
            TreePath path = ui.getPathForRow(tree, selRow);
            if (path != null && path.getPathCount() > 1) {
                int  newIndex = ui.getRowForPath(tree, path.getParentPath());
                if (newIndex != -1) {
                    tree.setSelectionInterval(newIndex, newIndex);
                    ui.ensureRowsAreVisible(newIndex, newIndex);
                }
            }
        }

        private void page(JTree tree, BasicTreeUI ui, int direction,
                          boolean addToSelection, boolean changeSelection) {

            // disable moving of lead unless in discontiguous mode
            if (!addToSelection && !changeSelection &&
                    tree.getSelectionModel().getSelectionMode() !=
                        TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION) {
                changeSelection = true;
            }

            int           rowCount;

            if((rowCount = ui.getRowCount(tree)) > 0 &&
                           ui.treeSelectionModel != null) {
                Dimension         maxSize = tree.getSize();
                TreePath          lead = ui.getLeadSelectionPath();
                TreePath          newPath;
                Rectangle         visRect = tree.getVisibleRect();

                if(direction == -1) {
                    // up.
                    newPath = ui.getClosestPathForLocation(tree, visRect.x,
                                                         visRect.y);
                    if(newPath.equals(lead)) {
                        visRect.y = Math.max(0, visRect.y - visRect.height);
                        newPath = tree.getClosestPathForLocation(visRect.x,
                                                                 visRect.y);
                    }
                }
                else {
                    // down
                    visRect.y = Math.min(maxSize.height, visRect.y +
                                         visRect.height - 1);
                    newPath = tree.getClosestPathForLocation(visRect.x,
                                                             visRect.y);
                    if(newPath.equals(lead)) {
                        visRect.y = Math.min(maxSize.height, visRect.y +
                                             visRect.height - 1);
                        newPath = tree.getClosestPathForLocation(visRect.x,
                                                                 visRect.y);
                    }
                }
                Rectangle            newRect = ui.getPathBounds(tree, newPath);

                newRect.x = visRect.x;
                newRect.width = visRect.width;
                if(direction == -1) {
                    newRect.height = visRect.height;
                }
                else {
                    newRect.y -= (visRect.height - newRect.height);
                    newRect.height = visRect.height;
                }

                if(addToSelection) {
                    ui.extendSelection(newPath);
                }
                else if(changeSelection) {
                    tree.setSelectionPath(newPath);
                }
                else {
                    ui.setLeadSelectionPath(newPath, true);
                }
                tree.scrollRectToVisible(newRect);
            }
        }

        private void home(JTree tree, BasicTreeUI ui, int direction,
                          boolean addToSelection, boolean changeSelection) {

            // disable moving of lead unless in discontiguous mode
            if (!addToSelection && !changeSelection &&
                    tree.getSelectionModel().getSelectionMode() !=
                        TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION) {
                changeSelection = true;
            }

            int rowCount = ui.getRowCount(tree);

            if (rowCount > 0) {
                if(direction == -1) {
                    ui.ensureRowsAreVisible(0, 0);
                    if (addToSelection) {
                        TreePath        aPath = ui.getAnchorSelectionPath();
                        int             aRow = (aPath == null) ? -1 :
                                        ui.getRowForPath(tree, aPath);

                        if (aRow == -1) {
                            tree.setSelectionInterval(0, 0);
                        }
                        else {
                            tree.setSelectionInterval(0, aRow);
                            ui.setAnchorSelectionPath(aPath);
                            ui.setLeadSelectionPath(ui.getPathForRow(tree, 0));
                        }
                    }
                    else if(changeSelection) {
                        tree.setSelectionInterval(0, 0);
                    }
                    else {
                        ui.setLeadSelectionPath(ui.getPathForRow(tree, 0),
                                                true);
                    }
                }
                else {
                    ui.ensureRowsAreVisible(rowCount - 1, rowCount - 1);
                    if (addToSelection) {
                        TreePath        aPath = ui.getAnchorSelectionPath();
                        int             aRow = (aPath == null) ? -1 :
                                        ui.getRowForPath(tree, aPath);

                        if (aRow == -1) {
                            tree.setSelectionInterval(rowCount - 1,
                                                      rowCount -1);
                        }
                        else {
                            tree.setSelectionInterval(aRow, rowCount - 1);
                            ui.setAnchorSelectionPath(aPath);
                            ui.setLeadSelectionPath(ui.getPathForRow(tree,
                                                               rowCount -1));
                        }
                    }
                    else if(changeSelection) {
                        tree.setSelectionInterval(rowCount - 1, rowCount - 1);
                    }
                    else {
                        ui.setLeadSelectionPath(ui.getPathForRow(tree,
                                                          rowCount - 1), true);
                    }
                }
            }
        }
    }
} // End of class BasicTreeUI
