/*******************************************************************************
 * Copyright (c) 2000, 2008 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.widgets;

import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.internal.*;

/**
 * Instances of this class provide a selectable user interface object
 * that displays a hierarchy of items and issues notification when an
 * item in the hierarchy is selected.
 * <p>
 * The item children that may be added to instances of this class
 * must be of type <code>TreeItem</code>.
 * </p><p>
 * Style <code>VIRTUAL</code> is used to create a <code>Tree</code> whose
 * <code>TreeItem</code>s are to be populated by the client on an on-demand basis
 * instead of up-front.  This can provide significant performance improvements for
 * trees that are very large or for which <code>TreeItem</code> population is
 * expensive (for example, retrieving values from an external source).
 * </p><p>
 * Here is an example of using a <code>Tree</code> with style <code>VIRTUAL</code>:
 * <code><pre>
 *  final Tree tree = new Tree(parent, SWT.VIRTUAL | SWT.BORDER);
 *  tree.setItemCount(20);
 *  tree.addListener(SWT.SetData, new Listener() {
 *      public void handleEvent(Event event) {
 *          TreeItem item = (TreeItem)event.item;
 *          TreeItem parentItem = item.getParentItem();
 *          String text = null;
 *          if (parentItem == null) {
 *              text = "node " + tree.indexOf(item);
 *          } else {
 *              text = parentItem.getText() + " - " + parentItem.indexOf(item);
 *          }
 *          item.setText(text);
 *          System.out.println(text);
 *          item.setItemCount(10);
 *      }
 *  });
 * </pre></code>
 * </p><p>
 * Note that although this class is a subclass of <code>Composite</code>,
 * it does not normally make sense to add <code>Control</code> children to
 * it, or set a layout on it, unless implementing something like a cell
 * editor.
 * </p><p>
 * <dl>
 * <dt><b>Styles:</b></dt>
 * <dd>SINGLE, MULTI, CHECK, FULL_SELECTION, VIRTUAL, NO_SCROLL</dd>
 * <dt><b>Events:</b></dt>
 * <dd>Selection, DefaultSelection, Collapse, Expand, SetData, MeasureItem, EraseItem, PaintItem</dd>
 * </dl>
 * </p><p>
 * Note: Only one of the styles SINGLE and MULTI may be specified.
 * </p><p>
 * IMPORTANT: This class is <em>not</em> intended to be subclassed.
 * </p>
 *
 * @see <a href="http://www.eclipse.org/swt/snippets/#tree">Tree, TreeItem, TreeColumn snippets</a>
 * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: ControlExample</a>
 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
 */
public class Tree extends Composite {
	Canvas header;
	TreeColumn[] columns = new TreeColumn [0];
	TreeColumn[] orderedColumns;
	TreeItem[] items = NO_ITEMS;
	TreeItem[] availableItems = NO_ITEMS;
	TreeItem[] selectedItems = NO_ITEMS;
	TreeItem focusItem, anchorItem, insertMarkItem;
	TreeItem lastClickedItem;
	Event lastSelectionEvent;
	int availableItemsCount = 0;
	boolean insertMarkPrecedes = false;
	boolean linesVisible, ignoreKey, ignoreDispose, customHeightSet;
	int topIndex = 0, horizontalOffset = 0;
	int fontHeight = 0, imageHeight = 0, itemHeight = 0;
	int headerImageHeight = 0, orderedCol0imageWidth = 0;
	TreeColumn resizeColumn;
	int resizeColumnX = -1;
	int drawCount = 0;
	boolean inExpand = false;	/* for item creation within Expand callback */
	TreeColumn sortColumn;
	int sortDirection = SWT.NONE;

	/* column header tooltip */
	Listener toolTipListener;
	Shell toolTipShell;
	Label toolTipLabel;

	Rectangle arrowBounds, expanderBounds, checkboxBounds, clientArea;

	static final TreeItem[] NO_ITEMS = new TreeItem [0];

	static final int MARGIN_IMAGE = 3;
	static final int MARGIN_CELL = 1;
	static final int SIZE_HORIZONTALSCROLL = 5;
	static final int TOLLERANCE_COLUMNRESIZE = 2;
	static final int WIDTH_HEADER_SHADOW = 2;
	static final int WIDTH_CELL_HIGHLIGHT = 1;
	static final int [] toolTipEvents = new int[] {SWT.MouseExit, SWT.MouseHover, SWT.MouseMove, SWT.MouseDown};
	static final String ELLIPSIS = "...";						//$NON-NLS-1$
	static final String ID_EXPANDED = "EXPANDED";				//$NON-NLS-1$
	static final String ID_COLLAPSED = "COLLAPSED";			//$NON-NLS-1$
	static final String ID_UNCHECKED = "UNCHECKED";			//$NON-NLS-1$
	static final String ID_GRAYUNCHECKED = "GRAYUNCHECKED";	//$NON-NLS-1$
	static final String ID_CHECKMARK = "CHECKMARK";			//$NON-NLS-1$
	static final String ID_CONNECTOR_COLOR = "CONNECTOR_COLOR";	//$NON-NLS-1$
	static final String ID_ARROWUP = "ARROWUP";				//$NON-NLS-1$
	static final String ID_ARROWDOWN = "ARROWDOWN";			//$NON-NLS-1$

//	TEMPORARY CODE
boolean hasFocus;

public boolean isFocusControl() {
	return hasFocus;
}

/**
 * Constructs a new instance of this class given its parent
 * and a style value describing its behavior and appearance.
 * <p>
 * The style value is either one of the style constants defined in
 * class <code>SWT</code> which is applicable to instances of this
 * class, or must be built by <em>bitwise OR</em>'ing together 
 * (that is, using the <code>int</code> "|" operator) two or more
 * of those <code>SWT</code> style constants. The class description
 * lists the style constants that are applicable to the class.
 * Style bits are also inherited from superclasses.
 * </p>
 *
 * @param parent a composite control which will be the parent of the new instance (cannot be null)
 * @param style the style of control to construct
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
 *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
 * </ul>
 *
 * @see SWT#SINGLE
 * @see SWT#MULTI
 * @see SWT#CHECK
 * @see SWT#FULL_SELECTION
 * @see SWT#VIRTUAL
 * @see SWT#NO_SCROLL
 * @see Widget#checkSubclass
 * @see Widget#getStyle
 */
public Tree (Composite parent, int style) {
	super (parent, checkStyle (style));
	setForeground (null);	/* set foreground and background to chosen default colors */
	setBackground (null);
	GC gc = new GC (this);
	fontHeight = gc.getFontMetrics ().getHeight ();
	gc.dispose ();
	itemHeight = fontHeight + (2 * getCellPadding ());
	initImages (display);
	expanderBounds = getExpandedImage ().getBounds ();
	checkboxBounds = getUncheckedImage ().getBounds ();
	arrowBounds = getArrowDownImage ().getBounds ();
	clientArea = getClientArea ();
	
	Listener listener = new Listener () {
		public void handleEvent (Event event) {
			handleEvents (event);
		}
	};
	addListener (SWT.Paint, listener);
	addListener (SWT.MouseDown, listener);
	addListener (SWT.MouseUp, listener);
	addListener (SWT.MouseDoubleClick, listener);
	addListener (SWT.Dispose, listener);	
	addListener (SWT.Resize, listener);
	addListener (SWT.KeyDown, listener);
	addListener (SWT.FocusOut, listener);
	addListener (SWT.FocusIn, listener);
	addListener (SWT.Traverse, listener);

	header = new Canvas (this, SWT.NO_REDRAW_RESIZE | SWT.NO_FOCUS);
	header.setVisible (false);
	header.setBounds (0, 0, 0, fontHeight + 2 * getHeaderPadding ());
	header.addListener (SWT.Paint, listener);
	header.addListener (SWT.MouseDown, listener);
	header.addListener (SWT.MouseUp, listener);
	header.addListener (SWT.MouseHover, listener);
	header.addListener (SWT.MouseDoubleClick, listener);
	header.addListener (SWT.MouseMove, listener);
	header.addListener (SWT.MouseExit, listener);
	header.addListener (SWT.MenuDetect, listener);

	toolTipListener = new Listener () {
		public void handleEvent (Event event) {
			switch (event.type) {
				case SWT.MouseHover:
				case SWT.MouseMove:
					if (headerUpdateToolTip (event.x)) break;
					// FALL THROUGH
				case SWT.MouseExit:
				case SWT.MouseDown:
					headerHideToolTip ();
					break;
			}
		}
	};

	ScrollBar hBar = getHorizontalBar ();
	if (hBar != null) {
		hBar.setValues (0, 0, 1, 1, 1, 1);
		hBar.setVisible (false);
		hBar.addListener (SWT.Selection, listener);
	}
	ScrollBar vBar = getVerticalBar ();
	if (vBar != null) {
		vBar.setValues (0, 0, 1, 1, 1, 1);
		vBar.setVisible (false);
		vBar.addListener (SWT.Selection, listener);
	}
}
/**
 * Adds the listener to the collection of listeners who will
 * be notified when the user changes the receiver's selection, by sending
 * it one of the messages defined in the <code>SelectionListener</code>
 * interface.
 * <p>
 * When <code>widgetSelected</code> is called, the item field of the event object is valid.
 * If the receiver has the <code>SWT.CHECK</code> style and the check selection changes,
 * the event object detail field contains the value <code>SWT.CHECK</code>.
 * <code>widgetDefaultSelected</code> is typically called when an item is double-clicked.
 * The item field of the event object is valid for default selection, but the detail field is not used.
 * </p>
 *
 * @param listener the listener which should be notified when the user changes the receiver's selection
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see SelectionListener
 * @see #removeSelectionListener
 * @see SelectionEvent
 */
public void addSelectionListener (SelectionListener listener) {
	checkWidget ();
	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
	TypedListener typedListener = new TypedListener (listener);	
	addListener (SWT.Selection, typedListener);
	addListener (SWT.DefaultSelection, typedListener);
}
/**
 * Adds the listener to the collection of listeners who will
 * be notified when an item in the receiver is expanded or collapsed
 * by sending it one of the messages defined in the <code>TreeListener</code>
 * interface.
 *
 * @param listener the listener which should be notified
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see TreeListener
 * @see #removeTreeListener
 */
public void addTreeListener (TreeListener listener) {
	checkWidget ();
	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
	TypedListener typedListener = new TypedListener (listener);	
	addListener (SWT.Expand, typedListener);
	addListener (SWT.Collapse, typedListener);
}
boolean checkData (TreeItem item, boolean redraw) {
	if (item.cached) return true;
	if ((style & SWT.VIRTUAL) != 0) {
		item.cached = true;
		Event event = new Event ();
		TreeItem parentItem = item.getParentItem ();
		event.item = item;
		event.index = parentItem == null ? indexOf (item) : parentItem.indexOf (item);
		sendEvent (SWT.SetData, event);
		if (isDisposed () || item.isDisposed ()) return false;
		if (redraw) redrawItem (item.availableIndex, false);
	}
	return true;
}
static int checkStyle (int style) {
	/*
	* Feature in Windows.  Even when WS_HSCROLL or
	* WS_VSCROLL is not specified, Windows creates
	* trees and tables with scroll bars.  The fix
	* is to set H_SCROLL and V_SCROLL.
	* 
	* NOTE: This code appears on all platforms so that
	* applications have consistent scroll bar behavior.
	*/
	if ((style & SWT.NO_SCROLL) == 0) {
		style |= SWT.H_SCROLL | SWT.V_SCROLL;
	}
	style |= SWT.NO_REDRAW_RESIZE | SWT.NO_BACKGROUND | SWT.DOUBLE_BUFFERED;
	//TEMPORARY CODE
	style |= SWT.FULL_SELECTION;
	return checkBits (style, SWT.SINGLE, SWT.MULTI, 0, 0, 0, 0);
}
protected void checkSubclass () {
	if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
}
/**
 * Clears the item at the given zero-relative index in the receiver.
 * The text, icon and other attributes of the item are set to the default
 * value.  If the tree was created with the <code>SWT.VIRTUAL</code> style,
 * these attributes are requested again as needed.
 *
 * @param index the index of the item to clear
 * @param all <code>true</code> if all child items of the indexed item should be
 * cleared recursively, and <code>false</code> otherwise
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @see SWT#VIRTUAL
 * @see SWT#SetData
 * 
 * @since 3.2
 */
public void clear (int index, boolean recursive) {
	checkWidget ();
	if (!(0 <= index && index < items.length)) error (SWT.ERROR_INVALID_RANGE);
	TreeItem item = items [index];
	
	/* if there are no columns then the horizontal scrollbar may need adjusting */
	TreeItem[] availableDescendents = null;
	int oldRightX = 0;
	if (columns.length == 0) {
		if (recursive) {
			availableDescendents = item.computeAvailableDescendents ();
			for (int i = 0; i < availableDescendents.length; i++) {
				Rectangle bounds = availableDescendents [i].getBounds (false);
				oldRightX = Math.max (oldRightX, bounds.x + bounds.width);
			}
		} else {
			Rectangle bounds = item.getBounds (false);
			oldRightX = bounds.x + bounds.width;
		}
	}
	
	/* clear the item(s) */
	item.clear ();
	if (recursive) {
		item.clearAll (true, false);
	}

	/* adjust the horizontal scrollbar if needed */
	if (columns.length == 0) {
		int newRightX = 0;
		if (recursive) {
			for (int i = 0; i < availableDescendents.length; i++) {
				Rectangle bounds = availableDescendents [i].getBounds (false);
				newRightX = Math.max (newRightX, bounds.x + bounds.width);
			}
		} else {
			Rectangle bounds = item.getBounds (false);
			newRightX = bounds.x + bounds.width;
		}
		updateHorizontalBar (newRightX, newRightX - oldRightX);
	}
	
	/* redraw the item(s) */
	if (recursive && item.expanded) {
		int descendentCount = availableDescendents == null ?
			item.computeAvailableDescendentCount () :
			availableDescendents.length;
		redrawItems (item.availableIndex, item.availableIndex + descendentCount - 1, false);
	} else {
		redrawItem (item.availableIndex, false);
	}
}
/**
 * Clears all the items in the receiver. The text, icon and other
 * attributes of the items are set to their default values. If the
 * tree was created with the <code>SWT.VIRTUAL</code> style, these
 * attributes are requested again as needed.
 * 
 * @param all <code>true</code> if all child items should be cleared
 * recursively, and <code>false</code> otherwise
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @see SWT#VIRTUAL
 * @see SWT#SetData
 * 
 * @since 3.2
 */
public void clearAll (boolean recursive) {
	checkWidget ();
	if (items.length == 0) return;
	
	/* if there are no columns then the horizontal scrollbar may need adjusting */
	int oldRightX = 0;
	if (columns.length == 0 && !recursive) {
		for (int i = 0; i < items.length; i++) {
			Rectangle bounds = items [i].getBounds (false);
			oldRightX = Math.max (oldRightX, bounds.x + bounds.width);
		}
	}

	/* clear the item(s) */
	for (int i = 0; i < items.length; i++) {
		items [i].clear ();
		if (recursive) items [i].clearAll (true, false);
	}

	/* adjust the horizontal scrollbar if needed */
	if (columns.length == 0) {
		if (recursive) {
			updateHorizontalBar ();		/* recompute from scratch */
		} else {
			/*
			 * All cleared root items will have the same x and width values now,
			 * so just measure the first one as a sample.
			 */
			Rectangle bounds = items [0].getBounds (false);
			int newRightX = bounds.x + bounds.width;
			updateHorizontalBar (newRightX, newRightX - oldRightX);
		}
	}
	
	/* redraw the item(s) */
	if (recursive) {
		redrawItems (0, availableItemsCount - 1, false);
	} else {
		for (int i = 0; i < items.length; i++) {
			redrawItem (items [i].availableIndex, false);
		}
	}
}
/*
 * Returns the ORDERED index of the column that the specified x falls within,
 * or -1 if the x lies to the right of the last column.
 */
int computeColumnIntersect (int x, int startColumn) {
	TreeColumn[] orderedColumns = getOrderedColumns ();
	if (orderedColumns.length - 1 < startColumn) return -1;
	int rightX = orderedColumns [startColumn].getX ();
	for (int i = startColumn; i < orderedColumns.length; i++) {
		rightX += orderedColumns [i].width;
		if (x < rightX) return i;
	}
	return -1;
}
public Point computeSize (int wHint, int hHint, boolean changed) {
	checkWidget ();
	int width = 0, height = 0;
	if (wHint != SWT.DEFAULT) {
		width = wHint;
	} else {
		if (columns.length == 0) {
			for (int i = 0; i < availableItemsCount; i++) {
				Rectangle itemBounds = availableItems [i].getBounds (false);
				width = Math.max (width, itemBounds.x + itemBounds.width);
			}
		} else {
			TreeColumn[] orderedColumns = getOrderedColumns ();
			TreeColumn lastColumn = orderedColumns [orderedColumns.length - 1];
			width = lastColumn.getX () + lastColumn.width;
		}
	}
	if (hHint != SWT.DEFAULT) {
		height = hHint;
	} else {
		height = getHeaderHeight () + availableItemsCount * itemHeight;
	}
	Rectangle result = computeTrim (0, 0, width, height);
	return new Point (result.width, result.height);
}
void createItem (TreeColumn column, int index) {
	TreeColumn[] newColumns = new TreeColumn [columns.length + 1];
	System.arraycopy (columns, 0, newColumns, 0, index);
	newColumns [index] = column;
	System.arraycopy (columns, index, newColumns, index + 1, columns.length - index);
	columns = newColumns;
	
	if (orderedColumns != null) {
		int insertIndex = 0;
		if (index > 0) {
			insertIndex = columns [index - 1].getOrderIndex () + 1;
		}
		TreeColumn[] newOrderedColumns = new TreeColumn [orderedColumns.length + 1];
		System.arraycopy (orderedColumns, 0, newOrderedColumns, 0, insertIndex);
		newOrderedColumns [insertIndex] = column;
		System.arraycopy (
			orderedColumns,
			insertIndex,
			newOrderedColumns,
			insertIndex + 1,
			orderedColumns.length - insertIndex);
		orderedColumns = newOrderedColumns;
	}

	if (columns.length == 1) {
		column.itemImageWidth = orderedCol0imageWidth;
	} else {
		if (column.getOrderIndex () == 0) orderedCol0imageWidth = 0;
	}

	/* allow all items to update their internal structures accordingly */
	for (int i = 0; i < items.length; i++) {
		items [i].addColumn (column);
	}

	/* existing items become hidden when going from 0 to 1 column (0 width) */
	if (columns.length == 1 && availableItemsCount > 0) {
		redrawFromItemDownwards (topIndex);
	} else {
		/* checkboxes become hidden when creating a column with index == ordered index == 0 (0 width) */
		if (availableItemsCount > 0 && (style & SWT.CHECK) != 0 && index == 0 && column.getOrderIndex () == 0) {
			redrawFromItemDownwards (topIndex);
		}
	}
}
void createItem (TreeItem item, int index) {
	TreeItem[] newItems = new TreeItem [items.length + 1];
	System.arraycopy (items, 0, newItems, 0, index);
	newItems [index] = item;
	System.arraycopy (items, index, newItems, index + 1, items.length - index);
	items = newItems;

	/* determine the item's availability index */
	int startIndex;
	if (index == items.length - 1) {
		startIndex = availableItemsCount;		/* last item */
	} else {
		startIndex = items [index + 1].availableIndex;
	}

	if (availableItemsCount == availableItems.length) {
		int grow = drawCount <= 0 ? 4 : Math.max (4, availableItems.length * 3 / 2);
		TreeItem[] newAvailableItems = new TreeItem [availableItems.length + grow];
		System.arraycopy (availableItems, 0, newAvailableItems, 0, availableItems.length);
		availableItems = newAvailableItems;
	}
	if (startIndex != availableItemsCount) {
		/* new item is not at end of list, so shift other items right to create space for it */
		System.arraycopy (
			availableItems,
			startIndex,
			availableItems,
			startIndex + 1,
			availableItemsCount - startIndex);
	}
	availableItems [startIndex] = item;
	availableItemsCount++;

	/* update the availableIndex for items bumped down by this new item */
	for (int i = startIndex; i < availableItemsCount; i++) {
		availableItems [i].availableIndex = i;
	}

	/* update scrollbars */
	updateVerticalBar ();
	Rectangle bounds = item.getBounds (false);
	int rightX = bounds.x + bounds.width;
	updateHorizontalBar (rightX, rightX);
	/* 
	 * If new item is above viewport then adjust topIndex and the vertical
	 * scrollbar so that the current viewport items will not change.
	 */
	if (item.availableIndex < topIndex) {
		topIndex++;
		ScrollBar vBar = getVerticalBar ();
		if (vBar != null) vBar.setSelection (topIndex);
		return;
	}
	/*
	 * If this is the first item and the receiver has focus then its boundary
	 * focus ring must be removed. 
	 */
	if (availableItemsCount == 1 && isFocusControl ()) {
		focusItem = item;
		redraw ();
		return;
	}
	int redrawIndex = index;
	if (redrawIndex > 0 && item.isLastChild ()) redrawIndex--;
	redrawFromItemDownwards (items [redrawIndex].availableIndex);
}
/**
 * Deselects an item in the receiver.  If the item was already
 * deselected, it remains deselected.
 *
 * @param item the item to be deselected
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the item is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @since 3.4
 */
public void deselect (TreeItem item) {
	checkWidget ();
	if (item == null) error (SWT.ERROR_NULL_ARGUMENT);
	if (item.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
	deselectItem (item);
	redrawItem (item.availableIndex, true);
}
/**
 * Deselects all selected items in the receiver.
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void deselectAll () {
	checkWidget ();
	TreeItem[] oldSelection = selectedItems;
	selectedItems = NO_ITEMS;
	for (int i = 0; i < oldSelection.length; i++) {
		redrawItem (oldSelection [i].availableIndex, true);
	}
}
void deselectItem (TreeItem item) {
	int index = getSelectionIndex (item);
	if (index == -1) return;
	TreeItem[] newSelectedItems = new TreeItem [selectedItems.length - 1];
	System.arraycopy (selectedItems, 0, newSelectedItems, 0, index);
	System.arraycopy (
		selectedItems,
		index + 1,
		newSelectedItems,
		index,
		newSelectedItems.length - index);
	selectedItems = newSelectedItems;
}
void destroyItem (TreeColumn column) {
	headerHideToolTip ();
	int index = column.getIndex ();
	int orderedIndex = column.getOrderIndex ();

	TreeColumn[] newColumns = new TreeColumn [columns.length - 1];
	System.arraycopy (columns, 0, newColumns, 0, index);
	System.arraycopy (columns, index + 1, newColumns, index, newColumns.length - index);
	columns = newColumns;

	if (orderedColumns != null) {
		if (columns.length < 2) {
			orderedColumns = null;
		} else {
			int removeIndex = column.getOrderIndex ();
			TreeColumn[] newOrderedColumns = new TreeColumn [orderedColumns.length - 1];
			System.arraycopy (orderedColumns, 0, newOrderedColumns, 0, removeIndex);
			System.arraycopy (
				orderedColumns,
				removeIndex + 1,
				newOrderedColumns,
				removeIndex,
				newOrderedColumns.length - removeIndex);
			orderedColumns = newOrderedColumns;
		}
	}

	if (orderedIndex == 0 && columns.length > 0) {
		orderedCol0imageWidth = columns [getColumnOrder ()[0]].itemImageWidth;
	}

	/* allow all items to update their internal structures accordingly */
	for (int i = 0; i < items.length; i++) {
		items [i].removeColumn (column, index, orderedIndex);
	}

	/* update horizontal scrollbar */
	int lastColumnIndex = columns.length - 1;
	if (lastColumnIndex < 0) {		/* no more columns */
		updateHorizontalBar ();
	} else {
		int newWidth = 0;
		for (int i = 0; i < columns.length; i++) {
			newWidth += columns [i].width;
		}
		ScrollBar hBar = getHorizontalBar (); 
		if (hBar != null) {
			hBar.setMaximum (newWidth);
			hBar.setVisible (clientArea.width < newWidth);
			int selection = hBar.getSelection ();
			if (selection != horizontalOffset) {
				horizontalOffset = selection;
				redraw ();
				if (header.isVisible () && drawCount <= 0) header.redraw ();
			}
		}
	}
	TreeColumn[] orderedColumns = getOrderedColumns ();
	for (int i = orderedIndex; i < orderedColumns.length; i++) {
		if (!orderedColumns [i].isDisposed ()) {
			orderedColumns [i].sendEvent (SWT.Move);
		}
	}

	if (sortColumn == column) {
		sortColumn = null;
	}
}
/*
 * Allows the Tree to update internal structures it has that may contain the
 * item being destroyed.  The argument is not necessarily a root-level item.
 */
void destroyItem (TreeItem item) {
	if (item == focusItem) reassignFocus ();

	/* availableItems array */
	int availableIndex = item.availableIndex; 
	if (availableIndex != -1) {
		Rectangle bounds = item.getBounds (false);
		int rightX = bounds.x + bounds.width;

		if (availableIndex != availableItemsCount - 1) {
			/* item is not at end of available items list, so must shift items left to reclaim its slot */
			System.arraycopy (
				availableItems,
				availableIndex + 1,
				availableItems,
				availableIndex,
				availableItemsCount - availableIndex - 1);
			availableItems [availableItemsCount - 1] = null;
		} else {
			availableItems [availableIndex] = null;	/* last item, so no array copy needed */
		}
		availableItemsCount--;

		if (drawCount <= 0 && availableItems.length - availableItemsCount == 4) {
			/* shrink the available items array */
			TreeItem[] newAvailableItems = new TreeItem [availableItemsCount];
			System.arraycopy (availableItems, 0, newAvailableItems, 0, newAvailableItems.length);
			availableItems = newAvailableItems;
		}

		/* update the availableIndex on affected items */
		for (int i = availableIndex; i < availableItemsCount; i++) {
			availableItems [i].availableIndex = i;
		}
		item.availableIndex = -1;
		int oldTopIndex = topIndex;
		updateVerticalBar ();
		updateHorizontalBar (0, -rightX);
		/* 
		 * If destroyed item is above viewport then adjust topIndex and the vertical
		 * scrollbar so that the current viewport items will not change. 
		 */
		if (availableIndex < topIndex) {
			topIndex = oldTopIndex - 1;
			ScrollBar vBar = getVerticalBar ();
			if (vBar != null) vBar.setSelection (topIndex);
		}
	}
	/* selectedItems array */
	if (item.isSelected ()) {
		int selectionIndex = getSelectionIndex (item);
		TreeItem[] newSelectedItems = new TreeItem [selectedItems.length - 1];
		System.arraycopy (selectedItems, 0, newSelectedItems, 0, selectionIndex);
		System.arraycopy (
			selectedItems,
			selectionIndex + 1,
			newSelectedItems,
			selectionIndex,
			newSelectedItems.length - selectionIndex);
		selectedItems = newSelectedItems;
	}
	/* root-level items array */
	if (item.depth == 0) {
		int index = item.getIndex ();
		TreeItem[] newItems = new TreeItem [items.length - 1];
		System.arraycopy (items, 0, newItems, 0, index);
		System.arraycopy (items, index + 1, newItems, index, newItems.length - index);
		items = newItems;
	}
	if (item == anchorItem) anchorItem = null;
	if (item == insertMarkItem) insertMarkItem = null;
	if (item == lastClickedItem) lastClickedItem = null;
	/*
	 * If this was the last item and the receiver has focus then its boundary
	 * focus ring must be redrawn.
	 */
	if (availableItemsCount == 0 && isFocusControl ()) {
		redraw ();
		return;
	}
}
Image getArrowDownImage () {
	return (Image) display.getData (ID_ARROWDOWN);
}
Image getArrowUpImage () {
	return (Image) display.getData (ID_ARROWUP);
}
int getCellPadding () {
	return MARGIN_CELL + WIDTH_CELL_HIGHLIGHT; 
}
Image getCheckmarkImage () {
	return (Image) display.getData (ID_CHECKMARK);
}
public Control[] getChildren () {
	checkWidget ();
	Control[] controls = _getChildren ();
	if (header == null) return controls;
	Control[] result = new Control [controls.length - 1];
	/* remove the Header from the returned set of children */
	int index = 0;
	for (int i = 0; i < controls.length; i++) {
		 if (controls [i] != header) {
		 	result [index++] = controls [i];
		 }
	}
	return result;
}
Image getCollapsedImage () {
	return (Image) display.getData (ID_COLLAPSED);
}
/**
 * Returns the column at the given, zero-relative index in the
 * receiver. Throws an exception if the index is out of range.
 * Columns are returned in the order that they were created.
 * If no <code>TreeColumn</code>s were created by the programmer,
 * this method will throw <code>ERROR_INVALID_RANGE</code> despite
 * the fact that a single column of data may be visible in the tree.
 * This occurs when the programmer uses the tree like a list, adding
 * items but never creating a column.
 *
 * @param index the index of the column to return
 * @return the column at the given index
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @see Tree#getColumnOrder()
 * @see Tree#setColumnOrder(int[])
 * @see TreeColumn#getMoveable()
 * @see TreeColumn#setMoveable(boolean)
 * @see SWT#Move
 * 
 * @since 3.1
 */
public TreeColumn getColumn (int index) {
	checkWidget ();
	if (!(0 <= index && index < columns.length)) error (SWT.ERROR_INVALID_RANGE);
	return columns [index];
}
/**
 * Returns the number of columns contained in the receiver.
 * If no <code>TreeColumn</code>s were created by the programmer,
 * this value is zero, despite the fact that visually, one column
 * of items may be visible. This occurs when the programmer uses
 * the tree like a list, adding items but never creating a column.
 *
 * @return the number of columns
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @since 3.1
 */
public int getColumnCount () {
	checkWidget ();
	return columns.length;
}
/**
 * Returns an array of zero-relative integers that map
 * the creation order of the receiver's items to the
 * order in which they are currently being displayed.
 * <p>
 * Specifically, the indices of the returned array represent
 * the current visual order of the items, and the contents
 * of the array represent the creation order of the items.
 * </p><p>
 * Note: This is not the actual structure used by the receiver
 * to maintain its list of items, so modifying the array will
 * not affect the receiver. 
 * </p>
 *
 * @return the current visual order of the receiver's items
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @see Tree#setColumnOrder(int[])
 * @see TreeColumn#getMoveable()
 * @see TreeColumn#setMoveable(boolean)
 * @see SWT#Move
 * 
 * @since 3.2
 */
public int[] getColumnOrder () {
	checkWidget ();
	int[] result = new int [columns.length];
	if (orderedColumns != null) {
		for (int i = 0; i < result.length; i++) {
			result [i] = orderedColumns [i].getIndex ();
		}
	} else {
		for (int i = 0; i < columns.length; i++) {
			result [i] = i;
		}
	}
	return result;
}
/**
 * Returns an array of <code>TreeColumn</code>s which are the
 * columns in the receiver. Columns are returned in the order
 * that they were created.  If no <code>TreeColumn</code>s were
 * created by the programmer, the array is empty, despite the fact
 * that visually, one column of items may be visible. This occurs
 * when the programmer uses the tree like a list, adding items but
 * never creating a column.
 * <p>
 * Note: This is not the actual structure used by the receiver
 * to maintain its list of items, so modifying the array will
 * not affect the receiver. 
 * </p>
 *
 * @return the items in the receiver
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @see Tree#getColumnOrder()
 * @see Tree#setColumnOrder(int[])
 * @see TreeColumn#getMoveable()
 * @see TreeColumn#setMoveable(boolean)
 * @see SWT#Move
 * 
 * @since 3.1
 */
public TreeColumn[] getColumns () {
	checkWidget ();
	TreeColumn[] result = new TreeColumn [columns.length];
	System.arraycopy (columns, 0, result, 0, columns.length);
	return result;
}
Color getConnectorColor () {
	return (Color) display.getData (ID_CONNECTOR_COLOR);
}
Image getExpandedImage () {
	return (Image) display.getData (ID_EXPANDED);
}
Image getGrayUncheckedImage () {
	return (Image) display.getData (ID_GRAYUNCHECKED);
}
/**
 * Returns the width in pixels of a grid line.
 *
 * @return the width of a grid line in pixels
 * 
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @since 3.1
 */
public int getGridLineWidth () {
	checkWidget ();
	return 1;
}
/**
 * Returns the height of the receiver's header 
 *
 * @return the height of the header or zero if the header is not visible
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @since 3.1 
 */
public int getHeaderHeight () {
	checkWidget ();
	if (!header.getVisible ()) return 0;
	return header.getSize ().y;
}
int getHeaderPadding () {
	return MARGIN_CELL + WIDTH_HEADER_SHADOW; 
}
/**
 * Returns <code>true</code> if the receiver's header is visible,
 * and <code>false</code> otherwise.
 * <p>
 * If one of the receiver's ancestors is not visible or some
 * other condition makes the receiver not visible, this method
 * may still indicate that it is considered visible even though
 * it may not actually be showing.
 * </p>
 *
 * @return the receiver's header's visibility state
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @since 3.1
 */
public boolean getHeaderVisible () {
	checkWidget ();
	return header.getVisible ();
}
/**
 * Returns the item at the given point in the receiver
 * or null if no such item exists. The point is in the
 * coordinate system of the receiver.
 * <p>
 * The item that is returned represents an item that could be selected by the user.
 * For example, if selection only occurs in items in the first column, then null is 
 * returned if the point is outside of the item. 
 * Note that the SWT.FULL_SELECTION style hint, which specifies the selection policy,
 * determines the extent of the selection.
 * </p>
 *
 * @param point the point used to locate the item
 * @return the item at the given point, or null if the point is not in a selectable item
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the point is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public TreeItem getItem (Point point) {
	checkWidget ();
	if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
	int index = (point.y - getHeaderHeight ()) / itemHeight + topIndex;
	if (!(0 <= index && index < availableItemsCount)) return null;		/* below the last item */
	TreeItem result = availableItems [index];
	if (!result.getHitBounds ().contains (point)) return null;	/* considers the x value */
	return result;
}
/**
 * Returns the item at the given, zero-relative index in the
 * receiver. Throws an exception if the index is out of range.
 *
 * @param index the index of the item to return
 * @return the item at the given index
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @since 3.1
 */
public TreeItem getItem (int index) {
	checkWidget ();
	if (!(0 <= index && index < items.length)) error (SWT.ERROR_INVALID_RANGE);
	return items [index];
}
/**
 * Returns the number of items contained in the receiver
 * that are direct item children of the receiver.  The
 * number that is returned is the number of roots in the
 * tree.
 *
 * @return the number of items
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public int getItemCount () {
	checkWidget ();
	return items.length;
}
/**
 * Returns the height of the area which would be used to
 * display <em>one</em> of the items in the tree.
 *
 * @return the height of one item
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public int getItemHeight () {
	checkWidget ();
	return itemHeight;
}
/**
 * Returns a (possibly empty) array of items contained in the
 * receiver that are direct item children of the receiver.  These
 * are the roots of the tree.
 * <p>
 * Note: This is not the actual structure used by the receiver
 * to maintain its list of items, so modifying the array will
 * not affect the receiver. 
 * </p>
 *
 * @return the items
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public TreeItem[] getItems () {
	checkWidget ();
	TreeItem[] result = new TreeItem [items.length];
	System.arraycopy (items, 0, result, 0, items.length);
	return result;	
}
/*
 * Returns the current y-coordinate that the specified item should have. 
 */
int getItemY (TreeItem item) {
	int index = item.availableIndex;
	if (index == -1) return -1;
	return (index - topIndex) * itemHeight + getHeaderHeight ();
}
/**
 * Returns <code>true</code> if the receiver's lines are visible,
 * and <code>false</code> otherwise.
 * <p>
 * If one of the receiver's ancestors is not visible or some
 * other condition makes the receiver not visible, this method
 * may still indicate that it is considered visible even though
 * it may not actually be showing.
 * </p>
 *
 * @return the visibility state of the lines
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @since 3.1
 */
public boolean getLinesVisible () {
	checkWidget ();
	return linesVisible;
}
TreeColumn[] getOrderedColumns () {
	if (orderedColumns != null) return orderedColumns;
	return columns;
}
/**
 * Returns the receiver's parent item, which must be a
 * <code>TreeItem</code> or null when the receiver is a
 * root.
 *
 * @return the receiver's parent item
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public TreeItem getParentItem () {
	checkWidget ();
	return null;
}
/**
 * Returns an array of <code>TreeItem</code>s that are currently
 * selected in the receiver. The order of the items is unspecified.
 * An empty array indicates that no items are selected. 
 * <p>
 * Note: This is not the actual structure used by the receiver
 * to maintain its selection, so modifying the array will
 * not affect the receiver. 
 * </p>
 * @return an array representing the selection
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public TreeItem[] getSelection () {
	checkWidget ();
	int count = selectedItems.length;
	TreeItem[] result = new TreeItem [count];
	if (count > 0) {
		if (count == 1) {
			System.arraycopy (selectedItems, 0, result, 0, count);
		} else {
			getSelection (result, items, 0);
		}
	}
	return result;
}
int getSelection (TreeItem[] result, TreeItem[] items, int index) {
	for (int i = 0; i < items.length; i++) {
		TreeItem item = items [i];
		if (item.isSelected ()) result [index++] = item;
		if (index == result.length) break;
		index = getSelection (result, items [i].items, index);
		if (index == result.length) break;
	}
	return index;
}
/**
 * Returns the number of selected items contained in the receiver.
 *
 * @return the number of selected items
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public int getSelectionCount () {
	checkWidget ();
	return selectedItems.length;
}
/*
 * Returns the index of the argument in the receiver's array of currently-
 * selected items, or -1 if the item is not currently selected.
 */
int getSelectionIndex (TreeItem item) {
	for (int i = 0; i < selectedItems.length; i++) {
		if (selectedItems [i] == item) return i;
	}
	return -1;
}
/**
 * Returns the column which shows the sort indicator for
 * the receiver. The value may be null if no column shows
 * the sort indicator.
 *
 * @return the sort indicator 
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @see #setSortColumn(TreeColumn)
 * 
 * @since 3.2
 */
public TreeColumn getSortColumn () {
	checkWidget ();
	return sortColumn;
}
/**
 * Returns the direction of the sort indicator for the receiver. 
 * The value will be one of <code>UP</code>, <code>DOWN</code> 
 * or <code>NONE</code>.
 *
 * @return the sort direction
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @see #setSortDirection(int)
 * 
 * @since 3.2
 */
public int getSortDirection () {
	checkWidget ();
	return sortDirection;
}
/**
 * Returns the item which is currently at the top of the receiver.
 * This item can change when items are expanded, collapsed, scrolled
 * or new items are added or removed.
 *
 * @return the item at the top of the receiver 
 * 
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @since 2.1
 */
public TreeItem getTopItem () {
	checkWidget ();
	if (availableItemsCount == 0) return null;
	return availableItems [topIndex];
}
Image getUncheckedImage () {
	return (Image) display.getData (ID_UNCHECKED);
}
void handleEvents (Event event) {
	switch (event.type) {
		case SWT.Paint:
			if (event.widget == header) {
				headerOnPaint (event);
			} else {
				onPaint (event);
			}
			break;
		case SWT.MenuDetect: {
			notifyListeners (SWT.MenuDetect, event);
			break;
			}
		case SWT.MouseDown:
			if (event.widget == header) {
				headerOnMouseDown (event);
			} else {
				onMouseDown (event);
			}
			break;
		case SWT.MouseUp:
			if (event.widget == header) {
				headerOnMouseUp (event);
			} else {
				onMouseUp (event);
			}
			break;
		case SWT.MouseHover:
			headerOnMouseHover (event); break;
		case SWT.MouseMove:
			headerOnMouseMove (event); break;
		case SWT.MouseDoubleClick:
			if (event.widget == header) {
				headerOnMouseDoubleClick (event);
			} else {
				onMouseDoubleClick (event);
			}
			break;
		case SWT.MouseExit:
			headerOnMouseExit (); break;
		case SWT.Dispose:
			onDispose (event); break;		
		case SWT.KeyDown:
			onKeyDown (event); break;
		case SWT.Resize:
			onResize (event); break;
		case SWT.Selection:
			if (event.widget == getHorizontalBar ()) {
				onScrollHorizontal (event);
			}
			if (event.widget == getVerticalBar ()) {
				onScrollVertical (event);
			}
			break;
		case SWT.FocusOut:
			onFocusOut (); break;
		case SWT.FocusIn:
			onFocusIn (); break;	
		case SWT.Traverse:
			switch (event.detail) {
				case SWT.TRAVERSE_ESCAPE:
				case SWT.TRAVERSE_RETURN:
				case SWT.TRAVERSE_TAB_NEXT:
				case SWT.TRAVERSE_TAB_PREVIOUS:
				case SWT.TRAVERSE_PAGE_NEXT:
				case SWT.TRAVERSE_PAGE_PREVIOUS:
					event.doit = true;
					break;
			}
			break;			
	}
}
String headerGetToolTip (int x) {
	if (resizeColumn != null) return null;
	int orderedIndex = computeColumnIntersect (x, 0);
	if (orderedIndex == -1) return null;
	TreeColumn[] orderedColumns = getOrderedColumns ();
	TreeColumn column = orderedColumns [orderedIndex];
	if (column.toolTipText == null) return null;

	/* no tooltip should appear if the hover is at a column resize opportunity */
	int columnX = column.getX ();
	if (orderedIndex > 0 && orderedColumns [orderedIndex - 1].resizable) {
		/* left column bound is resizable */
		if (x - columnX <= TOLLERANCE_COLUMNRESIZE) return null;
	}
	if (column.resizable) {
		/* right column bound is resizable */
		int columnRightX = columnX + column.width;
		if (columnRightX - x <= TOLLERANCE_COLUMNRESIZE) return null;
	}
	return removeMnemonics (column.toolTipText);
}
void headerHideToolTip() {
	if (toolTipShell == null) return;
	for (int i = 0; i < toolTipEvents.length; i++) {
		header.removeListener (toolTipEvents [i], toolTipListener);
	}
	toolTipShell.dispose ();
	toolTipShell = null;
	toolTipLabel = null;
}
void headerOnMouseDoubleClick (Event event) {
	if (!isFocusControl ()) setFocus ();
	if (columns.length == 0) return;
	TreeColumn[] orderedColumns = getOrderedColumns ();
	int x = -horizontalOffset;
	for (int i = 0; i < orderedColumns.length; i++) {
		TreeColumn column = orderedColumns [i];
		x += column.width;
		if (event.x < x) {
			/* found the clicked column */
			TreeColumn packColumn = null;
			if (x - event.x <= TOLLERANCE_COLUMNRESIZE) {
				/* clicked on column bound for this column */
				packColumn = column;
			} else {
				if (i > 0 && event.x - column.getX () <= TOLLERANCE_COLUMNRESIZE) {
					/* clicked on column bound that applies to previous column */
					packColumn = orderedColumns [i - 1];
				}
			}
			if (packColumn != null) {
				packColumn.pack ();
				resizeColumn = null;
				if (Math.abs (packColumn.getX () + packColumn.width - event.x) > TOLLERANCE_COLUMNRESIZE) {
					/* column separator has relocated away from pointer location */
					setCursor (null);
				}
				return;
			}
			/* did not click on column separator, so just fire column event */
			Event newEvent = new Event ();
			newEvent.widget = column;
			column.postEvent (SWT.DefaultSelection, newEvent);
			return;
		}
	}
}
void headerOnMouseDown (Event event) {
	if (event.button != 1) return;
	TreeColumn[] orderedColumns = getOrderedColumns ();
	int x = -horizontalOffset;
	for (int i = 0; i < orderedColumns.length; i++) {
		TreeColumn column = orderedColumns [i]; 
		x += column.width;
		/* if close to a resizable column separator line then begin column resize */
		if (column.resizable && Math.abs (x - event.x) <= TOLLERANCE_COLUMNRESIZE) {
			resizeColumn = column;
			resizeColumnX = x;
			return;
		}
		/*
		 * If within column but not near separator line then start column drag
		 * if column is moveable, or just fire column Selection otherwise.
		 */
		if (event.x < x) {
			if (column.moveable) {
				/* open tracker on the dragged column's header cell */
				int columnX = column.getX ();
				int pointerOffset = event.x - columnX;
				headerHideToolTip ();
				Tracker tracker = new Tracker (this, SWT.NONE);
				tracker.setRectangles (new Rectangle[] {
					new Rectangle (columnX, 0, column.width, getHeaderHeight ())
				});
				if (!tracker.open ()) return;	/* cancelled */
				/* determine which column was dragged onto */
				Rectangle result = tracker.getRectangles () [0];
				int pointerX = result.x + pointerOffset;
				if (pointerX < 0) return;	/* dragged too far left */
				x = -horizontalOffset;
				for (int destIndex = 0; destIndex < orderedColumns.length; destIndex++) {
					TreeColumn destColumn = orderedColumns [destIndex];
					x += destColumn.width;
					if (pointerX < x) {
						int oldIndex = column.getOrderIndex ();
						if (destIndex == oldIndex) {	/* dragged onto self */
							Event newEvent = new Event ();
							newEvent.widget = column;
							column.postEvent (SWT.Selection, newEvent);
							return;
						}
						int leftmostIndex = Math.min (destIndex, oldIndex);
						int[] oldOrder = getColumnOrder ();
						int[] newOrder = new int [oldOrder.length];
						System.arraycopy (oldOrder, 0, newOrder, 0, leftmostIndex);
						if (leftmostIndex == oldIndex) {
							/* column moving to the right */
							System.arraycopy (oldOrder, oldIndex + 1, newOrder, oldIndex, destIndex - oldIndex);
						} else {
							/* column moving to the left */
							System.arraycopy (oldOrder, destIndex, newOrder, destIndex + 1, oldIndex - destIndex);
						}
						newOrder [destIndex] = oldOrder [oldIndex];
						int rightmostIndex = Math.max (destIndex, oldIndex);
						System.arraycopy (
							oldOrder,
							rightmostIndex + 1,
							newOrder,
							rightmostIndex + 1,
							newOrder.length - rightmostIndex - 1);
						setColumnOrder (newOrder);
						return;
					}
				}
				return;		/* dragged too far right */
			}
			/* column is not moveable */
			Event newEvent = new Event ();
			newEvent.widget = column;
			column.postEvent (SWT.Selection, newEvent);
			return;
		}
	}
}
void headerOnMouseExit () {
	if (resizeColumn != null) return;
	setCursor (null);	/* ensure that a column resize cursor does not escape */
}
void headerOnMouseHover (Event event) {
	headerShowToolTip (event.x);
}
void headerOnMouseMove (Event event) {
	if (resizeColumn == null) {
		/* not currently resizing a column */
		for (int i = 0; i < columns.length; i++) {
			TreeColumn column = columns [i]; 
			int x = column.getX () + column.width;
			if (Math.abs (x - event.x) <= TOLLERANCE_COLUMNRESIZE) {
				if (column.resizable) {
					setCursor (display.getSystemCursor (SWT.CURSOR_SIZEWE));
				} else {
					setCursor (null);
				}
				return;
			}
		}
		setCursor (null);
		return;
	}
	
	/* currently resizing a column */
	
	/* don't allow the resize x to move left of the column's x position */
	if (event.x <= resizeColumn.getX ()) return;

	/* redraw the resizing line at its new location */
	GC gc = new GC (this);
	gc.setForeground (display.getSystemColor (SWT.COLOR_BLACK));
	int lineHeight = clientArea.height;
	redraw (resizeColumnX - 1, 0, 1, lineHeight, false);
	resizeColumnX = event.x;
	gc.drawLine (resizeColumnX - 1, 0, resizeColumnX - 1, lineHeight);
	gc.dispose ();
}
void headerOnMouseUp (Event event) {
	if (resizeColumn == null) return;	/* not resizing a column */

	/* remove the resize line */
	GC gc = new GC (this);
	redraw (resizeColumnX - 1, 0, 1, clientArea.height, false);
	gc.dispose ();

	int newWidth = resizeColumnX - resizeColumn.getX ();
	if (newWidth != resizeColumn.width) {
		setCursor (null);
		updateColumnWidth (resizeColumn, newWidth);
	}
	resizeColumnX = -1;
	resizeColumn = null;
}
void headerOnPaint (Event event) {
	TreeColumn[] orderedColumns = getOrderedColumns ();
	int numColumns = orderedColumns.length;
	GC gc = event.gc;
	Rectangle clipping = gc.getClipping ();
	int startColumn = -1, endColumn = -1;
	if (numColumns > 0) {
		startColumn = computeColumnIntersect (clipping.x, 0);
		if (startColumn != -1) {	/* the clip x is within a column's bounds */
			endColumn = computeColumnIntersect (clipping.x + clipping.width, startColumn);
			if (endColumn == -1) endColumn = numColumns - 1;
		}
	} else {
		startColumn = endColumn = 0;
	}

	/* paint the column header shadow that spans the full header width */
	Point headerSize = header.getSize ();
	headerPaintHShadows (gc, 0, 0, headerSize.x, headerSize.y);

	/* if all damage is to the right of the last column then finished */
	if (startColumn == -1) return;
	
	/* paint each of the column headers */
	if (numColumns == 0) return;	/* no headers to paint */
	for (int i = startColumn; i <= endColumn; i++) {
		headerPaintVShadows (gc, orderedColumns [i].getX (), 0, orderedColumns [i].width, headerSize.y);
		orderedColumns [i].paint (gc);
	}
}
void headerPaintHShadows (GC gc, int x, int y, int width, int height) {
	gc.setClipping (x, y, width, height);
	int endX = x + width;
	gc.setForeground (display.getSystemColor (SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW));
	gc.drawLine (x, y, endX, y);					/* highlight shadow */
	gc.setForeground (display.getSystemColor (SWT.COLOR_WIDGET_NORMAL_SHADOW));
	gc.drawLine (x, height - 2, endX, height - 2);	/* lowlight shadow */
	gc.setForeground (display.getSystemColor (SWT.COLOR_WIDGET_DARK_SHADOW));
	gc.drawLine (x, height - 1, endX, height - 1);	/* outer shadow */
}
void headerPaintVShadows (GC gc, int x, int y, int width, int height) {
	gc.setClipping (x, y, width, height);
	int endX = x + width;
	gc.setForeground (display.getSystemColor (SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW));
	gc.drawLine (x, y, x, y + height - 1);					/* highlight shadow */
	gc.setForeground (display.getSystemColor (SWT.COLOR_WIDGET_NORMAL_SHADOW));
	gc.drawLine (endX - 2, y + 1, endX - 2, height - 2);	/* light inner shadow */
	gc.setForeground (display.getSystemColor (SWT.COLOR_WIDGET_DARK_SHADOW));
	gc.drawLine (endX - 1, y, endX - 1, height - 1);		/* dark outer shadow */
}
void headerShowToolTip (int x) {
	String tooltip = headerGetToolTip (x);
	if (tooltip == null || tooltip.length () == 0) return;

	if (toolTipShell == null) {
		toolTipShell = new Shell (getShell (), SWT.ON_TOP | SWT.TOOL);
		toolTipLabel = new Label (toolTipShell, SWT.CENTER);
		Display display = toolTipShell.getDisplay ();
		toolTipLabel.setForeground (display.getSystemColor (SWT.COLOR_INFO_FOREGROUND));
		toolTipLabel.setBackground (display.getSystemColor (SWT.COLOR_INFO_BACKGROUND));
		for (int i = 0; i < toolTipEvents.length; i++) {
			header.addListener (toolTipEvents [i], toolTipListener);
		}
	}
	if (headerUpdateToolTip (x)) {
		toolTipShell.setVisible (true);
	} else {
		headerHideToolTip ();
	}
}
boolean headerUpdateToolTip (int x) {
	String tooltip = headerGetToolTip (x);
	if (tooltip == null || tooltip.length () == 0) return false;
	if (tooltip.equals (toolTipLabel.getText ())) return true;

	toolTipLabel.setText (tooltip);
	TreeColumn column = getOrderedColumns () [computeColumnIntersect (x, 0)];
	toolTipShell.setData (new Integer (column.getIndex ()));
	Point labelSize = toolTipLabel.computeSize (SWT.DEFAULT, SWT.DEFAULT, true);
	labelSize.x += 2; labelSize.y += 2;
	toolTipLabel.setSize (labelSize);
	toolTipShell.pack ();
	/*
	 * On some platforms, there is a minimum size for a shell  
	 * which may be greater than the label size.
	 * To avoid having the background of the tip shell showing
	 * around the label, force the label to fill the entire client area.
	 */
	Rectangle area = toolTipShell.getClientArea ();
	toolTipLabel.setSize (area.width, area.height);

	/* Position the tooltip and ensure it's not located off the screen */
	Point cursorLocation = getDisplay ().getCursorLocation ();
	int cursorHeight = 21;	/* assuming cursor is 21x21 */ 
	Point size = toolTipShell.getSize ();
	Rectangle rect = getMonitor ().getBounds ();
	Point pt = new Point (cursorLocation.x, cursorLocation.y + cursorHeight + 2);
	pt.x = Math.max (pt.x, rect.x);
	if (pt.x + size.x > rect.x + rect.width) pt.x = rect.x + rect.width - size.x;
	if (pt.y + size.y > rect.y + rect.height) pt.y = cursorLocation.y - 2 - size.y;
	toolTipShell.setLocation (pt);
	return true;
}
/**
 * Searches the receiver's list starting at the first column
 * (index 0) until a column is found that is equal to the 
 * argument, and returns the index of that column. If no column
 * is found, returns -1.
 *
 * @param column the search column
 * @return the index of the column
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the column is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @since 3.1
 */
public int indexOf (TreeColumn column) {
	checkWidget ();
	if (column == null) error (SWT.ERROR_NULL_ARGUMENT);
	if (column.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
	return column.getIndex ();
}
/**
 * Searches the receiver's list starting at the first item
 * (index 0) until an item is found that is equal to the 
 * argument, and returns the index of that item. If no item
 * is found, returns -1.
 *
 * @param item the search item
 * @return the index of the item
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the item is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @since 3.1
 */
public int indexOf (TreeItem item) {
	checkWidget ();
	if (item == null) error (SWT.ERROR_NULL_ARGUMENT);
	if (item.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
	if (item.parentItem != null || item.parent != this) return -1;
	return item.getIndex ();
}
static void initImages (final Display display) {
	PaletteData fourBit = new PaletteData (new RGB[] {
		new RGB (0, 0, 0), new RGB (128, 0, 0), new RGB (0, 128, 0), new RGB (128, 128, 0),
		new RGB (0, 0, 128), new RGB (128, 0, 128), new RGB (0, 128, 128), new RGB (128, 128, 128),
		new RGB (192, 192, 192), new RGB (255, 0, 0), new RGB (0, 255, 0), new RGB (255, 255, 0),
		new RGB (0, 0, 255), new RGB (255, 0, 255), new RGB (0, 255, 255), new RGB (255, 255, 255)});

	if (display.getData (ID_EXPANDED) == null) {
		ImageData expanded = new ImageData (
			9, 9, 4, 										/* width, height, depth */
			fourBit, 4,
			new byte[] {
				119, 119, 119, 119, 112, 0, 0, 0,
				127, -1, -1, -1, 112, 0, 0, 0,
				127, -1, -1, -1, 112, 0, 0, 0,
				127, -1, -1, -1, 112, 0, 0, 0,
				127, 0, 0, 15, 112, 0, 0, 0,
				127, -1, -1, -1, 112, 0, 0, 0,
				127, -1, -1, -1, 112, 0, 0, 0,
				127, -1, -1, -1, 112, 0, 0, 0,
				119, 119, 119, 119, 112, 0, 0, 0});
		expanded.transparentPixel = 15;		/* use white for transparency */
		display.setData (ID_EXPANDED, new Image (display, expanded));
	}

	if (display.getData (ID_COLLAPSED) == null) {
		ImageData collapsed = new ImageData (
			9, 9, 4, 										/* width, height, depth */
			fourBit, 4,
			new byte[] {
				119, 119, 119, 119, 112, 0, 0, 0,
				127, -1, -1, -1, 112, 0, 0, 0,
				127, -1, 15, -1, 112, 0, 0, 0,
				127, -1, 15, -1, 112, 0, 0, 0,
				127, 0, 0, 15, 112, 0, 0, 0,
				127, -1, 15, -1, 112, 0, 0, 0,
				127, -1, 15, -1, 112, 0, 0, 0,
				127, -1, -1, -1, 112, 0, 0, 0,
				119, 119, 119, 119, 112, 0, 0, 0});
		collapsed.transparentPixel = 15;	/* use white for transparency */
		display.setData (ID_COLLAPSED, new Image (display, collapsed));
	}

	PaletteData arrowPalette = new PaletteData (new RGB[] {
		new RGB (0, 0, 0), new RGB (255, 255, 255)});
	if (display.getData (ID_ARROWDOWN) == null) {
		ImageData arrowDown = new ImageData (
			7, 4, 1,
			arrowPalette, 1,
			new byte[] {0x00, (byte)0x83, (byte)0xC7, (byte)0xEF});
		arrowDown.transparentPixel = 0x1;	/* use white for transparency */
		display.setData (ID_ARROWDOWN, new Image (display, arrowDown));
	}
	if (display.getData (ID_ARROWUP) == null) {
		ImageData arrowUp = new ImageData (
			7, 4, 1,
			arrowPalette, 1,
			new byte[] {(byte)0xEF, (byte)0xC7, (byte)0x83, 0x00});
		arrowUp.transparentPixel = 0x1;		/* use white for transparency */
		display.setData (ID_ARROWUP, new Image (display, arrowUp));
	}

	PaletteData checkMarkPalette = new PaletteData (
		new RGB[] {new RGB (0, 0, 0), new RGB (252, 3, 251)});
	byte[] checkbox = new byte[] {0, 0, 127, -64, 127, -64, 127, -64, 127, -64, 127, -64, 127, -64, 127, -64, 127, -64, 127, -64, 0, 0};
	ImageData checkmark = new ImageData (7, 7, 1, checkMarkPalette, 1, new byte[] {-4, -8, 112, 34, 6, -114, -34});
	checkmark.transparentPixel = 1;
	if (display.getData (ID_CHECKMARK) == null) {
		display.setData (ID_CHECKMARK, new Image (display, checkmark));
	}
	
	if (display.getData (ID_UNCHECKED) == null) {
		PaletteData uncheckedPalette = new PaletteData (	
			new RGB[] {new RGB (128, 128, 128), new RGB (255, 255, 255)});
		ImageData unchecked = new ImageData (11, 11, 1, uncheckedPalette, 2, checkbox);
		display.setData (ID_UNCHECKED, new Image (display, unchecked));
	}
	
	if (display.getData (ID_GRAYUNCHECKED) == null) {
		PaletteData grayUncheckedPalette = new PaletteData (	
			new RGB[] {new RGB (128, 128, 128), new RGB (192, 192, 192)});
		ImageData grayUnchecked = new ImageData (11, 11, 1, grayUncheckedPalette, 2, checkbox);
		display.setData (ID_GRAYUNCHECKED, new Image (display, grayUnchecked));
	}
	
	if (display.getData (ID_CONNECTOR_COLOR) == null) {
		display.setData (ID_CONNECTOR_COLOR, new Color (display, 170, 170, 170));
	}

	display.disposeExec (new Runnable () {
		public void run() {
			Image expanded = (Image) display.getData (ID_EXPANDED);
			if (expanded != null) expanded.dispose ();
			Image collapsed = (Image) display.getData (ID_COLLAPSED);
			if (collapsed != null) collapsed.dispose ();
			Color connectorColor = (Color) display.getData (ID_CONNECTOR_COLOR);
			if (connectorColor != null) connectorColor.dispose ();
			Image unchecked = (Image) display.getData (ID_UNCHECKED);
			if (unchecked != null) unchecked.dispose ();
			Image grayUnchecked = (Image) display.getData (ID_GRAYUNCHECKED);
			if (grayUnchecked != null) grayUnchecked.dispose ();
			Image checkmark = (Image) display.getData (ID_CHECKMARK);
			if (checkmark != null) checkmark.dispose ();
			Image arrowDown = (Image) display.getData (ID_ARROWDOWN);
			if (arrowDown != null) arrowDown.dispose ();
			Image arrowUp = (Image) display.getData (ID_ARROWUP);
			if (arrowUp != null) arrowUp.dispose ();

			display.setData (ID_EXPANDED, null);
			display.setData (ID_COLLAPSED, null);
			display.setData (ID_CONNECTOR_COLOR, null);
			display.setData (ID_UNCHECKED, null);
			display.setData (ID_GRAYUNCHECKED, null);
			display.setData (ID_CHECKMARK, null);
			display.setData (ID_ARROWDOWN, null);
			display.setData (ID_ARROWUP, null);
		}
	});
}
/*
 * Important: Assumes that item just became available (ie.- was either created
 * or the parent item was expanded) and the parent is available.
 */
void makeAvailable (TreeItem item) {
	int parentItemCount = item.parentItem.items.length; 
	int index = 0;
	if (parentItemCount == 1) {		/* this is the only child of parentItem */
		index = item.parentItem.availableIndex + 1;
	} else {
		/* determine this item's index in its parent */
		int itemIndex = 0;
		TreeItem[] items = item.parentItem.items;
		for (int i = 0; i < items.length; i++) {
			if (items [i] == item) {
				itemIndex = i;
				break;
			}
		}
		if (itemIndex != parentItemCount - 1) {	/* this is not the last child */
			index = items [itemIndex + 1].availableIndex;
		} else {	/* this is the last child */
			TreeItem previousItem = items [itemIndex - 1];
			index = previousItem.availableIndex + previousItem.computeAvailableDescendentCount ();
		}
	}

	if (availableItemsCount == availableItems.length) {
		int grow = drawCount <= 0 ? 4 : Math.max (4, availableItems.length * 3 / 2);
		TreeItem[] newAvailableItems = new TreeItem [availableItems.length + grow];
		System.arraycopy (availableItems, 0, newAvailableItems, 0, availableItems.length);
		availableItems = newAvailableItems;
	}
	if (index != availableItemsCount) {
		/* new item is not at end of list, so shift other items right to create space for it */
		System.arraycopy (availableItems, index, availableItems, index + 1, availableItemsCount - index);
	}
	availableItems [index] = item;
	availableItemsCount++;

	/* update availableIndex as needed */
	for (int i = index; i < availableItemsCount; i++) {
		availableItems [i].availableIndex = i;
	}
}

/*
 * Important: Assumes that item is available and its descendents have just become
 * available (ie.- they were either created or the item was expanded).
 */
void makeDescendentsAvailable (TreeItem item, TreeItem[] descendents) {
	int itemAvailableIndex = item.availableIndex;
	TreeItem[] newAvailableItems = new TreeItem [availableItemsCount + descendents.length - 1];
	
	System.arraycopy (availableItems, 0, newAvailableItems, 0, itemAvailableIndex);
	System.arraycopy (descendents, 0, newAvailableItems, itemAvailableIndex, descendents.length);
	int startIndex = itemAvailableIndex + 1;
	System.arraycopy (
		availableItems,
		startIndex,
		newAvailableItems,
		itemAvailableIndex + descendents.length,
		availableItemsCount - startIndex);
	availableItems = newAvailableItems;
	availableItemsCount = availableItems.length;
	
	/* update availableIndex as needed */
	for (int i = itemAvailableIndex; i < availableItemsCount; i++) {
		availableItems [i].availableIndex = i;
	}
}

/*
 * Important: Assumes that item is available and its descendents have just become
 * unavailable (ie.- they were either disposed or the item was collapsed).
 */
void makeDescendentsUnavailable (TreeItem item, TreeItem[] descendents) {
	int descendentsLength = descendents.length;
	TreeItem[] newAvailableItems = new TreeItem [availableItemsCount - descendentsLength + 1];
	
	System.arraycopy (availableItems, 0, newAvailableItems, 0, item.availableIndex + 1);
	int startIndex = item.availableIndex + descendentsLength;
	System.arraycopy (
		availableItems,
		startIndex,
		newAvailableItems,
		item.availableIndex + 1,
		availableItemsCount - startIndex);
	availableItems = newAvailableItems;
	availableItemsCount = availableItems.length;
	
	/* update availableIndexes */
	for (int i = 1; i < descendents.length; i++) {
		/* skip the first descendent since this is the item being collapsed */
		descendents [i].availableIndex = -1;
	}
	for (int i = item.availableIndex; i < availableItemsCount; i++) {
		availableItems [i].availableIndex = i;
	}
	
	/* remove the selection from all descendents */
	for (int i = selectedItems.length - 1; i >= 0; i--) {
		if (selectedItems [i] != item && selectedItems [i].hasAncestor (item)) {
			removeSelectedItem (i);
		}
	}
	
	/* if the anchorItem is being hidden then clear it */
	if (anchorItem != null && anchorItem != item && anchorItem.hasAncestor (item)) {
		anchorItem = null;
	}
}
void onArrowDown (int stateMask) {
	if ((stateMask & (SWT.SHIFT | SWT.CTRL)) == 0) {
		/* Down Arrow with no modifiers */
		int newFocusIndex = focusItem.availableIndex + 1;
		if (newFocusIndex == availableItemsCount) return; 	/* at bottom */
		selectItem (availableItems [newFocusIndex], false);
		setFocusItem (availableItems [newFocusIndex], true);
		redrawItem (newFocusIndex, true);
		showItem (availableItems [newFocusIndex]);
		Event newEvent = new Event ();
		newEvent.item = availableItems [newFocusIndex];
		postEvent (SWT.Selection, newEvent);
		return;
	}
	if ((style & SWT.SINGLE) != 0) {
		if ((stateMask & SWT.CTRL) != 0) {
			/* CTRL+Down Arrow, CTRL+Shift+Down Arrow */
			int visibleItemCount = (clientArea.height - getHeaderHeight ()) / itemHeight;
			if (availableItemsCount <= topIndex + visibleItemCount) return;	/* at bottom */
			update ();
			topIndex++;
			ScrollBar vBar = getVerticalBar ();
			if (vBar != null) vBar.setSelection (topIndex);
			GC gc = new GC (this);
			gc.copyArea (
				0, 0,
				clientArea.width, clientArea.height,
				0, -itemHeight);
			gc.dispose ();
			return;
		}
		/* Shift+Down Arrow */
		int newFocusIndex = focusItem.availableIndex + 1;
		if (newFocusIndex == availableItemsCount) return; 	/* at bottom */
		selectItem (availableItems [newFocusIndex], false);
		setFocusItem (availableItems [newFocusIndex], true);
		redrawItem (newFocusIndex, true);
		showItem (availableItems [newFocusIndex]);
		Event newEvent = new Event ();
		newEvent.item = availableItems [newFocusIndex];
		postEvent (SWT.Selection, newEvent);
		return;
	}
	/* SWT.MULTI */
	if ((stateMask & SWT.CTRL) != 0) {
		if ((stateMask & SWT.SHIFT) != 0) {
			/* CTRL+Shift+Down Arrow */
			int visibleItemCount = (clientArea.height - getHeaderHeight ()) / itemHeight;
			if (availableItemsCount <= topIndex + visibleItemCount) return;	/* at bottom */
			update ();
			topIndex++;
			ScrollBar vBar = getVerticalBar ();
			if (vBar != null) vBar.setSelection (topIndex);
			GC gc = new GC (this);
			gc.copyArea (
				0, 0,
				clientArea.width, clientArea.height,
				0, -itemHeight);
			gc.dispose ();
			return;
		}
		/* CTRL+Down Arrow */
		int focusIndex = focusItem.availableIndex; 
		if (focusIndex == availableItemsCount - 1) return;	/* at bottom */
		TreeItem newFocusItem = availableItems [focusIndex + 1];
		setFocusItem (newFocusItem, true);
		redrawItem (newFocusItem.availableIndex, true);
		showItem (newFocusItem);
		return;
	}
	/* Shift+Down Arrow */
	int newFocusIndex = focusItem.availableIndex + 1;
	if (newFocusIndex == availableItemsCount) return; 	/* at bottom */
	if (anchorItem == null) anchorItem = focusItem;
	if (focusItem.availableIndex < anchorItem.availableIndex) {
		deselectItem (focusItem);
		redrawItem (focusItem.availableIndex, true);
	}
	selectItem (availableItems [newFocusIndex], true);
	setFocusItem (availableItems [newFocusIndex], true);
	redrawItem (newFocusIndex, true);
	showItem (availableItems [newFocusIndex]);
	Event newEvent = new Event ();
	newEvent.item = availableItems [newFocusIndex];
	postEvent (SWT.Selection, newEvent);
}
void onArrowLeft (int stateMask) {
	if ((stateMask & SWT.CTRL) != 0) {
		/* CTRL+Left Arrow, CTRL+Shift+Left Arrow */
		if (horizontalOffset == 0) return;
		int newSelection = Math.max (0, horizontalOffset - SIZE_HORIZONTALSCROLL);
		update ();
		GC gc = new GC (this);
		gc.copyArea (
			0, 0,
			clientArea.width, clientArea.height,
			horizontalOffset - newSelection, 0);
		gc.dispose ();
		if (header.getVisible ()) {
			header.update ();
			Rectangle headerClientArea = header.getClientArea ();
			gc = new GC (header);
			gc.copyArea (
				0, 0,
				headerClientArea.width, headerClientArea.height,
				horizontalOffset - newSelection, 0);
			gc.dispose();
		}
		horizontalOffset = newSelection;
		ScrollBar hBar = getHorizontalBar (); 
		if (hBar != null) hBar.setSelection (horizontalOffset);
		return;
	}
	/* Left Arrow with no modifiers, Shift+Left Arrow */
	if (focusItem.expanded) {
		focusItem.setExpanded (false);
		Event newEvent = new Event ();
		newEvent.item = focusItem;
		sendEvent (SWT.Collapse, newEvent);
		return;
	}
	TreeItem parentItem = focusItem.parentItem;
	if (parentItem == null) return;
	
	selectItem (parentItem, false);
	setFocusItem (parentItem, true);
	redrawItem (parentItem.availableIndex, true);
	showItem (parentItem);
	Event newEvent = new Event ();
	newEvent.item = parentItem;
	postEvent (SWT.Selection, newEvent);
}
void onArrowRight (int stateMask) {
	if ((stateMask & SWT.CTRL) != 0) {
		/* CTRL+Right Arrow, CTRL+Shift+Right Arrow */
		ScrollBar hBar = getHorizontalBar ();
		if (hBar != null) {
			int maximum = hBar.getMaximum ();
			int clientWidth = clientArea.width;
			if ((horizontalOffset + clientWidth) == maximum) return;
			if (maximum <= clientWidth) return;
			int newSelection = Math.min (horizontalOffset + SIZE_HORIZONTALSCROLL, maximum - clientWidth);
			update ();
			GC gc = new GC (this);
			gc.copyArea (
				0, 0,
				clientArea.width, clientArea.height,
				horizontalOffset - newSelection, 0);
			gc.dispose ();
			if (header.getVisible ()) {
				Rectangle headerClientArea = header.getClientArea ();
				header.update ();
				gc = new GC (header);
				gc.copyArea (
					0, 0,
					headerClientArea.width, headerClientArea.height,
					horizontalOffset - newSelection, 0);
				gc.dispose();
			}
			horizontalOffset = newSelection;
			hBar.setSelection (horizontalOffset);
		}
		return;
	}
	/* Right Arrow with no modifiers, Shift+Right Arrow */
	TreeItem[] children = focusItem.items;
	if (children.length == 0) return;
	if (!focusItem.expanded) {
		focusItem.setExpanded (true);
		Event newEvent = new Event ();
		newEvent.item = focusItem;
		inExpand = true;
		sendEvent (SWT.Expand, newEvent);
		inExpand = false;
		if (isDisposed ()) return;
		if (focusItem.items.length == 0) {
			focusItem.expanded = false;
		}
		return;
	}
	selectItem (children [0], false);
	setFocusItem (children [0], true);
	redrawItem (children [0].availableIndex, true);
	showItem (children [0]);
	Event newEvent = new Event ();
	newEvent.item = children [0];
	postEvent (SWT.Selection, newEvent);
}
void onArrowUp (int stateMask) {
	if ((stateMask & (SWT.SHIFT | SWT.CTRL)) == 0) {
		/* Up Arrow with no modifiers */
		int newFocusIndex = focusItem.availableIndex - 1;
		if (newFocusIndex < 0) return; 		/* at top */
		TreeItem item = availableItems [newFocusIndex];
		selectItem (item, false);
		setFocusItem (item, true);
		redrawItem (newFocusIndex, true);
		showItem (item);
		Event newEvent = new Event ();
		newEvent.item = item;
		postEvent (SWT.Selection, newEvent);
		return;
	}
	if ((style & SWT.SINGLE) != 0) {
		if ((stateMask & SWT.CTRL) != 0) {
			/* CTRL+Up Arrow, CTRL+Shift+Up Arrow */
			if (topIndex == 0) return;	/* at top */
			update ();
			topIndex--;
			ScrollBar vBar = getVerticalBar ();
			if (vBar != null) vBar.setSelection (topIndex);
			GC gc = new GC (this);
			gc.copyArea (
				0, 0,
				clientArea.width, clientArea.height,
				0, itemHeight);
			gc.dispose ();
			return;
		}
		/* Shift+Up Arrow */
		int newFocusIndex = focusItem.availableIndex - 1;
		if (newFocusIndex < 0) return; 	/* at top */
		TreeItem item = availableItems [newFocusIndex];
		selectItem (item, false);
		setFocusItem (item, true);
		redrawItem (newFocusIndex, true);
		showItem (item);
		Event newEvent = new Event ();
		newEvent.item = item;
		postEvent (SWT.Selection, newEvent);
		return;
	}
	/* SWT.MULTI */
	if ((stateMask & SWT.CTRL) != 0) {
		if ((stateMask & SWT.SHIFT) != 0) {
			/* CTRL+Shift+Up Arrow */
			if (topIndex == 0) return;	/* at top */
			update ();
			topIndex--;
			ScrollBar vBar = getVerticalBar ();
			if (vBar != null) vBar.setSelection (topIndex);
			GC gc = new GC (this);
			gc.copyArea (
				0, 0,
				clientArea.width, clientArea.height,
				0, itemHeight);
			gc.dispose ();
			return;
		}
		/* CTRL+Up Arrow */
		int focusIndex = focusItem.availableIndex; 
		if (focusIndex == 0) return;	/* at top */
		TreeItem newFocusItem = availableItems [focusIndex - 1];
		setFocusItem (newFocusItem, true);
		showItem (newFocusItem);
		redrawItem (newFocusItem.availableIndex, true);
		return;
	}
	/* Shift+Up Arrow */
	int newFocusIndex = focusItem.availableIndex - 1;
	if (newFocusIndex < 0) return; 		/* at top */
	if (anchorItem == null) anchorItem = focusItem;
	if (anchorItem.availableIndex < focusItem.availableIndex) {
		deselectItem (focusItem);
		redrawItem (focusItem.availableIndex, true);
	}
	TreeItem item = availableItems [newFocusIndex];
	selectItem (item, true);
	setFocusItem (item, true);
	redrawItem (newFocusIndex, true);
	showItem (item);
	Event newEvent = new Event ();
	newEvent.item = item;
	postEvent (SWT.Selection, newEvent);
}
void onCR () {
	if (focusItem == null) return;
	Event event = new Event ();
	event.item = focusItem;
	postEvent (SWT.DefaultSelection, event);
}
void onDispose (Event event) {
	if (isDisposed ()) return;
	if (ignoreDispose) return;
	ignoreDispose = true;
	notifyListeners(SWT.Dispose, event);
	event.type = SWT.None;
	for (int i = 0; i < items.length; i++) {
		items [i].dispose (false);
	}
	for (int i = 0; i < columns.length; i++) {
		columns [i].dispose (false);
	}
	if (toolTipShell != null) {
		toolTipShell.dispose ();
		toolTipShell = null;
		toolTipLabel = null;
	}
	toolTipListener = null;
	topIndex = availableItemsCount = horizontalOffset = 0;
	availableItems = items = selectedItems = null;
	columns = orderedColumns = null;
	focusItem = anchorItem = insertMarkItem = lastClickedItem = null;
	lastSelectionEvent = null;
	header = null;
	resizeColumn = sortColumn = null;
	expanderBounds = null;
}
void onEnd (int stateMask) {
	int lastAvailableIndex = availableItemsCount - 1;
	if ((stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) {
		/* End with no modifiers */
		if (focusItem.availableIndex == lastAvailableIndex) return; 	/* at bottom */
		TreeItem item = availableItems [lastAvailableIndex]; 
		selectItem (item, false);
		setFocusItem (item, true);
		redrawItem (lastAvailableIndex, true);
		showItem (item);
		Event newEvent = new Event ();
		newEvent.item = item;
		postEvent (SWT.Selection, newEvent);
		return;
	}
	if ((style & SWT.SINGLE) != 0) {
		if ((stateMask & SWT.CTRL) != 0) {
			/* CTRL+End, CTRL+Shift+End */
			int visibleItemCount = (clientArea.height - getHeaderHeight ()) / itemHeight;
			setTopItem (availableItems [availableItemsCount - visibleItemCount]);
			return;
		}
		/* Shift+End */
		if (focusItem.availableIndex == lastAvailableIndex) return; /* at bottom */
		TreeItem item = availableItems [lastAvailableIndex]; 
		selectItem (item, false);
		setFocusItem (item, true);
		redrawItem (lastAvailableIndex, true);
		showItem (item);
		Event newEvent = new Event ();
		newEvent.item = item;
		postEvent (SWT.Selection, newEvent);
		return;
	}
	/* SWT.MULTI */
	if ((stateMask & SWT.CTRL) != 0) {
		if ((stateMask & SWT.SHIFT) != 0) {
			/* CTRL+Shift+End */
			showItem (availableItems [lastAvailableIndex]);
			return;
		}
		/* CTRL+End */
		if (focusItem.availableIndex == lastAvailableIndex) return; /* at bottom */
		TreeItem item = availableItems [lastAvailableIndex];
		setFocusItem (item, true);
		showItem (item);
		redrawItem (item.availableIndex, true);
		return;
	}
	/* Shift+End */
	if (anchorItem == null) anchorItem = focusItem;
	TreeItem selectedItem = availableItems [lastAvailableIndex];
	if (selectedItem == focusItem && selectedItem.isSelected ()) return;
	int anchorIndex = anchorItem.availableIndex;
	int selectIndex = selectedItem.availableIndex;
	TreeItem[] newSelection = new TreeItem [selectIndex - anchorIndex + 1];
	int writeIndex = 0;
	for (int i = anchorIndex; i <= selectIndex; i++) {
		newSelection [writeIndex++] = availableItems [i];
	}
	setSelection (newSelection, false);
	setFocusItem (selectedItem, true);
	redrawItems (anchorIndex, selectIndex, true);
	showItem (selectedItem);
	Event newEvent = new Event ();
	newEvent.item = selectedItem;
	postEvent (SWT.Selection, newEvent);
}
void onFocusIn () {
	hasFocus = true;

	if (items.length == 0) {
		redraw ();
		return;
	}
	if (focusItem != null) {
		redrawItem (focusItem.availableIndex, true);
		return;
	}
	/* an initial focus item must be selected */
	TreeItem initialFocus = null;
	if (selectedItems.length > 0) {
		for (int i = 0; i < selectedItems.length && initialFocus == null; i++) {
			if (selectedItems [i].isAvailable ()) {
				initialFocus = selectedItems [i];
			}
		}
		if (initialFocus == null) {
			/* none of the selected items are available */
			initialFocus = availableItems [topIndex];
		}
	} else {
		initialFocus = availableItems [topIndex];
	}
	setFocusItem (initialFocus, false);
	redrawItem (initialFocus.availableIndex, true);
	return;
}
void onFocusOut () {
	hasFocus = false;

	if (items.length == 0) {
		redraw ();
		return;
	}	

	if (focusItem != null) {
		redrawItem (focusItem.availableIndex, true);
	}
}
void onHome (int stateMask) {
	if ((stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) {
		/* Home with no modifiers */
		if (focusItem.availableIndex == 0) return; 		/* at top */
		TreeItem item = availableItems [0];
		selectItem (item, false);
		setFocusItem (item, true);
		redrawItem (0, true);
		showItem (item);
		Event newEvent = new Event ();
		newEvent.item = item;
		postEvent (SWT.Selection, newEvent);
		return;
	}
	if ((style & SWT.SINGLE) != 0) {
		if ((stateMask & SWT.CTRL) != 0) {
			/* CTRL+Home, CTRL+Shift+Home */
			setTopItem (availableItems [0]);
			return;
		}
		/* Shift+Home */
		if (focusItem.availableIndex == 0) return; 		/* at top */
		TreeItem item = availableItems [0];
		selectItem (item, false);
		setFocusItem (item, true);
		redrawItem (0, true);
		showItem (item);
		Event newEvent = new Event ();
		newEvent.item = item;
		postEvent (SWT.Selection, newEvent);
		return;
	}
	/* SWT.MULTI */
	if ((stateMask & SWT.CTRL) != 0) {
		if ((stateMask & SWT.SHIFT) != 0) {
			/* CTRL+Shift+Home */
			setTopItem (availableItems [0]);
			return;
		}
		/* CTRL+Home */
		if (focusItem.availableIndex == 0) return; /* at top */
		TreeItem item = availableItems [0];
		setFocusItem (item, true);
		showItem (item);
		redrawItem (item.availableIndex, true);
		return;
	}
	/* Shift+Home */
	if (anchorItem == null) anchorItem = focusItem;
	TreeItem selectedItem = availableItems [0];
	if (selectedItem == focusItem && selectedItem.isSelected ()) return;
	int anchorIndex = anchorItem.availableIndex;
	int selectIndex = selectedItem.availableIndex;
	TreeItem[] newSelection = new TreeItem [anchorIndex + 1];
	int writeIndex = 0;
	for (int i = anchorIndex; i >= 0; i--) {
		newSelection [writeIndex++] = availableItems [i];
	}
	setSelection (newSelection, false);
	setFocusItem (selectedItem, true);
	redrawItems (anchorIndex, selectIndex, true);
	showItem (selectedItem);
	Event newEvent = new Event ();
	newEvent.item = selectedItem;
	postEvent (SWT.Selection, newEvent);
}
void onKeyDown (Event event) {
	if (ignoreKey) {
		ignoreKey = false;
		return;
	}
	ignoreKey = true;
	notifyListeners (event.type, event);
	event.type = SWT.None;
	if (!event.doit) return;
	if (focusItem == null) return;
	if ((event.stateMask & SWT.SHIFT) == 0 && event.keyCode != SWT.SHIFT) {
		anchorItem = null;
	}
	switch (event.keyCode) {
		case SWT.ARROW_UP:
			onArrowUp (event.stateMask);
			return;
		case SWT.ARROW_DOWN:
			onArrowDown (event.stateMask);
			return;
		case SWT.ARROW_LEFT:
			onArrowLeft (event.stateMask);
			return;
		case SWT.ARROW_RIGHT:
			onArrowRight (event.stateMask);
			return;
		case SWT.PAGE_UP:
			onPageUp (event.stateMask);
			return;
		case SWT.PAGE_DOWN:
			onPageDown (event.stateMask);
			return;
		case SWT.HOME:
			onHome (event.stateMask);
			return;
		case SWT.END:
			onEnd (event.stateMask);
			return;
	}
	if (event.character == ' ') {
		onSpace ();
		return;
	}
	if (event.character == SWT.CR) {
		onCR ();
		return;
	}
	if ((event.stateMask & SWT.CTRL) != 0) return;

	int initialIndex = focusItem.availableIndex;
	char character = Character.toLowerCase (event.character);
	/* check available items from current focus item to bottom */
	for (int i = initialIndex + 1; i < availableItemsCount; i++) {
		TreeItem item = availableItems [i];
		String text = item.getText (0, false);
		if (text.length() > 0) {
			if (Character.toLowerCase (text.charAt (0)) == character) {
				selectItem (item, false);
				setFocusItem (item, true);
				redrawItem (i, true);
				showItem (item);
				Event newEvent = new Event ();
				newEvent.item = item;
				postEvent (SWT.Selection, newEvent);
				return;
			}
		}
	}
	/* check available items from top to current focus item */
	for (int i = 0; i < initialIndex; i++) {
		TreeItem item = availableItems [i];
		String text = item.getText (0, false);
		if (text.length() > 0) {
			if (Character.toLowerCase (text.charAt (0)) == character) {
				selectItem (item, false);
				setFocusItem (item, true);
				redrawItem (i, true);
				showItem (item);
				Event newEvent = new Event ();
				newEvent.item = item;
				postEvent (SWT.Selection, newEvent);
				return;
			}
		}
	}
}
void onMouseDoubleClick (Event event) {
	if (!isFocusControl ()) setFocus ();
	int index = (event.y - getHeaderHeight ()) / itemHeight + topIndex;
	if  (!(0 <= index && index < availableItemsCount)) return;	/* not on an available item */
	TreeItem selectedItem = availableItems [index];
	
	/* 
	 * If the two clicks of the double click did not occur over the same item then do not
	 * consider this to be a default selection.
	 */
	if (selectedItem != lastClickedItem) return;

	/* if click was in expander box then don't fire event */
	if (selectedItem.items.length > 0 && selectedItem.getExpanderBounds ().contains (event.x, event.y)) {
		return;
	}
	
	if (!selectedItem.getHitBounds ().contains (event.x, event.y)) return;	/* considers x */
	
	Event newEvent = new Event ();
	newEvent.item = selectedItem;
	postEvent (SWT.DefaultSelection, newEvent);
}
void onMouseDown (Event event) {
	if (!isFocusControl ()) forceFocus ();
	int index = (event.y - getHeaderHeight ()) / itemHeight + topIndex;
	if (!(0 <= index && index < availableItemsCount)) return;	/* not on an available item */
	TreeItem selectedItem = availableItems [index];
	
	/* if click was in expander box */
	if (selectedItem.items.length > 0 && selectedItem.getExpanderBounds ().contains (event.x, event.y)) {
		if (event.button != 1) return;
		boolean expand = !selectedItem.expanded;
		selectedItem.setExpanded (expand);
		Event newEvent = new Event ();
		newEvent.item = selectedItem;
		if (expand) {
			inExpand = true;
			sendEvent (SWT.Expand, newEvent);
			inExpand = false;
			if (isDisposed ()) return;
			if (selectedItem.items.length == 0) {
				selectedItem.expanded = false;
			}
		} else {
			sendEvent (SWT.Collapse, newEvent);
		}
		return;
	}
	/* if click was in checkbox */
	if ((style & SWT.CHECK) != 0 && selectedItem.getCheckboxBounds ().contains (event.x, event.y)) {
		if (event.button != 1) return;
		selectedItem.setChecked (!selectedItem.checked);
		Event newEvent = new Event ();
		newEvent.item = selectedItem;
		newEvent.detail = SWT.CHECK;
		postEvent (SWT.Selection, newEvent);
		return;
	}
	
	if (!selectedItem.getHitBounds ().contains (event.x, event.y)) return;
	
	if ((event.stateMask & SWT.SHIFT) == 0 && event.keyCode != SWT.SHIFT) anchorItem = null;

	boolean sendSelection = true;
	/* Detect when this is the second click of a DefaultSelection and don't fire Selection */
	if (lastSelectionEvent != null && lastSelectionEvent.item == selectedItem) {
		if (event.time - lastSelectionEvent.time <= display.getDoubleClickTime ()) {
			sendSelection = false;
		} else {
			lastSelectionEvent = event;
			event.item = selectedItem;
		}
	} else {
		lastSelectionEvent = event;
		event.item = selectedItem;
	}

	if ((style & SWT.SINGLE) != 0) {
		if (!selectedItem.isSelected ()) {
			if (event.button == 1) {
				selectItem (selectedItem, false);
				setFocusItem (selectedItem, true);
				redrawItem (selectedItem.availableIndex, true);
				if (sendSelection) {
					Event newEvent = new Event ();
					newEvent.item = selectedItem;
					postEvent (SWT.Selection, newEvent);
				}
				return;
			}
			if ((event.stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) {
				selectItem (selectedItem, false);
				setFocusItem (selectedItem, true);
				redrawItem (selectedItem.availableIndex, true);
				if (sendSelection) {
					Event newEvent = new Event ();
					newEvent.item = selectedItem;
					postEvent (SWT.Selection, newEvent);
				}
				return;
			}
		}
		/* item is selected */
		if (event.button == 1) {
			/* fire a selection event, though the selection did not change */
			if (sendSelection) {
				Event newEvent = new Event ();
				newEvent.item = selectedItem;
				postEvent (SWT.Selection, newEvent);
			}
			return;
		}
	}
	/* SWT.MULTI */
	if (!selectedItem.isSelected ()) {
		if (event.button == 1) {
			if ((event.stateMask & (SWT.CTRL | SWT.SHIFT)) == SWT.SHIFT) {
				if (anchorItem == null) anchorItem = focusItem;
				int anchorIndex = anchorItem.availableIndex;
				int selectIndex = selectedItem.availableIndex;
				TreeItem[] newSelection = new TreeItem [Math.abs (anchorIndex - selectIndex) + 1];
				int step = anchorIndex < selectIndex ? 1 : -1;
				int writeIndex = 0;
				for (int i = anchorIndex; i != selectIndex; i += step) {
					newSelection [writeIndex++] = availableItems [i];
				}
				newSelection [writeIndex] = availableItems [selectIndex];
				setSelection (newSelection, false);
				setFocusItem (selectedItem, true);
				redrawItems (
					Math.min (anchorIndex, selectIndex),
					Math.max (anchorIndex, selectIndex),
					true);
				if (sendSelection) {
					Event newEvent = new Event ();
					newEvent.item = selectedItem;
					postEvent (SWT.Selection, newEvent);
				}
				return;
			}
			selectItem (selectedItem, (event.stateMask & SWT.CTRL) != 0);
			setFocusItem (selectedItem, true);
			redrawItem (selectedItem.availableIndex, true);
			if (sendSelection) {
				Event newEvent = new Event ();
				newEvent.item = selectedItem;
				postEvent (SWT.Selection, newEvent);
			}
			return;
		}
		/* button 3 */
		if ((event.stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) {
			selectItem (selectedItem, false);
			setFocusItem (selectedItem, true);
			redrawItem (selectedItem.availableIndex, true);
			if (sendSelection) {
				Event newEvent = new Event ();
				newEvent.item = selectedItem;
				postEvent (SWT.Selection, newEvent);
			}
			return;
		}
	}
	/* item is selected */
	if (event.button != 1) return;
	if ((event.stateMask & SWT.CTRL) != 0) {
		removeSelectedItem (getSelectionIndex (selectedItem));
		setFocusItem (selectedItem, true);
		redrawItem (selectedItem.availableIndex, true);
		if (sendSelection) {
			Event newEvent = new Event ();
			newEvent.item = selectedItem;
			postEvent (SWT.Selection, newEvent);
		}
		return;
	}
	if ((event.stateMask & SWT.SHIFT) != 0) {
		if (anchorItem == null) anchorItem = focusItem;
		int anchorIndex = anchorItem.availableIndex;
		int selectIndex = selectedItem.availableIndex;
		TreeItem[] newSelection = new TreeItem [Math.abs (anchorIndex - selectIndex) + 1];
		int step = anchorIndex < selectIndex ? 1 : -1;
		int writeIndex = 0;
		for (int i = anchorIndex; i != selectIndex; i += step) {
			newSelection [writeIndex++] = availableItems [i];
		}
		newSelection [writeIndex] = availableItems [selectIndex];
		setSelection (newSelection, false);
		setFocusItem (selectedItem, true);
		redrawItems (
			Math.min (anchorIndex, selectIndex),
			Math.max (anchorIndex, selectIndex),
			true);
		if (sendSelection) {
			Event newEvent = new Event ();
			newEvent.item = selectedItem;
			postEvent (SWT.Selection, newEvent);
		}
		return;
	}
	selectItem (selectedItem, false);
	setFocusItem (selectedItem, true);
	redrawItem (selectedItem.availableIndex, true);
	if (sendSelection) {
		Event newEvent = new Event ();
		newEvent.item = selectedItem;
		postEvent (SWT.Selection, newEvent);
	}
}
void onMouseUp (Event event) {
	int index = (event.y - getHeaderHeight ()) / itemHeight + topIndex;
	if (!(0 <= index && index < availableItemsCount)) return;	/* not on an available item */
	lastClickedItem = availableItems [index];
}
void onPageDown (int stateMask) {
	int visibleItemCount = (clientArea.height - getHeaderHeight ()) / itemHeight;
	if ((stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) {
		/* PageDown with no modifiers */
		int newFocusIndex = focusItem.availableIndex + visibleItemCount - 1;
		newFocusIndex = Math.min (newFocusIndex, availableItemsCount - 1);
		if (newFocusIndex == focusItem.availableIndex) return;
		TreeItem item = availableItems [newFocusIndex];
		selectItem (item, false);
		setFocusItem (item, true);
		showItem (item);
		redrawItem (item.availableIndex, true);
		return;
	}
	if ((stateMask & (SWT.CTRL | SWT.SHIFT)) == (SWT.CTRL | SWT.SHIFT)) {
		/* CTRL+Shift+PageDown */
		int newTopIndex = topIndex + visibleItemCount;
		newTopIndex = Math.min (newTopIndex, availableItemsCount - visibleItemCount);
		if (newTopIndex == topIndex) return;
		setTopItem (availableItems [newTopIndex]);
		return;
	}
	if ((style & SWT.SINGLE) != 0) {
		if ((stateMask & SWT.SHIFT) != 0) {
			/* Shift+PageDown */
			int newFocusIndex = focusItem.availableIndex + visibleItemCount - 1;
			newFocusIndex = Math.min (newFocusIndex, availableItemsCount - 1);
			if (newFocusIndex == focusItem.availableIndex) return;
			TreeItem item = availableItems [newFocusIndex];
			selectItem (item, false);
			setFocusItem (item, true);
			showItem (item);
			redrawItem (item.availableIndex, true);
			return;
		}
		/* CTRL+PageDown */
		int newTopIndex = topIndex + visibleItemCount;
		newTopIndex = Math.min (newTopIndex, availableItemsCount - visibleItemCount);
		if (newTopIndex == topIndex) return;
		setTopItem (availableItems [newTopIndex]);
		return;
	}
	/* SWT.MULTI */
	if ((stateMask & SWT.CTRL) != 0) {
		/* CTRL+PageDown */
		int bottomIndex = Math.min (topIndex + visibleItemCount - 1, availableItemsCount - 1);
		if (focusItem.availableIndex != bottomIndex) {
			/* move focus to bottom item in viewport */
			setFocusItem (availableItems [bottomIndex], true);
			redrawItem (bottomIndex, true);
		} else {
			/* at bottom of viewport, so set focus to bottom item one page down */
			int newFocusIndex = Math.min (availableItemsCount - 1, bottomIndex + visibleItemCount);
			if (newFocusIndex == focusItem.availableIndex) return;
			setFocusItem (availableItems [newFocusIndex], true);
			showItem (availableItems [newFocusIndex]);
			redrawItem (newFocusIndex, true);
		}
		return;
	}
	/* Shift+PageDown */
	if (anchorItem == null) anchorItem = focusItem;
	int anchorIndex = anchorItem.availableIndex;
	int bottomIndex = Math.min (topIndex + visibleItemCount - 1, availableItemsCount - 1);
	int selectIndex;
	if (focusItem.availableIndex != bottomIndex) {
		/* select from focus to bottom item in viewport */
		selectIndex = bottomIndex;
	} else {
		/* already at bottom of viewport, so select to bottom of one page down */
		selectIndex = Math.min (availableItemsCount - 1, bottomIndex + visibleItemCount);
		if (selectIndex == focusItem.availableIndex && focusItem.isSelected ()) return;
	}
	TreeItem selectedItem = availableItems [selectIndex];
	TreeItem[] newSelection = new TreeItem [Math.abs (anchorIndex - selectIndex) + 1];
	int step = anchorIndex < selectIndex ? 1 : -1;
	int writeIndex = 0;
	for (int i = anchorIndex; i != selectIndex; i += step) {
		newSelection [writeIndex++] = availableItems [i];
	}
	newSelection [writeIndex] = availableItems [selectIndex];
	setSelection (newSelection, false);
	setFocusItem (selectedItem, true);
	showItem (selectedItem);
	Event newEvent = new Event ();
	newEvent.item = selectedItem;
	postEvent (SWT.Selection, newEvent);
}
void onPageUp (int stateMask) {
	int visibleItemCount = (clientArea.height - getHeaderHeight ()) / itemHeight;
	if ((stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) {
		/* PageUp with no modifiers */
		int newFocusIndex = Math.max (0, focusItem.availableIndex - visibleItemCount + 1);
		if (newFocusIndex == focusItem.availableIndex) return;
		TreeItem item = availableItems [newFocusIndex];
		selectItem (item, false);
		setFocusItem (item, true);
		showItem (item);
		redrawItem (item.availableIndex, true);
		return;
	}
	if ((stateMask & (SWT.CTRL | SWT.SHIFT)) == (SWT.CTRL | SWT.SHIFT)) {
		/* CTRL+Shift+PageUp */
		int newTopIndex = Math.max (0, topIndex - visibleItemCount);
		if (newTopIndex == topIndex) return;
		setTopItem (availableItems [newTopIndex]);
		return;
	}
	if ((style & SWT.SINGLE) != 0) {
		if ((stateMask & SWT.SHIFT) != 0) {
			/* Shift+PageUp */
			int newFocusIndex = Math.max (0, focusItem.availableIndex - visibleItemCount + 1);
			if (newFocusIndex == focusItem.availableIndex) return;
			TreeItem item = availableItems [newFocusIndex];
			selectItem (item, false);
			setFocusItem (item, true);
			showItem (item);
			redrawItem (item.availableIndex, true);
			return;
		}
		/* CTRL+PageUp */
		int newTopIndex = Math.max (0, topIndex - visibleItemCount);
		if (newTopIndex == topIndex) return;
		setTopItem (availableItems [newTopIndex]);
		return;
	}
	/* SWT.MULTI */
	if ((stateMask & SWT.CTRL) != 0) {
		/* CTRL+PageUp */
		if (focusItem.availableIndex != topIndex) {
			/* move focus to top item in viewport */
			setFocusItem (availableItems [topIndex], true);
			redrawItem (topIndex, true);
		} else {
			/* at top of viewport, so set focus to top item one page up */
			int newFocusIndex = Math.max (0, focusItem.availableIndex - visibleItemCount);
			if (newFocusIndex == focusItem.availableIndex) return;
			setFocusItem (availableItems [newFocusIndex], true);
			showItem (availableItems [newFocusIndex]);
			redrawItem (newFocusIndex, true);
		}
		return;
	}
	/* Shift+PageUp */
	if (anchorItem == null) anchorItem = focusItem;
	int anchorIndex = anchorItem.availableIndex;
	int selectIndex;
	if (focusItem.availableIndex != topIndex) {
		/* select from focus to top item in viewport */
		selectIndex = topIndex;
	} else {
		/* already at top of viewport, so select to top of one page up */
		selectIndex = Math.max (0, topIndex - visibleItemCount);
		if (selectIndex == focusItem.availableIndex && focusItem.isSelected ()) return;
	}
	TreeItem selectedItem = availableItems [selectIndex];
	TreeItem[] newSelection = new TreeItem [Math.abs (anchorIndex - selectIndex) + 1];
	int step = anchorIndex < selectIndex ? 1 : -1;
	int writeIndex = 0;
	for (int i = anchorIndex; i != selectIndex; i += step) {
		newSelection [writeIndex++] = availableItems [i];
	}
	newSelection [writeIndex] = availableItems [selectIndex];
	setSelection (newSelection, false);
	setFocusItem (selectedItem, true);
	showItem (selectedItem);
	Event newEvent = new Event ();
	newEvent.item = selectedItem;
	postEvent (SWT.Selection, newEvent);
}
void onPaint (Event event) {
	TreeColumn[] orderedColumns = getOrderedColumns ();
	GC gc = event.gc;
	Rectangle clipping = gc.getClipping ();
	int headerHeight = getHeaderHeight ();
	int numColumns = orderedColumns.length;
	int startColumn = -1, endColumn = -1;
	if (numColumns > 0) {
		startColumn = computeColumnIntersect (clipping.x, 0);
		if (startColumn != -1) {	/* the clip x is within a column's bounds */
			endColumn = computeColumnIntersect (clipping.x + clipping.width, startColumn);
			if (endColumn == -1) endColumn = numColumns - 1;
		}
	} else {
		startColumn = endColumn = 0;
	}

	/* Determine the items to be painted */
	int startIndex = (clipping.y - headerHeight) / itemHeight + topIndex;
	int endIndex = -1;
	if (startIndex < availableItemsCount) {
		endIndex = startIndex + Compatibility.ceil (clipping.height, itemHeight);
	}
	startIndex = Math.max (0, startIndex);
	endIndex = Math.min (endIndex, availableItemsCount - 1);

	/* fill background not handled by items */
	gc.setBackground (getBackground ());
	gc.setClipping (clipping);
	int bottomY = endIndex >= 0 ? getItemY (availableItems [endIndex]) + itemHeight : 0;
	int fillHeight = Math.max (0, clientArea.height - bottomY);
	if (fillHeight > 0) {	/* space below bottom item */
		drawBackground (gc, 0, bottomY, clientArea.width, fillHeight);
	}
	if (columns.length > 0) {
		TreeColumn column = orderedColumns [orderedColumns.length - 1];	/* last column */
		int rightX = column.getX () + column.width;
		if (rightX < clientArea.width) {
			drawBackground (gc, rightX, 0, clientArea.width - rightX, clientArea.height - fillHeight);
		}
	}

	/* paint the items */
	boolean noFocusDraw = false;
	int[] lineDash = gc.getLineDash ();
	int lineWidth = gc.getLineWidth ();
	for (int i = startIndex; i <= Math.min (endIndex, availableItemsCount - 1); i++) {
		TreeItem item = availableItems [i];
		if (!item.isDisposed ()) {	/* ensure that item was not disposed in a callback */
			if (startColumn == -1) {
				/* indicates that region to paint is to the right of the last column */
				noFocusDraw = item.paint (gc, null, true) || noFocusDraw;
			} else {
				if (numColumns == 0) {
					noFocusDraw = item.paint (gc, null, false) || noFocusDraw;
				} else {
					for (int j = startColumn; j <= Math.min (endColumn, columns.length - 1); j++) {
						if (!item.isDisposed ()) {	/* ensure that item was not disposed in a callback */
							noFocusDraw = item.paint (gc, orderedColumns [j], false) || noFocusDraw;
						}
						if (isDisposed () || gc.isDisposed ()) return;	/* ensure that receiver was not disposed in a callback */
					}
				}
			}
		}
		if (isDisposed () || gc.isDisposed ()) return;	/* ensure that receiver was not disposed in a callback */
	}

	/* repaint grid lines */
	gc.setClipping(clipping);
	gc.setLineWidth (lineWidth);
	if (linesVisible) {
		gc.setForeground (display.getSystemColor (SWT.COLOR_WIDGET_LIGHT_SHADOW));
		gc.setLineDash (lineDash);
		if (numColumns > 0 && startColumn != -1) {
			/* vertical column lines */
			for (int i = startColumn; i <= endColumn; i++) {
				int x = orderedColumns [i].getX () + orderedColumns [i].width - 1;
				gc.drawLine (x, clipping.y, x, clipping.y + clipping.height);
			}
		}
		/* horizontal item lines */
		bottomY = clipping.y + clipping.height;
		int rightX = clipping.x + clipping.width;
		int y = (clipping.y - headerHeight) / itemHeight * itemHeight + headerHeight;
		while (y <= bottomY) {
			gc.drawLine (clipping.x, y, rightX, y);
			y += itemHeight;
		}
	}

	/* draw focus rectangle */
	if (!noFocusDraw && isFocusControl ()) {
		if (focusItem != null) {
			Rectangle focusBounds = focusItem.getFocusBounds ();
			if (focusBounds.width > 0) {
				gc.setForeground (display.getSystemColor (SWT.COLOR_BLACK));
				gc.setClipping (focusBounds);
				if (focusItem.isSelected ()) {
					gc.setLineDash (new int[] {2, 2});
				} else {
					gc.setLineDash (new int[] {1, 1});
				}
				gc.drawFocus (focusBounds.x, focusBounds.y, focusBounds.width, focusBounds.height);
			}
		} else {
			/* no items, so draw focus border around Tree */
			int y = headerHeight + 1;
			int width = Math.max (0, clientArea.width - 2);
			int height = Math.max (0, clientArea.height - headerHeight - 2);
			gc.setForeground (display.getSystemColor (SWT.COLOR_BLACK));
			gc.setClipping (1, y, width, height);
			gc.setLineDash (new int[] {1, 1});
			gc.drawFocus (1, y, width, height);
		}
	}

	/* draw insert mark */
	if (insertMarkItem != null) {
		Rectangle focusBounds = insertMarkItem.getFocusBounds ();
		gc.setForeground (display.getSystemColor (SWT.COLOR_BLACK));
		gc.setClipping (focusBounds);
		gc.setLineDash (lineDash);
		if (insertMarkPrecedes) {
			gc.drawLine (focusBounds.x, focusBounds.y, focusBounds.x + focusBounds.width, focusBounds.y);
		} else {
			int y = focusBounds.y + focusBounds.height - 1;
			gc.drawLine (focusBounds.x, y, focusBounds.x + focusBounds.width, y);
		}
	}
}
void onResize (Event event) {
	clientArea = getClientArea ();
	/* vertical scrollbar */
	ScrollBar vBar = getVerticalBar ();
	if (vBar != null) {
		int clientHeight = (clientArea.height - getHeaderHeight ()) / itemHeight;
		int thumb = Math.min (clientHeight, availableItemsCount);
		vBar.setThumb (thumb);
		vBar.setPageIncrement (thumb);
		int index = vBar.getSelection ();
		if (index != topIndex) {
			topIndex = index;
			redraw ();
		}
		boolean visible = clientHeight < availableItemsCount;
		if (visible != vBar.getVisible ()) {
			vBar.setVisible (visible);
			clientArea = getClientArea ();
		}
	}
	
	/* horizontal scrollbar */ 
	ScrollBar hBar = getHorizontalBar (); 
	if (hBar != null) {
		int hBarMaximum = hBar.getMaximum ();
		int thumb = Math.min (clientArea.width, hBarMaximum);
		hBar.setThumb (thumb);
		hBar.setPageIncrement (thumb);
		horizontalOffset = hBar.getSelection ();
		boolean visible = clientArea.width < hBarMaximum;
		if (visible != hBar.getVisible ()) {
			hBar.setVisible (visible);
			clientArea = getClientArea ();
		}
	}
	
	/* header */
	int headerHeight = Math.max (fontHeight, headerImageHeight) + 2 * getHeaderPadding ();
	header.setSize (clientArea.width, headerHeight);
	
	/* if this is the focus control but there are no items then the boundary focus ring must be repainted */
	if (availableItemsCount == 0 && isFocusControl ()) redraw ();
}
void onScrollHorizontal (Event event) {
	ScrollBar hBar = getHorizontalBar (); 
	if (hBar == null) return;
	int newSelection = hBar.getSelection ();
	update ();
	if (availableItemsCount > 0) {
		GC gc = new GC (this);
		gc.copyArea (
			0, 0,
			clientArea.width, clientArea.height,
			horizontalOffset - newSelection, 0);
		gc.dispose ();
	} else {
		redraw ();	/* ensure that static focus rectangle updates properly */
	}
	if (drawCount <= 0 && header.isVisible ()) {
		header.update ();
		Rectangle headerClientArea = header.getClientArea ();
		GC gc = new GC (header);
		gc.copyArea (
			0, 0,
			headerClientArea.width, headerClientArea.height,
			horizontalOffset - newSelection, 0);
		gc.dispose ();
	}
	horizontalOffset = newSelection;
}
void onScrollVertical (Event event) {
	ScrollBar vBar = getVerticalBar ();
	if (vBar != null) {
		int newSelection = vBar.getSelection ();
		update ();
		GC gc = new GC (this);
		gc.copyArea (
			0, 0,
			clientArea.width, clientArea.height,
			0, (topIndex - newSelection) * itemHeight);
		gc.dispose ();
		topIndex = newSelection;
	}
}
void onSpace () {
	if (focusItem == null) return;
	if (!focusItem.isSelected ()) {
		selectItem (focusItem, (style & SWT.MULTI) != 0);
		redrawItem (focusItem.availableIndex, true);
	}
	if ((style & SWT.CHECK) != 0) {
		focusItem.setChecked (!focusItem.checked);
	}
	showItem (focusItem);
	Event event = new Event ();
	event.item = focusItem;
	postEvent (SWT.Selection, event);
	if ((style & SWT.CHECK) == 0) return;

	/* SWT.CHECK */
	event = new Event ();
	event.item = focusItem;
	event.detail = SWT.CHECK;
	postEvent (SWT.Selection, event);
}
/*
 * The current focus item is about to become unavailable, so reassign focus.
 */
void reassignFocus () {
	if (focusItem == null) return;
	
	/* reassign to current focus' parent item if it has one */
	if (focusItem.parentItem != null) {
		TreeItem item = focusItem.parentItem;
		setFocusItem (item, false);
		showItem (item);
		return;
	}
	
	/* 
	 * reassign to the previous root-level item if there is one, or the next
	 * root-level item otherwise
	 */
	int index = focusItem.getIndex ();
	if (index != 0) {
		index--;
	} else {
		index++;
	}
	if (index < items.length) {
		TreeItem item = items [index];
		setFocusItem (item, false);
		showItem (item);
	} else {
		setFocusItem (null, false);		/* no items left */
	}
}
public void redraw () {
	checkWidget ();
	if (drawCount <= 0) super.redraw ();
}
public void redraw (int x, int y, int width, int height, boolean all) {
	checkWidget ();
	if (drawCount <= 0) super.redraw (x, y, width, height, all);
}
/* 
 * Redraws from the specified index down to the last available item inclusive.  Note
 * that the redraw bounds do not extend beyond the current last item, so clients
 * that reduce the number of available items should use #redrawItems(int,int) instead
 * to ensure that redrawing extends down to the previous bottom item boundary.
 */
void redrawFromItemDownwards (int index) {
	redrawItems (index, availableItemsCount - 1, false);
}
/*
 * Redraws the tree item at the specified index.  It is valid for this index to reside
 * beyond the last available item.
 */
void redrawItem (int itemIndex, boolean focusBoundsOnly) {
	if (itemIndex == -1) return;
	if (itemIndex < availableItemsCount && !availableItems [itemIndex].isInViewport ()) return;
	redrawItems (itemIndex, itemIndex, focusBoundsOnly);
}
/*
 * Redraws the tree between the start and end item indices inclusive.  It is valid
 * for the end index value to extend beyond the last available item.
 */
void redrawItems (int startIndex, int endIndex, boolean focusBoundsOnly) {
	if (drawCount > 0) return;

	int startY = (startIndex - topIndex) * itemHeight + getHeaderHeight ();
	int height = (endIndex - startIndex + 1) * itemHeight;
	if (focusBoundsOnly) {
		boolean custom = hooks (SWT.EraseItem) || hooks (SWT.PaintItem);
		if (!custom && columns.length > 0) {
			TreeColumn lastColumn;
			if ((style & SWT.FULL_SELECTION) != 0) {
				TreeColumn[] orderedColumns = getOrderedColumns ();
				lastColumn = orderedColumns [orderedColumns.length - 1];
			} else {
				lastColumn = columns [0];
			}
			int rightX = lastColumn.getX () + lastColumn.getWidth ();
			if (rightX <= 0) return;	/* focus column(s) not visible */
		}
		endIndex = Math.min (endIndex, availableItemsCount - 1);
		for (int i = startIndex; i <= endIndex; i++) {
			TreeItem item = availableItems [i];
			if (item.isInViewport ()) {
				/* if custom painting is being done then repaint the full item */
				if (custom) {
					redraw (0, getItemY (item), clientArea.width, itemHeight, false);
				} else {
					/* repaint the item's focus bounds */
					Rectangle bounds = item.getFocusBounds ();
					redraw (bounds.x, startY, bounds.width, height, false);
				}
			}
		}
	} else {
		redraw (0, startY, clientArea.width, height, false);
	}
}
/**
 * Removes all of the items from the receiver.
 * 
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void removeAll () {
	checkWidget ();
	if (items.length == 0) return;
	setRedraw (false);

	setFocusItem (null, false);
	for (int i = 0; i < items.length; i++) {
		items [i].dispose (false);
	}
	items = availableItems = selectedItems = NO_ITEMS;
	availableItemsCount = topIndex = 0;
	anchorItem = lastClickedItem = insertMarkItem = null;
	lastSelectionEvent = null;
	inExpand = false;
	ScrollBar vBar = getVerticalBar ();
	if (vBar != null) {
		vBar.setMaximum (1);
		vBar.setVisible (false);
	}
	if (columns.length == 0) {
		horizontalOffset = 0;
		ScrollBar hBar = getHorizontalBar ();
		if (hBar != null) {
			hBar.setMaximum (1);
			hBar.setVisible (false);
		}
	}

	setRedraw (true);
}
String removeMnemonics (String string) {
	/* removes single ampersands and preserves double-ampersands */
	char [] chars = new char [string.length ()];
	string.getChars (0, chars.length, chars, 0);
	int i = 0, j = 0;
	for ( ; i < chars.length; i++, j++) {
		if (chars[i] == '&') {
			if (++i == chars.length) break;
			if (chars[i] == '&') {
				chars[j++] = chars[i - 1];
			}
		}
		chars[j] = chars[i];
	}
	if (i == j) return string;
	return new String (chars, 0, j);
}
void removeSelectedItem (int index) {
	TreeItem[] newSelectedItems = new TreeItem [selectedItems.length - 1];
	System.arraycopy (selectedItems, 0, newSelectedItems, 0, index);
	System.arraycopy (selectedItems, index + 1, newSelectedItems, index, newSelectedItems.length - index);
	selectedItems = newSelectedItems;
}
/**
 * Removes the listener from the collection of listeners who will
 * be notified when the user changes the receiver's selection.
 *
 * @param listener the listener which should no longer be notified
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see SelectionListener
 * @see #addSelectionListener
 */
public void removeSelectionListener (SelectionListener listener) {
	checkWidget ();
	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
	removeListener (SWT.Selection, listener);
	removeListener (SWT.DefaultSelection, listener);	
}
/**
 * Removes the listener from the collection of listeners who will
 * be notified when items in the receiver are expanded or collapsed.
 *
 * @param listener the listener which should no longer be notified
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see TreeListener
 * @see #addTreeListener
 */
public void removeTreeListener (TreeListener listener) {
	checkWidget ();
	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
	removeListener (SWT.Expand, listener);
	removeListener (SWT.Collapse, listener);
}
/**
 * Selects an item in the receiver.  If the item was already
 * selected, it remains selected.
 *
 * @param item the item to be selected
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the item is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @since 3.4
 */
public void select (TreeItem item) {
	checkWidget ();
	if (item == null) error (SWT.ERROR_NULL_ARGUMENT);
	if (item.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
	selectItem (item, (style & SWT.MULTI) != 0);
	redrawItem (item.availableIndex, true);
}
/**
 * Selects all of the items in the receiver.
 * <p>
 * If the receiver is single-select, do nothing.
 * </p>
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void selectAll () {
	checkWidget ();
	if ((style & SWT.SINGLE) != 0) return;
	selectedItems = new TreeItem [availableItemsCount];
	System.arraycopy (availableItems, 0, selectedItems, 0, availableItemsCount);
	redraw ();
}
void selectItem (TreeItem item, boolean addToSelection) {
	TreeItem[] oldSelectedItems = selectedItems;
	if (!addToSelection || (style & SWT.SINGLE) != 0) {
		selectedItems = new TreeItem[] {item};
		for (int i = 0; i < oldSelectedItems.length; i++) {
			if (oldSelectedItems [i] != item) {
				redrawItem (oldSelectedItems [i].availableIndex, true);
			}
		}
	} else {
		if (item.isSelected ()) return;
		selectedItems = new TreeItem [selectedItems.length + 1];
		System.arraycopy (oldSelectedItems, 0, selectedItems, 0, oldSelectedItems.length);
		selectedItems [selectedItems.length - 1] = item;
	}
}
public void setBackground (Color color) {
	checkWidget ();
	if (color == null) color = display.getSystemColor (SWT.COLOR_LIST_BACKGROUND); 
	super.setBackground (color);
}
/**
 * Sets the order that the items in the receiver should 
 * be displayed in to the given argument which is described
 * in terms of the zero-relative ordering of when the items
 * were added.
 *
 * @param order the new order to display the items
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the item order is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the item order is not the same length as the number of items</li>
 * </ul>
 * 
 * @see Tree#getColumnOrder()
 * @see TreeColumn#getMoveable()
 * @see TreeColumn#setMoveable(boolean)
 * @see SWT#Move
 * 
 * @since 3.2
 */
public void setColumnOrder (int [] order) {
	checkWidget ();
	if (order == null) error (SWT.ERROR_NULL_ARGUMENT);
	if (columns.length == 0) {
		if (order.length != 0) error (SWT.ERROR_INVALID_ARGUMENT);
		return;
	}
	if (order.length != columns.length) error (SWT.ERROR_INVALID_ARGUMENT);
	boolean reorder = false;
	boolean [] seen = new boolean [columns.length];
	int[] oldOrder = getColumnOrder ();
	for (int i = 0; i < order.length; i++) {
		int index = order [i];
		if (index < 0 || index >= columns.length) error (SWT.ERROR_INVALID_RANGE);
		if (seen [index]) error (SWT.ERROR_INVALID_ARGUMENT);
		seen [index] = true;
		if (index != oldOrder [i]) reorder = true;
	}
	if (!reorder) return;

	headerHideToolTip ();
	int[] oldX = new int [columns.length];
	for (int i = 0; i < columns.length; i++) {
		oldX [i] = columns [i].getX ();
	}
	orderedColumns = new TreeColumn [order.length];
	for (int i = 0; i < order.length; i++) {
		orderedColumns [i] = columns [order [i]];
	}
	/*
	 * If the first ordered column has changed then the old and new ordered column 0's
	 * have to recompute their display texts since they will now have just gained/lost
	 * space as a result of the hierarchy decorations that appear in ordered column 0.
	 */
	if (oldOrder [0] != order [0]) {
		orderedCol0imageWidth = columns [order [0]].itemImageWidth;
		GC gc = new GC (this);
		for (int i = 0; i < items.length; i++) {
			items [i].updateColumnWidth (columns [oldOrder [0]], gc);
			items [i].updateColumnWidth (columns [order [0]], gc);
		}
		gc.dispose();
	}
	for (int i = 0; i < orderedColumns.length; i++) {
		TreeColumn column = orderedColumns [i];
		if (!column.isDisposed () && column.getX () != oldX [column.getIndex ()]) {
			column.sendEvent (SWT.Move);
		}
	}

	redraw ();
	if (drawCount <= 0 && header.isVisible ()) header.redraw ();
}
void setFocusItem (TreeItem item, boolean redrawOldFocus) {
	if (item == focusItem) return;
	TreeItem oldFocusItem = focusItem;
	focusItem = item;
	if (redrawOldFocus && oldFocusItem != null) {
		redrawItem (oldFocusItem.availableIndex, true);
	}
}
public void setFont (Font value) {
	checkWidget ();
	Font oldFont = getFont ();
	super.setFont (value);
	Font font = getFont ();
	if (font.equals (oldFont)) return;
		
	GC gc = new GC (this);
	
	/* recompute the receiver's cached font height and item height values */
	fontHeight = gc.getFontMetrics ().getHeight ();
	setItemHeight (Math.max (fontHeight, imageHeight) + 2 * getCellPadding ());
	Point headerSize = header.getSize ();
	int newHeaderHeight = Math.max (fontHeight, headerImageHeight) + 2 * getHeaderPadding ();
	if (headerSize.y != newHeaderHeight) {
		header.setSize (headerSize.x, newHeaderHeight);
	}
	header.setFont (font);

	/* 
	 * Notify all columns and items of the font change so that elements that
	 * use the receiver's font can recompute their cached string widths.
	 */
	for (int i = 0; i < columns.length; i++) {
		columns [i].updateFont (gc);
	}
	for (int i = 0; i < items.length; i++) {
		items [i].updateFont (gc);
	}
	
	gc.dispose ();
	
	if (drawCount <= 0 && header.isVisible ()) header.redraw ();
	
	/* update scrollbars */
	if (columns.length == 0) updateHorizontalBar ();
	ScrollBar vBar = getVerticalBar ();
	if (vBar != null) {
		int thumb = (clientArea.height - getHeaderHeight ()) / itemHeight;
		if (vBar.getThumb () != thumb) {
			vBar.setThumb (thumb);
			vBar.setPageIncrement (thumb);
		}
		topIndex = vBar.getSelection ();
		vBar.setVisible (thumb < vBar.getMaximum ());
	}
	redraw ();
}
public void setForeground (Color color) {
	checkWidget ();
	if (color == null) color = display.getSystemColor (SWT.COLOR_LIST_FOREGROUND); 
	super.setForeground (color);
}
void setHeaderImageHeight (int value) {
	headerImageHeight = value;
	Point headerSize = header.getSize ();
	int newHeaderHeight = Math.max (fontHeight, headerImageHeight) + 2 * getHeaderPadding ();
	if (headerSize.y != newHeaderHeight) {
		header.setSize (headerSize.x, newHeaderHeight);
	}
}
/**
 * Marks the receiver's header as visible if the argument is <code>true</code>,
 * and marks it invisible otherwise. 
 * <p>
 * If one of the receiver's ancestors is not visible or some
 * other condition makes the receiver not visible, marking
 * it visible may not actually cause it to be displayed.
 * </p>
 *
 * @param show the new visibility state
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @since 3.1
 */
public void setHeaderVisible (boolean value) {
	checkWidget ();
	if (header.getVisible () == value) return;		/* no change */
	headerHideToolTip ();
	header.setVisible (value);
	updateVerticalBar ();
	redraw ();
}
void setImageHeight (int value) {
	imageHeight = value;
	setItemHeight (Math.max (fontHeight, imageHeight) + 2 * getCellPadding ());
}
/**
 * Display a mark indicating the point at which an item will be inserted.
 * The drop insert item has a visual hint to show where a dragged item 
 * will be inserted when dropped on the tree.
 * 
 * @param item the insert item.  Null will clear the insertion mark.
 * @param before true places the insert mark above 'item'. false places 
 *	the insert mark below 'item'.
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void setInsertMark (TreeItem item, boolean before) {
	checkWidget ();
	if (item != null && item.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
	if (item != null && item.parent != this) return;
	if (item == insertMarkItem && before == insertMarkPrecedes) return;	/* no change */
	
	TreeItem oldInsertItem = insertMarkItem;
	insertMarkItem = item;
	insertMarkPrecedes = before;
	if (oldInsertItem != null && oldInsertItem.availableIndex != -1) {
		redrawItem (oldInsertItem.availableIndex, true);
	}
	if (item != null && item != oldInsertItem && item.availableIndex != -1) {
		redrawItem (item.availableIndex, true);
	}
}
/**
 * Sets the number of root-level items contained in the receiver.
 *
 * @param count the number of items
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @since 3.2
 */
public void setItemCount (int count) {
	checkWidget ();
	count = Math.max (0, count);
	if (count == items.length) return;
	int oldCount = availableItemsCount;
	int redrawStart, redrawEnd;

	/* if the new item count is less than the current count then remove all excess items from the end */
	if (count < items.length) {
		redrawStart = count > 0 ? items [count - 1].availableIndex : 0;
		redrawEnd = availableItemsCount - 1;
		availableItemsCount = items [count].availableIndex;
		for (int i = count; i < items.length; i++) {
			items [i].dispose (false);
		}
		if (count == 0) {
			items = Tree.NO_ITEMS;
		} else {
			TreeItem[] newItems = new TreeItem [count];
			System.arraycopy (items, 0, newItems, 0, count);
			items = newItems;
		}

		int newSelectedCount = 0;
		for (int i = 0; i < selectedItems.length; i++) {
			if (!selectedItems [i].isDisposed ()) newSelectedCount++;
		}
		if (newSelectedCount != selectedItems.length) {
			/* one or more selected items have been disposed */
			TreeItem[] newSelectedItems = new TreeItem [newSelectedCount];
			int pos = 0;
			for (int i = 0; i < selectedItems.length; i++) {
				TreeItem item = selectedItems [i];
				if (!item.isDisposed ()) {
					newSelectedItems [pos++] = item;
				}
			}
			selectedItems = newSelectedItems;
		}

		if (insertMarkItem != null && insertMarkItem.isDisposed ()) insertMarkItem = null;
		if (lastClickedItem != null && lastClickedItem.isDisposed ()) lastClickedItem = null;
		if (anchorItem != null && anchorItem.isDisposed ()) anchorItem = null;
		if (focusItem != null && focusItem.isDisposed ()) {
			TreeItem newFocusItem = count > 0 ? items [count - 1] : null; 
			setFocusItem (newFocusItem, false);
		}
		if (columns.length == 0) updateHorizontalBar ();
	} else {
		int grow = count - items.length;
		redrawStart = items.length == 0 ? 0 : items [items.length - 1].availableIndex;
		redrawEnd = availableItemsCount + grow - 1;
		TreeItem[] newItems = new TreeItem [count];
		System.arraycopy (items, 0, newItems, 0, items.length);
		items = newItems;
		if (availableItems.length < availableItemsCount + grow) {
			TreeItem[] newAvailableItems = new TreeItem [availableItemsCount + grow];
			System.arraycopy (availableItems, 0, newAvailableItems, 0, availableItemsCount);
			availableItems = newAvailableItems;
		}
		for (int i = items.length - grow; i < count; i++) {
			TreeItem newItem = new TreeItem (this, SWT.NONE, i, false);
			items [i] = newItem;
			items [i].availableIndex = availableItemsCount;
			availableItems [availableItemsCount++] = newItem;
		}
		if (oldCount == 0) focusItem = availableItems [0];
	}

	updateVerticalBar ();
	/*
	 * If this is the focus control and the available item count is going from 0->!0 or !0->0
	 * then the receiver must be redrawn to ensure that its boundary focus ring is updated.
	 */
	if ((oldCount == 0 || availableItemsCount == 0) && isFocusControl ()) {
		redraw ();
		return;
	}
	redrawItems (redrawStart, redrawEnd, false);
}
boolean setItemHeight (int value) {
	boolean update = !customHeightSet || itemHeight < value; 
	if (update) itemHeight = value;
	return update;
}
/**
 * Marks the receiver's lines as visible if the argument is <code>true</code>,
 * and marks it invisible otherwise. 
 * <p>
 * If one of the receiver's ancestors is not visible or some
 * other condition makes the receiver not visible, marking
 * it visible may not actually cause it to be displayed.
 * </p>
 *
 * @param show the new visibility state
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @since 3.1
 */
public void setLinesVisible (boolean value) {
	checkWidget ();
	if (linesVisible == value) return;		/* no change */
	linesVisible = value;
	redraw ();
}
public void setMenu (Menu menu) {
	super.setMenu (menu);
	header.setMenu (menu);
}
public void setRedraw (boolean value) {
	checkWidget();
	if (value) {
		if (--drawCount == 0) {
			if (availableItems.length - availableItemsCount > 3) {
				TreeItem[] newAvailableItems = new TreeItem [availableItemsCount];
				System.arraycopy (availableItems, 0, newAvailableItems, 0, availableItemsCount);
				availableItems = newAvailableItems;
			}
			updateVerticalBar ();
			updateHorizontalBar ();
		}
	} else {
		drawCount++;
	}
	super.setRedraw (value);
	header.setRedraw (value);
}
/**
 * Sets the receiver's selection to the given item.
 * The current selection is cleared before the new item is selected.
 * <p>
 * If the item is not in the receiver, then it is ignored.
 * </p>
 *
 * @param item the item to select
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the item is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @since 3.2
 */
public void setSelection (TreeItem item) {
	checkWidget ();
	if (item == null) error (SWT.ERROR_NULL_ARGUMENT);
	setSelection (new TreeItem [] {item}, true);
}
/**
 * Sets the receiver's selection to be the given array of items.
 * The current selection is cleared before the new items are selected.
 * <p>
 * Items that are not in the receiver are ignored.
 * If the receiver is single-select and multiple items are specified,
 * then all items are ignored.
 * </p>
 *
 * @param items the array of items
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the array of items is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if one of the items has been disposed</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see Tree#deselectAll()
 */
public void setSelection (TreeItem[] items) {
	checkWidget ();
	if (items == null) error (SWT.ERROR_NULL_ARGUMENT);
	setSelection (items, true);
}

void setSelection (TreeItem[] items, boolean updateViewport) {
	if (items.length == 0 || ((style & SWT.SINGLE) != 0 && items.length > 1)) {
		deselectAll ();
		return;
	}
	TreeItem[] oldSelection = selectedItems;
	
	/* remove null and duplicate items */
	int index = 0;
	selectedItems = new TreeItem [items.length];	/* initially assume all valid items */
	for (int i = 0; i < items.length; i++) {
		TreeItem item = items [i];
		if (item != null && item.parent == this && !item.isSelected ()) {
			selectedItems [index++] = item;
		}
	}
	if (index != items.length) {
		/* an invalid item was provided so resize the array accordingly */
		TreeItem[] temp = new TreeItem [index];
		System.arraycopy (selectedItems, 0, temp, 0, index);
		selectedItems = temp;
	}
	if (selectedItems.length == 0) {	/* no valid items */
		deselectAll ();
		return;
	}

	for (int i = 0; i < oldSelection.length; i++) {
		if (!oldSelection [i].isSelected ()) {
			int availableIndex = oldSelection [i].availableIndex;
			if (availableIndex != -1) {
				redrawItem (availableIndex, true);
			}
		}
	}
	if (updateViewport) {
		showItem (selectedItems [0]);
		setFocusItem (selectedItems [0], true);
	}
	for (int i = 0; i < selectedItems.length; i++) {
		int availableIndex = selectedItems [i].availableIndex;
		if (availableIndex != -1) {
			redrawItem (availableIndex, true);
		}
	}
}
/**
 * Sets the column used by the sort indicator for the receiver. A null
 * value will clear the sort indicator.  The current sort column is cleared 
 * before the new column is set.
 *
 * @param column the column used by the sort indicator or <code>null</code>
 * 
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the column is disposed</li> 
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @since 3.2
 */
public void setSortColumn (TreeColumn column) {
	checkWidget ();
	if (column != null && column.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
	if (column == sortColumn) return;
	if (sortColumn != null && !sortColumn.isDisposed ()) {
		sortColumn.setSortDirection (SWT.NONE);
	}
	sortColumn = column;
	if (sortColumn != null) {
		sortColumn.setSortDirection (sortDirection);
	}
}
/**
 * Sets the direction of the sort indicator for the receiver. The value 
 * can be one of <code>UP</code>, <code>DOWN</code> or <code>NONE</code>.
 *
 * @param direction the direction of the sort indicator 
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @since 3.2
 */
public void setSortDirection (int direction) {
	checkWidget ();
	if (direction != SWT.UP && direction != SWT.DOWN && direction != SWT.NONE) return;
	sortDirection = direction;
	if (sortColumn == null || sortColumn.isDisposed ()) return;
	sortColumn.setSortDirection (sortDirection);
}
/**
 * Sets the item which is currently at the top of the receiver.
 * This item can change when items are expanded, collapsed, scrolled
 * or new items are added or removed.
 *
 * @param item the item to be shown
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the item is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see Tree#getTopItem()
 * 
 * @since 2.1
 */
public void setTopItem (TreeItem item) {
	checkWidget ();
	if (item == null) error (SWT.ERROR_NULL_ARGUMENT);
	if (item.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
	if (item.parent != this) return;

	/* item must be available */
	if (!item.isAvailable ()) item.parentItem.expandAncestors ();

	int visibleItemCount = (clientArea.height - getHeaderHeight ()) / itemHeight;
	if (availableItemsCount < visibleItemCount) return;
	int index = Math.min (item.availableIndex, availableItemsCount - visibleItemCount);
	if (topIndex == index) return;

	update ();
	int change = topIndex - index;
	topIndex = index;
	ScrollBar vBar = getVerticalBar ();
	if (vBar != null) vBar.setSelection (topIndex);
	if (drawCount <= 0) {
		GC gc = new GC (this);
		gc.copyArea (0, 0, clientArea.width, clientArea.height, 0, change * itemHeight);
		gc.dispose ();
	}
}
/**
 * Shows the column.  If the column is already showing in the receiver,
 * this method simply returns.  Otherwise, the columns are scrolled until
 * the column is visible.
 *
 * @param column the column to be shown
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the item is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @since 3.1
 */
public void showColumn (TreeColumn column) {
	checkWidget ();
	if (column == null) error (SWT.ERROR_NULL_ARGUMENT);
	if (column.isDisposed ()) error(SWT.ERROR_INVALID_ARGUMENT);
	if (column.parent != this) return;

	int x = column.getX ();
	int rightX = x + column.width;
	if (0 <= x && rightX <= clientArea.width) return;	 /* column is fully visible */

	headerHideToolTip ();
	int absX = 0;	/* the X of the column irrespective of the horizontal scroll */
	TreeColumn[] orderedColumns = getOrderedColumns ();
	for (int i = 0; i < column.getOrderIndex (); i++) {
		absX += orderedColumns [i].width;
	}
	if (x < clientArea.x) { 	/* column is to left of viewport */
		horizontalOffset = absX;
	} else {
		horizontalOffset = absX + column.width - clientArea.width;
	}
	ScrollBar hBar = getHorizontalBar (); 
	if (hBar != null) hBar.setSelection (horizontalOffset);
	redraw ();
	if (drawCount <= 0 && header.isVisible ()) header.redraw ();
}
/**
 * Shows the item.  If the item is already showing in the receiver,
 * this method simply returns.  Otherwise, the items are scrolled
 * and expanded until the item is visible.
 *
 * @param item the item to be shown
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the item is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see Tree#showSelection()
 */
public void showItem (TreeItem item) {
	checkWidget ();
	if (item == null) error (SWT.ERROR_NULL_ARGUMENT);
	if (item.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
	if (item.parent != this) return;
	
	/* item must be available */
	if (!item.isAvailable ()) item.parentItem.expandAncestors ();
	
	int index = item.availableIndex;
	int visibleItemCount = (clientArea.height - getHeaderHeight ()) / itemHeight;
	/* nothing to do if item is already in viewport */
	if (topIndex <= index && index < topIndex + visibleItemCount) return;
	
	if (index <= topIndex) {
		/* item is above current viewport, so show on top */
		setTopItem (item);
	} else {
		/* item is below current viewport, so show on bottom */
		visibleItemCount = Math.max (visibleItemCount, 1);	/* item to show should be top item */
		setTopItem (availableItems [Math.min (index - visibleItemCount + 1, availableItemsCount - 1)]);
	}
}
/**
 * Shows the selection.  If the selection is already showing in the receiver,
 * this method simply returns.  Otherwise, the items are scrolled until
 * the selection is visible.
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see Tree#showItem(TreeItem)
 */
public void showSelection () {
	checkWidget ();
	if (selectedItems.length == 0) return;
	showItem (selectedItems [0]);
}
void updateColumnWidth (TreeColumn column, int width) {
	headerHideToolTip ();
	int oldWidth = column.width;
	int columnX = column.getX ();
	int x = columnX + oldWidth - 1;	/* -1 ensures that grid line is included */

	update ();
	GC gc = new GC (this);
	gc.copyArea (x, 0, clientArea.width - x, clientArea.height, columnX + width - 1, 0);	/* dest x -1 offsets x's -1 above */
	if (width > oldWidth) {
		/* column width grew */
		int change = width - oldWidth + 1;	/* +1 offsets x's -1 above */
		/* -1/+1 below ensure that right bound of selection redraws correctly in column */
		redraw (x - 1, 0, change + 1, clientArea.height, false);
	} else {
		int change = oldWidth - width + 1;	/* +1 offsets x's -1 above */
		redraw (clientArea.width - change, 0, change, clientArea.height, false);
	}
	/* the focus box must be repainted because its stipple may become shifted as a result of its new width */
	if (focusItem != null) redrawItem (focusItem.availableIndex, true);

	GC headerGC = new GC (header);
	if (drawCount <= 0 && header.getVisible ()) {
		Rectangle headerBounds = header.getClientArea ();
		header.update ();
		x -= 1;	/* -1 ensures that full header column separator is included */
		headerGC.copyArea (x, 0, headerBounds.width - x, headerBounds.height, columnX + width - 2, 0);	/* dest x -2 offsets x's -1s above */
		if (width > oldWidth) {
			/* column width grew */
			int change = width - oldWidth + 2;	/* +2 offsets x's -1s above */
			header.redraw (x, 0, change, headerBounds.height, false);
		} else {
			int change = oldWidth - width + 2;	/* +2 offsets x's -1s above */
			header.redraw (headerBounds.width - change, 0, change, headerBounds.height, false);
		}
	}

	column.width = width;

	/*
	 * Notify column and all items of column width change so that display labels
	 * can be recomputed if needed.
	 */
	column.updateWidth (headerGC);
	headerGC.dispose ();
	for (int i = 0; i < items.length; i++) {
		items [i].updateColumnWidth (column, gc);
	}
	gc.dispose ();

	int maximum = 0;
	for (int i = 0; i < columns.length; i++) {
		maximum += columns [i].width;
	}
	ScrollBar hBar = getHorizontalBar ();
	if (hBar != null) {
		hBar.setMaximum (Math.max (1, maximum));	/* setting a value of 0 here is ignored */
		if (hBar.getThumb () != clientArea.width) {
			hBar.setThumb (clientArea.width);
			hBar.setPageIncrement (clientArea.width);
		}
		int oldHorizontalOffset = horizontalOffset;	/* hBar.setVisible() can modify horizontalOffset */
		hBar.setVisible (clientArea.width < maximum);
		int selection = hBar.getSelection ();
		if (selection != oldHorizontalOffset) {
			horizontalOffset = selection;
			redraw ();
			if (drawCount <= 0 && header.getVisible ()) header.redraw ();
		}
	}

	column.sendEvent (SWT.Resize);
	TreeColumn[] orderedColumns = getOrderedColumns ();
	for (int i = column.getOrderIndex () + 1; i < orderedColumns.length; i++) {
		if (!orderedColumns [i].isDisposed ()) {
			orderedColumns [i].sendEvent (SWT.Move);
		}
	}

	if (availableItemsCount == 0) redraw ();	/* ensure that static focus rectangle updates properly */
}
/*
 * This is a naive implementation that computes the value from scratch.
 */
void updateHorizontalBar () {
	if (drawCount > 0) return;
	ScrollBar hBar = getHorizontalBar ();
	if (hBar == null) return;

	int maxX = 0;
	if (columns.length > 0) {
		for (int i = 0; i < columns.length; i++) {
			maxX += columns [i].width;
		}
	} else {
		for (int i = 0; i < availableItemsCount; i++) {
			Rectangle itemBounds = availableItems [i].getCellBounds (0);
			maxX = Math.max (maxX, itemBounds.x + itemBounds.width + horizontalOffset);
		}
	}
	
	int clientWidth = clientArea.width;
	if (maxX != hBar.getMaximum ()) {
		hBar.setMaximum (Math.max (1, maxX));	/* setting a value of 0 here is ignored */
	}
	int thumb = Math.min (clientWidth, maxX);
	if (thumb != hBar.getThumb ()) {
		hBar.setThumb (thumb);
		hBar.setPageIncrement (thumb);
	}
	hBar.setVisible (clientWidth < maxX);
	
	/* reclaim any space now left on the right */
	if (maxX < horizontalOffset + thumb) {
		horizontalOffset = maxX - thumb;
		hBar.setSelection (horizontalOffset);
		redraw ();
	} else {
		int selection = hBar.getSelection ();
		if (selection != horizontalOffset) {
			horizontalOffset = selection;
			redraw ();
		}
	}
}
/*
 * Update the horizontal bar, if needed, in response to an item change (eg.- created,
 * disposed, expanded, etc.).  newRightX is the new rightmost X value of the item,
 * and rightXchange is the change that led to the item's rightmost X value becoming
 * newRightX (so oldRightX + rightXchange = newRightX)
 */
void updateHorizontalBar (int newRightX, int rightXchange) {
	if (drawCount > 0) return;
	ScrollBar hBar = getHorizontalBar ();
	if (hBar == null) return;

	newRightX += horizontalOffset;
	int barMaximum = hBar.getMaximum ();
	if (newRightX > barMaximum) {	/* item has extended beyond previous maximum */
		hBar.setMaximum (newRightX);
		int clientAreaWidth = clientArea.width;
		int thumb = Math.min (newRightX, clientAreaWidth);
		if (hBar.getThumb () != thumb) {
			hBar.setThumb (thumb);
			hBar.setPageIncrement (thumb);
		}
		hBar.setVisible (clientAreaWidth <= newRightX);
		return;
	}

	int previousRightX = newRightX - rightXchange;
	if (previousRightX != barMaximum) {
		/* this was not the rightmost item, so just check for client width change */
		int clientAreaWidth = clientArea.width;
		int thumb = Math.min (barMaximum, clientAreaWidth);
		if (hBar.getThumb () != thumb) {
			hBar.setThumb (thumb);
			hBar.setPageIncrement (thumb);
		}
		hBar.setVisible (clientAreaWidth <= barMaximum);
		return;
	}
	updateHorizontalBar ();		/* must search for the new rightmost item */
}
void updateVerticalBar () {
	if (drawCount > 0) return;
	ScrollBar vBar = getVerticalBar ();
	if (vBar == null) return;

	int pageSize = (clientArea.height - getHeaderHeight ()) / itemHeight;
	int maximum = Math.max (1, availableItemsCount);
	if (maximum != vBar.getMaximum ()) {
		vBar.setMaximum (maximum);
	}
	int thumb = Math.min (pageSize, maximum);
	if (thumb != vBar.getThumb ()) {
		vBar.setThumb (thumb);
		vBar.setPageIncrement (thumb);
	}
	vBar.setVisible (pageSize < maximum);

	/* reclaim any space now left on the bottom */
	if (maximum < topIndex + thumb) {
		topIndex = maximum - thumb;
		vBar.setSelection (topIndex);
		redraw ();
	} else {
		int selection = vBar.getSelection ();
		if (selection != topIndex) {
			topIndex = selection;
			redraw ();
		}
	}
}
}
