/*
 * Copyright 1997-2007 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 = null;
        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 && event instanceof MouseEvent) {
                    /* 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) &&
                event.isControlDown());
    }

    /**
     * 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(bounds);
            bounds = getPathBounds(tree, newPath);
            if(bounds != null)
                tree.repaint(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 {

        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 (int i = 0; i < displayPaths.length; i++) {
                    TreePath path = displayPaths[i];

                    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(Object o1, Object o2) {
            int row1 = tree.getRowForPath((TreePath)o1);
            int row2 = tree.getRowForPath((TreePath)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 selOrder = new ArrayList();
            for (int i = 0; i < paths.length; i++) {
                selOrder.add(paths[i]);
            }
            Collections.sort(selOrder, this);
            int n = selOrder.size();
            TreePath[] displayPaths = new TreePath[n];
            for (int i = 0; i < n; i++) {
                displayPaths[i] = (TreePath) 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() || e.isControlDown() || e.isMetaDown() ||
                    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);

            if (inputMap != null && inputMap.get(key) != null) {
                return true;
            }
            return false;
        }


        //
        // 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 (e.isControlDown()) {
                    // 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 (me.isControlDown()) {
                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);
        }

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

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