/*******************************************************************************
 * 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.graphics.*;
import org.eclipse.swt.internal.Compatibility;

/**
 * Instances of this class represent a selectable user interface object
 * that represents a hierarchy of tree items in a tree widget.
 * 
 * <dl>
 * <dt><b>Styles:</b></dt>
 * <dd>(none)</dd>
 * <dt><b>Events:</b></dt>
 * <dd>(none)</dd>
 * </dl>
 * <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/">Sample code and further information</a>
 * @noextend This class is not intended to be subclassed by clients.
 */
public class TreeItem extends Item {
	Tree parent;
	TreeItem parentItem;
	TreeItem[] items = Tree.NO_ITEMS;
	int availableIndex = -1;	/* index in parent's flat list of available (though not necessarily within viewport) items */
	int depth = 0;				/* cached for performance, does not change after instantiation */
	boolean checked, grayed, expanded, cached;

	String[] texts;
	int[] textWidths = new int [1];	/* cached string measurements */
	int customWidth = -1;				/* width specified by Measure callback */
	int fontHeight;						/* cached item font height */
	int[] fontHeights;
	Image[] images;
	Color foreground, background;
	String[] displayTexts;
	Color[] cellForegrounds, cellBackgrounds;
	Font font;
	Font[] cellFonts;
	
	static final int INDENT_HIERARCHY = 6;	/* the margin between an item's expander and its checkbox or content */
	static final int MARGIN_TEXT = 3;			/* the left and right margins within the text's space */

/**
 * Constructs a new instance of this class given its parent
 * (which must be a <code>Tree</code> or a <code>TreeItem</code>)
 * and a style value describing its behavior and appearance.
 * The item is added to the end of the items maintained by its parent.
 * <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 tree 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
 * @see Widget#checkSubclass
 * @see Widget#getStyle
 */
public TreeItem (Tree parent, int style) {
	this (parent, style, checkNull (parent).items.length);
}
/**
 * Constructs a new instance of this class given its parent
 * (which must be a <code>Tree</code> or a <code>TreeItem</code>),
 * a style value describing its behavior and appearance, and the index
 * at which to place it in the items maintained by its parent.
 * <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 tree control which will be the parent of the new instance (cannot be null)
 * @param style the style of control to construct
 * @param index the zero-relative index to store the receiver in its parent
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
 *    <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</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
 * @see Widget#checkSubclass
 * @see Widget#getStyle
 */
public TreeItem (Tree parent, int style, int index) {
	this (parent, style, index, true);
}
/**
 * Constructs a new instance of this class given its parent
 * (which must be a <code>Tree</code> or a <code>TreeItem</code>)
 * and a style value describing its behavior and appearance.
 * The item is added to the end of the items maintained by its parent.
 * <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 parentItem a tree 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
 * @see Widget#checkSubclass
 * @see Widget#getStyle
 */
public TreeItem (TreeItem parentItem, int style) {
	this (parentItem, style, checkNull (parentItem).items.length);
}
/**
 * Constructs a new instance of this class given its parent
 * (which must be a <code>Tree</code> or a <code>TreeItem</code>),
 * a style value describing its behavior and appearance, and the index
 * at which to place it in the items maintained by its parent.
 * <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 parentItem a tree control which will be the parent of the new instance (cannot be null)
 * @param style the style of control to construct
 * @param index the zero-relative index to store the receiver in its parent
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
 *    <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</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
 * @see Widget#checkSubclass
 * @see Widget#getStyle
 */
public TreeItem (TreeItem parentItem, int style, int index) {
	this (parentItem, style, index, true);
}
TreeItem (TreeItem parentItem, int style, int index, boolean notifyParent) {
	super (parentItem, style);
	this.parentItem = parentItem;
	parent = parentItem.parent;
	depth = parentItem.depth + 1;
	int validItemIndex = parentItem.items.length;
	if (!(0 <= index && index <= validItemIndex)) error (SWT.ERROR_INVALID_RANGE);
	int columnCount = parent.columns.length;
	if (columnCount > 0) {
		displayTexts = new String [columnCount];
		if (columnCount > 1) {
			texts = new String [columnCount];
			textWidths = new int [columnCount];
			images = new Image [columnCount];
		}
	}
	if (notifyParent) parentItem.addItem (this, index);
}
TreeItem (Tree parent, int style, int index, boolean notifyParent) {
	super (parent, style);
	int validItemIndex = parent.items.length;
	if (!(0 <= index && index <= validItemIndex)) error (SWT.ERROR_INVALID_RANGE);
	this.parent = parent;
	int columnCount = parent.columns.length;
	if (columnCount > 0) {
		displayTexts = new String [columnCount];
		if (columnCount > 1) {
			texts = new String [columnCount];
			textWidths = new int [columnCount];
			images = new Image [columnCount];
		}
	}
	if (notifyParent) parent.createItem (this, index);
}
/*
 * Updates internal structures in the receiver and its child items to handle the creation of a new column.
 */
void addColumn (TreeColumn column) {
	int index = column.getIndex ();
	int columnCount = parent.columns.length;

	if (columnCount > 1) {
		if (columnCount == 2) {
			texts = new String [2];
		} else {
			String[] newTexts = new String [columnCount];
			System.arraycopy (texts, 0, newTexts, 0, index);
			System.arraycopy (texts, index, newTexts, index + 1, columnCount - index - 1);
			texts = newTexts;
		}
		if (index == 0) {
			texts [1] = text;
			text = "";	//$NON-NLS-1$
		}

		if (columnCount == 2) {
			images = new Image [2];
		} else {
			Image[] newImages = new Image [columnCount];
			System.arraycopy (images, 0, newImages, 0, index);
			System.arraycopy (images, index, newImages, index + 1, columnCount - index - 1);
			images = newImages;
		}
		if (index == 0) {
			images [1] = image;
			image = null;
		}
		
		int[] newTextWidths = new int [columnCount];
		System.arraycopy (textWidths, 0, newTextWidths, 0, index);
		System.arraycopy (textWidths, index, newTextWidths, index + 1, columnCount - index - 1);
		textWidths = newTextWidths;
	} else {
		customWidth = -1;		/* columnCount == 1 */
	}

	/*
	 * The length of displayTexts always matches the parent's column count, unless this
	 * count is zero, in which case displayTexts is null.  
	 */
	String[] newDisplayTexts = new String [columnCount];
	if (columnCount > 1) {
		System.arraycopy (displayTexts, 0, newDisplayTexts, 0, index);
		System.arraycopy (displayTexts, index, newDisplayTexts, index + 1, columnCount - index - 1);
	}
	displayTexts = newDisplayTexts;

	if (cellBackgrounds != null) {
		Color[] newCellBackgrounds = new Color [columnCount];
		System.arraycopy (cellBackgrounds, 0, newCellBackgrounds, 0, index);
		System.arraycopy (cellBackgrounds, index, newCellBackgrounds, index + 1, columnCount - index - 1);
		cellBackgrounds = newCellBackgrounds;
	}
	if (cellForegrounds != null) {
		Color[] newCellForegrounds = new Color [columnCount];
		System.arraycopy (cellForegrounds, 0, newCellForegrounds, 0, index);
		System.arraycopy (cellForegrounds, index, newCellForegrounds, index + 1, columnCount - index - 1);
		cellForegrounds = newCellForegrounds;
	}
	if (cellFonts != null) {
		Font[] newCellFonts = new Font [columnCount];
		System.arraycopy (cellFonts, 0, newCellFonts, 0, index);
		System.arraycopy (cellFonts, index, newCellFonts, index + 1, columnCount - index - 1);
		cellFonts = newCellFonts;

		int[] newFontHeights = new int [columnCount];
		System.arraycopy (fontHeights, 0, newFontHeights, 0, index);
		System.arraycopy (fontHeights, index, newFontHeights, index + 1, columnCount - index - 1);
		fontHeights = newFontHeights;
	}

	int orderedIndex = column.getOrderIndex ();
	if (orderedIndex == 0 && columnCount > 1) {
		/*
		 * The new second ordered column now has more space available to it than it did while
		 * it was the first ordered column since it no longer has to show hierarchy decorations,
		 * so recompute its displayText.
		 */
		TreeColumn[] orderedColumns = parent.getOrderedColumns ();
		int secondColumnIndex = orderedColumns [1].getIndex ();
		GC gc = new GC (parent);
		gc.setFont (getFont (secondColumnIndex, false));
		computeDisplayText (secondColumnIndex, gc);
		gc.dispose ();
	}
	
	/* notify all child items as well */
	for (int i = 0; i < items.length; i++) {
		items[i].addColumn (column);
	}
}
/*
 * Adds a child item to the receiver.
 */
void addItem (TreeItem item, int index) {
	TreeItem[] newChildren = new TreeItem [items.length + 1];
	System.arraycopy (items, 0, newChildren, 0, index);
	newChildren [index] = item;
	System.arraycopy (items, index, newChildren, index + 1, items.length - index);
	items = newChildren;

	if (!item.isAvailable ()) {
		/* receiver will now need an expander box if this is its first child */
		if (isInViewport () && items.length == 1) {
			Rectangle bounds = getExpanderBounds ();
			parent.redraw (bounds.x, bounds.y, bounds.width, bounds.height, false);
		}
		return;
	}
	
	/* item should be available immediately so update parent */
	parent.makeAvailable (item);
	
	/* update scrollbars */
	Rectangle bounds = item.getBounds (false);
	int rightX = bounds.x + bounds.width;
	parent.updateHorizontalBar (rightX, rightX);
	parent.updateVerticalBar ();
	/* 
	 * 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 < parent.topIndex) {
		parent.topIndex++;
		ScrollBar vBar = parent.getVerticalBar ();
		if (vBar != null) vBar.setSelection (parent.topIndex);
		return;
	}
	
	parent.redrawFromItemDownwards (availableIndex);
}
static Tree checkNull (Tree tree) {
	if (tree == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
	return tree;
}
static TreeItem checkNull (TreeItem item) {
	if (item == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
	return item;
}
protected void checkSubclass () {
	if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
}
void clear () {
	checked = grayed = false;
	texts = null;
	textWidths = new int [1];
	fontHeight = 0;
	fontHeights = null;
	images = null;
	foreground = background = null;
	displayTexts = null;
	cellForegrounds = cellBackgrounds = null;
	font = null;
	cellFonts = null;
	cached = false;
	text = "";
	image = null;

	int columnCount = parent.columns.length;
	if (columnCount > 0) {
		displayTexts = new String [columnCount];
		if (columnCount > 1) {
			texts = new String [columnCount];
			textWidths = new int [columnCount];
			images = new Image [columnCount];
		}
	}
}
/**
 * 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 (item.availableIndex != -1 && parent.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);
	}
	if (item.availableIndex == -1) return;	/* no visual update needed */

	/* adjust the horizontal scrollbar if needed */
	if (parent.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;
		}
		parent.updateHorizontalBar (newRightX, newRightX - oldRightX);
	}

	/* redraw the item(s) */
	if (recursive) {
		int descendentCount = availableDescendents == null ?
			item.computeAvailableDescendentCount () :
			availableDescendents.length;
		parent.redrawItems (item.availableIndex, item.availableIndex + descendentCount - 1, false);
	} else {
		parent.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) {
	clearAll (recursive, true);
}
void clearAll (boolean recursive, boolean doVisualUpdate) {
	checkWidget ();
	if (items.length == 0) return;

	/* if there are no columns then the horizontal scrollbar may need adjusting */
	TreeItem[] availableDescendents = null;
	int oldRightX = 0;
	if (doVisualUpdate && availableIndex != -1 && expanded && parent.columns.length == 0) {
		if (recursive) {
			availableDescendents = computeAvailableDescendents ();
			/*
			 * i starts at 1 here because item 0 in availableDescendents
			 * will be the receiver, but this item is not being cleared.
			 */
			for (int i = 1; i < availableDescendents.length; i++) {
				Rectangle bounds = availableDescendents [i].getBounds (false);
				oldRightX = Math.max (oldRightX, bounds.x + bounds.width);
			}
		} else {
			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);
	}

	if (!doVisualUpdate || availableIndex == -1 || !expanded) return;	/* no visual update needed */

	/* adjust the horizontal scrollbar if needed */
	if (parent.columns.length == 0) {
		int newRightX = 0;
		if (recursive) {
			/*
			 * i starts at 1 here because item 0 in availableDescendents
			 * is the receiver, but this item was not cleared.
			 */
			for (int i = 1; i < availableDescendents.length; i++) {
				Rectangle bounds = availableDescendents [i].getBounds (false);
				newRightX = Math.max (newRightX, bounds.x + bounds.width);
			}
		} else {
			/*
			 * All cleared direct child 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);
			newRightX = bounds.x + bounds.width;
		}
		parent.updateHorizontalBar (newRightX, newRightX - oldRightX);
	}

	/* redraw the item(s) */
	if (recursive) {
		int startIndex = items [0].availableIndex;
		TreeItem lastChild = items [items.length - 1]; 
		int endIndex = lastChild.availableIndex + lastChild.computeAvailableDescendentCount () - 1;
		parent.redrawItems (startIndex, endIndex, false);
	} else {
		for (int i = 0; i < items.length; i++) {
			parent.redrawItem (items [i].availableIndex, false);
		}
	}
}
/*
 * Returns a collection of all tree items descending from the receiver, including
 * the receiver.  The order of the items in this collection are receiver, child0tree,
 * child1tree, ..., childNtree. 
 */
TreeItem[] computeAllDescendents () {
	int childCount = items.length;
	TreeItem[][] childResults = new TreeItem [childCount][];
	int count = 1;	/* receiver */
	for (int i = 0; i < childCount; i++) {
		childResults [i] = items [i].computeAllDescendents ();
		count += childResults [i].length;
	}
	TreeItem[] result = new TreeItem [count];
	int index = 0;
	result [index++] = this;
	for (int i = 0; i < childCount; i++) {
		System.arraycopy (childResults [i], 0, result, index, childResults [i].length);
		index += childResults [i].length;
	}
	return result;
}
/*
 * Returns the number of tree items descending from the receiver, including the
 * receiver, that are currently available.  It is assumed that the receiver is
 * currently available. 
 */
int computeAvailableDescendentCount () {
	int result = 1;		/* receiver */
	if (!expanded) return result;
	for (int i = 0; i < items.length; i++) {
		result += items [i].computeAvailableDescendentCount ();
	}
	return result;
}
/*
 * Returns a collection of the tree items descending from the receiver, including
 * the receiver, that are currently available.  It is assumed that the receiver is
 * currently available.  The order of the items in this collection are receiver,
 * child0tree, child1tree, ..., childNtree. 
 */
TreeItem[] computeAvailableDescendents () {
	if (!expanded) return new TreeItem[] {this};
	int childCount = items.length;
	TreeItem[][] childResults = new TreeItem [childCount][];
	int count = 1;	/* receiver */
	for (int i = 0; i < childCount; i++) {
		childResults [i] = items [i].computeAvailableDescendents ();
		count += childResults [i].length;
	}
	TreeItem[] result = new TreeItem [count];
	int index = 0;
	result [index++] = this;
	for (int i = 0; i < childCount; i++) {
		System.arraycopy (childResults [i], 0, result, index, childResults [i].length);
		index += childResults [i].length;
	}
	return result;
}
void computeDisplayText (int columnIndex, GC gc) {
	if ((parent.style & SWT.VIRTUAL) != 0 && !cached) return;	/* nothing to do */

	int columnCount = parent.columns.length;
	if (columnCount == 0) {
		String text = getText (0, false);
		textWidths [columnIndex] = gc.stringExtent (text).x;
		return;
	}

	int orderedIndex = parent.columns.length == 0 ? 0 : parent.columns [columnIndex].getOrderIndex ();
	TreeColumn column = parent.columns [columnIndex];
	int availableWidth;
	if (orderedIndex == 0) {
		/* ordered column 0 is always LEFT and must consider hierarchy decorations */
		availableWidth = column.getX () + column.width - getTextX (columnIndex) - 2 * MARGIN_TEXT;
	} else {
		/* ordered columns > 0 may not be LEFT so cannot use getTextX (int) */
		availableWidth = column.width - 2 * parent.getCellPadding () - 2 * MARGIN_TEXT;
		if (images [columnIndex] != null) {
			availableWidth -= images [columnIndex].getBounds ().width;
			availableWidth -= Tree.MARGIN_IMAGE;
		}
	}
	String text = getText (columnIndex, false);
	int textWidth = gc.stringExtent (text).x;
	if (textWidth <= availableWidth) {
		displayTexts [columnIndex] = text;
		textWidths [columnIndex] = textWidth;
		return;
	}

	/* Ellipsis will be needed, so subtract their width from the available text width */
	int ellipsisWidth = gc.stringExtent (Tree.ELLIPSIS).x;
	availableWidth -= ellipsisWidth;
	if (availableWidth <= 0) {
		displayTexts [columnIndex] = Tree.ELLIPSIS;
		textWidths [columnIndex] = ellipsisWidth;
		return;
	}
	
	/* Make initial guess. */
	int index = Math.min (availableWidth / gc.getFontMetrics ().getAverageCharWidth (), text.length ());
	textWidth = gc.stringExtent (text.substring (0, index)).x;

	/* Initial guess is correct. */
	if (availableWidth == textWidth) {
		displayTexts [columnIndex] = text.substring (0, index) + Tree.ELLIPSIS;
		textWidths [columnIndex] = textWidth + ellipsisWidth;
		return;
	}

	/* Initial guess is too high, so reduce until fit is found. */
	if (availableWidth < textWidth) {
		do {
			index--;
			if (index < 0) {
				displayTexts [columnIndex] = Tree.ELLIPSIS;
				textWidths [columnIndex] = ellipsisWidth;
				return;
			}
			text = text.substring (0, index);
			textWidth = gc.stringExtent (text).x;
		} while (availableWidth < textWidth);
		displayTexts [columnIndex] = text + Tree.ELLIPSIS;
		textWidths [columnIndex] = textWidth + ellipsisWidth;
		return;
	}
	
	/* Initial guess is too low, so increase until overrun is found. */
	int previousWidth = 0;
	while (textWidth < availableWidth) {
		index++;
		previousWidth = textWidth;
		textWidth = gc.stringExtent (text.substring (0, index)).x;
	}
	displayTexts [columnIndex] = text.substring (0, index - 1) + Tree.ELLIPSIS;
	textWidths [columnIndex] = previousWidth + ellipsisWidth;
}
void computeDisplayTexts (GC gc) {
	if ((parent.style & SWT.VIRTUAL) != 0 && !cached) return;	/* nothing to do */

	int columnCount = parent.columns.length;
	if (columnCount == 0) return;
	
	for (int i = 0; i < columnCount; i++) {
		gc.setFont (getFont (i, false));
		computeDisplayText (i, gc);
	}
}
/*
 * Computes the cached text widths.
 */
void computeTextWidths (GC gc) {
	if ((parent.style & SWT.VIRTUAL) != 0 && !cached) return;	/* nothing to do */

	int validColumnCount = Math.max (1, parent.columns.length);
	textWidths = new int [validColumnCount];
	for (int i = 0; i < textWidths.length; i++) {
		String value = getDisplayText (i);
		if (value != null) {
			gc.setFont (getFont (i, false));
			textWidths [i] = gc.stringExtent (value).x;
		}
	}
}
public void dispose () {
	if (isDisposed ()) return;
	int startIndex = -1, endIndex = -1;
	Tree parent = this.parent;
	int index = getIndex ();
	
	/* determine the indices, if any, that will need to be visually updated */
	if (isAvailable ()) {
		if (isLastChild () && index > 0) {
			/* vertical connector lines no longer needed for this item */
			if (parentItem != null) {
				startIndex = parentItem.items [index - 1].availableIndex;
			} else {
				startIndex = parent.items [index - 1].availableIndex;
			}
		} else {
			startIndex = availableIndex;
		}
		endIndex = parent.availableItemsCount - 1;
	}

	/* for performance do this upfront for whole descendent chain */
	TreeItem focusItem = parent.focusItem; 
	if (focusItem != null && focusItem.hasAncestor (this)) {
		parent.setFocusItem (this, false);
		parent.reassignFocus ();
		focusItem = parent.focusItem;
		if (focusItem != null) {
			parent.redrawItem (focusItem.availableIndex, true);
		}
	}
	if (parentItem != null) parentItem.removeItem (this, index);
	dispose (true);
	if (startIndex != -1) {
		parent.redrawItems (startIndex, endIndex, false);
	}
}
void dispose (boolean notifyParent) {
	if (isDisposed ()) return;
	for (int i = 0; i < items.length; i++) {
		items [i].dispose (notifyParent);
	}
	if (notifyParent) parent.destroyItem (this);
	super.dispose ();	/* super is intentional here */
	background = foreground = null;
	cellBackgrounds = cellForegrounds = null;
	font = null;
	cellFonts = null;
	images = null;
	texts = displayTexts = null;
	textWidths = fontHeights = null;
	parent = null;
	parentItem = null;
	items = null;
}
/*
 * Ensure that all ancestors of the receiver are expanded
 */
void expandAncestors () {
	if (parentItem != null) parentItem.expandAncestors ();
	setExpanded (true);
	Event newEvent = new Event ();
	newEvent.item = this;
	parent.inExpand = true;
	parent.sendEvent (SWT.Expand, newEvent);
	parent.inExpand = false;
	if (isDisposed ()) return;
	if (items.length == 0) {
		expanded = false;
	}
}
/**
 * Returns the receiver's background color.
 *
 * @return the background color
 * 
 * @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.0
 * 
 */
public Color getBackground () {
	checkWidget ();
	if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
	if (background != null) return background;
	return parent.getBackground ();
}
/**
 * Returns the background color at the given column index in the receiver.
 *
 * @param index the column index
 * @return the background color
 *
 * @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 Color getBackground (int columnIndex) {
	checkWidget ();
	if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
	int validColumnCount = Math.max (1, parent.columns.length);
	if (!(0 <= columnIndex && columnIndex < validColumnCount)) return getBackground ();
	if (cellBackgrounds == null || cellBackgrounds [columnIndex] == null) return getBackground ();
	return cellBackgrounds [columnIndex];
}
/**
 * Returns a rectangle describing the receiver's size and location
 * relative to its parent.
 *
 * @return the receiver's bounding rectangle
 *
 * @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 Rectangle getBounds () {
	checkWidget ();
	return getBounds (true);
}
Rectangle getBounds (boolean checkData) {
	if (checkData && !parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
	if (!isAvailable ()) return new Rectangle (0, 0, 0, 0);
	TreeColumn[] orderedColumns = parent.getOrderedColumns ();
	int orderedCol0Index = orderedColumns.length == 0 ? 0 : orderedColumns [0].getIndex ();
	int x = getTextX (orderedCol0Index);
	int width = textWidths [orderedCol0Index] + 2 * MARGIN_TEXT;
	if (orderedColumns.length > 0) {
		TreeColumn column = orderedColumns [0];
		int right = column.getX () + column.width;
		if (x + width > right) {
			width = Math.max (0, right - x);
		}
	}
	return new Rectangle (x, parent.getItemY (this), width, parent.itemHeight);
}
/**
 * Returns a rectangle describing the receiver's size and location
 * relative to its parent at a column in the tree.
 *
 * @param index the index that specifies the column
 * @return the receiver's bounding column rectangle
 *
 * @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 Rectangle getBounds (int columnIndex) {
	checkWidget ();
	if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
	if (!isAvailable ()) return new Rectangle (0, 0, 0, 0);
	TreeColumn[] columns = parent.columns;
	int columnCount = columns.length;
	int validColumnCount = Math.max (1, columnCount);
	if (!(0 <= columnIndex && columnIndex < validColumnCount)) {
		return new Rectangle (0, 0, 0, 0);
	}
	/*
	 * If there are no columns then this is the bounds of the receiver's content.
	 */
	if (columnCount == 0) {
		return new Rectangle (
			getContentX (0),
			parent.getItemY (this),
			getContentWidth (0),
			parent.itemHeight - 1);
	}

	TreeColumn column = columns [columnIndex];
	if (column.getOrderIndex () == 0) {
		/* 
		 * For ordered column 0 this is bounds from the beginning of the content to the
		 * end of the column.
		 */
		int x = getContentX (columnIndex);
		int offset = x - column.getX ();
		int width = Math.max (0, column.width - offset - 1);		/* max is for columns with small widths */
		return new Rectangle (x, parent.getItemY (this) + 1, width, parent.itemHeight - 1);
	}
	/*
	 * For ordered columns > 0 this is the bounds of the tree cell.
	 */
	return new Rectangle (column.getX (), parent.getItemY (this) + 1, column.width, parent.itemHeight - 1);
}
/*
 * Returns the full bounds of a cell in a tree, regardless of its content.
 */
Rectangle getCellBounds (int columnIndex) {
	int y = parent.getItemY (this);
	if (parent.columns.length == 0) {
		int width;
		if (customWidth != -1) {
			width = getContentX (0) + customWidth + parent.horizontalOffset;
		} else {
			int textPaintWidth = textWidths [0] + 2 * MARGIN_TEXT;
			width = getTextX (0) + textPaintWidth + parent.horizontalOffset;
		}
		return new Rectangle (-parent.horizontalOffset, y, width, parent.itemHeight);
	}
	TreeColumn column = parent.columns [columnIndex];
	return new Rectangle (column.getX (), y, column.width, parent.itemHeight);
}
/*
 * Returns the bounds of the receiver's checkbox, or null if the parent's style does not
 * include SWT.CHECK.
 */
Rectangle getCheckboxBounds () {
	if ((parent.getStyle () & SWT.CHECK) == 0) return null;
	int itemHeight = parent.itemHeight;
	Rectangle result = parent.checkboxBounds;
	Point[] hLinePoints = getHconnectorEndpoints ();
	result.x = hLinePoints [1].x;
	result.y = parent.getItemY (this) + (itemHeight - result.height) / 2;
	return result;
}
/**
 * Returns <code>true</code> if the receiver is checked,
 * and false otherwise.  When the parent does not have
 * the <code>CHECK style, return false.
 * <p>
 *
 * @return the checked 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>
 */
public boolean getChecked () {
	checkWidget ();
	if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
	return checked;
}
int getContentWidth (int columnIndex) {
	int width = textWidths [columnIndex] + 2 * MARGIN_TEXT;
	int orderedIndex = parent.columns.length == 0 ? 0 : parent.columns [columnIndex].getOrderIndex ();
	if (orderedIndex == 0) {
		width += parent.orderedCol0imageWidth;
		if (parent.orderedCol0imageWidth > 0) width += Tree.MARGIN_IMAGE;
	} else {
		Image image = getImage (columnIndex, false);
		if (image != null) {
			width += image.getBounds ().width + Tree.MARGIN_IMAGE;
		}
	}
	return width;
}
/*
 * Returns the x value where the receiver's content (ie.- its image or text) begins
 * for the specified column.  For ordered columns > 0 this is dependent upon column
 * alignment, and for ordered column 0 this is dependent upon the receiver's depth in
 * the tree item hierarchy and the presence/absence of a checkbox.
 */
int getContentX (int columnIndex) {
	int orderedIndex = parent.columns.length == 0 ? 0 : parent.columns [columnIndex].getOrderIndex ();
	if (orderedIndex > 0) {
		TreeColumn column = parent.columns [columnIndex];
		int contentX = column.getX () + parent.getCellPadding ();
		if ((column.style & SWT.LEFT) != 0) return contentX;

		/* column is not left-aligned */
		int contentWidth = getContentWidth (columnIndex);
		if ((column.style & SWT.RIGHT) != 0) {
			int padding = parent.getCellPadding ();
			contentX = Math.max (contentX, column.getX () + column.width - padding - contentWidth);	
		} else {	/* SWT.CENTER */
			contentX = Math.max (contentX, column.getX () + (column.width - contentWidth) / 2);
		}
		return contentX;
	}

	/* ordered column 0 (always left-aligned) */
	if ((parent.style & SWT.CHECK) != 0) {
		Rectangle checkBounds = getCheckboxBounds ();
		return checkBounds.x + checkBounds.width + Tree.MARGIN_IMAGE;
	}

	int contentX = parent.getCellPadding () - parent.horizontalOffset;
	if (parentItem != null) {
		int expanderWidth = parent.expanderBounds.width + INDENT_HIERARCHY;
		contentX += expanderWidth * depth;
	}
	contentX += parent.expanderBounds.width;
	return contentX + Tree.MARGIN_IMAGE + INDENT_HIERARCHY;
}
String getDisplayText (int columnIndex) {
	if (parent.columns.length == 0) return getText (0, false);
	String result = displayTexts [columnIndex];
	return result != null ? result : "";	//$NON-NLS-1$
}
/**
 * Returns <code>true</code> if the receiver is expanded,
 * and false otherwise.
 * <p>
 *
 * @return the expanded 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>
 */
public boolean getExpanded () {
	checkWidget ();
	if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
	return expanded;
}
/*
 * Returns the bounds of the receiver's expander box, regardless of whether the
 * receiver currently has children or not.
 */ 
Rectangle getExpanderBounds () {
	int itemHeight = parent.itemHeight;
	int x = parent.getCellPadding () - parent.horizontalOffset;
	int y = parent.getItemY (this);
	if (parentItem != null) {
		int expanderWidth = parent.expanderBounds.width + INDENT_HIERARCHY;
		x += expanderWidth * depth;
	}
	return new Rectangle (
		x, y + (itemHeight - parent.expanderBounds.height) / 2,
		parent.expanderBounds.width, parent.expanderBounds.height);
}
/*
 * Returns the bounds that should be used for drawing a focus rectangle on the receiver
 */
Rectangle getFocusBounds () {
	TreeColumn[] columns = parent.columns;
	int orderedCol0index = columns.length == 0 ? 0 : parent.getOrderedColumns ()[0].getIndex ();
	int x = getTextX (orderedCol0index);

	int width;
	if (columns.length > 0) {
		/* ensure that the focus x does not start beyond the right bound of ordered column 0 */
		int rightX = columns [orderedCol0index].getX () + columns [orderedCol0index].width;
		x = Math.min (x, rightX - 1);
		
		TreeColumn column;
		if ((parent.style & SWT.FULL_SELECTION) != 0) {
			int[] columnOrder = parent.getColumnOrder ();
			column = columns [columnOrder [columnOrder.length - 1]];	/* last ordered column */
		} else {
			column = columns [orderedCol0index];
		}
		width = column.getX () + column.width - x - 1;
	} else {	/* no columns */
		if (customWidth != -1) {
			width = customWidth;
		} else {
			width = textWidths [0] + 2 * MARGIN_TEXT;
		}
	}

	return new Rectangle (
		x,
		parent.getItemY (this) + (parent.linesVisible ? 1 : 0),
		width,
		parent.itemHeight - (parent.linesVisible ? 1 : 0));
}
/**
 * Returns the font that the receiver will use to paint textual information for this item.
 *
 * @return the receiver's font
 *
 * @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.0
 */
public Font getFont () {
	checkWidget ();
	return getFont (true);
}
Font getFont (boolean checkData) {
	if (checkData && !parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
	if (font != null) return font;
	return parent.getFont ();
}
/**
 * Returns the font that the receiver will use to paint textual information
 * for the specified cell in this item.
 *
 * @param index the column index
 * @return the receiver's font
 *
 * @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 Font getFont (int columnIndex) {
	checkWidget ();
	return getFont (columnIndex, true);
}
Font getFont (int columnIndex, boolean checkData) {
	if (checkData && !parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
	int validColumnCount = Math.max (1, parent.columns.length);
	if (!(0 <= columnIndex && columnIndex < validColumnCount)) return getFont (checkData);
	if (cellFonts == null || cellFonts [columnIndex] == null) return getFont (checkData);
	return cellFonts [columnIndex];
}
int getFontHeight () {
	if (fontHeight != 0) return fontHeight;
	return parent.fontHeight;
}
int getFontHeight (int columnIndex) {
	if (fontHeights == null || fontHeights [columnIndex] == 0) return getFontHeight ();
	return fontHeights [columnIndex];
}
/**
 * Returns the foreground color that the receiver will use to draw.
 *
 * @return the receiver's foreground color
 *
 * @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.0
 * 
 */
public Color getForeground () {
	checkWidget ();
	if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
	if (foreground != null) return foreground;
	return parent.getForeground ();
}
/**
 * 
 * Returns the foreground color at the given column index in the receiver.
 *
 * @param index the column index
 * @return the foreground color
 *
 * @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 Color getForeground (int columnIndex) {
	checkWidget ();
	if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
	int validColumnCount = Math.max (1, parent.columns.length);
	if (!(0 <= columnIndex && columnIndex < validColumnCount)) return getForeground ();
	if (cellForegrounds == null || cellForegrounds [columnIndex] == null) return getForeground ();
	return cellForegrounds [columnIndex];
}
/**
 * Returns <code>true</code> if the receiver is grayed,
 * and false otherwise. When the parent does not have
 * the <code>CHECK style, return false.
 * <p>
 *
 * @return the grayed state of the checkbox
 *
 * @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 boolean getGrayed () {
	checkWidget ();
	if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
	return grayed;
}
/*
 * Answers the start and end points of the horizontal connector line that is
 * drawn between an item's expander box and its checkbox or content.
 */
Point[] getHconnectorEndpoints () {
	Rectangle expanderBounds = getExpanderBounds ();
	int x, width;
	if (items.length == 0) {	/* no child items, so no expander box */
		x = expanderBounds.x + Compatibility.ceil (expanderBounds.width, 2);
		width = Compatibility.floor (expanderBounds.width, 2) + INDENT_HIERARCHY;
	} else {					/* has child items */
		x = expanderBounds.x + expanderBounds.width;
		width = INDENT_HIERARCHY;
	}
	int y = expanderBounds.y + expanderBounds.height / 2;
	return new Point[] {
		new Point (x, y),
		new Point (x + width, y)
	};
}
/*
 * Returns the bounds representing the clickable region that should select the receiver.
 */
Rectangle getHitBounds () {
	int[] columnOrder = parent.getColumnOrder ();
	int orderedCol0index = columnOrder.length == 0 ? 0 : parent.columns [columnOrder [0]].getIndex ();
	int contentX = getContentX (orderedCol0index);
	int width = 0;
	TreeColumn[] columns = parent.columns;
	if (columns.length == 0) {
		width = getContentWidth (0); 
	} else {
		/* 
		 * If there are columns then this spans from the beginning of the receiver's column 0
		 * image or text to the end of either column 0 or the last column (FULL_SELECTION).
		 */
		TreeColumn column;
		if ((parent.style & SWT.FULL_SELECTION) != 0) {
			column = columns [columnOrder [columnOrder.length - 1]];	/* last column */
		} else {
			column = columns [orderedCol0index];
		}
		width = column.getX () + column.width - contentX;
	}
	return new Rectangle (contentX, parent.getItemY (this), width, parent.itemHeight);
}
public Image getImage () {
	checkWidget ();
	if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
	return super.getImage ();
}
/**
 * Returns the image stored at the given column index in the receiver,
 * or null if the image has not been set or if the column does not exist.
 *
 * @param index the column index
 * @return the image stored at the given column index 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>
 * 
 * @since 3.1
 */
public Image getImage (int columnIndex) {
	checkWidget ();
	return getImage (columnIndex, true);
}
Image getImage (int columnIndex, boolean checkData) {
	if (checkData && !parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
	int validColumnCount = Math.max (1, parent.columns.length);
	if (!(0 <= columnIndex && columnIndex < validColumnCount)) return null;
	if (columnIndex == 0) return super.getImage ();	/* super is intentional here */
	return images [columnIndex];
}
/**
 * Returns a rectangle describing the size and location
 * relative to its parent of an image at a column in the
 * tree.
 *
 * @param index the index that specifies the column
 * @return the receiver's bounding image rectangle
 *
 * @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 Rectangle getImageBounds (int columnIndex) {
	checkWidget ();
	if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
	int validColumnCount = Math.max (1, parent.columns.length);
	if (!(0 <= columnIndex && columnIndex < validColumnCount)) return new Rectangle (0,0,0,0);

	int padding = parent.getCellPadding ();
	int startX = getContentX (columnIndex);
	int itemHeight = parent.itemHeight;
	int imageSpaceY = itemHeight - 2 * padding;
	int y = parent.getItemY (this);
	int orderedIndex = parent.columns.length == 0 ? 0 : parent.columns [columnIndex].getOrderIndex ();
	Image image = getImage (columnIndex, false); 
	int drawWidth = 0;
	if (orderedIndex == 0) {
		/* for ordered column 0 all images have the same width */
		drawWidth = parent.orderedCol0imageWidth;
	} else {
		if (image != null) drawWidth = image.getBounds ().width;
	}
	return new Rectangle (startX, y + padding, drawWidth, imageSpaceY);
}
int getIndex () {
	TreeItem[] items;
	if (parentItem != null) {
		items = parentItem.items;
	} else {
		items = parent.items;
	}
	for (int i = 0; i < items.length; i++) {
		if (items [i] == this) return i;
	}
	return -1;
}
/**
 * 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 (index < 0) error (SWT.ERROR_INVALID_RANGE);
	if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
	if (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.
 *
 * @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 ();
	if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
	return items.length;
}
String getNameText () {
	if ((parent.style & SWT.VIRTUAL) != 0) {
		if (!cached) return "*virtual*"; //$NON-NLS-1$
	}
	return super.getNameText ();
}
/**
 * Returns a (possibly empty) array of <code>TreeItem</code>s which
 * are the direct item children of the receiver.
 * <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 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>
 */
public TreeItem [] getItems () {
	checkWidget ();
	if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
	TreeItem[] result = new TreeItem [items.length];
	System.arraycopy (items, 0, result, 0, items.length);
	return result;
}
/**
 * Returns the receiver's parent, which must be a <code>Tree</code>.
 *
 * @return the receiver's parent
 *
 * @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 Tree getParent () {
	checkWidget ();
	return parent;
}
/**
 * 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 parentItem;
}
/*
 * Returns the receiver's ideal width for the specified columnIndex.
 */
int getPreferredWidth (int columnIndex) {
	int width = 0;
	GC gc = new GC (parent);
	gc.setFont (getFont (columnIndex, false));
	width += gc.stringExtent (getText (columnIndex, false)).x + 2 * MARGIN_TEXT;
	int orderedIndex = parent.columns.length == 0 ? 0 : parent.columns [columnIndex].getOrderIndex ();
	if (orderedIndex == 0) {
		if (parent.orderedCol0imageWidth > 0) {
			width += parent.orderedCol0imageWidth;
			width += Tree.MARGIN_IMAGE;
		}
	} else {
		Image image = getImage (columnIndex, false);
		if (image != null) {
			width += image.getBounds ().width;
			width += Tree.MARGIN_IMAGE;
		}
	}

	if (parent.hooks (SWT.MeasureItem)) {
		Event event = new Event ();
		event.item = this;
		event.gc = gc;
		event.index = columnIndex;
		event.x = getContentX (columnIndex);
		event.y = parent.getItemY (this);
		event.width = width;
		event.height = parent.itemHeight;
		parent.sendEvent (SWT.MeasureItem, event);
		if (parent.itemHeight != event.height) {
			parent.customHeightSet = true;
			boolean update = parent.setItemHeight (event.height + 2 * parent.getCellPadding ());
			if (update) parent.redraw ();
		}
		width = event.width;
	}
	gc.dispose ();

	if (orderedIndex == 0) {
		return getContentX (columnIndex) + parent.horizontalOffset + width + parent.getCellPadding ();	/* right side cell pad */
	}

	return width + 2 * parent.getCellPadding ();
}
public String getText () {
	checkWidget ();
	if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
	return super.getText ();
}
/**
 * Returns the text stored at the given column index in the receiver,
 * or empty string if the text has not been set.
 *
 * @param index the column index
 * @return the text stored at the given column index 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>
 * 
 * @since 3.1
 */
public String getText (int columnIndex) {
	checkWidget ();
	return getText (columnIndex, true);
}
String getText (int columnIndex, boolean checkData) {
	if (checkData && !parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
	int validColumnCount = Math.max (1, parent.columns.length);
	if (!(0 <= columnIndex && columnIndex < validColumnCount)) return "";	//$NON-NLS-1$
	if (columnIndex == 0) return super.getText ();	/* super is intentional here */
	if (texts [columnIndex] == null) return "";	//$NON-NLS-1$
	return texts [columnIndex];
}
/**
 * Returns a rectangle describing the size and location
 * relative to its parent of the text at a column in the
 * tree.
 *
 * @param index the index that specifies the column
 * @return the receiver's bounding text rectangle
 *
 * @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.3
 */
public Rectangle getTextBounds (int columnIndex) {
	checkWidget ();
	if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
	if (!isAvailable ()) return new Rectangle (0, 0, 0, 0);
	TreeColumn[] columns = parent.columns;
	int columnCount = columns.length;
	int validColumnCount = Math.max (1, columnCount);
	if (!(0 <= columnIndex && columnIndex < validColumnCount)) {
		return new Rectangle (0, 0, 0, 0);
	}
	/*
	 * If there are no columns then this is the bounds of the receiver's content.
	 */
	if (columnCount == 0) {
		int x = getTextX (0) + MARGIN_TEXT;
		int width = Math.max (0, getContentX(0) + getContentWidth (0) - x);
		return new Rectangle (
			x,
			parent.getItemY (this),
			width,
			parent.itemHeight - 1);
	}

	TreeColumn column = columns [columnIndex];
	if (column.getOrderIndex () == 0) {
		/* 
		 * For ordered column 0 this is bounds from the beginning of the content to the
		 * end of the column.
		 */
		int x = getTextX (columnIndex) + MARGIN_TEXT;
		int offset = x - column.getX ();
		int width = Math.max (0, column.width - offset - 1);		/* max is for columns with small widths */
		return new Rectangle (x, parent.getItemY (this) + 1, width, parent.itemHeight - 1);
	}
	/*
	 * For ordered columns > 0 this is the bounds of the tree cell.
	 */
	int x = getTextX (columnIndex) + MARGIN_TEXT;
	int offset = x - column.getX ();
	int width = Math.max (0, column.width - offset - MARGIN_TEXT);
	return new Rectangle (x, parent.getItemY (this) + 1, width, parent.itemHeight - 1);
}
/*
 * Returns the x value where the receiver's text begins.
 */
int getTextX (int columnIndex) {
	int orderedIndex = parent.columns.length == 0 ? 0 : parent.columns [columnIndex].getOrderIndex ();
	int textX = getContentX (columnIndex);
	if (orderedIndex == 0) {
		textX += parent.orderedCol0imageWidth;
		if (parent.orderedCol0imageWidth > 0) textX += Tree.MARGIN_IMAGE;
	} else {
		Image image = getImage (columnIndex, false);
		if (image != null) {
			textX += image.getBounds ().width + Tree.MARGIN_IMAGE;	
		}
	}
	return textX;
}
/*
 * Returns true if the receiver descends from (or is identical to) the item.
 */
boolean hasAncestor (TreeItem item) {
	if (this == item) return true;
	if (parentItem == null) return false;
	return parentItem.hasAncestor (item);
}
/**
 * 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 != this) return -1;
	return item.getIndex ();
}
/*
 * Returns true if the receiver is currently available (though not necessary in the viewport).
 */
boolean isAvailable () {
	if (parentItem == null) return true; 	/* root items are always available */
	if (!parentItem.expanded) return false;
	return parentItem.isAvailable ();
}
/*
 * Answers a boolean indicating whether the receiver's y is within the current
 * viewport of the parent.
 */
boolean isInViewport () {
	if (availableIndex == -1) return false;
	int topIndex = parent.topIndex;
	if (availableIndex < topIndex) return false;
	int visibleCount = parent.clientArea.height / parent.itemHeight;
	return availableIndex <= topIndex + visibleCount;
}
/*
 * Returns true if the receiver is the last child of its parent item, or of its parent
 * if the receiver is a root item, and false otherwise.
 */
boolean isLastChild () {
	if (parentItem != null) {
		return getIndex () == parentItem.items.length - 1;
	}
	return getIndex () == parent.items.length - 1;
}
boolean isSelected () {
	return parent.getSelectionIndex (this) != -1;
}
/*
 * The backgroundOnly argument indicates whether the item should only
 * worry about painting its background color and selection.
 *
 * Returns a boolean indicating whether to abort drawing focus on the item.
 * If the receiver is not the current focus item then this value is irrelevant.
 */
boolean paint (GC gc, TreeColumn column, boolean backgroundOnly) {
	if (!parent.checkData (this, true)) return false;
	int columnIndex = 0, orderedIndex = 0, x = 0;
	if (column != null) {
		columnIndex = column.getIndex ();
		orderedIndex = column.getOrderIndex ();
		x = column.getX ();
	}

	/* 
	 * Capture GC attributes that will need to be restored later in the paint
	 * process to ensure that the item paints as intended without being affected
	 * by GC changes made in MeasureItem/EraseItem/PaintItem callbacks.
	 */
	int oldAlpha = gc.getAlpha ();
	boolean oldAdvanced = gc.getAdvanced ();
	int oldAntialias = gc.getAntialias ();
	Pattern oldBackgroundPattern = gc.getBackgroundPattern ();
	Pattern oldForegroundPattern = gc.getForegroundPattern ();
	int oldInterpolation = gc.getInterpolation ();
	int[] oldLineDash = gc.getLineDash ();
	int oldLineWidth = gc.getLineWidth ();
	int oldTextAntialias = gc.getTextAntialias ();

	if (parent.hooks (SWT.MeasureItem)) {
		int contentWidth = getContentWidth (columnIndex);
		int contentX = getContentX (columnIndex);
		gc.setFont (getFont (columnIndex, false));
		Event event = new Event ();
		event.item = this;
		event.gc = gc;
		event.index = columnIndex;
		event.x = contentX;
		event.y = parent.getItemY (this);
		event.width = contentWidth;
		event.height = parent.itemHeight;
		parent.sendEvent (SWT.MeasureItem, event);
		event.gc = null;
		if (gc.isDisposed ()) return false;
		gc.setAlpha (oldAlpha);
		gc.setAntialias (oldAntialias);
		gc.setBackgroundPattern (oldBackgroundPattern);
		gc.setForegroundPattern (oldForegroundPattern);
		gc.setInterpolation (oldInterpolation);
		gc.setLineDash (oldLineDash);
		gc.setLineWidth (oldLineWidth);
		gc.setTextAntialias (oldTextAntialias);
		gc.setAdvanced (oldAdvanced);
		if (isDisposed ()) return false;
		if (parent.itemHeight != event.height) {
			parent.customHeightSet = true;
			boolean update = parent.setItemHeight (event.height + 2 * parent.getCellPadding ());
			if (update) parent.redraw ();
		}
		if (parent.columns.length == 0) {
			int change = event.width - (customWidth != -1 ? customWidth : contentWidth);
			if (event.width != contentWidth || customWidth != -1) customWidth = event.width;
			if (change != 0) {	/* scrollbar may be affected since no columns */
				parent.updateHorizontalBar (contentX + event.width, change);
				// TODO what if clip is too small now?
			}
		}
	}

	/* if this cell is completely to the right of the client area then there's no need to paint it */
	Rectangle clientArea = parent.clientArea;
	if (clientArea.x + clientArea.width < x) return false;

	Rectangle cellBounds = getCellBounds (columnIndex);
	if (parent.linesVisible) {
		cellBounds.y++;
		cellBounds.height--;
	}
	int cellRightX = 0;
	if (column != null) {
		cellRightX = column.getX () + column.width;
	} else {
		cellRightX = cellBounds.x + cellBounds.width;
	}

	/* restrict the clipping region to the cell */
	gc.setClipping (x, cellBounds.y, clientArea.width - x, cellBounds.height);
	
	int y = parent.getItemY (this);
	int itemHeight = parent.itemHeight;

	/* draw the parent background color/image of this cell */
	if (column == null) {
		parent.drawBackground (gc, 0, y, clientArea.width, itemHeight);
	} else {
		int fillWidth = cellBounds.width;
		if (parent.linesVisible) fillWidth--;
		parent.drawBackground (gc, cellBounds.x, cellBounds.y, fillWidth, cellBounds.height);
	}

	boolean isSelected = isSelected ();
	boolean isFocusItem = parent.focusItem == this && parent.isFocusControl ();
	boolean drawBackground = true;
	boolean drawForeground = true;
	boolean drawSelection = isSelected;
	boolean drawFocus = isFocusItem;
	if (parent.hooks (SWT.EraseItem)) {
		drawBackground = background != null || (cellBackgrounds != null && cellBackgrounds [columnIndex] != null);
		gc.setFont (getFont (columnIndex, false));
		if (isSelected && (columnIndex == 0 || (parent.style & SWT.FULL_SELECTION) != 0)) {
			gc.setForeground (display.getSystemColor (SWT.COLOR_LIST_SELECTION_TEXT));
			gc.setBackground (display.getSystemColor (SWT.COLOR_LIST_SELECTION));
		} else {
			gc.setForeground (getForeground (columnIndex));
			gc.setBackground (getBackground (columnIndex));
		}
		Event event = new Event ();
		event.item = this;
		event.gc = gc;
		event.index = columnIndex;
		event.doit = true;
		event.detail = SWT.FOREGROUND;
		if (drawBackground) event.detail |= SWT.BACKGROUND;
		if (isSelected) event.detail |= SWT.SELECTED;
		if (isFocusItem) event.detail |= SWT.FOCUSED;
		event.x = cellBounds.x;
		event.y = cellBounds.y;
		event.width = cellBounds.width;
		event.height = cellBounds.height;
		gc.setClipping (cellBounds);
		parent.sendEvent (SWT.EraseItem, event);
		event.gc = null;
		if (gc.isDisposed ()) return false;
		gc.setAlpha (oldAlpha);
		gc.setAntialias (oldAntialias);
		gc.setBackgroundPattern (oldBackgroundPattern);
		gc.setClipping (cellBounds);
		gc.setForegroundPattern (oldForegroundPattern);
		gc.setInterpolation (oldInterpolation);
		gc.setLineDash (oldLineDash);
		gc.setLineWidth (oldLineWidth);
		gc.setTextAntialias (oldTextAntialias);
		gc.setAdvanced (oldAdvanced);
		if (isDisposed ()) return false;
		if (!event.doit) {
			drawBackground = drawForeground = drawSelection = drawFocus = false;
		} else {
			drawBackground = drawBackground && (event.detail & SWT.BACKGROUND) != 0;
			drawForeground = (event.detail & SWT.FOREGROUND) != 0;
			drawSelection = isSelected && (event.detail & SWT.SELECTED) != 0;
			drawFocus = isFocusItem && (event.detail & SWT.FOCUSED) != 0;
		}
	}

	/* draw the cell's set background if appropriate */
	if (drawBackground) {
		gc.setBackground (getBackground (columnIndex));
		if (columnIndex == 0 && (column == null || column.getOrderIndex () == 0)) {
			Rectangle focusBounds = getFocusBounds ();
			int fillWidth = 0;
			if (column == null) {
				fillWidth = focusBounds.width;
			} else {
				fillWidth = column.width - focusBounds.x;
				if (parent.linesVisible) fillWidth--;
			}
			gc.fillRectangle (focusBounds.x, focusBounds.y, fillWidth, focusBounds.height);
		} else {
			int fillWidth = cellBounds.width;
			gc.fillRectangle (cellBounds.x, cellBounds.y, fillWidth, cellBounds.height);
		}
	}

	/* draw the selection bar if the receiver is selected */
	if (drawSelection && isSelected && (orderedIndex == 0 || (parent.style & SWT.FULL_SELECTION) != 0)) {
		gc.setBackground (display.getSystemColor (SWT.COLOR_LIST_SELECTION));
		if (orderedIndex == 0) {
			Rectangle focusBounds = getFocusBounds ();
			int fillWidth = focusBounds.width;
			if (parent.columns.length < 2 || (parent.style & SWT.FULL_SELECTION) == 0) {
				fillWidth -= 2;	/* space for right bound of focus rect */
			}
			if (fillWidth > 0) {
				gc.fillRectangle (focusBounds.x + 1, focusBounds.y + 1, fillWidth, focusBounds.height - 2);
			}
		} else {
			int fillWidth = column.width;
			int[] columnOrder = parent.getColumnOrder ();
			if (columnIndex == columnOrder [columnOrder.length - 1]) {
				fillWidth -= 2;		/* space for right bound of focus rect */
			}
			if (fillWidth > 0) {
				gc.fillRectangle (
					column.getX (),
					cellBounds.y + 1,
					fillWidth,
					cellBounds.height - 2);
			}
		}
	}
		
	if (backgroundOnly) return false;

	/* Draw column 0 decorations */
	if (orderedIndex == 0) {
		gc.setClipping (cellBounds);

		/* Draw hierarchy connector lines */
		Rectangle expanderBounds = getExpanderBounds ();
		Color oldForeground = gc.getForeground ();
		gc.setForeground (parent.getConnectorColor ());

		/* Draw vertical line above expander */
		int lineX = expanderBounds.x + expanderBounds.width / 2;
		int y2 = expanderBounds.y;
		if (items.length == 0) {
			y2 += expanderBounds.height / 2;
		}
		/* Do not draw this line iff this is the very first item in the tree */ 
		if (parentItem != null || getIndex () != 0) {
			gc.drawLine (lineX, y, lineX, y2);
		}

		/* Draw vertical line below expander if the receiver has lower siblings */
		if (!isLastChild ()) {
			if (items.length != 0) y2 += expanderBounds.height;
			gc.drawLine (lineX, y2, lineX, y + itemHeight);
		}

		/* Draw horizontal line to right of expander */
		Point[] endpoints = getHconnectorEndpoints ();
		gc.drawLine (endpoints [0].x, endpoints [0].y, endpoints [1].x - Tree.MARGIN_IMAGE, endpoints [1].y);
		
		/* 
		 * Draw hierarchy lines that are needed by other items that are shown below
		 * this item but whose parents are shown above (ie.- lines to the left of
		 * this item's connector line).
		 */
		TreeItem item = parentItem;
		while (item != null) {
			if (!item.isLastChild ()) {
				Rectangle itemExpanderBounds = item.getExpanderBounds ();
				lineX = itemExpanderBounds.x + itemExpanderBounds.width / 2;
				gc.drawLine (lineX, y, lineX, y + itemHeight);
			}
			item = item.parentItem;
		}

		gc.setForeground (oldForeground);

		/* Draw expand/collapse image if receiver has children */
		if (items.length > 0) {
			Image image = expanded ? parent.getExpandedImage () : parent.getCollapsedImage ();
			gc.drawImage (image, expanderBounds.x, expanderBounds.y);
		}
		
		/* Draw checkbox if parent Tree has style SWT.CHECK */
		if ((parent.style & SWT.CHECK) != 0) {
			Image baseImage = grayed ? parent.getGrayUncheckedImage () : parent.getUncheckedImage ();
			Rectangle checkboxBounds = getCheckboxBounds ();
			gc.drawImage (baseImage, checkboxBounds.x, checkboxBounds.y);
			/* Draw checkmark if item is checked */
			if (checked) {
				Image checkmarkImage = parent.getCheckmarkImage ();
				Rectangle checkmarkBounds = checkmarkImage.getBounds ();
				int xInset = (checkboxBounds.width - checkmarkBounds.width) / 2;
				int yInset = (checkboxBounds.height - checkmarkBounds.height) / 2;
				gc.drawImage (checkmarkImage, checkboxBounds.x + xInset, checkboxBounds.y + yInset);
			}
		}
	}

	if (drawForeground) {
		Image image = getImage (columnIndex, false);
		String text = getDisplayText (columnIndex);
		Rectangle imageArea = getImageBounds (columnIndex);
		int startX = imageArea.x;
		
		/* while painting the cell's content restrict the clipping region */
		int padding = parent.getCellPadding ();
		gc.setClipping (
			startX,
			cellBounds.y + padding - (parent.linesVisible ? 1 : 0),
			cellRightX - startX - padding,
			cellBounds.height - 2 * (padding - (parent.linesVisible ? 1 : 0)));
	
		/* draw the image */
		if (image != null) {
			Rectangle imageBounds = image.getBounds ();
			gc.drawImage (
				image,
				0, 0,									/* source x, y */
				imageBounds.width, imageBounds.height,	/* source width, height */
				imageArea.x, imageArea.y,				/* dest x, y */
				imageArea.width, imageArea.height);		/* dest width, height */
		}
		
		/* draw the text */
		if (text.length () > 0) {
			gc.setFont (getFont (columnIndex, false));
			int fontHeight = getFontHeight (columnIndex);
			if (drawSelection && (orderedIndex == 0 || (parent.style & SWT.FULL_SELECTION) != 0)) {
				gc.setForeground (display.getSystemColor (SWT.COLOR_LIST_SELECTION_TEXT));
			} else {
				if (!isSelected || drawSelection) {
					gc.setForeground (getForeground (columnIndex));
				}
			}
			x = getTextX (columnIndex) + MARGIN_TEXT;
			gc.drawString (text, x, y + (itemHeight - fontHeight) / 2, true);
		}
	}
	
	if (parent.hooks (SWT.PaintItem)) {
		int contentWidth = getContentWidth (columnIndex);
		int contentX = getContentX (columnIndex);
		gc.setFont (getFont (columnIndex, false));
		if (isSelected && (columnIndex == 0 || (parent.style & SWT.FULL_SELECTION) != 0)) {
			gc.setForeground (display.getSystemColor (SWT.COLOR_LIST_SELECTION_TEXT));
			gc.setBackground (display.getSystemColor (SWT.COLOR_LIST_SELECTION));
		} else {
			gc.setForeground (getForeground (columnIndex));
			gc.setBackground (getBackground (columnIndex));
		}
		Event event = new Event ();
		event.item = this;
		event.gc = gc;
		event.index = columnIndex;
		if (isSelected) event.detail |= SWT.SELECTED;
		if (drawFocus) event.detail |= SWT.FOCUSED;
		event.x = contentX;
		event.y = cellBounds.y;
		event.width = contentWidth;
		event.height = cellBounds.height;
		gc.setClipping (cellBounds);
		parent.sendEvent (SWT.PaintItem, event);
		event.gc = null;
		if (gc.isDisposed ()) return false;
		gc.setAlpha (oldAlpha);
		gc.setAntialias (oldAntialias);
		gc.setBackgroundPattern (oldBackgroundPattern);
		gc.setClipping (cellBounds);
		gc.setForegroundPattern (oldForegroundPattern);
		gc.setInterpolation (oldInterpolation);
		gc.setLineDash (oldLineDash);
		gc.setLineWidth (oldLineWidth);
		gc.setTextAntialias (oldTextAntialias);
		gc.setAdvanced (oldAdvanced);
		drawFocus = isFocusItem && (event.detail & SWT.FOCUSED) != 0;
	}

	return isFocusItem && !drawFocus;
}
/*
 * Redraw part of the receiver.  If either EraseItem or PaintItem is hooked then
 * only full cells should be damaged, so adjust accordingly.  If neither of these
 * events are hooked then the exact bounds given for damaging can be used.
 */
void redraw (int x, int y, int width, int height, int columnIndex) {
	if (!parent.hooks (SWT.EraseItem) && !parent.hooks (SWT.PaintItem)) {
		parent.redraw (x, y, width, height, false);
		return;
	}
	Rectangle cellBounds = getCellBounds (columnIndex);
	parent.redraw (cellBounds.x, cellBounds.y, cellBounds.width, cellBounds.height, false);
}
void redrawItem () {
	if (!isAvailable ()) return;
	parent.redraw (0, parent.getItemY (this), parent.clientArea.width, parent.itemHeight, false);
}
/*
 * Updates internal structures in the receiver and its child items to handle the removal of a column.
 */
void removeColumn (TreeColumn column, int index, int orderedIndex) {
	int columnCount = parent.columns.length;

	if (columnCount == 0) {
		/* reverts to normal tree when last column disposed */
		cellBackgrounds = cellForegrounds = null;
		displayTexts = null;
		cellFonts = null;
		fontHeights = null;
		GC gc = new GC (parent);
		computeTextWidths (gc);
		gc.dispose ();
		/* notify all child items as well */
		for (int i = 0; i < items.length; i++) {
			items [i].removeColumn (column, index, orderedIndex);
		}
		return;
	}

	String[] newTexts = new String [columnCount];
	System.arraycopy (texts, 0, newTexts, 0, index);
	System.arraycopy (texts, index + 1, newTexts, index, columnCount - index);
	texts = newTexts;
	
	Image[] newImages = new Image [columnCount];
	System.arraycopy (images, 0, newImages, 0, index);
	System.arraycopy (images, index + 1, newImages, index, columnCount - index);
	images = newImages;

	int[] newTextWidths = new int [columnCount];
	System.arraycopy (textWidths, 0, newTextWidths, 0, index);
	System.arraycopy (textWidths, index + 1, newTextWidths, index, columnCount - index);
	textWidths = newTextWidths;

	String[] newDisplayTexts = new String [columnCount];
	System.arraycopy (displayTexts, 0, newDisplayTexts, 0, index);
	System.arraycopy (displayTexts, index + 1, newDisplayTexts, index, columnCount - index);
	displayTexts = newDisplayTexts;

	if (cellBackgrounds != null) {
		Color[] newCellBackgrounds = new Color [columnCount];
		System.arraycopy (cellBackgrounds, 0, newCellBackgrounds, 0, index);
		System.arraycopy (cellBackgrounds, index + 1, newCellBackgrounds, index, columnCount - index);
		cellBackgrounds = newCellBackgrounds;
	}
	if (cellForegrounds != null) {
		Color[] newCellForegrounds = new Color [columnCount];
		System.arraycopy (cellForegrounds, 0, newCellForegrounds, 0, index);
		System.arraycopy (cellForegrounds, index + 1, newCellForegrounds, index, columnCount - index);
		cellForegrounds = newCellForegrounds;
	}
	if (cellFonts != null) {
		Font[] newCellFonts = new Font [columnCount];
		System.arraycopy (cellFonts, 0, newCellFonts, 0, index);
		System.arraycopy (cellFonts, index + 1, newCellFonts, index, columnCount - index);
		cellFonts = newCellFonts;

		int[] newFontHeights = new int [columnCount];
		System.arraycopy (fontHeights, 0, newFontHeights, 0, index);
		System.arraycopy (fontHeights, index + 1, newFontHeights, index, columnCount - index);
		fontHeights = newFontHeights;
	}

	if (index == 0) {
		text = texts [0] != null ? texts [0] : "";	//$NON-NLS-1$
		texts [0] = null;
		image = images [0];
		images [0] = null;
	}

	if (orderedIndex == 0) {
		/* 
		 * The new first ordered column will not have as much width available to it as it did when
		 * it was the second ordered column since it now has to show hierarchy decorations as well,
		 * so recompute its displayText. 
		 */
		int firstColumnIndex = parent.getOrderedColumns () [0].getIndex ();
		GC gc = new GC (parent);
		gc.setFont (getFont (firstColumnIndex, false));
		computeDisplayText (firstColumnIndex, gc);
		gc.dispose ();
	}
	if (columnCount < 2) {
		texts = null;
		images = null;
	}

	/* notify all child items as well */
	for (int i = 0; i < items.length; i++) {
		items [i].removeColumn (column, index, orderedIndex);
	}
}
/**
 * Removes all of the items from the receiver.
 * <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>
 *
 * @since 3.1
 */
public void removeAll () {
	checkWidget ();
	if (items.length == 0) return;

	int lastAvailableIndex = parent.availableItemsCount - 1;
	/* for performance do this upfront for whole descendent chain */
	TreeItem focusItem = parent.focusItem; 
	if (focusItem != null && focusItem.hasAncestor (this)) {
		parent.setFocusItem (this, false);
	}
	while (items.length > 0) {
		items [0].dispose (true);
		removeItem (items [0], 0);
	}
	items = Tree.NO_ITEMS;
	expanded = false;
	if (isAvailable ()) {
		parent.redrawItems (availableIndex, lastAvailableIndex, false);
	}
}
/*
 * Removes a child item from the receiver.
 */
void removeItem (TreeItem item, int index) {
	if (isDisposed ()) return;
	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 (items.length == 0) {
		items = Tree.NO_ITEMS;
		/* condition below handles creation of item within Expand callback */
		if (!parent.inExpand) {
			expanded = false;
			if (isInViewport ()) {
				Rectangle bounds = getExpanderBounds ();	/* expander box no longer needed */
				parent.redraw (bounds.x, bounds.y, bounds.width, bounds.height, false);
			}
		}
		return;
	}
}
/**
 * Sets the receiver's background color to the color specified
 * by the argument, or to the default system color for the item
 * if the argument is null.
 *
 * @param color the new color (or null)
 * 
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the argument 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 2.0
 * 
 */
public void setBackground (Color color) {
	checkWidget ();
	if (color != null && color.isDisposed ()) {
		SWT.error (SWT.ERROR_INVALID_ARGUMENT);
	}
	Color oldColor = background;
	if (oldColor == color) return;
	background = color;
	if (oldColor != null && oldColor.equals (color)) return;
	if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
	redrawItem ();
}
/**
 * Sets the background color at the given column index in the receiver 
 * to the color specified by the argument, or to the default system color for the item
 * if the argument is null.
 *
 * @param index the column index
 * @param color the new color (or null)
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the argument 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 setBackground (int columnIndex, Color color) {
	checkWidget ();
	if (color != null && color.isDisposed ()) {
		SWT.error (SWT.ERROR_INVALID_ARGUMENT);
	}
	int validColumnCount = Math.max (1, parent.columns.length);
	if (!(0 <= columnIndex && columnIndex < validColumnCount)) return;
	if (cellBackgrounds == null) {
		if (color == null) return;
		cellBackgrounds = new Color [validColumnCount];
	}
	Color oldColor = cellBackgrounds [columnIndex];
	if (oldColor == color) return;
	cellBackgrounds [columnIndex] = color;
	if (oldColor != null && oldColor.equals (color)) return;
	if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
	if (isInViewport ()) {
		Rectangle bounds = getCellBounds (columnIndex);
		parent.redraw (bounds.x, bounds.y, bounds.width, bounds.height, false);
	}
}
/**
 * Sets the checked state of the receiver.
 * <p>
 *
 * @param checked the new checked 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>
 */
public void setChecked (boolean value) {
	checkWidget ();
	if ((parent.getStyle () & SWT.CHECK) == 0) return;
	if (checked == value) return;
	checked = value;
	if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
	if (isInViewport ()) {
		if (parent.hooks (SWT.EraseItem) || parent.hooks (SWT.PaintItem)) {
			redrawItem ();
		} else {
			Rectangle bounds = getCheckboxBounds ();
			parent.redraw (bounds.x, bounds.y, bounds.width, bounds.height, false);
		}
	}
}
/**
 * Sets the expanded state of the receiver.
 * <p>
 *
 * @param expanded the new expanded 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>
 */
public void setExpanded (boolean value) {
	checkWidget ();
	if (expanded == value) return;
	if (items.length == 0) return;
	if (parent.inExpand) return;
	if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
	if (value) {
		expanded = value;
		if (availableIndex == -1) return;

		TreeItem[] availableDescendents = computeAvailableDescendents ();
		int descendentsCount = availableDescendents.length;
		if (availableIndex != parent.availableItemsCount - 1) {
			/* the receiver is not the last available item */
			Rectangle clientArea = parent.clientArea;
			int y = parent.getItemY (this) + parent.itemHeight;
			if (0 < y && y < clientArea.height) {
				if (parent.drawCount <= 0) {
					parent.update ();
					GC gc = new GC (parent);
					gc.copyArea (
						0, y,
						clientArea.width, clientArea.height - y,
						0, y + ((descendentsCount - 1) * parent.itemHeight));				
					gc.dispose ();
				}
			}
		}

		parent.makeDescendentsAvailable (this, availableDescendents);

		/* update scrollbars */
		int rightX = 0;
		for (int i = 1; i < availableDescendents.length; i++) {
			Rectangle bounds = availableDescendents [i].getBounds (false);
			rightX = Math.max (rightX, bounds.x + bounds.width);
		}
		parent.updateHorizontalBar (rightX, rightX);
		parent.updateVerticalBar ();
		/* 
		 * If new item is above viewport then adjust topIndex and the vertical scrollbar
		 * so that the current viewport items will not change. 
		 */
		if (availableIndex < parent.topIndex) {
			parent.topIndex += descendentsCount - 1;
			ScrollBar vBar = parent.getVerticalBar ();
			if (vBar != null) vBar.setSelection (parent.topIndex);
			return;
		}

		int redrawStart = availableIndex + 1;
		int redrawEnd = redrawStart + descendentsCount - 2;
		parent.redrawItems (redrawStart, redrawEnd, false);
	} else {
		TreeItem[] descendents = computeAvailableDescendents ();
		expanded = value;
		if (availableIndex == -1) return;
		Rectangle clientArea = parent.clientArea;

		int y = parent.getItemY (this) + parent.itemHeight;
		int startY = y + (descendents.length - 1) * parent.itemHeight;
		if (y < clientArea.height && 0 < startY) {	/* determine whether any visual update is actually needed */
			if (parent.drawCount <= 0) {
				parent.update ();
				GC gc = new GC (parent);
				gc.copyArea (0, startY, clientArea.width, clientArea.height - startY, 0, y);
				gc.dispose ();
				int redrawY = y + Math.max (0, clientArea.height - startY);
				parent.redraw (0, redrawY, clientArea.width, clientArea.height - redrawY, false);
			}
		}

		parent.makeDescendentsUnavailable (this, descendents);

		/* 
		 * If all collapsed items are above the viewport then adjust topIndex and
		 * the vertical scrollbar so that the current viewport items will not change.
		 */
		int bottomIndex = availableIndex + descendents.length - 1;
		if (bottomIndex < parent.topIndex) {
			parent.topIndex = parent.topIndex - descendents.length + 1;
			ScrollBar vBar = parent.getVerticalBar ();
			if (vBar != null) vBar.setSelection (parent.topIndex);
		}
		
		parent.updateHorizontalBar ();
		parent.updateVerticalBar ();

		/* move focus (and selection if SWT.SINGLE) to item if a descendent had focus */
		TreeItem focusItem = parent.focusItem;
		if (focusItem != null && focusItem != this && focusItem.hasAncestor (this)) {
			parent.setFocusItem (this, false);
			if ((parent.style & SWT.SINGLE) != 0) {
				parent.selectItem (this, false);
			}
			/* Fire an event since the selection is being changed automatically */
			Event newEvent = new Event ();
			newEvent.item = this;
			parent.sendEvent (SWT.Selection, newEvent);
			if (isDisposed ()) return;
			parent.showItem (this);
			parent.redrawItem (availableIndex, true);
		}
	}
	/* redraw the receiver's expander box */
	if (isInViewport ()) {
		Rectangle bounds = getExpanderBounds ();
		parent.redraw (bounds.x, bounds.y, bounds.width, bounds.height, false);
	}
}
/**
 * Sets the font that the receiver will use to paint textual information
 * for this item to the font specified by the argument, or to the default font
 * for that kind of control if the argument is null.
 *
 * @param font the new font (or null)
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the argument 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.0
 */
public void setFont (Font font) {
	checkWidget ();
	if (font != null && font.isDisposed ()) {
		SWT.error (SWT.ERROR_INVALID_ARGUMENT);
	}
	Font oldFont = this.font;
	if (oldFont == font) return;
	this.font = font;
	if (oldFont != null && oldFont.equals (font)) return;
	
	Rectangle bounds = getBounds (false);
	int oldRightX = bounds.x + bounds.width;
	if ((parent.style & SWT.VIRTUAL) != 0) cached = true;

	/* recompute cached values for string measurements */
	GC gc = new GC (parent);
	gc.setFont (getFont (false));
	fontHeight = gc.getFontMetrics ().getHeight ();
	computeDisplayTexts (gc);
	computeTextWidths (gc);
	gc.dispose ();
	
	/* horizontal bar could be affected if tree has no columns */
	if (parent.columns.length == 0) {
		bounds = getBounds (false);
		int newRightX = bounds.x + bounds.width;
		parent.updateHorizontalBar (newRightX, newRightX - oldRightX);
	}
	redrawItem ();
}
/**
 * Sets the font that the receiver will use to paint textual information
 * for the specified cell in this item to the font specified by the 
 * argument, or to the default font for that kind of control if the 
 * argument is null.
 *
 * @param index the column index
 * @param font the new font (or null)
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the argument 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 setFont (int columnIndex, Font font) {
	checkWidget ();
	if (font != null && font.isDisposed ()) {
		SWT.error (SWT.ERROR_INVALID_ARGUMENT);
	}

	int validColumnCount = Math.max (1, parent.columns.length);
	if (!(0 <= columnIndex && columnIndex < validColumnCount)) return;
	if (cellFonts == null) {
		if (font == null) return;
		cellFonts = new Font [validColumnCount];
	}
	Font oldFont = cellFonts [columnIndex];
	if (oldFont == font) return;
	cellFonts [columnIndex] = font;
	if (oldFont != null && oldFont.equals (font)) return;
	if ((parent.style & SWT.VIRTUAL) != 0) cached = true;

	/* recompute cached values for string measurements */
	GC gc = new GC (parent);
	gc.setFont (getFont (columnIndex, false));
	if (fontHeights == null) fontHeights = new int [validColumnCount];
	fontHeights [columnIndex] = gc.getFontMetrics ().getHeight ();
	computeDisplayText (columnIndex, gc);
	gc.dispose ();

	if (isInViewport ()) {
		Rectangle bounds = getCellBounds (columnIndex);
		parent.redraw (bounds.x, bounds.y, bounds.width, bounds.height, false);
	}
}
/**
 * Sets the receiver's foreground color to the color specified
 * by the argument, or to the default system color for the item
 * if the argument is null.
 *
 * @param color the new color (or null)
 *
 * @since 2.0
 * 
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the argument 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 2.0
 * 
 */
public void setForeground (Color color) {
	checkWidget ();
	if (color != null && color.isDisposed ()) {
		SWT.error (SWT.ERROR_INVALID_ARGUMENT);
	}
	Color oldColor = foreground;
	if (oldColor == color) return;
	foreground = color;
	if (oldColor != null && oldColor.equals (color)) return;
	if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
	redrawItem ();
}
/**
 * Sets the foreground color at the given column index in the receiver 
 * to the color specified by the argument, or to the default system color for the item
 * if the argument is null.
 *
 * @param index the column index
 * @param color the new color (or null)
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the argument 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 setForeground (int columnIndex, Color value) {
	checkWidget ();
	if (value != null && value.isDisposed ()) {
		SWT.error (SWT.ERROR_INVALID_ARGUMENT);
	}
	int validColumnCount = Math.max (1, parent.columns.length);
	if (!(0 <= columnIndex && columnIndex < validColumnCount)) return;
	if (cellForegrounds == null) {
		if (value == null) return;
		cellForegrounds = new Color [validColumnCount];
	}
	Color oldColor = cellForegrounds [columnIndex];
	if (oldColor == value) return;
	cellForegrounds [columnIndex] = value;
	if (oldColor != null && oldColor.equals (value)) return;
	if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
	if (isInViewport ()) {
		redraw (
			getTextX (columnIndex),
			parent.getItemY (this),
			textWidths [columnIndex] + 2 * MARGIN_TEXT,
			parent.itemHeight,
			columnIndex);
	}
}
/**
 * Sets the grayed state of the checkbox for this item.  This state change 
 * only applies if the Tree was created with the SWT.CHECK style.
 *
 * @param grayed the new grayed state of the checkbox
 *
 * @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 setGrayed (boolean value) {
	checkWidget ();
	if ((parent.getStyle () & SWT.CHECK) == 0) return;
	if (grayed == value) return;
	grayed = value;
	if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
	if (isInViewport ()) {
		Rectangle bounds = getCheckboxBounds ();
		parent.redraw (bounds.x, bounds.y, bounds.width, bounds.height, false);
	}
}
public void setImage (Image value) {
	checkWidget ();
	setImage (0, value);
}
/**
 * Sets the image for multiple columns in the tree. 
 * 
 * @param images the array of new images
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the array of images is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if one of the images 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 setImage (Image[] value) {
	checkWidget ();
	if (value == null) error (SWT.ERROR_NULL_ARGUMENT);
	
	// TODO make a smarter implementation of this
	for (int i = 0; i < value.length; i++) {
		if (value [i] != null) setImage (i, value [i]);
	}
}
/**
 * Sets the receiver's image at a column.
 *
 * @param index the column index
 * @param image the new image
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the image 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 setImage (int columnIndex, Image value) {
	checkWidget ();
	if (value != null && value.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);

	TreeColumn[] columns = parent.columns;
	int validColumnCount = Math.max (1, columns.length);
	if (!(0 <= columnIndex && columnIndex < validColumnCount)) return;
	Image image = getImage (columnIndex, false);
	if (value == image) return;
	if (value != null && value.equals (image)) return;
	if (columnIndex == 0) {
		super.setImage (value);
	} else {
		images [columnIndex] = value;
	}
	if ((parent.style & SWT.VIRTUAL) != 0) cached = true;

	/* 
	 * An image width change may affect the space available for the item text, so
	 * recompute the displayText if there are columns.
	 */
	if (columns.length > 0) {
		GC gc = new GC (parent);
		gc.setFont (getFont (columnIndex, false));
		computeDisplayText (columnIndex, gc);
		gc.dispose ();
	}

	if (value == null) {
		redrawItem ();	// TODO why the whole item?
		return;
	}

	if (columns.length == 0) {
		if (parent.imageHeight == 0) {
			/* this is the first image being put into the parent Tree */
			Rectangle bounds = value.getBounds ();
			parent.orderedCol0imageWidth = bounds.width;
			parent.setImageHeight (bounds.height);
			parent.redrawItems (0, parent.availableItemsCount - 1, false);
		} else {
			redrawItem ();
		}
		return;
	}

	/* there are 1+ columns */
	TreeColumn column = columns [columnIndex];
	int orderedIndex = column.getOrderIndex ();
	Rectangle bounds = value.getBounds ();
	if (column.itemImageWidth == 0) column.itemImageWidth = bounds.width;

	if (parent.imageHeight == 0) {
		/* this is the first image being put into the parent Tree */
		int oldItemHeight = parent.itemHeight;
		parent.setImageHeight (bounds.height);

		if (orderedIndex == 0) {	/* the first ordered column */
			parent.orderedCol0imageWidth = bounds.width;
			/* 
			 * All column 0 cells will now have less room available for their texts,
			 * so all items must now recompute their column 0 displayTexts.
			 */
			TreeItem[] rootItems = parent.items;
			GC gc = new GC (parent);
			for (int i = 0; i < rootItems.length; i++) {
				rootItems [i].updateColumnWidth (column, gc);
			}
			gc.dispose ();
			if (oldItemHeight != parent.itemHeight) {
				/* the item height grew as a result of the new image height, so redraw everything */
				parent.redraw ();
			} else {
				/* redraw the column since all items should now have image space */
				parent.redraw (column.getX (), 0, column.width, parent.clientArea.height, false);
			}
		} else {	/* not the first ordered column */
			if (oldItemHeight != parent.itemHeight) {
				/* the item height grew as a result of the new image height, so redraw everything */
				parent.redraw ();
			} else {
				redrawItem ();
			}
		}
		return;
	}

	if (orderedIndex == 0 && parent.orderedCol0imageWidth == 0) {
		/* this is the first image being put into the current ordered column 0 */
		parent.orderedCol0imageWidth = bounds.width;
		/* 
		 * All column 0 cells will now have less room available for their texts,
		 * so all items must now recompute their column 0 displayTexts.
		 */
		TreeItem[] rootItems = parent.items;
		GC gc = new GC (parent);
		for (int i = 0; i < rootItems.length; i++) {
			rootItems [i].updateColumnWidth (column, gc);
		}
		gc.dispose ();
		parent.redraw (column.getX (), 0, column.width, parent.clientArea.height, false);
		return;
	}

	redrawItem ();	// TODO why the whole item?
}
/**
 * Sets the number of child 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 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 : availableIndex;
		redrawEnd = parent.availableItemsCount - 1;
		for (int i = count; i < items.length; i++) {
			items [i].dispose (true);
		}
		if (count == 0) {
			items = Tree.NO_ITEMS;
		} else {
			TreeItem[] newItems = new TreeItem [count];
			System.arraycopy (items, 0, newItems, 0, count);
			items = newItems;
		}
		if (count == 0) expanded = false;
	} else {
		int oldAvailableDescendentCount = computeAvailableDescendentCount ();
		int grow = count - items.length;
		redrawStart = items.length == 0 ? availableIndex : items [items.length - 1].availableIndex;
		redrawEnd = expanded && isAvailable () ? parent.availableItemsCount + grow  - 1: redrawStart;
		TreeItem[] newItems = new TreeItem [count];
		System.arraycopy (items, 0, newItems, 0, items.length);
		items = newItems;
		for (int i = items.length - grow; i < count; i++) {
			items [i] = new TreeItem (this, SWT.NONE, i, false);
		}
		
		if (expanded && availableIndex != -1) {
			/* expand the availableItems array if necessary */
			if (parent.availableItems.length < parent.availableItemsCount + grow) {
				TreeItem[] newAvailableItems = new TreeItem [parent.availableItemsCount + grow];
				System.arraycopy (parent.availableItems, 0, newAvailableItems, 0, parent.availableItemsCount);
				parent.availableItems = newAvailableItems;
			}
			TreeItem[] availableItems = parent.availableItems;
			/* shift items right to create space for the new available items */
			int dest = availableIndex + oldAvailableDescendentCount + grow;
			System.arraycopy (
				availableItems,
				availableIndex + oldAvailableDescendentCount,
				availableItems,
				dest,
				availableItems.length - dest);
			parent.availableItemsCount += grow;
			/* copy new items in */
			System.arraycopy (
				items,
				items.length - grow,
				availableItems,
				availableIndex + oldAvailableDescendentCount,
				grow);
			/* update availableIndex for all affected items */
			for (int i = availableIndex + oldAvailableDescendentCount; i < parent.availableItemsCount; i++) {
				availableItems [i].availableIndex = i;
			}
		}
	}

	if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
	if (availableIndex != -1) {
		if (expanded) parent.updateVerticalBar ();
		parent.redrawItems (redrawStart, redrawEnd, false);
	}
}
public void setText (String value) {
	checkWidget ();
	Rectangle bounds = getBounds (false);
	int oldRightX = bounds.x + bounds.width;
	setText (0, value);
	/* horizontal bar could be affected if tree has no columns */
	if (parent.columns.length == 0) {
		bounds = getBounds (false);
		int newRightX = bounds.x + bounds.width;
		parent.updateHorizontalBar (newRightX, newRightX - oldRightX);
	}
}
/**
 * Sets the text for multiple columns in the tree. 
 * 
 * @param strings the array of new strings
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the text 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 void setText (String[] value) {
	checkWidget ();
	if (value == null) error (SWT.ERROR_NULL_ARGUMENT);
	Rectangle bounds = getBounds (false);
	int oldRightX = bounds.x + bounds.width;
	// TODO make a smarter implementation of this
	for (int i = 0; i < value.length; i++) {
		if (value [i] != null) setText (i, value [i]);
	}
	/* horizontal bar could be affected if tree has no columns */
	if (parent.columns.length == 0) {
		bounds = getBounds (false);
		int newRightX = bounds.x + bounds.width;
		parent.updateHorizontalBar (newRightX, newRightX - oldRightX);
	}
}
/**
 * Sets the receiver's text at a column
 *
 * @param index the column index
 * @param string the new text
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the text 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 void setText (int columnIndex, String value) {
	checkWidget ();
	if (value == null) error (SWT.ERROR_NULL_ARGUMENT);
	int validColumnCount = Math.max (1, parent.columns.length);
	if (!(0 <= columnIndex && columnIndex < validColumnCount)) return;
	if (value.equals (getText (columnIndex, false))) return;
	if (columnIndex == 0) {
		super.setText (value);
	} else {
		texts [columnIndex] = value;		
	}
	if ((parent.style & SWT.VIRTUAL) != 0) cached = true;

	int oldWidth = textWidths [columnIndex];
	GC gc = new GC (parent);
	gc.setFont (getFont (columnIndex, false));
	computeDisplayText (columnIndex, gc);
	gc.dispose ();
	if (availableIndex == -1) return;
	if (parent.columns.length == 0) {
		Rectangle bounds = getBounds (false);
		int rightX = bounds.x + bounds.width;
		parent.updateHorizontalBar (rightX, textWidths [columnIndex] - oldWidth);
	}
	if (isInViewport ()) {
		redraw (
			getTextX (columnIndex),
			parent.getItemY (this),
			Math.max (oldWidth, textWidths [columnIndex]) + 2 * MARGIN_TEXT,
			parent.itemHeight,
			columnIndex);
	}
}
/*
 * Perform any internal changes necessary to reflect a changed column width.
 */
void updateColumnWidth (TreeColumn column, GC gc) {
	int columnIndex = column.getIndex ();
	gc.setFont (getFont (columnIndex, false));
	String oldDisplayText = displayTexts [columnIndex];
	computeDisplayText (columnIndex, gc);

	/* the cell must be damaged if there is custom drawing being done or if the alignment is not LEFT */
	if (isInViewport ()) {
		boolean columnIsLeft = (column.style & SWT.LEFT) != 0;
		if (!columnIsLeft || parent.hooks (SWT.EraseItem) || parent.hooks (SWT.PaintItem)) {
			Rectangle cellBounds = getCellBounds (columnIndex);
			parent.redraw (cellBounds.x, cellBounds.y, cellBounds.width, cellBounds.height, false);
		} else {
			/* if the display text has changed then the cell text must be damaged in order to repaint */	
			if (oldDisplayText == null || !oldDisplayText.equals (displayTexts [columnIndex])) {
				Rectangle cellBounds = getCellBounds (columnIndex);
				int textX = getTextX (columnIndex);
				parent.redraw (textX, cellBounds.y, cellBounds.x + cellBounds.width - textX, cellBounds.height, false);
			}
		}
	}

	for (int i = 0; i < items.length; i++) {
		items [i].updateColumnWidth (column, gc);
	}
}

/*
 * The parent's font has changed, so if this font was being used by the receiver then
 * recompute its cached text sizes using the gc argument.  Pass this notification on to
 * all child items as well.
 */
void updateFont (GC gc) {
	if (font == null) {		/* receiver is using the Tree's font */
		computeDisplayTexts (gc);
		computeTextWidths (gc);
	}
	/* pass notification on to all children */
	for (int i = 0; i < items.length; i++) {
		items [i].updateFont (gc);
	}
}
}
