/*******************************************************************************
 * Copyright (c) 2007, 2012 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.common.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.common.utility.IndentingPrintWriter;
import org.eclipse.jpt.common.utility.internal.HashBag;
import org.eclipse.jpt.common.utility.internal.StringTools;
import org.eclipse.jpt.common.utility.internal.iterators.ReadOnlyIterator;
import org.eclipse.jpt.common.utility.internal.model.AbstractModel;
import org.eclipse.jpt.common.utility.internal.model.value.AbstractTreeNodeValueModel;
import org.eclipse.jpt.common.utility.internal.model.value.CollectionAspectAdapter;
import org.eclipse.jpt.common.utility.internal.model.value.ItemPropertyListValueModelAdapter;
import org.eclipse.jpt.common.utility.internal.model.value.NullListValueModel;
import org.eclipse.jpt.common.utility.internal.model.value.PropertyAspectAdapter;
import org.eclipse.jpt.common.utility.internal.model.value.SimpleListValueModel;
import org.eclipse.jpt.common.utility.internal.model.value.SimplePropertyValueModel;
import org.eclipse.jpt.common.utility.internal.model.value.SortedListValueModelWrapper;
import org.eclipse.jpt.common.utility.internal.model.value.StaticPropertyValueModel;
import org.eclipse.jpt.common.utility.internal.model.value.TransformationListValueModel;
import org.eclipse.jpt.common.utility.internal.model.value.swing.TreeModelAdapter;
import org.eclipse.jpt.common.utility.internal.swing.Displayable;
import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent;
import org.eclipse.jpt.common.utility.model.listener.ListChangeListener;
import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener;
import org.eclipse.jpt.common.utility.model.listener.StateChangeListener;
import org.eclipse.jpt.common.utility.model.value.CollectionValueModel;
import org.eclipse.jpt.common.utility.model.value.ListValueModel;
import org.eclipse.jpt.common.utility.model.value.PropertyValueModel;
import org.eclipse.jpt.common.utility.model.value.TreeNodeValueModel;
import org.eclipse.jpt.common.utility.model.value.ModifiablePropertyValueModel;

@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() {
		ModifiablePropertyValueModel<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 ModifiablePropertyValueModel<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 ModifiablePropertyValueModel<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");
		}
	}

}
