/*******************************************************************************
 * Copyright (c) 2000, 2006 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.tests.junit;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;
import org.junit.Before;
import org.junit.Test;

/**
 * Automated Test Suite for class org.eclipse.swt.widgets.TreeItem
 *
 * @see org.eclipse.swt.widgets.TreeItem
 */
public class Test_org_eclipse_swt_widgets_TreeItem extends Test_org_eclipse_swt_widgets_Item {

@Override
@Before
public void setUp() {
	super.setUp();
	makeCleanEnvironment();
}

@Test
public void test_ConstructorLorg_eclipse_swt_widgets_TreeI() {
	try {
		new TreeItem((TreeItem)null, SWT.NULL);
		fail("No exception thrown for parent == null");
	}
	catch (IllegalArgumentException e) {
	}

	for (int i=0; i<10; i++) {
		new TreeItem(tree, SWT.NONE);	
	}
	assertEquals(11, tree.getItemCount());
	new TreeItem(tree, SWT.NONE, 5);	
	assertEquals(12, tree.getItemCount());
}

@Test
public void test_ConstructorLorg_eclipse_swt_widgets_TreeII() {
	try {
		new TreeItem(tree, SWT.NONE, 5);
		fail("No exception thrown for illegal index argument");
	}
	catch (IllegalArgumentException e) {
	}
}

@Test
public void test_ConstructorLorg_eclipse_swt_widgets_TreeItemI() {
	for (int i = 0; i < 10; i++) {
		new TreeItem(treeItem, SWT.NONE);
	}
	assertEquals(10, treeItem.getItemCount());
	new TreeItem(treeItem, SWT.NONE, 5);
	assertEquals(1, tree.getItemCount());
}

@Test
public void test_ConstructorLorg_eclipse_swt_widgets_TreeItemII() {
	try {
		new TreeItem(treeItem, SWT.NONE, 5);
		fail("No exception thrown for illegal index argument");
	}
	catch (IllegalArgumentException e) {}
	assertEquals(1, tree.getItemCount());
}

@Test
public void test_getBounds() {
	if (SwtTestUtil.isGTK || SwtTestUtil.isCocoa) {
		//TODO Fix GTK and Cocoa failure.
		if (SwtTestUtil.verbose) {
			System.out.println("Excluded test_getBounds(org.eclipse.swt.tests.junit.Test_org_eclipse_swt_widgets_TreeItem)");
		}
		return;
	}
	Image image = images[0];
	Rectangle bounds;
	Rectangle bounds2;
	String string = "hello";
	
	// no columns
 	bounds = treeItem.getBounds();
	assertTrue(":1a:", bounds.x > 0 && bounds.height > 0);
	
	treeItem.setText(string);
	GC gc = new GC(tree);
	Point extent = gc.stringExtent(string);
	gc.dispose();
	bounds = treeItem.getBounds();
	assertTrue(":1b:", bounds.x > 0 && bounds.height > extent.y && bounds.width > extent.x);
	
	//
	makeCleanEnvironment();
	
	Rectangle rect = image.getBounds();
	treeItem.setImage(image);
	bounds = treeItem.getBounds();
	assertTrue(":1c:", bounds.x > 0 && bounds.height >= rect.height);
	bounds2 = treeItem.getImageBounds(0);
	assertTrue(":1d:", bounds.x >= bounds2.x + bounds2.width);
	
	//
	makeCleanEnvironment();
	
	TreeItem subItem = new TreeItem(treeItem, SWT.NONE);
	bounds = subItem.getBounds();
	assertTrue(":1e:", bounds.equals(new Rectangle(0, 0, 0, 0)));
	treeItem.setExpanded(true);
	bounds = subItem.getBounds();
	bounds2 = treeItem.getBounds();
	assertTrue(":1f:", bounds.x > bounds2.x && bounds.y >= bounds2.y + bounds2.height && bounds.height > 0);
	treeItem.setExpanded(false);
	bounds = subItem.getBounds();
	assertTrue(":1g:", bounds.equals(new Rectangle(0, 0, 0, 0)));
	
	treeItem.setExpanded(true);
	subItem.setText(string);
	bounds = subItem.getBounds();
	bounds2 = treeItem.getBounds();
	assertTrue(":1h:", bounds.x > bounds2.x && bounds.y >= bounds2.y + bounds2.height && bounds.height > extent.y && bounds.width > extent.x);
	
	//
	makeCleanEnvironment();
	subItem = new TreeItem(treeItem, SWT.NONE);
	treeItem.setExpanded(true);
	subItem.setImage(image);
	bounds = subItem.getBounds();
	assertTrue(":1i:", bounds.x > 0 && bounds.height >= rect.height);
	bounds2 = subItem.getImageBounds(0);
	assertTrue(":1j:", bounds.x >= bounds2.x + bounds2.width);
	
	// TODO no columns and CHECK style
	// TODO with columns
	// TODO with columns and CHECK style
}
void getBoundsIA() {	
	// no columns - plain style
	Image image = images[0];
	Rectangle imageBounds = image.getBounds();
	String string = "hello";
	GC gc = new GC(tree);
	Point stringExtent = gc.stringExtent(string);
	gc.dispose();
	
	Rectangle bounds;
	Rectangle bounds2;
	
	//
	makeCleanEnvironment();
	
 	bounds = treeItem.getBounds(0);
	assertTrue(":1a:", bounds.x > 0 && bounds.height > 0);
	bounds = treeItem.getBounds(-1);
	assertTrue(":1b:", bounds.equals(new Rectangle(0, 0, 0, 0)));	
 	bounds = treeItem.getBounds(1);
	assertTrue(":1c:", bounds.equals(new Rectangle(0, 0, 0, 0)));
	// unexpanded item
	TreeItem subItem = new TreeItem(treeItem, SWT.NONE);
	bounds = subItem.getBounds(0);
	assertTrue(":1d:", bounds.equals(new Rectangle(0, 0, 0, 0)));
	treeItem.setExpanded(true);
	bounds = subItem.getBounds(0);
	assertTrue(":1e:", bounds.x > 0 && bounds.height > 0);
	treeItem.setExpanded(false);
	bounds = subItem.getBounds(0);
	assertTrue(":1f:", bounds.equals(new Rectangle(0, 0, 0, 0)));
	treeItem.setExpanded(true);
	subItem.setText(string);
	bounds = subItem.getBounds(0);
	bounds2 = treeItem.getBounds(0);
	assertTrue(":1g:", bounds.x > bounds2.x && bounds.y >= bounds2.y + bounds2.height && bounds.height > stringExtent.y && bounds.width > stringExtent.x);	
	
	treeItem.setText(string);
	bounds = treeItem.getBounds(0);
	assertTrue(":1h:", bounds.x > 0 && bounds.height > stringExtent.y && bounds.width > stringExtent.x);
	bounds2 = treeItem.getBounds();
	//assertTrue(":1new:", bounds.equals(bounds2)); // TODO should bounds be equal?
	treeItem.setText("");
	bounds2 = treeItem.getBounds(0);
	assertTrue(":1i:", bounds2.x > 0 && bounds2.height > 0);
	assertTrue(":1j:", bounds2.width < bounds.width);
	
	//
	makeCleanEnvironment();
	
	treeItem.setImage(image);
	bounds = treeItem.getBounds(0);
	assertTrue(":1k:", bounds.x > 0 && bounds.height >= imageBounds.height && bounds.width >= imageBounds.width);
	treeItem.setImage((Image)null);
	bounds2 = treeItem.getBounds(0);
	assertTrue(":1l:", bounds2.x > 0 && bounds2.height > 0);
//	assertTrue(":1m:", bounds2.width > bounds.width); // once an image is added the space for it is always there
 	
	//
	makeCleanEnvironment();
	
	treeItem.setText(string);
	bounds = treeItem.getBounds(0);
	treeItem.setImage(image);
	bounds2 = treeItem.getBounds(0);
	assertTrue(":1n:", bounds2.x > 0 && bounds2.height > 0);
	assertTrue(":1o:", bounds2.width > bounds.width);
	assertTrue(":1p", bounds2.width >= stringExtent.x + imageBounds.width && bounds2.height >= Math.max(stringExtent.y, imageBounds.height));
}
void getBoundsIB() {
	// no columns and CHECK style
	Image image = images[0];
	Rectangle imageBounds = image.getBounds();
	String string = "hello";
	GC gc = new GC(tree);
	Point stringExtent = gc.stringExtent(string);
	gc.dispose();
	
	Rectangle bounds;
	Rectangle bounds2;
	
	Tree tree2 = new Tree(shell, SWT.CHECK);
	TreeItem treeItem2 = new TreeItem(tree2, SWT.NONE);
	
	bounds = treeItem2.getBounds(0);
	assertTrue(":2a:", bounds.x > 0 && bounds.height > 0);
	bounds = treeItem2.getBounds(-1);
	assertTrue(":2b:", bounds.equals(new Rectangle(0, 0, 0, 0)));	
 	bounds = treeItem2.getBounds(1);
	assertTrue(":2c:", bounds.equals(new Rectangle(0, 0, 0, 0)));
	// unexpanded item
	TreeItem subItem2 = new TreeItem(treeItem2, SWT.NONE);
	bounds = subItem2.getBounds(0);
	assertTrue(":2d:", bounds.equals(new Rectangle(0, 0, 0, 0)));
	treeItem2.setExpanded(true);
	bounds = subItem2.getBounds(0);
	assertTrue(":2e:", bounds.x > 0 && bounds.height > 0);
	treeItem2.setExpanded(false);
	bounds = subItem2.getBounds(0);
	assertTrue(":2f:", bounds.equals(new Rectangle(0, 0, 0, 0)));
	treeItem2.setExpanded(true);
	subItem2.setText(string);
	bounds = subItem2.getBounds(0);
	bounds2 = treeItem2.getBounds(0);
	assertTrue(":2g:", bounds.x > bounds2.x && bounds.y >= bounds2.y + bounds2.height && bounds.height > stringExtent.y && bounds.width > stringExtent.x);	

	treeItem2.setText(string);
	bounds = treeItem2.getBounds(0);
	assertTrue(":2h:", bounds.x > 0 && bounds.height > stringExtent.y && bounds.width > stringExtent.x);
	bounds2 = treeItem2.getBounds();
	//assertTrue(":2new:", bounds.equals(bounds2)); // TODO should bounds be equal?
	treeItem2.setText("");
	bounds2 = treeItem2.getBounds(0);
	assertTrue(":2i:", bounds2.x > 0 && bounds2.height > 0);
	assertTrue(":2j:", bounds2.width < bounds.width);
	
	tree2.dispose();
	tree2 = new Tree(shell, SWT.CHECK);
	treeItem2 = new TreeItem(tree2, SWT.NONE);
	
	treeItem2.setImage(image);
	bounds = treeItem2.getBounds(0);
	assertTrue(":2k:", bounds.x > 0 && bounds.height >= imageBounds.height && bounds.width >= imageBounds.width);
	treeItem2.setImage((Image)null);
	bounds2 = treeItem2.getBounds(0);
	assertTrue(":2l:", bounds2.x > 0 && bounds2.height > 0);
	//assertTrue(":2m:", bounds2.width < bounds.width);  // once an image is added the space for it is always there
	
	tree2.dispose();
	tree2 = new Tree(shell, SWT.CHECK);
	treeItem2 = new TreeItem(tree2, SWT.NONE);
	
	treeItem2.setText(string);
	bounds = treeItem2.getBounds(0);
	treeItem2.setImage(image);
	bounds2 = treeItem2.getBounds(0);
	assertTrue(":2n:", bounds2.x > 0 && bounds2.height > 0);
	assertTrue(":2o:", bounds2.width > bounds.width);
	assertTrue(":1p", bounds2.width >= stringExtent.x + imageBounds.width && bounds2.height >= Math.max(stringExtent.y, imageBounds.height));
}
void getBoundsIC() {
	// with columns
	
	Image image = images[0];
	Rectangle imageBounds = image.getBounds();
	String string1 = "hello";
	String string2 = "world";
	GC gc = new GC(tree);
	Point stringExtent1 = gc.stringExtent(string1);
	//Point stringExtent2 = gc.stringExtent(string2);
	gc.dispose();
	
	Rectangle bounds;
	Rectangle bounds2;
	
	//
	makeCleanEnvironment();

	TreeColumn column0 = new TreeColumn(tree, SWT.LEFT);
	TreeColumn column1 = new TreeColumn(tree, SWT.CENTER);
	
	bounds = treeItem.getBounds(0);
	assertTrue(":3a:", bounds.x > 0 && bounds.height > 0 && bounds.width == 0);
	bounds = treeItem.getBounds(1);
	assertTrue(":3b:", /*bounds.x > 0 &&*/ bounds.height > 0 && bounds.width == 0); // TODO bounds.x == 0 Is this right?
	bounds = treeItem.getBounds(-1);
	assertTrue(":3c:", bounds.equals(new Rectangle(0, 0, 0, 0)));	
 	bounds = treeItem.getBounds(2);
	assertTrue(":3d:", bounds.equals(new Rectangle(0, 0, 0, 0)));
	// unexpanded item
	TreeItem subItem = new TreeItem(treeItem, SWT.NONE);
	bounds = subItem.getBounds(0);
	assertTrue(":3e:", bounds.equals(new Rectangle(0, 0, 0, 0)));
	treeItem.setExpanded(true);
	bounds = subItem.getBounds(0);
	assertTrue(":3f:", bounds.x > 0 && bounds.height > 0);
	treeItem.setExpanded(false);
	bounds = subItem.getBounds(0);
	assertTrue(":3g:", bounds.equals(new Rectangle(0, 0, 0, 0)));
	treeItem.setExpanded(true);
	subItem.setText(new String[] {string1, string2});
	bounds = subItem.getBounds(0);
	bounds2 = treeItem.getBounds(0);
	assertTrue(":3h:", bounds.x > bounds2.x && bounds.y >= bounds2.y + bounds2.height && bounds.height > stringExtent1.y && bounds.width == 0);	

	column0.setWidth(100);
	bounds = treeItem.getBounds(0);
	assertTrue(":3i:", bounds.x > 0 && bounds.height > 0 && bounds.width > 0 && bounds.width < 100);
	bounds = treeItem.getBounds(1);
	assertTrue(":3j:", bounds.x >= 100 && bounds.height > 0 && bounds.width == 0);
	bounds = subItem.getBounds(0);
	bounds2 = treeItem.getBounds(0);
	assertTrue(":3k:", bounds.x > bounds2.x && bounds.y >= bounds2.y + bounds2.height && bounds.height > stringExtent1.y && bounds.width > 0 && bounds.width < 100);	

	column1.setWidth(200);
	bounds = treeItem.getBounds(0);
	assertTrue(":3l:", bounds.x > 0 && bounds.height > 0 && bounds.width > 0 && bounds.width < 100);
	bounds = treeItem.getBounds(1);
	assertTrue(":3m:", bounds.x >= 100 && bounds.height > 0 && bounds.width == 200);
	
	treeItem.setText(new String[] {string1, string2});
	bounds = treeItem.getBounds(0);
	assertTrue(":3n:", bounds.x > 0 && bounds.height > stringExtent1.y && bounds.width > 0 && bounds.width < 100);
	bounds = treeItem.getBounds(1);
	assertTrue(":3o:", bounds.x >= 100 && bounds.height > stringExtent1.y && bounds.width  == 200);
	treeItem.setText(new String[] {"", ""});
	bounds = treeItem.getBounds(0);
	assertTrue(":3p:", bounds.x > 0 && bounds.height > stringExtent1.y && bounds.width > 0 && bounds.width < 100);
	bounds = treeItem.getBounds(1);
	assertTrue(":3q:", bounds.x >= 100 && bounds.height > stringExtent1.y && bounds.width  == 200);
	
	//
	makeCleanEnvironment();
	column0 = new TreeColumn(tree, SWT.LEFT);
	column1 = new TreeColumn(tree, SWT.CENTER);
	column0.setWidth(100);
	column1.setWidth(200);
	
	treeItem.setImage(new Image[] {image, image});
	bounds = treeItem.getBounds(0);
	assertTrue(":3r:", bounds.x > 0 && bounds.height >= imageBounds.height && bounds.width > 0 && bounds.width < 100);
	bounds = treeItem.getBounds(1);
	assertTrue(":3s:", bounds.x >= 100 && bounds.height >= imageBounds.height && bounds.width  == 200);
 	treeItem.setImage(new Image[] {null, null});
	bounds = treeItem.getBounds(0);
	assertTrue(":3t:", bounds.x > 0 && bounds.height > 0 && bounds.width > 0 && bounds.width < 100);
	bounds = treeItem.getBounds(1);
	assertTrue(":3u:", bounds.x >= 100 && bounds.height > 0 && bounds.width  == 200);
	
	//
	makeCleanEnvironment();
	column0 = new TreeColumn(tree, SWT.LEFT);
	column1 = new TreeColumn(tree, SWT.CENTER);
	column0.setWidth(100);
	column1.setWidth(200);
	
	treeItem.setText(new String[] {string1, string2});
	treeItem.setImage(new Image[] {image, image});
	bounds = treeItem.getBounds(0);
	assertTrue(":3v:", bounds.x > 0 && bounds.height > stringExtent1.y && bounds.height >= imageBounds.height && bounds.width > 0 && bounds.width < 100);
	bounds = treeItem.getBounds(1);
	assertTrue(":3w:", bounds.x > 0 && bounds.height > stringExtent1.y && bounds.height >= imageBounds.height && bounds.width  == 200);
	
	//
	makeCleanEnvironment();
	
	treeItem.setText(string1);
	new TreeColumn(tree, SWT.RIGHT);
	bounds = treeItem.getBounds(0);
	assertTrue(":3x:", bounds.x > 0 && bounds.height > stringExtent1.y && bounds.width  == 0);
}

void getBoundsID() {
	// with columns and CHECK style
	Image image = images[0];
	Rectangle imageBounds = image.getBounds();
	String string1 = "hello";
	String string2 = "world";
	GC gc = new GC(tree);
	Point stringExtent1 = gc.stringExtent(string1);
	//Point stringExtent2 = gc.stringExtent(string2);
	gc.dispose();
	
	Rectangle bounds;
	Rectangle bounds2;
	
	Tree tree2 = new Tree(shell, SWT.CHECK);
	TreeItem treeItem2 = new TreeItem(tree2, SWT.NONE);
	TreeColumn column0 = new TreeColumn(tree2, SWT.LEFT);
	TreeColumn column1 = new TreeColumn(tree2, SWT.CENTER);
	
	bounds = treeItem2.getBounds(0);
	assertTrue(":4a:", bounds.x > 0 && bounds.height > 0 && bounds.width == 0);
	bounds = treeItem2.getBounds(1);
	assertTrue(":4b:", /*bounds.x > 0 &&*/ bounds.height > 0 && bounds.width == 0); // TODO bounds.x == 0 Is this right?
	bounds = treeItem2.getBounds(-1);
	assertTrue(":4c:", bounds.equals(new Rectangle(0, 0, 0, 0)));	
 	bounds = treeItem2.getBounds(2);
	assertTrue(":4d:", bounds.equals(new Rectangle(0, 0, 0, 0)));
	// unexpanded item
	TreeItem subItem2 = new TreeItem(treeItem2, SWT.NONE);
	bounds = subItem2.getBounds(0);
	assertTrue(":4e:", bounds.equals(new Rectangle(0, 0, 0, 0)));
	treeItem2.setExpanded(true);
	bounds = subItem2.getBounds(0);
	assertTrue(":4f:", bounds.x > 0 && bounds.height > 0);
	treeItem2.setExpanded(false);
	bounds = subItem2.getBounds(0);
	assertTrue(":4g:", bounds.equals(new Rectangle(0, 0, 0, 0)));
	treeItem2.setExpanded(true);
	subItem2.setText(new String[] {string1, string2});
	bounds = subItem2.getBounds(0);
	bounds2 = treeItem2.getBounds(0);
	assertTrue(":4h:", bounds.x > bounds2.x && bounds.y >= bounds2.y + bounds2.height && bounds.height > stringExtent1.y && bounds.width == 0);	
	
	column0.setWidth(100);
	bounds = treeItem2.getBounds(0);
	assertTrue(":4i:", bounds.x > 0 && bounds.height > 0 && bounds.width > 0 && bounds.width < 100);
	bounds = treeItem2.getBounds(1);
	assertTrue(":4j:", bounds.x >= 100 && bounds.height > 0 && bounds.width == 0);
	bounds = subItem2.getBounds(0);
	bounds2 = treeItem2.getBounds(0);
	assertTrue(":4k:", bounds.x > bounds2.x && bounds.y >= bounds2.y + bounds2.height && bounds.height > stringExtent1.y && bounds.width > 0 && bounds.width < 100);	

	
	column1.setWidth(200);
	bounds = treeItem2.getBounds(0);
	assertTrue(":4l:", bounds.x > 0 && bounds.height > 0 && bounds.width > 0 && bounds.width < 100);
	bounds = treeItem2.getBounds(1);
	assertTrue(":4m:", bounds.x >= 100 && bounds.height > 0 && bounds.width == 200);
	
	treeItem2.setText(new String[] {string1, string2});
	bounds = treeItem2.getBounds(0);
	assertTrue(":4n:", bounds.x > 0 && bounds.height > stringExtent1.y && bounds.width > 0 && bounds.width < 100);
	bounds = treeItem2.getBounds(1);
	assertTrue(":4o:", bounds.x >= 100 && bounds.height > stringExtent1.y && bounds.width  == 200);
	treeItem2.setText(new String[] {"", ""});
	bounds = treeItem2.getBounds(0);
	assertTrue(":4p:", bounds.x > 0 && bounds.height > stringExtent1.y && bounds.width > 0 && bounds.width < 100);
	bounds = treeItem2.getBounds(1);
	assertTrue(":4q:", bounds.x >= 100 && bounds.height > stringExtent1.y && bounds.width  == 200);
	
	//
	tree2.dispose();
	tree2 = new Tree(shell, SWT.CHECK);
	treeItem2 = new TreeItem(tree2, SWT.NONE);
	column0 = new TreeColumn(tree2, SWT.LEFT);
	column1 = new TreeColumn(tree2, SWT.CENTER);
	column0.setWidth(100);
	column1.setWidth(200);
	
	treeItem2.setImage(new Image[] {image, image});
	bounds = treeItem2.getBounds(0);
	assertTrue(":4r:", bounds.x > 0 && bounds.height >= imageBounds.height && bounds.width > 0 && bounds.width < 100);
	bounds = treeItem2.getBounds(1);
	assertTrue(":4s:", bounds.x >= 100 && bounds.height >= imageBounds.height && bounds.width  == 200);
 	treeItem2.setImage(new Image[] {null, null});
	bounds = treeItem2.getBounds(0);
	assertTrue(":4t:", bounds.x > 0 && bounds.height > 0 && bounds.width > 0 && bounds.width < 100);
	bounds = treeItem2.getBounds(1);
	assertTrue(":4u:", bounds.x >= 100 && bounds.height > 0 && bounds.width  == 200);
	
	//
	tree2.dispose();
	tree2 = new Tree(shell, SWT.CHECK);
	treeItem2 = new TreeItem(tree2, SWT.NONE);
	column0 = new TreeColumn(tree2, SWT.LEFT);
	column1 = new TreeColumn(tree2, SWT.CENTER);
	column0.setWidth(100);
	column1.setWidth(200);
	
	treeItem2.setText(new String[] {string1, string2});
	treeItem2.setImage(new Image[] {image, image});
	bounds = treeItem2.getBounds(0);
	assertTrue(":4v:", bounds.x > 0 && bounds.height > stringExtent1.y && bounds.height >= imageBounds.height && bounds.width > 0 && bounds.width < 100);
	bounds = treeItem2.getBounds(1);
	assertTrue(":4w:", bounds.x >= 100 && bounds.height > stringExtent1.y && bounds.height >= imageBounds.height && bounds.width  == 200);
	
	//
	tree2.dispose();
	tree2 = new Tree(shell, SWT.CHECK);
	treeItem2 = new TreeItem(tree2, SWT.NONE);
	
	treeItem2.setText(string1);
	new TreeColumn(tree2, SWT.RIGHT);
	bounds = treeItem2.getBounds(0);
	assertTrue(":4x:", bounds.x > 0 && bounds.height > stringExtent1.y && bounds.width  == 0);
}

@Test
public void test_getBoundsI() {
	if (SwtTestUtil.isGTK || SwtTestUtil.isCocoa) {
		//TODO Fix Gtk and Cocoa failure.
		if (SwtTestUtil.verbose) {
			System.out.println("Excluded test_getBoundsI(org.eclipse.swt.tests.junit.Test_org_eclipse_swt_widgets_TreeItem)");
		}
		return;
	}
	getBoundsIA();
	getBoundsIB();
	getBoundsIC();
	getBoundsID();
}

@Test
public void test_getExpanded() {
	assertEquals(false, treeItem.getExpanded());
	// there must be at least one subitem before you can set the treeitem expanded
	new TreeItem(treeItem, 0);
	treeItem.setExpanded(true);
	assertTrue(treeItem.getExpanded());
	treeItem.setExpanded(false);
	assertEquals(false, treeItem.getExpanded());
}

@Test
public void test_getImageBoundsI() {
/**
 * Test without item image
 */
	Rectangle bounds;
	Tree tree2 = new Tree(shell, SWT.CHECK);
	TreeItem treeItem2 = new TreeItem(tree2, SWT.NULL);
	
	assertEquals(new Rectangle(0, 0, 0, 0), treeItem.getImageBounds(-1));
	
	// TODO - should this width be 0 or a value?
	bounds = treeItem.getImageBounds(0);
	assertTrue(":b:", bounds.width == 0);
	
	assertEquals(new Rectangle(0, 0, 0, 0), treeItem.getImageBounds(1));
	
	assertEquals(new Rectangle(0, 0, 0, 0), treeItem2.getImageBounds(-1));
	
	// TODO - should this width be 0 or a value?
	//bounds = treeItem2.getImageBounds(0);
	//assertTrue(":e:", bounds.width == 0);
	
	assertEquals(new Rectangle(0, 0, 0, 0), treeItem2.getImageBounds(1));
 	//
	makeCleanEnvironment();
	
	Image image = images[0];	
//	int imageWidth = image.getBounds().width;
//	int imageHeight;
	
	treeItem.setImage(0, image);
//	imageHeight = tree.getItemHeight() - tree.getGridLineWidth();
	assertEquals(new Rectangle(0, 0, 0, 0), treeItem.getImageBounds(-1));
	
	bounds = treeItem.getImageBounds(0);
//	assertTrue(":b:", bounds.x > 0 && bounds.width == imageWidth && bounds.height == imageHeight);	
// 	assertEquals(new Rectangle(0, 0, 0, 0), treeItem.getImageBounds(1));	


	//
	makeCleanEnvironment();	
	
	tree2.dispose();
	tree2 = new Tree(shell, SWT.CHECK);
	treeItem2.dispose();
	treeItem2 = new TreeItem(tree2, SWT.NULL);
//	Rectangle imageBounds = image.getBounds();
//	imageWidth = imageBounds.width; 	treeItem2.setImage(0, image);
//	imageHeight = tree2.getItemHeight() - tree2.getGridLineWidth();
	assertEquals(new Rectangle(0, 0, 0, 0), treeItem2.getImageBounds(-1));
	
	bounds = treeItem2.getImageBounds(0);	// bounds.width should be check box width if they are wider than image
//	assertTrue(":b:", bounds.x > 0 && bounds.width > 0 && bounds.height == imageHeight);
// 	assertEquals(new Rectangle(0, 0, 0, 0), treeItem2.getImageBounds(1));	


	//
	makeCleanEnvironment();

	tree2.dispose();
	tree2 = new Tree(shell, SWT.CHECK);
	treeItem2.dispose();
	treeItem2 = new TreeItem(tree2, SWT.NULL);
	image = images[1];
//	imageBounds = image.getBounds();
//	imageWidth = imageBounds.width;
 	treeItem2.setImage(0, image);
//	imageHeight = tree2.getItemHeight() - tree2.getGridLineWidth();
	assertEquals(new Rectangle(0, 0, 0, 0), treeItem2.getImageBounds(-1));
 	bounds = treeItem2.getImageBounds(0);	// bounds.width should be check box width if check box is wider than image
//	assertTrue(":b:", bounds.x > 0 && bounds.width > 0 && bounds.height == imageHeight);
 	assertEquals(new Rectangle(0, 0, 0, 0), treeItem2.getImageBounds(1));
}

@Test
public void test_getItemI() {
	int number = 15;
	TreeItem[] items = new TreeItem[number];
	for (int i = 0; i < number; i++)
		items[i] = new TreeItem(treeItem, 0);

	for (int i = 0; i < number; i++)
		assertEquals("i=" + i, items[i], treeItem.getItem(i));
	try {
		treeItem.getItem(number);
		fail("No exception thrown for illegal index argument");
	}
	catch (IllegalArgumentException e) {
	}
	
	try {
		treeItem.getItem(number+1);
		fail("No exception thrown for illegal index argument");
	}
	catch (IllegalArgumentException e) {
	}
	
	try {
		treeItem.getItem(-1);
		fail("No exception thrown for illegal index argument");
	}
	catch (IllegalArgumentException e) {
	}
}

@Test
public void test_getItemCount() {
	for (int i = 0; i < 10; i++) {
		assertEquals(i, treeItem.getItemCount());
		new TreeItem(treeItem, 0);
	}
	assertTrue("b: ", treeItem.getItemCount() == 10);
}

@Test
public void test_getItems() {
	int[] cases = {0, 10, 100};
	TreeItem [][] items = new TreeItem [cases.length][];
	for (int j = 0; j < cases.length; j++) {
		items [j] = new TreeItem [cases [j]];
	}
	for (int j = 0; j < cases.length; j++) {
		for (int i = 0; i < cases[j]; i++) {
			TreeItem ti = new TreeItem(treeItem, 0);
			items [j][i] = ti;
		}
		assertArrayEquals(items[j], treeItem.getItems());
		for (int i = 0; i < cases[j]; i++) {
			items [j][i].dispose();
		}
		assertEquals(0, treeItem.getItemCount());
	}
}

@Test
public void test_getParent() {
	assertEquals(tree, treeItem.getParent());
}

@Test
public void test_getParentItem() {
	TreeItem tItem = new TreeItem(treeItem, SWT.NULL);
	assertEquals(treeItem, tItem.getParentItem());
}

@Test
public void test_setBackgroundILorg_eclipse_swt_graphics_Color() {
	Display display = treeItem.getDisplay();
	Color red = display.getSystemColor(SWT.COLOR_RED);
	Color blue = display.getSystemColor(SWT.COLOR_BLUE);
	
	// no columns
	assertEquals(tree.getBackground(), treeItem.getBackground(0));
	assertEquals(treeItem.getBackground(), treeItem.getBackground(0));
	treeItem.setBackground(0, red);
	assertEquals(red, treeItem.getBackground(0));
	
	// index beyond range - no error
	treeItem.setBackground(10, red);
	assertEquals(treeItem.getBackground(), treeItem.getBackground(10));
	
	// with columns
	new TreeColumn(tree, SWT.LEFT);
	new TreeColumn(tree, SWT.LEFT);
	
	// index beyond range - no error
	treeItem.setBackground(10, red);
	assertEquals(treeItem.getBackground(), treeItem.getBackground(10));
	
	treeItem.setBackground(0, red);
	assertEquals(red, treeItem.getBackground(0));
	treeItem.setBackground(0, null);
	assertEquals(tree.getBackground(),treeItem.getBackground(0));

	treeItem.setBackground(0, blue);
	treeItem.setBackground(red);
	assertEquals(blue, treeItem.getBackground(0));
	
	treeItem.setBackground(0, null);
	assertEquals(red, treeItem.getBackground(0));
	
	treeItem.setBackground(null);
	assertEquals(tree.getBackground(),treeItem.getBackground(0));
	
	try { 
		Color color = new Color(display, 255, 0, 0);
		color.dispose();
		treeItem.setBackground(color);
		fail("No exception thrown for color disposed");		
	} catch (IllegalArgumentException e) {
	}
}

@Test
public void test_setBackgroundLorg_eclipse_swt_graphics_Color() {
	Color color = new Color(treeItem.getDisplay(), 255, 0, 0);
	treeItem.setBackground(color);
	assertEquals(color, treeItem.getBackground());
	treeItem.setBackground(null);
	assertEquals(tree.getBackground(),treeItem.getBackground());
	color.dispose();
	try { 
		treeItem.setBackground(color);
		fail("No exception thrown for color disposed");		
	} catch (IllegalArgumentException e) {
	}
}

@Test
public void test_setCheckedZ() {
	assertEquals(false, treeItem.getChecked());
	
	treeItem.setChecked(true);
	assertEquals(false, treeItem.getChecked());

	Tree t = new Tree(shell, SWT.CHECK);
	TreeItem ti = new TreeItem(t, SWT.NULL);
	ti.setChecked(true);
	assertTrue(ti.getChecked());
	
	ti.setChecked(false);
	assertEquals(false, ti.getChecked());
	t.dispose();
}

@Test
public void test_setExpandedZ() {
	assertEquals(false, treeItem.getExpanded());
	
	// there must be at least one subitem before you can set the treeitem expanded
	treeItem.setExpanded(true);
	assertEquals(false, treeItem.getExpanded());


	new TreeItem(treeItem, SWT.NULL);
	treeItem.setExpanded(true);
	assertTrue(treeItem.getExpanded());
	treeItem.setExpanded(false);
	assertEquals(false, treeItem.getExpanded());
		
	TreeItem ti = new TreeItem(treeItem, SWT.NULL);
	ti.setExpanded(true);
	treeItem.setExpanded(false);
	assertEquals(false, ti.getExpanded());
}

@Test
public void test_setFontLorg_eclipse_swt_graphics_Font() {
	Font font = treeItem.getFont();
	treeItem.setFont(font);
	assertTrue(font.equals(treeItem.getFont()));
	
	font = new Font(treeItem.getDisplay(), SwtTestUtil.testFontName, 10, SWT.NORMAL);
	treeItem.setFont(font);
	assertTrue(font.equals(treeItem.getFont()));

	treeItem.setFont(null);
	assertTrue(tree.getFont().equals( treeItem.getFont()));
	
	font.dispose();
	try {
		treeItem.setFont(font);
		treeItem.setFont(null);
		fail("No exception thrown for disposed font");
	} catch (IllegalArgumentException e) {
	}
}

@Test
public void test_setFontILorg_eclipse_swt_graphics_Font() {
	Display display = treeItem.getDisplay();
	Font font = new Font(display, SwtTestUtil.testFontName, 10, SWT.NORMAL);
	
	// no columns
	assertTrue(tree.getFont().equals( treeItem.getFont(0)));
	assertTrue(treeItem.getFont().equals(treeItem.getFont(0)));
	treeItem.setFont(0, font);
	assertTrue(font.equals(treeItem.getFont(0)));
	
	// index beyond range - no error
	treeItem.setFont(10, font);
	assertTrue(treeItem.getFont().equals(treeItem.getFont(10)));
	
	// with columns
	new TreeColumn(tree, SWT.LEFT);
	new TreeColumn(tree, SWT.LEFT);
	
	// index beyond range - no error
	treeItem.setFont(10, font);
	assertTrue(treeItem.getFont().equals(treeItem.getFont(10)));
	
	treeItem.setFont(0, font);
	assertTrue(font.equals(treeItem.getFont(0)));
	treeItem.setFont(0, null);
	assertTrue(tree.getFont().equals(treeItem.getFont(0)));
	
	Font font2 = new Font(display, SwtTestUtil.testFontName, 20, SWT.NORMAL);
	
	treeItem.setFont(0, font);
	treeItem.setFont(font2);
	assertTrue(font.equals(treeItem.getFont(0)));
	
	treeItem.setFont(0, null);
	assertTrue(font2.equals(treeItem.getFont(0)));
	
	treeItem.setFont(null);
	assertTrue(tree.getFont().equals(treeItem.getFont(0)));
	
	font.dispose();
	font2.dispose();
	
	try {
		treeItem.setFont(0, font);
		treeItem.setFont(0, null);
		fail("No exception thrown for disposed font");
	} catch (IllegalArgumentException e) {
	}
}

@Test
public void test_setForegroundILorg_eclipse_swt_graphics_Color() {
	Display display = treeItem.getDisplay();
	Color red = display.getSystemColor(SWT.COLOR_RED);
	Color blue = display.getSystemColor(SWT.COLOR_BLUE);
	
	// no columns
	assertEquals(tree.getForeground(), treeItem.getForeground(0));
	assertEquals(treeItem.getForeground(), treeItem.getForeground(0));
	treeItem.setForeground(0, red);
	assertEquals(red, treeItem.getForeground(0));
	
	// index beyond range - no error
	treeItem.setForeground(10, red);
	assertEquals(treeItem.getForeground(), treeItem.getForeground(10));
	
	// with columns
	new TreeColumn(tree, SWT.LEFT);
	new TreeColumn(tree, SWT.LEFT);
	
	// index beyond range - no error
	treeItem.setForeground(10, red);
	assertEquals(treeItem.getForeground(), treeItem.getForeground(10));
	
	treeItem.setForeground(0, red);
	assertEquals(red, treeItem.getForeground(0));
	treeItem.setForeground(0, null);
	assertEquals(tree.getForeground(),treeItem.getForeground(0));

	treeItem.setForeground(0, blue);
	treeItem.setForeground(red);
	assertEquals(blue, treeItem.getForeground(0));
	
	treeItem.setForeground(0, null);
	assertEquals(red, treeItem.getForeground(0));
	
	treeItem.setForeground(null);
	assertEquals(tree.getForeground(),treeItem.getForeground(0));
	
	try { 
		Color color = new Color(display, 255, 0, 0);
		color.dispose();
		treeItem.setForeground(color);
		fail("No exception thrown for color disposed");		
	} catch (IllegalArgumentException e) {
	}
}

@Test
public void test_setForegroundLorg_eclipse_swt_graphics_Color() {
	Color color = new Color(treeItem.getDisplay(), 255, 0, 0);
	treeItem.setForeground(color);
	assertEquals(color, treeItem.getForeground());
	treeItem.setForeground(null);
	assertEquals(tree.getForeground(),treeItem.getForeground());
	color.dispose();
	try { 
		treeItem.setForeground(color);
		fail("No exception thrown for color disposed");
	} catch (IllegalArgumentException e) {
	}
}

@Test
public void test_setGrayedZ() {
	Tree newTree = new Tree(shell, SWT.CHECK);
	TreeItem tItem = new TreeItem(newTree,0);
	assertEquals(false, tItem.getGrayed());
	tItem.setGrayed(true);
	assertTrue(tItem.getGrayed());
	tItem.setGrayed(false);
	assertEquals(false, tItem.getGrayed());
	newTree.dispose();
}

@Test
public void test_setImage$Lorg_eclipse_swt_graphics_Image() {
	assertNull(treeItem.getImage(1));	
 	treeItem.setImage(-1, null);		
	assertNull(treeItem.getImage(-1));	
		
	treeItem.setImage(0, images[0]);
	assertEquals(images[0], treeItem.getImage(0));	
 	String texts[] = new String[images.length];
	for (int i = 0; i < texts.length; i++) {
		texts[i] = String.valueOf(i);
	}
	
	//tree.setText(texts);				// create enough columns for TreeItem.setImage(Image[]) to work
	int columnCount = tree.getColumnCount();
	if (columnCount < texts.length) {
		for (int i = columnCount; i < texts.length; i++){
			new TreeColumn(tree, SWT.NONE);
		}
	}
	TreeColumn[] columns = tree.getColumns();
	for (int i = 0; i < texts.length; i++) {
		columns[i].setText(texts[i]);
	}
	treeItem.setImage(1, images[1]);
	assertEquals(images[1], treeItem.getImage(1));	
 	treeItem.setImage(images);
	for (int i = 0; i < images.length; i++) {
		assertEquals(images[i], treeItem.getImage(i));
	}
	try {
		treeItem.setImage((Image []) null);
		fail("No exception thrown for images == null");
	}
	catch (IllegalArgumentException e) {
	}
}

@Test
public void test_setImageILorg_eclipse_swt_graphics_Image() {
	// no columns
	assertEquals(null, treeItem.getImage(0));
	treeItem.setImage(0, images[0]);
	assertEquals(images[0], treeItem.getImage(0));
	
	// index beyond range - no error
	treeItem.setImage(10, images[0]);
	assertEquals(null, treeItem.getImage(10));
	
	// with columns
	new TreeColumn(tree, SWT.LEFT);
	new TreeColumn(tree, SWT.LEFT);
	
	// index beyond range - no error
	treeItem.setImage(10, images[0]);
	assertEquals(null, treeItem.getImage(10));
	
	treeItem.setImage(0, images[0]);
	assertEquals(images[0], treeItem.getImage(0));
	treeItem.setImage(0, null);
	assertEquals(null, treeItem.getImage(0));
	
	treeItem.setImage(0, images[0]);
	treeItem.setImage(images[1]);
	assertEquals(images[1], treeItem.getImage(0));
	
	treeItem.setImage(images[1]);
	treeItem.setImage(0, images[0]);
	assertEquals(images[0], treeItem.getImage(0));
	
	images[0].dispose();
	try {
		treeItem.setImage(0, images[0]);
		treeItem.setImage(0, null);
		fail("No exception thrown for disposed font");
	} catch (IllegalArgumentException e) {
	}
}

@Test
public void test_setText$Ljava_lang_String() {
	final String TestString = "test";
	final String TestStrings[] = new String[] {TestString, TestString + "1", TestString + "2"};
	
	try {
		treeItem.setText((String []) null);
		fail("No exception thrown for strings == null");
	}
	catch (IllegalArgumentException e) {
	}
	
   /*
 	* Test the getText/setText API with a Tree that has only 
 	* the default column.
 	*/
	
	assertEquals(0, treeItem.getText(1).length());
	
	treeItem.setText(TestStrings);
	assertEquals(TestStrings[0], treeItem.getText(0));
	for (int i = 1; i < TestStrings.length; i++) {
		assertEquals(0, treeItem.getText(i).length());
	}
	
	
   /*
 	* Test the getText/setText API with a Tree that enough 
 	* columns to fit all test item texts.
 	*/
 		
	int columnCount = tree.getColumnCount();
	if (columnCount < images.length) {
		for (int i = columnCount; i < images.length; i++){
			new TreeColumn(tree, SWT.NONE);
		}
	}
	TreeColumn[] columns = tree.getColumns();
	for (int i = 0; i < TestStrings.length; i++) {
		columns[i].setText(TestStrings[i]);
	}
	assertEquals(0, treeItem.getText(1).length());

}

@Test
public void test_setTextILjava_lang_String(){
	final String TestString = "test";
	final String TestStrings[] = new String[] {TestString, TestString + "1", TestString + "2"};

   /*
 	* Test the getText/setText API with a Tree that has only 
 	* the default column.
 	*/
	
	assertEquals(0, treeItem.getText(1).length());	
 	treeItem.setText(1, TestString);
	assertEquals(0, treeItem.getText(1).length());	
	assertEquals(0, treeItem.getText(0).length());
	
	treeItem.setText(0, TestString);
	assertEquals(TestString, treeItem.getText(0));
 	treeItem.setText(-1, TestStrings[1]);
	assertEquals(0, treeItem.getText(-1).length());	

   /*
 	* Test the getText/setText API with a Tree that enough 
 	* columns to fit all test item texts.
 	*/

	makeCleanEnvironment();
	
	//tree.setText(TestStrings);				// create anough columns for TreeItem.setText(String[]) to work
	int columnCount = tree.getColumnCount();
	if (columnCount < images.length) {
		for (int i = columnCount; i < images.length; i++){
			new TreeColumn(tree, SWT.NONE);
		}
	}
	TreeColumn[] columns = tree.getColumns();
	for (int i = 0; i < TestStrings.length; i++) {
		columns[i].setText(TestStrings[i]);
	}
	assertEquals(0, treeItem.getText(1).length());	


	treeItem.setText(1, TestString);
	assertEquals(TestString, treeItem.getText(1));	
	assertEquals(0, treeItem.getText(0).length());
	
	treeItem.setText(0, TestString);
	assertEquals(TestString, treeItem.getText(0));


	treeItem.setText(-1, TestStrings[1]);
	assertEquals(0, treeItem.getText(-1).length());	


	try {
		treeItem.setText(-1, null);		
		fail("No exception thrown for string == null");
	}
	catch (IllegalArgumentException e) {
	}
	
	try {
		treeItem.setText(0, null);		
		fail("No exception thrown for string == null");
	}
	catch (IllegalArgumentException e) {
	} 


}

/* custom */
TreeItem treeItem;
Tree tree;

// this method must be private or protected so the auto-gen tool keeps it
private void makeCleanEnvironment() {
	if ( treeItem != null ) treeItem.dispose();
	if ( tree != null ) tree.dispose();
	tree = new Tree(shell, 0);
	treeItem = new TreeItem(tree, 0);
	setWidget(treeItem);
}
}
