/*******************************************************************************
 * Copyright (c) 2007, 2010 Oracle. 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:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.utility.tests.internal.model.value.swing;

import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;

import javax.swing.Icon;
import javax.swing.JTree;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;

import junit.framework.TestCase;

import org.eclipse.jpt.utility.IndentingPrintWriter;
import org.eclipse.jpt.utility.internal.HashBag;
import org.eclipse.jpt.utility.internal.StringTools;
import org.eclipse.jpt.utility.internal.iterators.ReadOnlyIterator;
import org.eclipse.jpt.utility.internal.model.AbstractModel;
import org.eclipse.jpt.utility.internal.model.value.AbstractTreeNodeValueModel;
import org.eclipse.jpt.utility.internal.model.value.CollectionAspectAdapter;
import org.eclipse.jpt.utility.internal.model.value.ItemPropertyListValueModelAdapter;
import org.eclipse.jpt.utility.internal.model.value.NullListValueModel;
import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
import org.eclipse.jpt.utility.internal.model.value.SimpleListValueModel;
import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
import org.eclipse.jpt.utility.internal.model.value.SortedListValueModelWrapper;
import org.eclipse.jpt.utility.internal.model.value.StaticPropertyValueModel;
import org.eclipse.jpt.utility.internal.model.value.TransformationListValueModel;
import org.eclipse.jpt.utility.internal.model.value.swing.TreeModelAdapter;
import org.eclipse.jpt.utility.internal.swing.Displayable;
import org.eclipse.jpt.utility.model.event.PropertyChangeEvent;
import org.eclipse.jpt.utility.model.listener.ListChangeListener;
import org.eclipse.jpt.utility.model.listener.PropertyChangeListener;
import org.eclipse.jpt.utility.model.listener.StateChangeListener;
import org.eclipse.jpt.utility.model.value.CollectionValueModel;
import org.eclipse.jpt.utility.model.value.ListValueModel;
import org.eclipse.jpt.utility.model.value.PropertyValueModel;
import org.eclipse.jpt.utility.model.value.TreeNodeValueModel;
import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;

@SuppressWarnings("nls")
public class TreeModelAdapterTests extends TestCase {
	boolean eventFired;

	public TreeModelAdapterTests(String name) {
		super(name);
	}

	public void testGetRoot() {
		TreeModel treeModel = this.buildSortedTreeModel();
		treeModel.addTreeModelListener(new TestTreeModelListener());
		TestNode rootNode = (TestNode) treeModel.getRoot();
		TestModel root = rootNode.getTestModel();
		assertEquals("root", root.getName());
//		root.dump();
//		rootNode.dump();
	}

	public void testGetChild() {
		TreeModel treeModel = this.buildSortedTreeModel();
		treeModel.addTreeModelListener(new TestTreeModelListener());
		TestNode rootNode = (TestNode) treeModel.getRoot();

		TestNode expected = rootNode.childNamed("node 1");
		TestNode actual = (TestNode) treeModel.getChild(rootNode, 1);
		assertEquals(expected, actual);

		expected = rootNode.childNamed("node 2");
		actual = (TestNode) treeModel.getChild(rootNode, 2);
		assertEquals(expected, actual);
	}

	public void testGetChildCount() {
		TreeModel treeModel = this.buildSortedTreeModel();
		treeModel.addTreeModelListener(new TestTreeModelListener());
		TestNode rootNode = (TestNode) treeModel.getRoot();

		assertEquals(5, treeModel.getChildCount(rootNode));

		TestNode node = rootNode.childNamed("node 1");
		assertEquals(1, treeModel.getChildCount(node));
	}

	public void testGetIndexOfChild() {
		TreeModel treeModel = this.buildSortedTreeModel();
		treeModel.addTreeModelListener(new TestTreeModelListener());
		TestNode rootNode = (TestNode) treeModel.getRoot();

		TestNode child = rootNode.childNamed("node 0");
		assertEquals(0, treeModel.getIndexOfChild(rootNode, child));

		child = rootNode.childNamed("node 1");
		assertEquals(1, treeModel.getIndexOfChild(rootNode, child));

		child = rootNode.childNamed("node 2");
		assertEquals(2, treeModel.getIndexOfChild(rootNode, child));
		TestNode grandchild = child.childNamed("node 2.2");
		assertEquals(2, treeModel.getIndexOfChild(child, grandchild));
	}

	public void testIsLeaf() {
		TreeModel treeModel = this.buildSortedTreeModel();
		treeModel.addTreeModelListener(new TestTreeModelListener());
		TestNode rootNode = (TestNode) treeModel.getRoot();
		assertFalse(treeModel.isLeaf(rootNode));
		TestNode node = rootNode.childNamed("node 1");
		assertFalse(treeModel.isLeaf(node));
		node = rootNode.childNamed("node 3");
		assertTrue(treeModel.isLeaf(node));
	}


	public void testTreeNodesChanged() {
		// the only way to trigger a "node changed" event is to use an unsorted tree;
		// a sorted tree will will trigger only "node removed" and "node inserted" events
		TreeModel treeModel = this.buildUnsortedTreeModel();
		this.eventFired = false;
		treeModel.addTreeModelListener(new TestTreeModelListener() {
			@Override
			public void treeNodesChanged(TreeModelEvent e) {
				TreeModelAdapterTests.this.eventFired = true;
			}
		});
		TestNode rootNode = (TestNode) treeModel.getRoot();
		TestNode node = rootNode.childNamed("node 1");
		TestModel tm = node.getTestModel();
		tm.setName("node 1++");
		assertTrue(this.eventFired);

		this.eventFired = false;
		node = node.childNamed("node 1.1");
		tm = node.getTestModel();
		tm.setName("node 1.1++");
		assertTrue(this.eventFired);
	}

	public void testTreeNodesInserted() {
		// use an unsorted tree so the nodes are not re-shuffled...
		TreeModel treeModel = this.buildUnsortedTreeModel();
		this.eventFired = false;
		treeModel.addTreeModelListener(new TestTreeModelListener() {
			@Override
			public void treeNodesInserted(TreeModelEvent e) {
				TreeModelAdapterTests.this.eventFired = true;
			}
		});
		TestNode rootNode = (TestNode) treeModel.getRoot();
		TestNode node = rootNode.childNamed("node 1");
		TestModel tm = node.getTestModel();
		tm.addChild("new child...");
		assertTrue(this.eventFired);

		this.eventFired = false;
		node = node.childNamed("node 1.1");
		tm = node.getTestModel();
		tm.addChild("another new child...");
		assertTrue(this.eventFired);
	}

	public void testTreeNodesRemoved() {
		TreeModel treeModel = this.buildUnsortedTreeModel();
		this.eventFired = false;
		treeModel.addTreeModelListener(new TestTreeModelListener() {
			@Override
			public void treeNodesRemoved(TreeModelEvent e) {
				TreeModelAdapterTests.this.eventFired = true;
			}
		});
		TestNode rootNode = (TestNode) treeModel.getRoot();
		TestModel root = rootNode.getTestModel();
		root.removeChild(root.childNamed("node 3"));
		assertTrue(this.eventFired);

		this.eventFired = false;
		TestNode node = rootNode.childNamed("node 2");
		TestModel tm = node.getTestModel();
		tm.removeChild(tm.childNamed("node 2.2"));
		assertTrue(this.eventFired);
	}

	public void testTreeStructureChanged() {
		WritablePropertyValueModel<TreeNodeValueModel<Object>> nodeHolder = new SimplePropertyValueModel<TreeNodeValueModel<Object>>(this.buildSortedRootNode());
		TreeModel treeModel = this.buildTreeModel(nodeHolder);
		this.eventFired = false;
		treeModel.addTreeModelListener(new TestTreeModelListener() {
			@Override
			public void treeNodesInserted(TreeModelEvent e) {
				// do nothing
			}
			@Override
			public void treeNodesRemoved(TreeModelEvent e) {
				// do nothing
			}
			@Override
			public void treeStructureChanged(TreeModelEvent e) {
				TreeModelAdapterTests.this.eventFired = true;
			}
		});
		nodeHolder.setValue(this.buildUnsortedRootNode());
		assertTrue(this.eventFired);
	}

	/**
	 * test a problem we had where removing a child from a tree would cause
	 * the JTree to call #equals(Object) on each node removed (actually, it was
	 * TreePath, but that was because its own #equals(Object) was called by
	 * JTree); and since we had already removed the last listener from the
	 * aspect adapter, the aspect adapter would say its value was null; this
	 * would cause a NPE until we tweaked TreeModelAdapter to remove its
	 * listeners from a node only *after* the node had been completely
	 * removed from the JTree
	 * @see TreeModelAdapter#removeNode(Object[], int, TreeNodeValueModel)
	 * @see TreeModelAdapter#addNode(Object[], int, TreeNodeValueModel)
	 */
	public void testLazyInitialization() {
		TreeModel treeModel = this.buildSpecialTreeModel();
		JTree jTree = new JTree(treeModel);
		TestNode rootNode = (TestNode) treeModel.getRoot();
		TestModel root = rootNode.getTestModel();
		// this would cause a NPE:
		root.removeChild(root.childNamed("node 3"));
		assertEquals(treeModel, jTree.getModel());
	}


	private TreeModel buildSortedTreeModel() {
		return this.buildTreeModel(this.buildSortedRootNode());
	}

	private TestNode buildSortedRootNode() {
		return new SortedTestNode(this.buildRoot());
	}

	private TreeModel buildUnsortedTreeModel() {
		return this.buildTreeModel(this.buildUnsortedRootNode());
	}

	private TestNode buildUnsortedRootNode() {
		return new UnsortedTestNode(this.buildRoot());
	}

	private TreeModel buildSpecialTreeModel() {
		return this.buildTreeModel(this.buildSpecialRootNode());
	}

	private TestNode buildSpecialRootNode() {
		return new SpecialTestNode(this.buildRoot());
	}

	private TestModel buildRoot() {
		TestModel root = new TestModel("root");
		/*Node node_0 = */root.addChild("node 0");
		TestModel node_1 = root.addChild("node 1");
		TestModel node_1_1 = node_1.addChild("node 1.1");
		/*Node node_1_1_1 = */node_1_1.addChild("node 1.1.1");
		TestModel node_2 = root.addChild("node 2");
		/*Node node_2_0 = */node_2.addChild("node 2.0");
		/*Node node_2_1 = */node_2.addChild("node 2.1");
		/*Node node_2_2 = */node_2.addChild("node 2.2");
		/*Node node_2_3 = */node_2.addChild("node 2.3");
		/*Node node_2_4 = */node_2.addChild("node 2.4");
		/*Node node_2_5 = */node_2.addChild("node 2.5");
		/*Node node_3 = */root.addChild("node 3");
		/*Node node_4 = */root.addChild("node 4");
		return root;
	}


	// ********** member classes **********

	/**
	 * This is a typical model class with the typical change notifications
	 * for #name and #children.
	 */
	public static class TestModel extends AbstractModel {

		// the  parent is immutable; the root's parent is null
		private final TestModel parent;

		// the name is mutable; so I guess it isn't the "primary key" :-)
		private String name;
			public static final String NAME_PROPERTY = "name";

		private final Collection<TestModel> children;
			public static final String CHILDREN_COLLECTION = "children";


		public TestModel(String name) {	// root ctor
			this(null, name);
		}
		private TestModel(TestModel parent, String name) {
			super();
			this.parent = parent;
			this.name = name;
			this.children = new HashBag<TestModel>();
		}

		public TestModel getParent() {
			return this.parent;
		}

		public String getName() {
			return this.name;
		}
		public void setName(String name) {
			Object old = this.name;
			this.name = name;
			this.firePropertyChanged(NAME_PROPERTY, old, name);
		}

		public Iterator<TestModel> children() {
			return new ReadOnlyIterator<TestModel>(this.children);
		}
		public int childrenSize() {
			return this.children.size();
		}
		public TestModel addChild(String childName) {
			TestModel child = new TestModel(this, childName);
			this.addItemToCollection(child, this.children, CHILDREN_COLLECTION);
			return child;
		}
		public TestModel[] addChildren(String[] childNames) {
			TestModel[] newChildren = new TestModel[childNames.length];
			for (int i = 0; i < childNames.length; i++) {
				newChildren[i] = new TestModel(this, childNames[i]);
			}
			this.addItemsToCollection(newChildren, this.children, CHILDREN_COLLECTION);
			return newChildren;
		}
		public void removeChild(TestModel child) {
			this.removeItemFromCollection(child, this.children, CHILDREN_COLLECTION);
		}
		public void removeChildren(TestModel[] testModels) {
			this.removeItemsFromCollection(testModels, this.children, CHILDREN_COLLECTION);
		}
		public void clearChildren() {
			this.clearCollection(this.children, CHILDREN_COLLECTION);
		}
		public TestModel childNamed(String childName) {
			for (TestModel child : this.children) {
				if (child.getName().equals(childName)) {
					return child;
				}
			}
			throw new RuntimeException("child not found: " + childName);
		}

		public String dumpString() {
			StringWriter sw = new StringWriter();
			IndentingPrintWriter ipw = new IndentingPrintWriter(sw);
			this.dumpOn(ipw);
			return sw.toString();
		}
		public void dumpOn(IndentingPrintWriter writer) {
			writer.println(this);
			writer.indent();
			for (TestModel child : this.children) {
				child.dumpOn(writer);
			}
			writer.undent();
		}
		public void dumpOn(OutputStream stream) {
			IndentingPrintWriter writer = new IndentingPrintWriter(new OutputStreamWriter(stream));
			this.dumpOn(writer);
			writer.flush();
		}
		public void dump() {
			this.dumpOn(System.out);
		}

		@Override
		public String toString() {
			return StringTools.buildToStringFor(this, this.name);
		}

	}


	/**
	 * This Node wraps a TestModel and converts into something that can
	 * be used by TreeModelAdapter. It converts changes to the TestModel's
	 * name into "state changes" to the Node; and converts the
	 * TestModel's children into a ListValueModel of Nodes whose order is
	 * determined by subclass implementations.
	 */
	public static abstract class TestNode extends AbstractTreeNodeValueModel<Object> implements Displayable, Comparable<TestNode> {
		/** the model object wrapped by this node */
		private final TestModel testModel;
		/** this node's parent node; null for the root node */
		private final TestNode parent;
		/** this node's child nodes */
		private final ListValueModel<TreeNodeValueModel<Object>> childrenModel;
		/** a listener that notifies us when the model object's "internal state" changes */
		private final PropertyChangeListener testModelListener;


		// ********** constructors/initialization **********

		/**
		 * root node constructor
		 */
		public TestNode(TestModel testModel) {
			this(null, testModel);
		}

		/**
		 * branch or leaf node constructor
		 */
		public TestNode(TestNode parent, TestModel testModel) {
			super();
			this.parent = parent;
			this.testModel = testModel;
			this.childrenModel = this.buildChildrenModel(testModel);
			this.testModelListener = this.buildTestModelListener();
		}

		private PropertyChangeListener buildTestModelListener() {
			return new PropertyChangeListener() {
				public void propertyChanged(PropertyChangeEvent e) {
					TestNode.this.testModelChanged(e);
				}
			};
		}

		/**
		 * subclasses decide the order of the child nodes
		 */
		protected abstract ListValueModel<TreeNodeValueModel<Object>> buildChildrenModel(TestModel model);

		/**
		 * used by subclasses;
		 * transform the test model children into nodes
		 */
		protected ListValueModel<TreeNodeValueModel<Object>> buildNodeAdapter(TestModel model) {
			return new TransformationListValueModel<TestModel, TreeNodeValueModel<Object>>(this.buildChildrenAdapter(model)) {
				@Override
				protected TestNode transformItem(TestModel item) {
					return TestNode.this.buildChildNode(item);
				}
			};
		}

		/**
		 * subclasses must build a concrete node for the specified test model
		 */
		protected abstract TestNode buildChildNode(TestModel childTestModel);

		/**
		 * return a collection value model on the specified model's children
		 */
		protected CollectionValueModel<TestModel> buildChildrenAdapter(TestModel model) {
			return new CollectionAspectAdapter<TestModel, TestModel>(TestModel.CHILDREN_COLLECTION, model) {
				@Override
				protected Iterator<TestModel> iterator_() {
					return this.subject.children();
				}
				@Override
				protected int size_() {
					return this.subject.childrenSize();
				}
			};
		}


		// ********** TreeNodeValueModel implementation **********

		public TestModel getValue() {
			return this.testModel;
		}

		public TreeNodeValueModel<Object> parent() {
			return this.parent;
		}

		public ListValueModel<TreeNodeValueModel<Object>> childrenModel() {
			return this.childrenModel;
		}


		// ********** AbstractTreeNodeValueModel implementation **********

		@Override
		protected void engageValue() {
			this.testModel.addPropertyChangeListener(TestModel.NAME_PROPERTY, this.testModelListener);
		}

		@Override
		protected void disengageValue() {
			this.testModel.removePropertyChangeListener(TestModel.NAME_PROPERTY, this.testModelListener);
		}


		// ********** Displayable implementation **********

		public String displayString() {
			return this.testModel.getName();
		}

		public Icon icon() {
			return null;
		}


		// ********** debugging support **********

		public String dumpString() {
			StringWriter sw = new StringWriter();
			IndentingPrintWriter ipw = new IndentingPrintWriter(sw);
			this.dumpOn(ipw);
			return sw.toString();
		}

		public void dumpOn(IndentingPrintWriter writer) {
			writer.println(this);
			writer.indent();
			for (Iterator<TreeNodeValueModel<Object>> stream = this.childrenModel.iterator(); stream.hasNext(); ) {
				// cast to a TestNode (i.e. this won't work with a NameTestNode in the tree)
				((TestNode) stream.next()).dumpOn(writer);
			}
			writer.undent();
		}

		public void dumpOn(OutputStream stream) {
			IndentingPrintWriter writer = new IndentingPrintWriter(new OutputStreamWriter(stream));
			this.dumpOn(writer);
			writer.flush();
		}

		public void dump() {
			this.dumpOn(System.out);
		}


		// ********** behavior **********

		/**
		 * the model's name has changed, forward the event to our listeners
		 */
		protected void testModelChanged(PropertyChangeEvent e) {
			// we need to notify listeners that our "internal state" has changed
			this.fireStateChanged();
			// our display string stays in synch with the model's name
			this.firePropertyChanged(DISPLAY_STRING_PROPERTY, e.getOldValue(), e.getNewValue());
		}


		// ********** queries **********

		public TestModel getTestModel() {
			return this.testModel;
		}

		/**
		 * testing convenience method
		 */
		public TestNode childNamed(String name) {
			for (Iterator<TreeNodeValueModel<Object>> stream = this.childrenModel.iterator(); stream.hasNext(); ) {
				TreeNodeValueModel<Object> childNode = stream.next();
				if (childNode instanceof TestNode) {
					if (((TestNode) childNode).getTestModel().getName().equals(name)) {
						return (TestNode) childNode;
					}
				}
			}
			throw new IllegalArgumentException("child not found: " + name);
		}


		// ********** standard methods **********

		public int compareTo(TestNode o) {
			return this.displayString().compareTo(o.displayString());
		}

		@Override
		public String toString() {
			return "Node(" + this.testModel + ")";
		}

	}

	/**
	 * concrete implementation that keeps its children sorted
	 */
	public static class SortedTestNode extends TestNode {

		// ********** constructors **********
		public SortedTestNode(TestModel testModel) {
			super(testModel);
		}
		public SortedTestNode(TestNode parent, TestModel testModel) {
			super(parent, testModel);
		}

		// ********** initialization **********
		/** the list should be sorted */
		@Override
		protected ListValueModel<TreeNodeValueModel<Object>> buildChildrenModel(TestModel testModel) {
			return new SortedListValueModelWrapper<TreeNodeValueModel<Object>>(this.buildDisplayStringAdapter(testModel));
		}
		/** the display string (name) of each node can change */
		protected ListValueModel<TreeNodeValueModel<Object>> buildDisplayStringAdapter(TestModel testModel) {
			return new ItemPropertyListValueModelAdapter<TreeNodeValueModel<Object>>(this.buildNodeAdapter(testModel), DISPLAY_STRING_PROPERTY);
		}
		/** children are also sorted nodes */
		@Override
		protected TestNode buildChildNode(TestModel childNode) {
			return new SortedTestNode(this, childNode);
		}

	}


	/**
	 * concrete implementation that leaves its children unsorted
	 */
	public static class UnsortedTestNode extends TestNode {

		// ********** constructors **********
		public UnsortedTestNode(TestModel testModel) {
			super(testModel);
		}
		public UnsortedTestNode(TestNode parent, TestModel testModel) {
			super(parent, testModel);
		}

		// ********** initialization **********
		/** the list should NOT be sorted */
		@Override
		protected ListValueModel<TreeNodeValueModel<Object>> buildChildrenModel(TestModel testModel) {
			return this.buildNodeAdapter(testModel);
		}
		/** children are also unsorted nodes */
		@Override
		protected TestNode buildChildNode(TestModel childNode) {
			return new UnsortedTestNode(this, childNode);
		}

	}


	/**
	 * concrete implementation that leaves its children unsorted
	 * and has a special set of children for "node 3"
	 */
	public static class SpecialTestNode extends UnsortedTestNode {

		// ********** constructors **********
		public SpecialTestNode(TestModel testModel) {
			super(testModel);
		}
		public SpecialTestNode(TestNode parent, TestModel testModel) {
			super(parent, testModel);
		}

		// ********** initialization **********
		/** return a different list of children for "node 3" */
		@Override
		protected ListValueModel<TreeNodeValueModel<Object>> buildChildrenModel(TestModel testModel) {
			if (testModel.getName().equals("node 3")) {
				return this.buildSpecialChildrenModel();
			}
			return super.buildChildrenModel(testModel);
		}
		protected ListValueModel<TreeNodeValueModel<Object>> buildSpecialChildrenModel() {
			TreeNodeValueModel<Object>[] children = new NameTestNode[1];
			children[0] = new NameTestNode(this);
			return new SimpleListValueModel<TreeNodeValueModel<Object>>(Arrays.asList(children));
		}
		/** children are also special nodes */
		@Override
		protected TestNode buildChildNode(TestModel childNode) {
			return new SpecialTestNode(this, childNode);
		}

	}


	public static class NameTestNode extends AbstractTreeNodeValueModel<Object> {
		private final WritablePropertyValueModel<String> nameAdapter;
		private final SpecialTestNode specialNode;		// parent node
		private final PropertyChangeListener nameListener;
		private final ListValueModel<TreeNodeValueModel<Object>> childrenModel;

		// ********** construction/initialization **********

		public NameTestNode(SpecialTestNode specialNode) {
			super();
			this.nameListener = this.buildNameListener();
			this.specialNode = specialNode;
			this.nameAdapter = this.buildNameAdapter();
			this.childrenModel = new NullListValueModel<TreeNodeValueModel<Object>>();
		}
		protected PropertyChangeListener buildNameListener() {
			return new PropertyChangeListener() {
				public void propertyChanged(PropertyChangeEvent e) {
					NameTestNode.this.nameChanged(e);
				}
			};
		}
		protected WritablePropertyValueModel<String> buildNameAdapter() {
			return new PropertyAspectAdapter<TestModel, String>(TestModel.NAME_PROPERTY, this.getTestModel()) {
				@Override
				protected String buildValue_() {
					return this.subject.getName();
				}
				@Override
				protected void setValue_(String value) {
					this.subject.setName(value);
				}
			};
		}

		public TestModel getTestModel() {
			return this.specialNode.getTestModel();
		}

		// ********** TreeNodeValueModel implementation **********

		public String getValue() {
			return this.nameAdapter.getValue();
		}
		@Override
		public void setValue(Object value) {
			this.nameAdapter.setValue((String) value);
		}
		public TreeNodeValueModel<Object> parent() {
			return this.specialNode;
		}
		public ListValueModel<TreeNodeValueModel<Object>> childrenModel() {
			return this.childrenModel;
		}

		// ********** AbstractTreeNodeValueModel implementation **********

		@Override
		protected void engageValue() {
			this.nameAdapter.addPropertyChangeListener(PropertyValueModel.VALUE, this.nameListener);
		}
		@Override
		protected void disengageValue() {
			this.nameAdapter.removePropertyChangeListener(PropertyValueModel.VALUE, this.nameListener);
		}

		// ********** behavior **********

		protected void nameChanged(PropertyChangeEvent e) {
			// we need to notify listeners that our "value" has changed
			this.firePropertyChanged(VALUE, e.getOldValue(), e.getNewValue());
		}
	}

	private TreeModel buildTreeModel(TestNode root) {
		return this.buildTreeModel(new StaticPropertyValueModel<TreeNodeValueModel<Object>>(root));
	}

	private TreeModel buildTreeModel(PropertyValueModel<TreeNodeValueModel<Object>> rootHolder) {
		return new TreeModelAdapter<Object>(rootHolder) {
			@Override
			protected ListChangeListener buildChildrenListener() {
				return this.buildChildrenListener_();
			}
			@Override
			protected StateChangeListener buildNodeStateListener() {
				return this.buildNodeStateListener_();
			}
			@Override
			protected PropertyChangeListener buildNodeValueListener() {
				return this.buildNodeValueListener_();
			}
			@Override
			protected PropertyChangeListener buildRootListener() {
				return this.buildRootListener_();
			}
		};
	}



	/**
	 * listener that will blow up with any event;
	 * override and implement expected event methods
	 */
	public class TestTreeModelListener implements TreeModelListener {
		public void treeNodesChanged(TreeModelEvent e) {
			fail("unexpected event");
		}
		public void treeNodesInserted(TreeModelEvent e) {
			fail("unexpected event");
		}
		public void treeNodesRemoved(TreeModelEvent e) {
			fail("unexpected event");
		}
		public void treeStructureChanged(TreeModelEvent e) {
			fail("unexpected event");
		}
	}

}
