/*******************************************************************************
 * Copyright (c) 2007 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.internal.node;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import org.eclipse.jpt.utility.internal.iterators.CloneIterator;
import org.eclipse.jpt.utility.internal.iterators.CloneListIterator;
import org.eclipse.jpt.utility.internal.iterators.FilteringIterator;
import org.eclipse.jpt.utility.internal.model.AbstractModel;
import org.eclipse.jpt.utility.internal.model.ChangeEventDispatcher;
import org.eclipse.jpt.utility.internal.model.ChangeSupport;

/**
 * Base class for Node Model classes.
 * Provides support for the following:
 *     initialization
 *     enforced object identity wrt #equals()/#hashCode()
 *     containment hierarchy (parent/child)
 *     user comment
 *     dirty flag
 *     problems
 *     sorting
 * 
 * Typically, subclasses should consider implementing the following methods:
 *     the appropriate constructors
 *         (with the appropriately-restrictive type declaration for parent)
 *     #initialize()
 *     #initialize(Node parentNode)
 *     #checkParent(Node parentNode)
 *     #addChildrenTo(List list)
 *     #nodeRemoved(Node)
 *     #validator()
 *     #transientAspectNames() or
 *         #addTransientAspectNamesTo(Set transientAspectNames)
 *     #addProblemsTo(List currentProblems)
 *     #nonValidatedAspectNames()
 *         #addNonValidatedAspectNamesTo(Set nonValidatedAspectNames)
 *     #displayString()
 *     #toString(StringBuffer sb)
 */
public abstract class AbstractNodeModel 
	extends AbstractModel 
	implements NodeModel 
{

	/** Containment hierarchy. */
	private volatile Node parent;

	/** User comment. */
	private volatile String comment;
		public static final String COMMENT_PROPERTY = "comment";

	/** Track whether the node has changed. */
	private volatile boolean dirty;
	private volatile boolean dirtyBranch;

	/**
	 * The node's problems, as calculated during validation.
	 * This list should only be modified via a ProblemSynchronizer,
	 * allowing for asynchronous modification from another thread.
	 */
	private List<Problem> problems;		// pseudo-final
		private static final Object[] EMPTY_PROBLEM_MESSAGE_ARGUMENTS = new Object[0];

	/**
	 * Cache the node's "branch" problems, as calculated during validation.
	 * This list should only be modified via a ProblemSynchronizer,
	 * allowing for asynchronous modification from another thread.
	 * This must be recalculated every time this node or one of its
	 * descendants changes it problems.
	 */
	private List<Problem> branchProblems;		// pseudo-final



	/**
	 * Sets of transient aspect names, keyed by class.
	 * This is built up lazily, as the objects are modified.
	 */
	private static final Map<Class<? extends AbstractNodeModel>, Set<String>> transientAspectNameSets = new Hashtable<Class<? extends AbstractNodeModel>, Set<String>>();

	/**
	 * Sets of non-validated aspect names, keyed by class.
	 * This is built up lazily, as the objects are modified.
	 */
	private static final Map<Class<? extends AbstractNodeModel>, Set<String>> nonValidatedAspectNameSets = new Hashtable<Class<? extends AbstractNodeModel>, Set<String>>();


	// ********** constructors **********

	/**
	 * Most objects must have a parent.
	 * Use this constructor to create a new node.
	 * @see #initialize(Node)
	 */
	protected AbstractNodeModel(Node parent) {
		super();
		this.initialize(parent);
	}


	// ********** initialization **********

	/**
	 * Initialize a newly-created instance.
	 * @see #initialize(Node)
	 */
	@Override
	protected void initialize() {
		super.initialize();
		this.comment = "";

		// a new object is dirty, by definition
		this.dirty = true;
		this.dirtyBranch = true;

		this.problems = new Vector<Problem>();
		this.branchProblems = new Vector<Problem>();

	// when you override this method, don't forget to include:
	//	super.initialize();
	}

	/**
	 * Initialize a newly-created instance.
	 * @see #initialize()
	 */
	protected void initialize(Node parentNode) {
		this.checkParent(parentNode);
		this.parent = parentNode;
	// when you override this method, don't forget to include:
	//	super.initialize(parentNode);
	}

	/**
	 * Build a change support object that will notify the node
	 * when one of the node's aspects has changed.
	 * @see #aspectChanged(String)
	 */
	@Override
	protected ChangeSupport buildChangeSupport() {
		return new ChangeSupport(this) {
			private static final long serialVersionUID = 1L;
			@Override
			protected ChangeEventDispatcher dispatcher() {
				return AbstractNodeModel.this.changeEventDispatcher();
			}
			@Override
			protected ChangeSupport buildChildChangeSupport() {
				return AbstractNodeModel.this.buildChildChangeSupport();
			}
			@Override
			protected void sourceChanged(String aspectName) {
				super.sourceChanged(aspectName);
				AbstractNodeModel.this.aspectChanged(aspectName);
			}
		};
	}

	/**
	 * The aspect-specific change support objects do not need to
	 * notify the node of changes (the parent will take care of that);
	 * nor do they need to build "grandchildren" change support objects.
	 */
	protected ChangeSupport buildChildChangeSupport() {
		return new ChangeSupport(this) {
			private static final long serialVersionUID = 1L;
			@Override
			protected ChangeEventDispatcher dispatcher() {
				return AbstractNodeModel.this.changeEventDispatcher();
			}
			@Override
			protected ChangeSupport buildChildChangeSupport() {
				// there are no grandchildren
				throw new UnsupportedOperationException();
			}
		};
	}


	// ********** equality **********

	/**
	 * Enforce object identity - do not allow objects to be equal unless
	 * they are the same object.
	 * Do NOT override this method - we rely on object identity extensively.
	 */
	@Override
	public final boolean equals(Object o) {
		return this == o;
	}

	/**
	 * Enforce object identity - do not allow objects to be equal unless
	 * they are the same object.
	 * Do NOT override this method - we rely on object identity extensively.
	 */
	@Override
	public final int hashCode() {
		return super.hashCode();
	}


	// ********** containment hierarchy (parent/children) **********

	/**
	 * INTRA-TREE API?
	 * Return the node's parent in the containment hierarchy.
	 * Most nodes must have a parent.
	 */
	public final Node parent() {
		return this.parent;
	}

	/**
	 * Throw an IllegalArgumentException if the parent is not valid
	 * for the node.
	 * By default require a non-null parent. Override if other restrictions exist
	 * or the parent should be null.
	 */
	protected void checkParent(Node parentNode) {
		if (parentNode == null) {
			throw new IllegalArgumentException("The parent node cannot be null");
		}
	}

	/**
	 * INTRA-TREE API?
	 * Return the node's children, which are also nodes.
	 * Do NOT override this method.
	 * Override #addChildrenTo(List).
	 * @see #addChildrenTo(java.util.List)
	 */
	public final Iterator<Node> children() {
		List<Node> children = new ArrayList<Node>();
		this.addChildrenTo(children);
		return children.iterator();
	}

	/**
	 * Subclasses should override this method to add their children
	 * to the specified list.
	 * @see #children()
	 */
	protected void addChildrenTo(List<Node> list) {
		// this class has no children, subclasses will...
	// when you override this method, don't forget to include:
	//	super.addChildrenTo(list);
	}

	/**
	 * Return whether the node is a descendant of the specified node.
	 * By definition, a node is a descendant of itself.
	 */
	public final boolean isDescendantOf(Node node) {
		return (this == node) || this.parentIsDescendantOf(node);
	}

	protected boolean parentIsDescendantOf(Node node) {
		return (this.parent != null) && this.parent.isDescendantOf(node);
	}

	/**
	 * Return a collection holding all the node's "references", and all
	 * the node's descendants' "references". "References" are
	 * objects that are "referenced" by another object, as opposed
	 * to "owned" by another object.
	 */
	public final Iterator<Node> branchReferences() {
		Collection<Node> branchReferences = new ArrayList<Node>(1000);		// start big
		this.addBranchReferencesTo(branchReferences);
		return branchReferences.iterator();
	}

	/**
	 * INTRA-TREE API
	 * Add the node's "references", and all the node's descendants'
	 * "references", to the specified collection. "References" are
	 * objects that are "referenced" by another object, as opposed
	 * to "owned" by another object.
	 * This method is of particular concern to Handles, since most
	 * (hopefully all) "references" are held by Handles.
	 * @see Reference
	 * @see #children()
	 */
	public final void addBranchReferencesTo(Collection<Node> branchReferences) {
		for (Iterator<Node> stream = this.children(); stream.hasNext(); ) {
			Node child = stream.next();		// pull out the child to ease debugging
			child.addBranchReferencesTo(branchReferences);
		}
	}

	/**
	 * Return all the nodes in the object's branch of the tree,
	 * including the node itself. The nodes will probably returned
	 * in "depth-first" order.
	 * Only really used for testing and debugging.
	 */
	public final Iterator<Node> allNodes() {
		Collection<Node> nodes = new ArrayList<Node>(1000);		// start big
		this.addAllNodesTo(nodes);
		return nodes.iterator();
	}

	/**
	 * INTRA-TREE API?
	 * Add all the nodes in the object's branch of the tree,
	 * including the node itself, to the specified collection.
	 * Only really used for testing and debugging.
	 */
	public final void addAllNodesTo(Collection<Node> nodes) {
		nodes.add(this);
		for (Iterator<Node> stream = this.children(); stream.hasNext(); ) {
			Node child = stream.next();		// pull out the child to ease debugging
			child.addAllNodesTo(nodes);
		}
	}


	// ********** model synchronization support **********

	/**
	 * INTRA-TREE API
	 * This is a general notification that the specified node has been
	 * removed from the tree. The node receiving this notification
	 * should perform any necessary updates to remain in synch
	 * with the tree (e.g. clearing out or replacing any references
	 * to the removed node or any of the removed node's descendants).
	 * @see #isDescendantOf(Node)
	 */
	public void nodeRemoved(Node node) {
		for (Iterator<Node> stream = this.children(); stream.hasNext(); ) {
			Node child = stream.next();		// pull out the child to ease debugging
			child.nodeRemoved(node);
		}
	// when you override this method, don't forget to include:
	//	super.nodeRemoved(node);
	}

	/**
	 * convenience method
	 * return whether node1 is a descendant of node2;
	 * node1 can be null
	 */
	protected boolean nodeIsDescendantOf(Node node1, Node node2) {
		return (node1 != null) && node1.isDescendantOf(node2);
	}

	/**
	 * INTRA-TREE API
	 * This is a general notification that the specified node has been
	 * renamed. The node receiving this notification should mark its
	 * branch dirty if necessary (i.e. it references the renamed node
	 * or one of its descendants). This method is of particular concern
	 * to Handles.
	 * @see #isDescendantOf(Node)
	 */
	public void nodeRenamed(Node node) {
		for (Iterator<Node> stream = this.children(); stream.hasNext(); ) {
			Node child = stream.next();		// pull out the child to ease debugging
			child.nodeRenamed(node);
		}
	// when you override this method, don't forget to include:
	//	super.nodeRenamed(node);
	}
	
	
	// ********** user comment **********

	/**
	 * Return the object's user comment.
	 */
	public final String comment() {
		return this.comment;
	}

	/**
	 * Set the object's user comment.
	 */
	public final void setComment(String comment) {
		Object old = this.comment;
		this.comment = comment;
		this.firePropertyChanged(COMMENT_PROPERTY, old, comment);
	}


	// ********** change support **********

	/**
	 * INTRA-TREE API
	 * Return a change event dispatcher that will be used to dispatch
	 * change notifications to listeners.
	 * Typically only the root node directly holds a dispatcher.
	 */
	public ChangeEventDispatcher changeEventDispatcher() {
		if (this.parent == null) {
			throw new IllegalStateException("This node should not be firing change events during its construction.");
		}
		return this.parent.changeEventDispatcher();
	}

	/**
	 * Set a change event dispatcher that will be used to dispatch
	 * change notifications to listeners.
	 * Typically only the root node directly holds a dispatcher.
	 */
	public void setChangeEventDispatcher(ChangeEventDispatcher changeEventDispatcher) {
		if (this.parent == null) {
			throw new IllegalStateException("This root node should implement #setChangeEventDispatcher(ChangeEventDispatcher).");
		}
		throw new UnsupportedOperationException("Only root nodes implement #setChangeEventDispatcher(ChangeEventDispatcher).");
	}

	/**
	 * An aspect of the node has changed:
	 * 	- if it is a persistent aspect, mark the object dirty
	 * 	- if it is a significant aspect, validate the object
	 */
	protected void aspectChanged(String aspectName) {
		if (this.aspectIsPersistent(aspectName)) {
			// System.out.println(Thread.currentThread() + " dirty change: " + this + ": " + aspectName);
			this.markDirty();
		}
		if (this.aspectChangeRequiresValidation(aspectName)) {
			// System.out.println(Thread.currentThread() + " validation change: " + this + ": " + aspectName);
			this.validator().validate();
		}
	}

	/**
	 * INTRA-TREE API
	 * Return a validator that will be invoked whenever a
	 * "validated" aspect of the node tree changes.
	 * Typically only the root node directly holds a validator.
	 */
	public Node.Validator validator() {
		if (this.parent == null) {
			throw new IllegalStateException("This node should not be firing change events during its construction.");
		}
		return this.parent.validator();
	}

	/**
	 * Set a validator that will be invoked whenever a
	 * "validated" aspect of the node tree changes.
	 * Typically only the root node directly holds a validator.
	 */
	public void setValidator(Node.Validator validator) {
		if (this.parent == null) {
			throw new IllegalStateException("This root node should implement #setValidator(Node.Validator).");
		}
		throw new UnsupportedOperationException("Only root nodes implement #setValidator(Node.Validator).");
	}


	// ********** dirty flag support **********

	/**
	 * Return whether any persistent aspects of the object
	 * have changed since the object was last read or saved.
	 * This does NOT include changes to the object's descendants.
	 */
	public final boolean isDirty() {
		return this.dirty;
	}

	/**
	 * Return whether any persistent aspects of the object,
	 * or any of its descendants, have changed since the object and
	 * its descendants were last read or saved.
	 */
	public final boolean isDirtyBranch() {
		return this.dirtyBranch;
	}

	/**
	 * Return whether the object is unmodified
	 * since it was last read or saved.
	 * This does NOT include changes to the object's descendants.
	 */
	public final boolean isClean() {
		return ! this.dirty;
	}

	/**
	 * Return whether the object and all of its descendants
	 * are unmodified since the object and
	 * its descendants were last read or saved.
	 */
	public final boolean isCleanBranch() {
		return ! this.dirtyBranch;
	}

	/**
	 * Set the dirty branch flag setting. This is set to true
	 * when either the object or one of its descendants becomes dirty.
	 */
	private void setIsDirtyBranch(boolean dirtyBranch) {
		boolean old = this.dirtyBranch;
		this.dirtyBranch = dirtyBranch;
		this.firePropertyChanged(DIRTY_BRANCH_PROPERTY, old, dirtyBranch);
	}

	/**
	 * Mark the object as dirty and as a dirty branch.
	 * An object is marked dirty when either a "persistent" attribute
	 * has changed or its save location has changed.
	 */
	private void markDirty() {
		this.dirty = true;
		this.markBranchDirty();
	}

	/**
	 * INTRA-TREE API
	 * Mark the node and its parent as dirty branches.
	 * This message is propagated up the containment
	 * tree when a particular node becomes dirty.
	 */
	public void markBranchDirty() {
		// short-circuit any unnecessary propagation
		if (this.dirtyBranch) {
			// if this is already a dirty branch, the parent must be also
			return;
		}

		this.setIsDirtyBranch(true);
		this.markParentBranchDirty();
	}

	protected void markParentBranchDirty() {
		if (this.parent != null) {
			this.parent.markBranchDirty();
		}
	}

	/**
	 * Mark the object and all its descendants as dirty.
	 * This is used when the save location of some
	 * top-level object is changed and the entire
	 * containment tree must be marked dirty so it
	 * will be written out.
	 */
	public final void markEntireBranchDirty() {
		this.markDirty();
		for (Iterator<Node> stream = this.children(); stream.hasNext(); ) {
			Node child = stream.next();		// pull out the child to ease debugging
			child.markEntireBranchDirty();
		}
	}

	/**
	 * Mark the object and all its descendants as clean.
	 * Then notify the object's parent that it (the parent)
	 * might now be a clean branch also.
	 * Typically used when the object has just been
	 * read in or written out.
	 */
	public final void markEntireBranchClean() {
		this.cascadeMarkEntireBranchClean();
		this.markParentBranchCleanIfPossible();
	}

	protected void markParentBranchCleanIfPossible() {
		if (this.parent != null) {
			this.parent.markBranchCleanIfPossible();
		}
	}

	/**
	 * INTRA-TREE API
	 * Mark the node and all its descendants as clean.
	 * Typically used when the node has just been
	 * read in or written out.
	 * This method is for internal use only; it is not for
	 * client use.
	 * Not the best of method names.... :-(
	 */
	public final void cascadeMarkEntireBranchClean() {
		for (Iterator<Node> stream = this.children(); stream.hasNext(); ) {
			Node child = stream.next();		// pull out the child to ease debugging
			child.cascadeMarkEntireBranchClean();
		}
		this.dirty = false;
		this.setIsDirtyBranch(false);
	}

	/**
	 * INTRA-TREE API
	 * A child node's branch has been marked clean. If the node
	 * itself is clean and if all of its children are also clean, the
	 * node's branch can be marked clean. Then, if the node's
	 * branch is clean, the node will notify its parent that it might
	 * be clean also. This message is propagated up the containment
	 * tree when a particular node becomes clean.
	 */
	public final void markBranchCleanIfPossible() {
		// short-circuit any unnecessary propagation
		if (this.dirty) {
			// if the object is "locally" dirty, it is still a dirty branch
			return;
		}

		for (Iterator<Node> stream = this.children(); stream.hasNext(); ) {
			Node child = stream.next();		// pull out the child to ease debugging
			if (child.isDirtyBranch()) {
				return;
			}
		}

		this.setIsDirtyBranch(false);
		this.markParentBranchCleanIfPossible();
	}

	private boolean aspectIsPersistent(String aspectName) {
		return ! this.aspectIsTransient(aspectName);
	}

	private boolean aspectIsTransient(String aspectName) {
		return this.transientAspectNames().contains(aspectName);
	}

	/**
	 * Return a set of the object's transient aspect names.
	 * These are the aspects that, when they change, will NOT cause the
	 * object to be marked dirty.
	 * If you need instance-based calculation of your transient aspects,
	 * override this method. If class-based calculation is sufficient,
	 * override #addTransientAspectNamesTo(Set).
	 */
	protected final Set<String> transientAspectNames() {
		synchronized (transientAspectNameSets) {
			Set<String> transientAspectNames = transientAspectNameSets.get(this.getClass());
			if (transientAspectNames == null) {
				transientAspectNames = new HashSet<String>();
				this.addTransientAspectNamesTo(transientAspectNames);
				transientAspectNameSets.put(this.getClass(), transientAspectNames);
			}
			return transientAspectNames;
		}
	}

	/**
	 * Add the object's transient aspect names to the specified set.
	 * These are the aspects that, when they change, will NOT cause the
	 * object to be marked dirty.
	 * If class-based calculation of your transient aspects is sufficient,
	 * override this method. If you need instance-based calculation,
	 * override #transientAspectNames().
	 */
	protected void addTransientAspectNamesTo(Set<String> transientAspectNames) {
		transientAspectNames.add(DIRTY_BRANCH_PROPERTY);
		transientAspectNames.add(BRANCH_PROBLEMS_LIST);
		transientAspectNames.add(HAS_BRANCH_PROBLEMS_PROPERTY);
	// when you override this method, don't forget to include:
	//	super.addTransientAspectNamesTo(transientAspectNames);
	}

	/**
	 * Return the dirty nodes in the object's branch of the tree,
	 * including the node itself (if appropriate).
	 * Only really used for testing and debugging.
	 */
	public final Iterator<Node> allDirtyNodes() {
		return new FilteringIterator<Node>(this.allNodes()) {
			@Override
			protected boolean accept(Object o) {
				return (o instanceof AbstractNodeModel) && ((AbstractNodeModel) o).isDirty();
			}
		};
	}


	// ********** problems **********

	/**
	 * Return the node's problems.
	 * This does NOT include the problems of the node's descendants.
	 * @see #branchProblems()
	 */
	public final Iterator<Problem> problems() {
		return new CloneIterator<Problem>(this.problems);	// removes are not allowed
	}

	/**
	 * Return the size of the node's problems.
	 * This does NOT include the problems of the node's descendants.
	 * @see #branchProblemsSize()
	 */
	public final int problemsSize() {
		return this.problems.size();
	}

	/**
	 * Return whether the node has problems
	 * This does NOT include the problems of the node's descendants.
	 * @see #hasBranchProblems()
	 */
	public final boolean hasProblems() {
		return ! this.problems.isEmpty();
	}

	/**
	 * Return all the node's problems along with all the
	 * node's descendants' problems.
	 */
	public final ListIterator<Problem> branchProblems() {
		return new CloneListIterator<Problem>(this.branchProblems);	// removes are not allowed
	}

	/**
	 * Return the size of all the node's problems along with all the
	 * node's descendants' problems.
	 */
	public final int branchProblemsSize() {
		return this.branchProblems.size();
	}

	/**
	 * Return whether the node or any of its descendants have problems.
	 */
	public final boolean hasBranchProblems() {
		return ! this.branchProblems.isEmpty();
	}

	public final boolean containsBranchProblem(Problem problem) {
		return this.branchProblems.contains(problem);
	}

	protected final Problem buildProblem(String messageKey, Object[] messageArguments) {
		return new DefaultProblem(this, messageKey, messageArguments);
	}

	protected final Problem buildProblem(String messageKey) {
		return this.buildProblem(messageKey, EMPTY_PROBLEM_MESSAGE_ARGUMENTS);
	}

	protected final Problem buildProblem(String messageKey, Object messageArgument) {
		return this.buildProblem(messageKey, new Object[] {messageArgument});
	}

	protected final Problem buildProblem(String messageKey, Object messageArgument1, Object messageArgument2) {
		return this.buildProblem(messageKey, new Object[] {messageArgument1, messageArgument2});
	}

	protected final Problem buildProblem(String messageKey, Object messageArgument1, Object messageArgument2, Object messageArgument3) {
		return this.buildProblem(messageKey, new Object[] {messageArgument1, messageArgument2, messageArgument3});
	}

	/**
	 * Validate the node and all of its descendants,
	 * and update their sets of "branch" problems.
	 * If the node's "branch" problems have changed,
	 * notify the node's parent.
	 */
	public void validateBranch() {
		if (this.validateBranchInternal()) {
			// if our "branch" problems have changed, then
			// our parent must rebuild its "branch" problems also
			this.rebuildParentBranchProblems();
		}
	}

	protected void rebuildParentBranchProblems() {
		if (this.parent != null) {
			this.parent.rebuildBranchProblems();
		}
	}

	/**
	 * INTRA-TREE API
	 * Validate the node and all of its descendants,
	 * and update their sets of "branch" problems.
	 * Return true if the collection of "branch" problems has changed.
	 * This method is for internal use only; it is not for
	 * client use.
	 */
	public boolean validateBranchInternal() {
		// rebuild "branch" problems in children first
		for (Iterator<Node> stream = this.children(); stream.hasNext(); ) {
			Node child = stream.next();		// pull out the child to ease debugging
			// ignore the return value because we are going to rebuild our "branch"
			// problems no matter what, to see if they have changed
			child.validateBranchInternal();
		}

		this.problems.clear();
		this.addProblemsTo(this.problems);

		return this.checkBranchProblems();
	}

	/**
	 * Check for any problems and add them to the specified list.
	 * This method should ONLY add problems for this particular node;
	 * it should NOT add problems for any of this node's descendants
	 * or ancestors. (Although there will be times when it is debatable
	 * as to which node a problem "belongs" to....)
	 * 
	 * NB: This method should NOT modify ANY part of the node's state!
	 * It is a READ-ONLY behavior. ONLY the list of current problems
	 * passed in to the method should be modified.
	 */
	protected void addProblemsTo(List<Problem> currentProblems) {
		// The default is to do nothing.
		// When you override this method, don't forget to include:
	//	super.addProblemsTo(currentProblems);
	}

	/**
	 * Rebuild the "branch" problems and return whether they have
	 * changed.
	 * NB: The entire collection of "branch" problems must be re-calculated
	 * with EVERY "significant" change - we cannot keep it in synch via
	 * change notifications because if a descendant with problems is
	 * removed or replaced we will not receive notification that its
	 * problems were removed from our "branch" problems.
	 */
	private boolean checkBranchProblems() {
		List<Problem> oldBranchProblems = new Vector<Problem>(this.branchProblems);
		int oldSize = this.branchProblems.size();

		this.branchProblems.clear();
		this.branchProblems.addAll(this.problems);
		for (Iterator<Node> stream = this.children(); stream.hasNext(); ) {
			Node child = stream.next();		// pull out the child to ease debugging
			child.addBranchProblemsTo(this.branchProblems);
		}

		// if the size has changed to or from zero, our virtual flag has changed
		int newSize = this.branchProblems.size();
		if ((oldSize == 0) && (newSize != 0)) {
			this.firePropertyChanged(HAS_BRANCH_PROBLEMS_PROPERTY, false, true);
		} else if ((oldSize != 0) && (newSize == 0)) {
			this.firePropertyChanged(HAS_BRANCH_PROBLEMS_PROPERTY, true, false);
		}

		if (oldBranchProblems.equals(this.branchProblems)) {
			return false;		// our "branch" problems did not change
		}
		// our "branch" problems changed
		this.fireListChanged(BRANCH_PROBLEMS_LIST);
		return true;
	}

	/**
	 * INTRA-TREE API
	 * Add all the problems of the node and all
	 * the problems of its descendants to the
	 * specified collection.
	 */
	public final void addBranchProblemsTo(List<Problem> list) {
		list.addAll(this.branchProblems);
	}

	/**
	 * INTRA-TREE API
	 * A child node's "branch" problems changed;
	 * therefore the node's "branch" problems have changed also and
	 * must be rebuilt.
	 */
	public final void rebuildBranchProblems() {
		if ( ! this.checkBranchProblems()) {
			throw new IllegalStateException("we should not get here unless our \"branch\" problems have changed");
		}
		this.rebuildParentBranchProblems();
	}

	/**
	 * Clear the node's "branch" problems and the "branch"
	 * problems of all of its descendants.
	 * If the node's "branch" problems have changed,
	 * notify the node's parent.
	 */
	public final void clearAllBranchProblems() {
		if (this.clearAllBranchProblemsInternal()) {
			// if our "branch" problems have changed, then
			// our parent must rebuild its "branch" problems also
			this.rebuildParentBranchProblems();
		}
	}

	/**
	 * INTRA-TREE API
	 * Clear the node's "branch" problems and the "branch"
	 * problems of all of its descendants.
	 * Return true if the collection of "branch" problems has changed.
	 * This method is for internal use only; it is not for
	 * client use.
	 */
	public final boolean clearAllBranchProblemsInternal() {
		if (this.branchProblems.isEmpty()) {
			return false;
		}
		for (Iterator<Node> stream = this.children(); stream.hasNext(); ) {
			Node child = stream.next();		// pull out the child to ease debugging
			// ignore the return value because we are going to clear our "branch"
			// problems no matter what
			child.clearAllBranchProblemsInternal();
		}
		this.problems.clear();
		this.branchProblems.clear();
		this.firePropertyChanged(HAS_BRANCH_PROBLEMS_PROPERTY, true, false);
		this.fireListChanged(BRANCH_PROBLEMS_LIST);
		return true;
	}

	/**
	 * Return whether a change to specified aspect requires a re-validation
	 * of the node's tree.
	 */
	private boolean aspectChangeRequiresValidation(String aspectName) {
		return ! this.aspectChangeDoesNotRequireValidation(aspectName);
	}

	private boolean aspectChangeDoesNotRequireValidation(String aspectName) {
		return this.nonValidatedAspectNames().contains(aspectName);
	}

	/**
	 * Return a set of the object's "non-validated" aspect names.
	 * These are the aspects that, when they change, will NOT cause the
	 * object (or its containing tree) to be validated, i.e. checked for problems.
	 * If you need instance-based calculation of your "non-validated" aspects,
	 * override this method. If class-based calculation is sufficient,
	 * override #addNonValidatedAspectNamesTo(Set).
	 */
	protected final Set<String> nonValidatedAspectNames() {
		synchronized (nonValidatedAspectNameSets) {
			Set<String> nonValidatedAspectNames = nonValidatedAspectNameSets.get(this.getClass());
			if (nonValidatedAspectNames == null) {
				nonValidatedAspectNames = new HashSet<String>();
				this.addNonValidatedAspectNamesTo(nonValidatedAspectNames);
				nonValidatedAspectNameSets.put(this.getClass(), nonValidatedAspectNames);
			}
			return nonValidatedAspectNames;
		}
	}

	/**
	 * Add the object's "non-validated" aspect names to the specified set.
	 * These are the aspects that, when they change, will NOT cause the
	 * object (or its containing tree) to be validated, i.e. checked for problems.
	 * If class-based calculation of your "non-validated" aspects is sufficient,
	 * override this method. If you need instance-based calculation,
	 * override #nonValidatedAspectNames().
	 */
	protected void addNonValidatedAspectNamesTo(Set<String> nonValidatedAspectNames) {
		nonValidatedAspectNames.add(COMMENT_PROPERTY);
		nonValidatedAspectNames.add(DIRTY_BRANCH_PROPERTY);
		nonValidatedAspectNames.add(BRANCH_PROBLEMS_LIST);
		nonValidatedAspectNames.add(HAS_BRANCH_PROBLEMS_PROPERTY);
	// when you override this method, don't forget to include:
	//	super.addNonValidatedAspectNamesTo(nonValidatedAspectNames);
	}


	// ********** display methods **********

	/**
	 * Compare display strings.
	 */
	public int compareTo(Node node) {
		return DEFAULT_COMPARATOR.compare(this, node);
	}

	/**
	 * Return a developer-friendly String. If you want something useful for
	 * displaying in a user interface, use #displayString().
	 * If you want to give more information in your #toString(),
	 * override #toString(StringBuffer sb). 
	 * Whatever you add to that string buffer will show up between the parentheses.
	 * @see oracle.toplink.workbench.utility.AbstractModel#toString(StringBuffer sb)
	 * @see #displayString()
	 */
	@Override
	public final String toString() {
		return super.toString();
	}

}
