/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.core.tests.internal.dtree;

import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.core.internal.dtree.*;
import org.eclipse.core.internal.watson.DefaultElementComparator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;

/**
 * Test class for delta trees.
 */
public class DeltaDataTreeTest extends DataTreeTest {

	DeltaDataTree tree, emptyTree, changedTree, deltaTree;

	public DeltaDataTreeTest() {
		super();
	}

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

	/**
	 * Assert that the given tree is the same as the final delta tree
	 * created in the string of deltas in testLongDeltaChain and testReroot
	 *
	 */
	public void assertDelta(DeltaDataTree originalTree) {

		/* compare to tree */
		assertTrue("1", originalTree.includes(rootKey));
		assertTrue("2", originalTree.includes(leftKey));
		assertTrue("3", originalTree.includes(rightKey));
		assertTrue("4", originalTree.includes(rootKey.append("newTopLevel")));

		assertTrue("5", originalTree.includes(leftKey.append("new")));
		assertTrue("6", originalTree.includes(leftKey.append("two")));
		assertTrue("7", originalTree.includes(leftKey.append("three")));
		assertTrue("8", originalTree.includes(rightKey.append("rightOfRight")));

		/* this was removed from "tree" */
		assertTrue("9", !originalTree.includes(leftKey.append("one")));
	}

	/**
	 * Assert that the given tree is the same as the original "tree" created
	 * during setup
	 */
	public void assertTree(DeltaDataTree originalTree) {

		/* compare to tree */
		assertTrue("1", originalTree.includes(rootKey));
		assertTrue("2", originalTree.includes(leftKey));
		assertTrue("3", originalTree.includes(rightKey));

		assertTrue("4", originalTree.includes(leftKey.append("one")));
		assertTrue("5", originalTree.includes(leftKey.append("two")));
		assertTrue("6", originalTree.includes(leftKey.append("three")));
		assertTrue("7", originalTree.includes(rightKey.append("rightOfRight")));
	}

	/**
	 * Init tests
	 */
	@Override
	protected void setUp() {

		emptyTree = new DeltaDataTree();
		tree = new DeltaDataTree();
		rootKey = Path.ROOT;

		/* Add two children to root */
		try {
			tree.createChild(rootKey, "leftOfRoot");
			tree.createChild(rootKey, "rightOfRoot");
		} catch (ObjectNotFoundException e) {
			throw new Error("(1) Error in setUp");
		}

		leftKey = rootKey.append("leftOfRoot");
		rightKey = rootKey.append("rightOfRoot");

		/* Add three children to left of root and one to right of root */
		try {
			tree.createChild(leftKey, "one");
			tree.createChild(leftKey, "two");
			tree.createChild(leftKey, "three");

			tree.createChild(rightKey, "rightOfRight");
		} catch (ObjectNotFoundException e) {
			throw new Error("(2) Error in setUp");
		}

		changedTree = new DeltaDataTree();
		changedTree.createSubtree(rootKey, tree.copyCompleteSubtree(rootKey));
	}

	/**
	 * Run all tests
	 */

	public static Test suite() {
		TestSuite suite = new TestSuite(DeltaDataTreeTest.class.getName());
		suite.addTest(new DeltaDataTreeTest("testSetup"));

		suite.addTest(new DeltaDataTreeTest("testAddAndRemoveOnSameLayer"));
		suite.addTest(new DeltaDataTreeTest("testAddTwiceAndDelete"));
		suite.addTest(new DeltaDataTreeTest("testAssembleWithIn"));
		suite.addTest(new DeltaDataTreeTest("testCreateChild"));
		suite.addTest(new DeltaDataTreeTest("testDeleteChild"));
		suite.addTest(new DeltaDataTreeTest("testDeltaOnCompletelyDifferentTrees"));
		suite.addTest(new DeltaDataTreeTest("testEmpty"));
		suite.addTest(new DeltaDataTreeTest("testForwardDeltaOnDataDeltaNode"));
		suite.addTest(new DeltaDataTreeTest("testForwardDeltaWith"));
		suite.addTest(new DeltaDataTreeTest("testForwardDeltaWithEquality"));
		suite.addTest(new DeltaDataTreeTest("testGetChild"));
		suite.addTest(new DeltaDataTreeTest("testGetChildCount"));
		suite.addTest(new DeltaDataTreeTest("testGetChildren"));
		suite.addTest(new DeltaDataTreeTest("testGetNameOfChild"));
		suite.addTest(new DeltaDataTreeTest("testGetNamesOfChildren"));
		suite.addTest(new DeltaDataTreeTest("testIncludes"));
		suite.addTest(new DeltaDataTreeTest("testLongDeltaChain"));
		suite.addTest(new DeltaDataTreeTest("testNewEmptyDeltaTree"));
		suite.addTest(new DeltaDataTreeTest("testRegression1FVVP6L"));
		suite.addTest(new DeltaDataTreeTest("testRegression1FVVP6LWithChildren"));
		suite.addTest(new DeltaDataTreeTest("testReroot"));

		return suite;
	}

	/**
	 * Test for problem adding and deleting in same delta layer.
	 */
	public void testAddAndRemoveOnSameLayer() {
		IPath elementA = Path.ROOT.append("A");
		DeltaDataTree tree1 = new DeltaDataTree();

		tree1.createChild(Path.ROOT, "A", "Data for A");

		tree1.immutable();
		DeltaDataTree tree2;
		tree2 = tree1.newEmptyDeltaTree();

		tree2.createChild(elementA, "B", "New B Data");
		tree2.deleteChild(elementA, "B");

		tree2.immutable();

		//do a bunch of operations to ensure the tree isn't corrupt.
		tree1.compareWith(tree2, DefaultElementComparator.getComparator());
		tree2.compareWith(tree1, DefaultElementComparator.getComparator());
		tree1.forwardDeltaWith(tree2, DefaultElementComparator.getComparator());
		tree2.forwardDeltaWith(tree1, DefaultElementComparator.getComparator());
		tree1.copyCompleteSubtree(Path.ROOT);
		tree2.copyCompleteSubtree(Path.ROOT);
		tree1.reroot();
		tree2.reroot();
		tree1.makeComplete();
		tree2.makeComplete();
	}

	/**
	 * Test for problem when two complete nodes exist, and then
	 * the deleting only masks the first one.
	 */
	public void testAddTwiceAndDelete() {
		DeltaDataTree tree1 = new DeltaDataTree();

		tree1.createChild(Path.ROOT, "A", "Data for A");

		tree1.immutable();
		tree1 = tree1.newEmptyDeltaTree();

		tree1.createChild(Path.ROOT, "A", "New A Data");

		tree1.immutable();
		tree1 = tree1.newEmptyDeltaTree();

		tree1.deleteChild(Path.ROOT, "A");
		tree1.immutable();

		assertTrue(tree1.getChildCount(Path.ROOT) == 0);

	}

	public void testAssembleWithIn() {

		/**
		 * Answer the result of assembling @node1 (a node of the receiver)
		 * with @node2 (a node of @tree2).
		 * The @node2 represents a forward delta based on @node1.
		 */

		DeltaDataTree assembledTree;

		/* make a change */
		changedTree.deleteChild(leftKey, "two");

		/* make delta tree */
		deltaTree = tree.forwardDeltaWith(changedTree, DefaultElementComparator.getComparator());

		/* get changedTree from original and forward delta on original */
		assembledTree = tree.assembleWithForwardDelta(deltaTree);

		/* make sure the reconstructed tree is as expected */
		assertTrue(assembledTree.includes(rootKey));
		assertTrue(assembledTree.includes(leftKey));
		assertTrue(assembledTree.includes(leftKey.append("one")));
		assertTrue(!assembledTree.includes(leftKey.append("two")));
		assertTrue(assembledTree.includes(leftKey.append("three")));
		assertTrue(assembledTree.includes(rightKey));

	}

	/**
	 * Create a child of the specified node and give it the specified local name.<p>
	 * If a child with such a name exists, replace it with the new child
	 * @exception ObjectNotFoundException
	 *	parentKey does not exist in the receiver
	 */
	@Override
	public void testCreateChild() {

		boolean caught;
		int size;

		caught = false;
		/* Create child with bogus parent key */
		try {
			tree.createChild(rootKey.append("bogus"), "foobar");
		} catch (ObjectNotFoundException e) {
			caught = true;
		} finally {
			assertTrue("1", caught);
		}

		caught = false;
		/* Create child of empty tree with bogus parent */
		try {
			emptyTree.createChild(rootKey.append("bogus"), "foobar");
		} catch (ObjectNotFoundException e) {
			caught = true;
		} finally {
			assertTrue("2", caught);
		}

		/* Add child to empty tree */
		try {
			emptyTree.createChild(rootKey, "first");
		} catch (ObjectNotFoundException e) {
		}
		assertTrue("3", emptyTree.includes(rootKey.append("first")));

		/* Add root level child to non-empty tree */
		try {
			tree.createChild(rootKey, "NewTopLevel");
		} catch (ObjectNotFoundException e) {
		}
		assertTrue("4", tree.includes(rootKey.append("NewTopLevel")));
		assertTrue("5", tree.includes(leftKey));
		assertTrue("6", tree.includes(rightKey));
		assertTrue("7", tree.includes(leftKey.append("one")));

		/* Add child to leaf in non-empty tree */
		try {
			tree.createChild(leftKey.append("one"), "NewBottom");
		} catch (ObjectNotFoundException e) {
		}
		assertTrue("8", tree.includes(leftKey));
		assertTrue("9", tree.includes(rightKey));
		assertTrue("10", tree.includes(leftKey.append("one")));
		assertTrue("11", tree.includes(leftKey.append("one").append("NewBottom")));

		/* Add child to node containing only one child */
		try {
			tree.createChild(rightKey, "NewRight");
		} catch (ObjectNotFoundException e) {
		}
		assertTrue("12", tree.includes(leftKey));
		assertTrue("13", tree.includes(rightKey));
		assertTrue("14", tree.includes(rightKey.append("rightOfRight")));
		assertTrue("15", tree.includes(rightKey.append("NewRight")));

		/* Add same child twice */
		size = (tree.getNamesOfChildren(leftKey)).length;
		tree.createChild(leftKey, "double");
		tree.createChild(leftKey, "double");
		/* Make sure size has only increased by one */
		assertTrue((tree.getNamesOfChildren(leftKey)).length == size + 1);

		return;
	}

	/**
	 * Delete the child with the specified local name from the specified
	 * node.  Note: this method requires both parentKey and localName,
	 * making it impossible to delete the root node.<p>
	 *
	 * @exception ObjectNotFoundException
	 *	a child of parentKey with name localName does not exist in the receiver
	 */
	@Override
	public void testDeleteChild() {

		boolean caught;

		/* Delete from empty */
		caught = false;
		try {
			emptyTree.deleteChild(rootKey, "non-existant");
		} catch (ObjectNotFoundException e) {
			caught = true;
		} finally {
			assertTrue("1", caught);
		}

		/* delete a child that is not the child of parentKey */
		caught = false;
		try {
			tree.deleteChild(rootKey, "rightOfRight");
		} catch (ObjectNotFoundException e) {
			caught = true;
		} finally {
			assertTrue("2", caught);
		}
		assertTrue("3", tree.includes(rightKey.append("rightOfRight")));

		/* delete with bogus parent */
		caught = false;
		try {
			tree.deleteChild(rootKey.append("bogus"), "rightOfRight");
		} catch (ObjectNotFoundException e) {
			caught = true;
		} finally {
			assertTrue("4", caught);
		}
		assertTrue("5", tree.includes(rightKey.append("rightOfRight")));

		/* delete with bogus local name */
		caught = false;
		try {
			tree.deleteChild(leftKey, "four");
		} catch (ObjectNotFoundException e) {
			caught = true;
		} finally {
			assertTrue("6", caught);
		}
		assertTrue("7", tree.includes(leftKey));

		/* Delete a node with children */
		try {
			tree.deleteChild(rootKey, "leftOfRoot");
		} catch (ObjectNotFoundException e) {
		}

		assertTrue("8", !tree.includes(leftKey));
		assertTrue("9", !tree.includes(leftKey.append("one")));
		assertTrue("10", tree.includes(rootKey));

		/* delete a leaf */
		try {
			tree.deleteChild(rightKey, "rightOfRight");
		} catch (ObjectNotFoundException e) {
		}
		assertTrue("11", !tree.includes(rightKey.append("rightOfRight")));
		assertTrue("12", tree.includes(rightKey));

		return;
	}

	/**
	 * Creates a delta on two unrelated delta trees
	 */
	public void testDeltaOnCompletelyDifferentTrees() {

		DeltaDataTree newTree = new DeltaDataTree();

		/* Create a new tree */

		/* Add two children to root */
		try {
			newTree.createChild(rootKey, "newLeft");
			newTree.createChild(rootKey, "newRight");
		} catch (ObjectNotFoundException e) {
			throw new Error("(1) Error in setUp");
		}

		/* Add three children to left of root and one to right of root */
		try {
			newTree.createChild(rootKey.append("newLeft"), "newOne");
			newTree.createChild(rootKey.append("newLeft"), "newTwo");
			newTree.createChild(rootKey.append("newLeft"), "newThree");

			newTree.createChild(rootKey.append("newRight"), "newRightOfRight");
			newTree.createChild(rootKey.append("newRight").append("newRightOfRight"), "bottom");
		} catch (ObjectNotFoundException e) {
			throw new Error("(2) Error in setUp");
		}

		/* get delta on different trees */
		deltaTree = newTree.forwardDeltaWith(tree, DefaultElementComparator.getComparator());

		/* assert delta has same content as tree */
		assertTree(deltaTree);
		assertTrue(!deltaTree.includes(rootKey.append("newLeft")));
		assertTrue(!deltaTree.includes(rootKey.append("newRight")));

	}

	/**
	 * Initialize the receiver so that it is a complete, empty tree.  It does
	 * not represent a delta on another tree.  An empty tree is defined to
	 * have a root node with nil data and no children.
	 */
	@Override
	public void testEmpty() {

		assertTrue("1", emptyTree.includes(rootKey));
		assertTrue("2", TestHelper.getRootNode(emptyTree) != null);
		assertTrue("3", TestHelper.getRootNode(emptyTree).getChildren().length == 0);

		return;
	}

	/**
	 * Tests the forwardDeltaWith function where the delta is calculated
	 * between a data delta node in the old tree and a complete data node
	 * in the new tree.
	 * This is a regression test for a problem with DataDeltaNode.forwardDeltaWith(...).
	 */
	public void testForwardDeltaOnDataDeltaNode() {

		tree.immutable();
		DeltaDataTree tree1 = tree.newEmptyDeltaTree();

		tree1.setData(leftKey, "replaced");
		DeltaDataTree delta = tree1.forwardDeltaWith(changedTree, DefaultElementComparator.getComparator());
		assertTrue(delta.getData(leftKey) == null); // the value in changedTree
	}

	/**
	 * Tests the forwardDeltaWith() function
	 */
	public void testForwardDeltaWith() {

		DeltaDataTree assembledTree;

		/* make several changes */
		changedTree.deleteChild(leftKey, "two");
		changedTree.createChild(leftKey, "four");
		changedTree.createChild(leftKey, "five");
		changedTree.createChild(leftKey, "six");
		changedTree.createChild(rootKey, "NewTopLevel");

		/* make delta tree */
		deltaTree = tree.forwardDeltaWith(changedTree, DefaultElementComparator.getComparator());

		/* get changedTree from original and forward delta on original */
		assembledTree = tree.assembleWithForwardDelta(deltaTree);

		/* make sure the reconstructed tree is as expected */
		assertTrue(assembledTree.includes(rootKey));
		assertTrue(assembledTree.includes(leftKey));
		assertTrue(assembledTree.includes(rightKey));
		assertTrue(assembledTree.includes(rootKey.append("NewTopLevel")));

		assertTrue(assembledTree.includes(leftKey.append("one")));
		assertTrue(!assembledTree.includes(leftKey.append("two")));
		assertTrue(assembledTree.includes(leftKey.append("three")));
		assertTrue(assembledTree.includes(leftKey.append("four")));
		assertTrue(assembledTree.includes(leftKey.append("five")));
		assertTrue(assembledTree.includes(leftKey.append("six")));
		assertTrue(assembledTree.includes(rightKey.append("rightOfRight")));

	}

	/**
	 * Tests the forwardDeltaWith() function using the equality comparer.
	 */
	public void testForwardDeltaWithEquality() {

		DeltaDataTree assembledTree;

		/* make several changes */
		changedTree.deleteChild(leftKey, "two");
		changedTree.createChild(leftKey, "four");
		IPath oneKey = leftKey.append("one");
		changedTree.setData(oneKey, "New");

		/* make delta tree */
		deltaTree = tree.forwardDeltaWith(changedTree, DefaultElementComparator.getComparator());

		/* get changedTree from original and forward delta on original */
		assembledTree = tree.assembleWithForwardDelta(deltaTree);

		/* make sure the reconstructed tree is as expected */
		assertTrue(assembledTree.includes(rootKey));
		assertTrue(assembledTree.includes(leftKey));
		assertTrue(assembledTree.includes(rightKey));

		assertTrue(assembledTree.includes(leftKey.append("one")));
		assertTrue(!assembledTree.includes(leftKey.append("two")));
		assertTrue(assembledTree.includes(leftKey.append("three")));
		assertTrue(assembledTree.includes(leftKey.append("four")));
		Object data = assembledTree.getData(oneKey);
		assertTrue(data != null && data.equals("New"));

	}

	/**
	 * Answer the key of the child with the given index of the
	 * specified node.<p>
	 *
	 * @param NodeKey, int
	 * @return NodeKey
	 *
	 * @exception ObjectNotFoundException
	 * 	parentKey does not exist in the receiver
	 * @exception ArrayIndexOutOfBoundsException
	 *	if no child with the given index (runtime exception)
	 */
	@Override
	public void testGetChild() {

		boolean caught;

		/* Get valid children */
		caught = false;
		try {
			assertTrue(tree.getChild(rootKey, 0).equals(leftKey));
			assertTrue(tree.getChild(leftKey, 2).equals(leftKey.append("two")));
		} catch (ObjectNotFoundException e) {
			caught = true;
		}
		assertTrue(!caught);

		/* Get non-existant child of root */
		caught = false;
		try {
			tree.getChild(rootKey, 99);
		} catch (ArrayIndexOutOfBoundsException e) {
			caught = true;
		} catch (ObjectNotFoundException e) {
			throw new Error();
		}
		assertTrue(caught);

		/* Get non-existant child of interior node */
		caught = false;
		try {
			tree.getChild(leftKey, 99);
		} catch (ArrayIndexOutOfBoundsException e) {
			caught = true;
		} catch (ObjectNotFoundException e) {
			throw new Error();
		}
		assertTrue(caught);

		/* Get non-existant child of leaf node */
		caught = false;
		try {
			tree.getChild(leftKey.append("one"), 99);
		} catch (ArrayIndexOutOfBoundsException e) {
			caught = true;
		} catch (ObjectNotFoundException e) {
			throw new Error();
		}
		assertTrue(caught);

		/* Try to getChild using non-existent key */
		caught = false;
		try {
			tree.getChild(rootKey.append("bogus"), 0);
		} catch (ObjectNotFoundException e) {
			caught = true;
		}
		assertTrue(caught);

		return;
	}

	/**
	 * Answer  the number of children of the specified node.
	 *
	 * @exception ObjectNotFoundException
	 *	parentKey does not exist in the receiver
	 */
	@Override
	public void testGetChildCount() {

		boolean caught;

		caught = false;
		try {
			/* empty tree */
			assertTrue("1", emptyTree.getChildCount(rootKey) == 0);

			/* root node */
			assertTrue("2", tree.getChildCount(rootKey) == 2);

			/* interior nodes */
			assertTrue("3", tree.getChildCount(leftKey) == 3);
			assertTrue("4", tree.getChildCount(rightKey) == 1);

			/* leaf nodes */
			assertTrue("5", tree.getChildCount(leftKey.append("one")) == 0);
			assertTrue("6", tree.getChildCount(leftKey.append("three")) == 0);
			assertTrue("7", tree.getChildCount(rightKey.append("rightOfRight")) == 0);
		} catch (ObjectNotFoundException e) {
			caught = true;
		} finally {
			assertTrue(!caught);
		}

		caught = false;
		/* invalid parent key */
		try {
			tree.getChildCount(rootKey.append("bogus"));
		} catch (ObjectNotFoundException e) {
			caught = true;
		}
		assertTrue(caught);

		/* invalid parent of empty tree */
		caught = false;
		try {
			emptyTree.getChildCount(rootKey.append("bogus"));
		} catch (ObjectNotFoundException e) {
			caught = true;
		}
		assertTrue(caught);

		return;
	}

	/**
	 * Answer the keys for the children of the specified node.
	 *
	 * @exception ObjectNotFoundException
	 *	parentKey does not exist in the receiver"
	 */
	@Override
	public void testGetChildren() {

		boolean caught;
		IPath testChildren[], rootChildren[] = {leftKey, rightKey}, leftChildren[] = {leftKey.append("one"), leftKey.append("two"), leftKey.append("three")}, rightChildren[] = {rightKey.append("rightOfRight")};

		caught = false;
		try {
			/* empty tree */
			testChildren = emptyTree.getChildren(rootKey);
			assertTrue("1", testChildren.length == 0);

			/* root node */
			testChildren = tree.getChildren(rootKey);
			assertTrue("2", testChildren.length == 2);
			assertTrue("3", testChildren[0].equals(rootChildren[0]));
			assertTrue("4", testChildren[1].equals(rootChildren[1]));

			/* interior nodes */
			testChildren = tree.getChildren(leftKey);
			assertTrue("5", testChildren.length == 3);
			assertTrue("6", testChildren[0].equals(leftChildren[0]));
			assertTrue("7", testChildren[2].equals(leftChildren[1]));
			assertTrue("8", testChildren[1].equals(leftChildren[2]));

			/* leaf nodes */
			testChildren = tree.getChildren(leftChildren[0]);
			assertTrue("9", testChildren.length == 0);

			testChildren = tree.getChildren(rightChildren[0]);
			assertTrue("10", testChildren.length == 0);
		} catch (ObjectNotFoundException e) {
			caught = true;
		} finally {
			assertTrue("11", !caught);
		}

		caught = false;
		/* invalid parent key */
		try {
			tree.getChildren(rootKey.append("bogus"));
		} catch (ObjectNotFoundException e) {
			caught = true;
		}
		assertTrue("12", caught);

		/* invalid parent of empty tree */
		caught = false;
		try {
			emptyTree.getChildren(rootKey.append("bogus"));
		} catch (ObjectNotFoundException e) {
			caught = true;
		}
		assertTrue("13", caught);

		return;
	}

	/**
	 * Answer the local name of the child with the given index of the
	 * specified node.
	 * @exception ObjectNotFoundException
	 *	parentKey does not exist in the receiver
	 * @exception ArrayIndexOutOfBoundsException
	 *	if no child with the given index
	 */
	@Override
	public void testGetNameOfChild() {

		/* tested thoroughly in testGetChild() and testGetNamesOfChildren */

		return;
	}

	/**
	 * Returns the local names for the children of the specified node.
	 *
	 * @exception ObjectNotFoundException
	 *	parentKey does not exist in the receiver
	 */
	@Override
	public void testGetNamesOfChildren() {

		boolean caught;
		String testChildren[], rootChildren[] = {"leftOfRoot", "rightOfRoot"}, leftChildren[] = {"one", "two", "three"}, rightChildren[] = {"rightOfRight"};

		caught = false;
		try {
			/* empty tree */
			testChildren = emptyTree.getNamesOfChildren(rootKey);
			assertTrue("1", testChildren.length == 0);

			/* root node */
			testChildren = tree.getNamesOfChildren(rootKey);
			assertTrue("2", testChildren.length == 2);
			assertTrue("3", testChildren[0].equals(rootChildren[0]));
			assertTrue("4", testChildren[1].equals(rootChildren[1]));

			/* interior nodes */
			testChildren = tree.getNamesOfChildren(leftKey);
			assertTrue("5", testChildren.length == 3);
			assertTrue("6", testChildren[0].equals(leftChildren[0]));
			assertTrue("7", testChildren[2].equals(leftChildren[1]));
			assertTrue("8", testChildren[1].equals(leftChildren[2]));

			testChildren = tree.getNamesOfChildren(rightKey);
			assertTrue("8.1", testChildren.length == 1);
			assertTrue("8.2", testChildren[0].equals(rightChildren[0]));

			/* leaf nodes */
			testChildren = tree.getNamesOfChildren(leftKey.append("one"));
			assertTrue("9", testChildren.length == 0);

			testChildren = tree.getNamesOfChildren(rightKey.append("rightOfRight"));
			assertTrue("10", testChildren.length == 0);
		} catch (ObjectNotFoundException e) {
			caught = true;
		} finally {
			assertTrue("11", !caught);
		}

		caught = false;
		/* invalid parent key */
		try {
			tree.getNamesOfChildren(rootKey.append("bogus"));
		} catch (ObjectNotFoundException e) {
			caught = true;
		}
		assertTrue("12", caught);

		/* invalid parent of empty tree */
		caught = false;
		try {
			emptyTree.getNamesOfChildren(rootKey.append("bogus"));
		} catch (ObjectNotFoundException e) {
			caught = true;
		}
		assertTrue("13", caught);

		return;
	}

	/**
	 * Returns true if the receiver includes a node with the given key, false
	 * otherwise.
	 */
	@Override
	public void testIncludes() {

		/* tested in testCreateChild() and testDeleteChild() */

		assertTrue(emptyTree.includes(rootKey));
		assertTrue(tree.includes(rootKey));
		assertTrue(tree.includes(leftKey));
		assertTrue(tree.includes(rightKey));
		assertTrue(tree.includes(leftKey.append("one")));
		assertTrue(tree.includes(rightKey.append("rightOfRight")));

		assertTrue(!emptyTree.includes(rootKey.append("bogus")));
		assertTrue(!tree.includes(rootKey.append("bogus")));
		assertTrue(!tree.includes(leftKey.append("bogus")));
		assertTrue(!tree.includes(leftKey.append("one").append("bogus")));
		assertTrue(!tree.includes(rightKey.append("bogus")));

		return;
	}

	/**
	 * Tests operations on a chain of deltas
	 */
	public void testLongDeltaChain() {

		final int NUM_DELTAS = 10;

		DeltaDataTree deltas[] = new DeltaDataTree[NUM_DELTAS];

		/* create a delta on the original tree, and make a change */
		tree.immutable();
		deltas[0] = tree.newEmptyDeltaTree();
		deltas[0].createChild(leftKey, "new");
		assertTree(deltas[0]);
		assertTrue(deltas[0].includes(leftKey.append("new")));

		/* create a second delta and make a change to that */
		deltas[0].immutable();
		deltas[1] = deltas[0].newEmptyDeltaTree();
		deltas[1].deleteChild(leftKey, "one");
		assertEquals("parent 0 -> 1", deltas[1].getParent(), deltas[0]);
		assertTrue(!deltas[1].includes(leftKey.append("one")));

		/* create a third delta and make a change to that */
		deltas[1].immutable();
		deltas[2] = deltas[1].newEmptyDeltaTree();
		deltas[2].createChild(rootKey, "newTopLevel");
		assertEquals("parent 1 -> 2", deltas[2].getParent(), deltas[1]);
		assertEquals("parent 0 -> 2", deltas[2].getParent().getParent(), deltas[0]);
		assertTrue(!deltas[2].includes(leftKey.append("one")));
		assertTrue(deltas[2].includes(rootKey.append("newTopLevel")));

	}

	/**
	 * Tests the newEmptyDeltaTree method
	 */
	public void testNewEmptyDeltaTree() {

		tree.immutable();
		DeltaDataTree delta = tree.newEmptyDeltaTree();
		assertEquals("parent", tree, delta.getParent());
		assertTree(delta);

	}

	/**
	 * Test for problem deleting and re-adding in same delta layer.
	 */
	public void testRegression1FVVP6L() {
		IPath elementA = Path.ROOT.append("A");

		DeltaDataTree tree1 = new DeltaDataTree();

		tree1.createChild(Path.ROOT, "A", "Data for A");
		tree1.createChild(elementA, "B", "Data for B");

		tree1.immutable();
		tree1 = tree1.newEmptyDeltaTree();

		tree1.deleteChild(elementA, "B");
		tree1.createChild(elementA, "B", "New B Data");

		tree1.immutable();
		tree1 = tree1.newEmptyDeltaTree();

		tree1.deleteChild(elementA, "B");

		try {
			tree1.copyCompleteSubtree(Path.ROOT);
		} catch (RuntimeException e) {
			assertTrue("Unexpected error copying tree", false);
		}

	}

	/**
	 * Test for problem deleting and re-adding in same delta layer.
	 */
	public void testRegression1FVVP6LWithChildren() {
		IPath elementA = Path.ROOT.append("A");
		IPath elementB = elementA.append("B");
		IPath elementC = elementB.append("C");

		DeltaDataTree tree1 = new DeltaDataTree();

		tree1.createChild(Path.ROOT, "A", "Data for A");
		tree1.createChild(elementA, "B", "Data for B");
		tree1.createChild(elementB, "C", "Data for C");

		tree1.immutable();
		tree1 = tree1.newEmptyDeltaTree();

		tree1.deleteChild(elementA, "B");
		tree1.createChild(elementA, "B", "New B Data");

		tree1.immutable();
		tree1 = tree1.newEmptyDeltaTree();

		assertTrue("Child exists after deletion", !tree1.includes(elementC));

		try {
			tree1.copyCompleteSubtree(Path.ROOT);
		} catch (RuntimeException e) {
			assertTrue("Unexpected error copying tree", false);
		}

	}

	/**
	 * Tests the reroot function
	 */
	public void testReroot() {

		final int NUM_DELTAS = 10;

		DeltaDataTree deltas[] = new DeltaDataTree[NUM_DELTAS];

		/* create a delta on the original tree, and make a change */
		tree.immutable();
		deltas[0] = tree.newEmptyDeltaTree();
		deltas[0].createChild(leftKey, "new");
		assertTree(deltas[0]);
		assertTrue(deltas[0].includes(leftKey.append("new")));

		/* create a second delta and make a change to that */
		deltas[0].immutable();
		deltas[1] = deltas[0].newEmptyDeltaTree();
		deltas[1].deleteChild(leftKey, "one");
		assertEquals("parent 0 -> 1", deltas[1].getParent(), deltas[0]);
		assertTrue(!deltas[1].includes(leftKey.append("one")));

		/* create a third delta and make a change to that */
		deltas[1].immutable();
		deltas[2] = deltas[1].newEmptyDeltaTree();
		deltas[2].createChild(rootKey, "newTopLevel");
		assertEquals("parent 1 -> 2", deltas[2].getParent(), deltas[1]);
		assertEquals("parent 0 -> 2", deltas[2].getParent().getParent(), deltas[0]);
		assertTrue(!deltas[2].includes(leftKey.append("one")));
		assertTrue(deltas[2].includes(rootKey.append("newTopLevel")));

		/* create a fourth delta and reroot at it */
		deltas[2].immutable();
		deltas[3] = deltas[2].newEmptyDeltaTree();
		deltas[3].immutable();
		deltas[3].reroot();
		assertTrue(deltas[3].getParent() == null);
		assertTrue(deltas[2].getParent() == deltas[3]);
		assertTrue(deltas[1].getParent() == deltas[2]);
		assertTrue(deltas[0].getParent() == deltas[1]);

		/* test that all trees have the same representation as before rerooting */
		assertTree(tree);
		assertTrue(!tree.includes(leftKey.append("new")));
		assertTrue(tree.includes(leftKey.append("one")));
		assertTree(deltas[0]);
		assertTrue(deltas[0].includes(leftKey.append("new")));
		assertTrue(deltas[0].includes(leftKey.append("one")));
		assertTrue(deltas[1].includes(leftKey.append("new")));
		assertTrue(!deltas[1].includes(leftKey.append("one")));
		assertDelta(deltas[2]);
		assertDelta(deltas[3]);

	}

	/**
	 * Tests that the setUp() method is doing what it should
	 */
	public void testSetup() {

		assertTree(tree);
		assertTree(changedTree);

		return;
	}
}
