/* $Id$ */
/*
 * The Apache Software License, Version 1.1
 * 
 * Copyright (c) 1999 The Apache Software Foundation.  All rights 
 * reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 * 
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:  
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 * 
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written 
 *    permission, please contact apache\@apache.org.
 * 
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 * 
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 * 
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

package dom;

import org.w3c.dom.*;
import java.lang.reflect.*;
import java.io.StringWriter;
import java.io.PrintWriter;
import dom.util.Assertion;

/**
 * This class tests methods for XML DOM implementation
 * version 2.0 10/12/98
 * 
 * DOMException errors are tested by calls to DOMExceptionsTest from: Main, docBuilder...
 *
 * @author Philip W. Davis
 */
 
public class DTest {
	
	public static Element 		testElementNode;
	public static Attr 		testAttributeNode;
	public static Text 		testTextNode;
	public static CDATASection 	testCDATASectionNode;
	public static EntityReference 	testEntityReferenceNode;
	public static Entity 		testEntityNode;
	public static ProcessingInstruction testProcessingInstructionNode;
	public static Comment 		testCommentNode;
	public static Document 		testDocumentNode;
	public static DocumentType 	testDocumentTypeNode;
	public static DocumentFragment 	testDocumentFragmentNode;
	public static Notation 		testNotationNode;

/**
 * 
 * version 2.0 10/12/98
 *
 * @author Philip W. Davis
 */
public DTest() {
	super();
	
}
/**
 * version 3.0 01/25/99
 *  
 * @return org.w3c.dom.Document
 *
 * @author Philip W. Davis
 */
public Document createDocument() {
	return new org.apache.xerces.dom.DocumentImpl();	//Replace with a Document creator
}
/**
 * version 3.0 01/25/99
 * 
 * @return org.w3c.dom.DocumentType
 * @param name java.lang.String
 *
 * @author Philip W. Davis
 */
public DocumentType createDocumentType(Document doc, String name) {
	return ((org.apache.xerces.dom.DocumentImpl) doc).createDocumentType(name, null, null);	//Replace with a DocumentType creator
}
/**
 * version 3.0 01/25/99
 *  
 * @return org.w3c.dom.Entity
 * @param doc org.w3c.dom.Document
 * @param name java.lang.String
 *
 * @author Philip W. Davis
 */
public Entity createEntity(Document doc, String name) {
	return new org.apache.xerces.dom.EntityImpl((org.apache.xerces.dom.DocumentImpl)doc, name);	//Replace with an Entity creator
}
/**
 * version 3.0 01/25/99
 * 
 * @return org.w3c.dom.Notation
 * @param doc org.w3c.dom.Document
 * @param name java.lang.String
 *
 * @author Philip W. Davis
 */
public Notation createNotation(Document doc, String name) {
	return new org.apache.xerces.dom.NotationImpl((org.apache.xerces.dom.DocumentImpl) doc, name);	// Replace with a Notation creator
}
/**
 * This method builds test documents for the XML DOM implementation
 * version 2.0 10/12/98
 * @param document org.w3c.dom.Document
 * @param name document's name
 * @param type document's type
 *
 * @author Philip W. Davis
 */
public void docBuilder(org.w3c.dom.Document document, String name)
{
	Document doc = document;
	boolean OK = true;
		
	Element docFirstElement = doc.createElement(name + "FirstElement");
	doc.appendChild(docFirstElement);
	docFirstElement.setAttribute(name + "FirstElement", name + "firstElement");
	
	ProcessingInstruction docProcessingInstruction = doc.createProcessingInstruction(name +
					"TargetProcessorChannel", "This is " + doc + "'s processing instruction");
	docFirstElement.appendChild(docProcessingInstruction);
	
	Element docBody = doc.createElement(name + "TestBody");
	docFirstElement.appendChild(docBody);
	
	Element docBodyLevel21 = doc.createElement(name + "BodyLevel21");
	Element docBodyLevel22 = doc.createElement(name + "BodyLevel22");
	Element docBodyLevel23 = doc.createElement(name + "BodyLevel23");
	Element docBodyLevel24 = doc.createElement(name + "BodyLevel24");
	docBody.appendChild(docBodyLevel21);
	docBody.appendChild(docBodyLevel22);
	docBody.appendChild(docBodyLevel23);
	docBody.appendChild(docBodyLevel24);
	
	Element docBodyLevel31 = doc.createElement(name + "BodyLevel31");
	Element docBodyLevel32 = doc.createElement(name + "BodyLevel32");
	Element docBodyLevel33 = doc.createElement(name + "BodyLevel33");
	Element docBodyLevel34 = doc.createElement(name + "BodyLevel34");
	docBodyLevel21.appendChild(docBodyLevel31);
	docBodyLevel21.appendChild(docBodyLevel32);
	docBodyLevel22.appendChild(docBodyLevel33);
	docBodyLevel22.appendChild(docBodyLevel34);
	
	Text docTextNode11 = doc.createTextNode(name + "BodyLevel31'sChildTextNode11");
	Text docTextNode12 = doc.createTextNode(name + "BodyLevel31'sChildTextNode12");
	Text docTextNode13 = doc.createTextNode(name + "BodyLevel31'sChildTextNode13");
	Text docTextNode2 = doc.createTextNode(name + "TextNode2");
	Text docTextNode3 = doc.createTextNode(name + "TextNode3");
	Text docTextNode4 = doc.createTextNode(name + "TextNode4");
	docBodyLevel31.appendChild(docTextNode11);
	docBodyLevel31.appendChild(docTextNode12);
	docBodyLevel31.appendChild(docTextNode13);
	docBodyLevel32.appendChild(docTextNode2);
	docBodyLevel33.appendChild(docTextNode3);
	docBodyLevel34.appendChild(docTextNode4);
	
	CDATASection docCDATASection = doc.createCDATASection("<![CDATA[<greeting>Hello, world!</greeting>]]>");
	docBodyLevel23.appendChild(docCDATASection);
	
	Comment docComment = doc.createComment("This should be a comment of some kind ");
	docBodyLevel23.appendChild(docComment);
	
	EntityReference docReferenceEntity = doc.createEntityReference("ourEntityNode");
	docBodyLevel24.appendChild(docReferenceEntity);

	DTest make = new DTest();
	Notation docNotation = make.createNotation(doc, "ourNotationNode");
//	NotationImpl docNotation = new NotationImpl((DocumentImpl) doc, "ourNotationNode");//*****?
	DocumentType docType = (DocumentType)doc.getFirstChild();
	docType.getNotations().setNamedItem(docNotation);
	
	DocumentFragment docDocFragment = doc.createDocumentFragment();
	
//	System.out.println("This document's first element name is " + docFirstElement.getTagName() + "\n");


//***********Following are for errorTests
	Text docNode3 = doc.createTextNode(name + "docTextNode3");
	Text docNode4 = doc.createTextNode(name + "docTextNode4");
	
	Entity docEntity = (Entity) doc.getDoctype().getEntities().getNamedItem("ourEntityNode"); // Get the Entity node
	DocumentType docDocType = (DocumentType) doc.getFirstChild();	// Get the DocumentType node
	EntityReference entityReferenceText = (EntityReference) doc.getLastChild().getLastChild().getLastChild().getFirstChild();
	Text entityReferenceText2 = doc.createTextNode("entityReferenceText information");
//************************************************* ERROR TESTS
	DTest tests = new DTest();

	OK &= Assertion.assert(tests.DOMExceptionsTest(document, "appendChild", new Class[]{Node.class}, new Object[]{docBody}, DOMException.HIERARCHY_REQUEST_ERR )); 
	OK &= Assertion.assert(tests.DOMExceptionsTest(docNode3, "appendChild", new Class[]{Node.class}, new Object[]{docNode4}, DOMException.HIERARCHY_REQUEST_ERR )); 
	OK &= Assertion.assert(tests.DOMExceptionsTest(doc, "insertBefore", new Class[]{Node.class, Node.class}, new Object[]{docEntity, docFirstElement}, DOMException.HIERARCHY_REQUEST_ERR )); 
	OK &= Assertion.assert(tests.DOMExceptionsTest(doc, "replaceChild", new Class[]{Node.class, Node.class}, new Object[]{docCDATASection, docFirstElement}, DOMException.HIERARCHY_REQUEST_ERR )); 

        docFirstElement.setNodeValue("This shouldn't do anything!");
	OK &= Assertion.assert(docFirstElement.getNodeValue() == null);
        docReferenceEntity.setNodeValue("This shouldn't do anything!");
	OK &= Assertion.assert(docReferenceEntity.getNodeValue() == null);
        docEntity.setNodeValue("This shouldn't do anything!");
	OK &= Assertion.assert(docEntity.getNodeValue() == null);
        doc.setNodeValue("This shouldn't do anything!");
	OK &= Assertion.assert(doc.getNodeValue() == null);
        docType.setNodeValue("This shouldn't do anything!");
	OK &= Assertion.assert(docType.getNodeValue() == null);
        docDocFragment.setNodeValue("This shouldn't do anything!");
	OK &= Assertion.assert(docDocFragment.getNodeValue() == null);
        docNotation.setNodeValue("This shouldn't do anything!");
	OK &= Assertion.assert(docNotation.getNodeValue() == null);

	OK &= Assertion.assert(tests.DOMExceptionsTest(docReferenceEntity, "appendChild", new Class[]{Node.class}, new Object[]{entityReferenceText2 }, DOMException.NO_MODIFICATION_ALLOWED_ERR ));
	OK &= Assertion.assert(tests.DOMExceptionsTest(docBodyLevel32, "insertBefore", new Class[]{Node.class, Node.class}, new Object[]{docTextNode11,docBody }, DOMException.NOT_FOUND_ERR ));
	OK &= Assertion.assert(tests.DOMExceptionsTest(docBodyLevel32, "removeChild", new Class[]{Node.class}, new Object[]{docFirstElement}, DOMException.NOT_FOUND_ERR ));
	OK &= Assertion.assert(tests.DOMExceptionsTest(docBodyLevel32, "replaceChild", new Class[]{Node.class, Node.class}, new Object[]{docTextNode11,docFirstElement }, DOMException.NOT_FOUND_ERR ));


//!! Throws a NOT_FOUND_ERR	********
	 
	 //	docBodyLevel32.getAttributes().removeNamedItem(testAttribute.getName()); 	16  // To test removeNamedItem
	 
}//END OF DOCBUILDER
/**
 * version 3.0 01/25/99
 * 
 * @return boolean
 * @param node java.lang.Object
 * @param mNameIndex int
 * @param signatureIndex int
 * @param parameters java.lang.Object[]
 * @param code short
 *
 * @author Philip W. Davis
 */
public static boolean DOMExceptionsTest(Object node, String methodName, Class[] methodSignature, Object[] parameters, short code) {
	
	
	boolean asExpected = false;
	Method method;

	try
	{
		method = node.getClass().getMethod(methodName,methodSignature);
		method.invoke(node, parameters);
	}catch(InvocationTargetException exc)
	{
		Throwable realE = exc.getTargetException(); 
		if(realE instanceof DOMException)
		{
			asExpected = (((DOMException)realE).code== code);
			if(!asExpected)
				System.out.println("Wrong DOMException(" + ((DOMException)realE).code + ")");
		}
		else
			System.out.println("Wrong Exception (" + code + ")");

		if(!asExpected)
		{
			System.out.println("Expected DOMException (" + code + ") not thrown");			
		}
	}catch(Exception exc)
	{
		System.out.println("test invocation failure (" + exc + ")");
	}
	
	
	return (asExpected);
}

/**
 * @author Philip W. Davis
 * @param document org.w3c.dom.Document
 */
public void findTestNodes(Document document) {




	Node node = document;
	int nodeCount = 0;

	// Walk the tree until you find and assign all node types needed that exist.
	while (node != null && nodeCount < 12)
	{

		switch (node.getNodeType())
	{
		case org.w3c.dom.Node.ELEMENT_NODE :
			if (testElementNode == null) {testElementNode = (Element)node; nodeCount++;}
			break;
		case org.w3c.dom.Node.ATTRIBUTE_NODE :
			if (testAttributeNode == null) {testAttributeNode = (Attr)node; nodeCount++;}
			break;
		case org.w3c.dom.Node.TEXT_NODE :
			if (testTextNode == null) {testTextNode = (Text)node; nodeCount++;}
			break;
		case org.w3c.dom.Node.CDATA_SECTION_NODE :
			if (testCDATASectionNode == null) {testCDATASectionNode = (CDATASection)node; nodeCount++;}
			break;
		case org.w3c.dom.Node.ENTITY_REFERENCE_NODE :
			if (testEntityReferenceNode == null) {testEntityReferenceNode = (EntityReference)node; nodeCount++;}
			break;
		case org.w3c.dom.Node.ENTITY_NODE :
			if (testEntityNode == null) {testEntityNode = (Entity)node; nodeCount++;}
			break;
		case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE :
			if (testProcessingInstructionNode == null) {testProcessingInstructionNode = (ProcessingInstruction)node; nodeCount++;}
			break;
		case org.w3c.dom.Node.COMMENT_NODE :
			if (testCommentNode == null) {testCommentNode = (Comment)node; nodeCount++;}
			break;
		case org.w3c.dom.Node.DOCUMENT_TYPE_NODE :
			if (testDocumentTypeNode == null) {testDocumentTypeNode = (DocumentType)node; nodeCount++;}
			break;
		case org.w3c.dom.Node.DOCUMENT_FRAGMENT_NODE :
			if (testDocumentFragmentNode == null) {testDocumentFragmentNode = (DocumentFragment)node; nodeCount++;}
			break;
		case org.w3c.dom.Node.NOTATION_NODE :
			if (testNotationNode == null) {testNotationNode = (Notation)node; nodeCount++;}
			break;
		case org.w3c.dom.Node.DOCUMENT_NODE :
			if (testDocumentNode == null) {testDocumentNode = (Document)node; nodeCount++;}
			break;
		default:
	}// End of switch

	


	}// End of while
	













	
}

/**
 * @author Philip W. Davis
 * @param document org.w3c.dom.Document
 */
public void findTestNodes(Node node) {

	DTest test = new DTest();
	Node kid;
	// Walk the tree until you find and assign all node types needed that exist.
	
		
	if (node.getFirstChild() != null)
	{
		kid = node.getFirstChild();
		test.findTestNodes(kid);
	}
			
				
	if (node.getNextSibling() != null)
	{
		kid = node.getNextSibling();
		test.findTestNodes(kid);
	}

		
	switch (node.getNodeType())
	{
		case org.w3c.dom.Node.ELEMENT_NODE :
			if (testElementNode == null) {testElementNode = (Element)node; }
			break;
		case org.w3c.dom.Node.ATTRIBUTE_NODE :
			if (testAttributeNode == null) {testAttributeNode = (Attr)node; }
			break;
		case org.w3c.dom.Node.TEXT_NODE :
			if (testTextNode == null) {testTextNode = (Text)node; }
			break;
		case org.w3c.dom.Node.CDATA_SECTION_NODE :
			if (testCDATASectionNode == null) {testCDATASectionNode = (CDATASection)node; }
			break;
		case org.w3c.dom.Node.ENTITY_REFERENCE_NODE :
			if (testEntityReferenceNode == null) {testEntityReferenceNode = (EntityReference)node;}
			break;
		case org.w3c.dom.Node.ENTITY_NODE :
			if (testEntityNode == null) {testEntityNode = (Entity)node;}
			break;
		case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE :
			if (testProcessingInstructionNode == null) {testProcessingInstructionNode = (ProcessingInstruction)node;}
			break;
		case org.w3c.dom.Node.COMMENT_NODE :
			if (testCommentNode == null) {testCommentNode = (Comment)node;}
			break;
		case org.w3c.dom.Node.DOCUMENT_TYPE_NODE :
			if (testDocumentTypeNode == null) {testDocumentTypeNode = (DocumentType)node; }
			break;
		case org.w3c.dom.Node.DOCUMENT_FRAGMENT_NODE :
			if (testDocumentFragmentNode == null) {testDocumentFragmentNode = (DocumentFragment)node;}
			break;
		case org.w3c.dom.Node.NOTATION_NODE :
			if (testNotationNode == null) {testNotationNode = (Notation)node;}
			break;
		case org.w3c.dom.Node.DOCUMENT_NODE :
			if (testDocumentNode == null) {testDocumentNode = (Document)node;}
			break;
		default:
	}// End of switch
	

}
	
/**
 * 
 * version 2.0 10/12/98
 *
 * @author Philip W. Davis
 */

public static void main(String args[]) {
    System.out.println("# main()");
	
	DTest test = new DTest();

	long avgTime = 0;
	boolean OK = true;
	long startTime = 0;//****************Time the whole thing for efficiency of DOM implementation
	 
//	for (int i=0; i< 1000; i++)
//	{	
		startTime = System.currentTimeMillis();
//		if(!OK)
//		break;

	Document d = test.createDocument();
//	Document z = test.createDocument();

	DocumentType docDocType = test.createDocumentType(d,"testDocument1");
	d.appendChild(docDocType);

	Entity docEntity = test.createEntity( d, "ourEntityNode");
	Text entityChildText = d.createTextNode("entityChildText information"); // Build a branch for entityReference tests
        ((org.apache.xerces.dom.NodeImpl)docEntity).setReadOnly(false, true);
	docEntity.appendChild(entityChildText);					  // & for READONLY_ERR tests
        ((org.apache.xerces.dom.NodeImpl)docEntity).setReadOnly(true, true);
	docDocType.getEntities().setNamedItem(docEntity);
	
	test.docBuilder(d, "d");

	test.findTestNodes((Node)d);
//	test.docBuilder(z, "z");
	try {
/**/		test.testAttr(d);
		test.testCDATASection(d);
		test.testCharacterData(d);
		test.testChildNodeList(d);
		test.testComment(d);
		test.testDeepNodeList(d);
		test.testDocument(d);
		test.testDocumentFragment(d);
		test.testDocumentType(d);
		test.testDOMImplementation(d);
		test.testElement(d);
		test.testEntity(d);
		test.testEntityReference(d);
		test.testNode(d);
		test.testNotation(d);
		test.testPI(d);
		test.testText(d);
/**/		test.testDOMerrors(d);
	
//!! Throws WRONG_DOCUMENT_ERR **********
		
	//	z.appendChild(d.createComment("Test doc d comment"));// Tries to append z document with document d comment
	//	d.getDocumentElement().appendChild(z.createElement("newZdocElement"));// Tries to append d document with document z Element
	//	d.getLastChild().getLastChild().insertBefore(z.createElement("newZdocElement"),d.getLastChild().getLastChild().getFirstChild());// Tries to insert into d document with document z Element
	//	d.replaceChild(z.createElement("newZdocElement"),d.getLastChild().getLastChild().getFirstChild());	// Tries to replace in d document with document z Element

	/*	Attribute newAttribute = d.createAttribute("newAttribute");
		d.getDocumentElement().setAttributeNode(newAttribute);
		d.getDocumentElement().getAttributes().setNamedItem(z.createAttribute("newzAttribute"));
	*/
		
//!! Throws INVALID_CHARACTER_ERR **********
	// ******This just gets us through each method. JKess has a comprehensive test of Invalid Names******
	//	d.createAttribute("Invalid Name"); // Name with blank space
	//	d.createElement("5InvalidName"); // Name starts with numeric
	//	d.createProcessingInstruction("This is the target processor channel","InvalidName>");// Name ends with >
	//	d.getDocumentElement().setAttribute("Invalid%Name",""); // Name contains %
		

//!!	******** NO_DATA_ALLOWED_ERR ********No cases to test as of 9/15


//!! 	******** NO_MODIFICATION_ALLOWED_ERR ******** When read only exists
	/*
		

		
		//**** FOR Element when read only exists********
		.removeAttribute("aString");		   //***** Not until read only exists.
		.removeAttributeNode(Attribute); 	   //***** Not until read only exists.
		.setAttribute("aString", "anotherString"); //***** Not until read only exists.
		
		
		//**** FOR Node when read only exists********
		.appendChild(aNode);			//***** Not until read only exists.
		.insertBefore(aNode, AnotherNode);	//***** Not until read only exists.
		.removeChild(aNode);			//***** Not until read only exists.
		.replaceChild(aNode);			//***** Not until read only exists.
		
		.splitText(2); //***** Not until read only exists.
		
		.setNamedItem(Node); //***** Not until read only exists.
	*/
	

//!!******** NOT_SUPPORTED_ERR	********For HTML when implemented
	/*
		.createCDATASection("String stuff");
		.createEntityReference("String stuff");
		.createProcessingInstruction("String stuff", "Some more String stuff");
	*/

	} catch (Exception e) {
		System.out.println("Exception is: ");
		e.printStackTrace();
		OK = false;
		
	}
//System.err.println("Elapsed time (measured in seconds): " +   ((System.currentTimeMillis() - startTime) / 1000.0));
	avgTime += System.currentTimeMillis() - startTime;
//	}//END OF FOR
	  
	
//	System.err.println("Elapsed time (measured in seconds): " +
//					   ((System.currentTimeMillis() - startTime) / 1000.0));
//	      System.err.println("Elapsed time (measured in mili-seconds): " +
//					   ((System.currentTimeMillis() - startTime)));


//	System.err.println("Average Elapsed time (measured in seconds): " + (avgTime/10000000.0) );

}
/**
 * This method tests Attr methods for the XML DOM implementation
 * version 2.0 10/12/98
 * @param document org.w3c.dom.Document
 *
 * @author Philip W. Davis
 */
public void testAttr(org.w3c.dom.Document document)
{
	
	Node node;	
	Attr attributeNode, attribute2;
	String compare;
	boolean T = true;
	boolean F = false;
	boolean OK = true;
// For debugging*****	println("\n          testAttr's outputs:\n");

	Attr testAttribute = document.createAttribute("testAttribute");
	testAttribute.setValue("testAttribute's value");
	node = document.getDocumentElement(); // node gets first element
	((Element)node).setAttributeNode(testAttribute);
	attributeNode = ((Element)node).getAttributeNode("testAttribute");

	compare = "testAttribute";
	if (!compare.equals(attributeNode.getName()))
	{
		System.out.println("Warning!!! Attr's 'getName' method failed to work properly!");
		OK = false;
	}
	compare = "testAttribute's value";
	if (!compare.equals(attributeNode.getNodeValue()))
	{
		System.out.println("Warning!!! Attr's 'getNodeValue' method failed to work properly!");
		OK = false;
	}
	if (! T ==attributeNode.getSpecified())
	{
		System.out.println("Warning!!! Attr's 'getSpecified' method failed to work properly!");
		OK = false;
	}
	
	if (!compare.equals(attributeNode.getValue()))
	{
		System.out.println("Warning!!! Attr's 'getValue' method failed to work properly!");
		OK = false;
	}
	
	attributeNode.setNodeValue("Reset Value");
	compare = "Reset Value";
	if (!compare.equals(attributeNode.getNodeValue()))
	{
		System.out.println("Warning!!! Attr's 'setNodeValue' method failed to work properly!");
		OK = false;
	}
	((org.apache.xerces.dom.AttrImpl)attributeNode).setSpecified(F);//***** How do we change this for external use??
	if (! F ==attributeNode.getSpecified())
	{
		System.out.println("Warning!!! Attr's 'setSpecified' method failed to work properly!");
		OK = false;
	}
	
	attributeNode.setValue(null);
	if (! attributeNode.getValue().equals(""))
	{
		System.out.println("Warning!!! Attr's 'setValue' to 'null' method failed to work properly!");
		OK = false;
	}
	
	attributeNode.setValue("Another value ");
	compare = "Another value ";
	if (!compare.equals(attributeNode.getValue()))
	{
		System.out.println("Warning!!! Attr's 'setValue' method failed to work properly!");
		OK = false;
	}

	node = attributeNode.cloneNode(T);//*****?
	// Check nodes for equality, both their name and value or lack thereof
	if (! (node.getNodeName().equals(attributeNode.getNodeName()) &&	     // Compares node names for equality
	      (node.getNodeValue() != null && attributeNode.getNodeValue() != null)  // Checks to make sure each node has a value node
	    ?  node.getNodeValue().equals(attributeNode.getNodeValue()) 	     // If both have value nodes test those value nodes for equality
	    : (node.getNodeValue() == null && attributeNode.getNodeValue() == null)))// If one node doesn't have a value node make sure both don't
		{	
			System.out.println("'cloneNode' did not clone the Attribute node correctly");
			OK = false;
		}
		// Deep clone test comparison is in testNode & testDocument

//************************************************* ERROR TESTS
	DTest tests = new DTest();
        Assertion.assert(
          tests.DOMExceptionsTest(document.getDocumentElement(),
                                  "appendChild",
                                  new Class[]{Node.class},
                                  new Object[]{attributeNode},
                                  DOMException.HIERARCHY_REQUEST_ERR));

	attribute2 = document.createAttribute("testAttribute2");
        Assertion.assert(
          tests.DOMExceptionsTest(document.getDocumentElement(),
                                  "removeAttributeNode",
                                  new Class[]{Attr.class},
                                  new Object[]{attribute2},
                                  DOMException.NOT_FOUND_ERR));

        Element element = (Element)document.getLastChild().getLastChild();
        // Tests setNamedItem
        Assertion.assert(
          tests.DOMExceptionsTest(element,
                                  "setAttributeNode",
                                  new Class[]{Attr.class},
                                  new Object[]{testAttribute},
                                  DOMException.INUSE_ATTRIBUTE_ERR));
	
	if (! OK)
		System.out.println("\n*****The Attr method calls listed above failed, all others worked correctly.*****");
//	println("");
}
/**
 * This method tests CDATASection methods for the XML DOM implementation
 * version 2.0 10/12/98
 * @param document org.w3c.dom.Document
 *
 * @author Philip W. Davis
 */
public void testCDATASection(org.w3c.dom.Document document)
{
	
	Node node, node2;
	boolean T = true;
	boolean OK = true;
// For debugging*****	println("\n          testCDATASection's outputs:\n");
	node = document.getDocumentElement().getElementsByTagName("dBodyLevel23").item(0).getFirstChild(); // node gets CDATASection node

	node2 = node.cloneNode(T);//*****?
	// Check nodes for equality, both their name and value or lack thereof
	if (! (node.getNodeName().equals(node2.getNodeName()) && 		// Compares node names for equality
	      (node.getNodeValue() != null && node2.getNodeValue() != null)     // Checks to make sure each node has a value node
	    ?  node.getNodeValue().equals(node2.getNodeValue()) 		// If both have value nodes test those value nodes for equality
	    : (node.getNodeValue() == null && node2.getNodeValue() == null)))	// If one node doesn't have a value node make sure both don't
	{
		System.out.println("'cloneNode' did not clone the CDATASection node correctly");
		OK = false;
	}
	// Deep clone test comparison is in testNode & testDocument
	
// For debugging*****	println("All CDATASection method calls worked correctly.");
		
	if (! OK)
		System.out.println("\n*****The CDATASection method calls listed above failed, all others worked correctly.*****");
//	println("");
}
/**
 * This method tests CharacterData methods for the XML DOM implementation
 * version 2.0 10/12/98
 * @param document org.w3c.dom.Document
 *
 * @author Philip W. Davis
 */
public void testCharacterData(org.w3c.dom.Document document)
{
	CharacterData charData;
	String compareData, newData, resetData;
	boolean OK = true;
// For debugging*****	println("\n          testCharacterData's outputs:\n");
	charData = (CharacterData) document.getDocumentElement().getElementsByTagName("dBodyLevel31").item(0).getFirstChild(); // charData gets textNode11
	compareData = "dBodyLevel31'sChildTextNode11";
	if (!compareData.equals(charData.getData()))
	{
		System.out.println("Warning!!! CharacterData's 'getData' failed to work properly!\n This may corrupt other CharacterData tests!!!*****");
		OK = false;
	}	
	
	resetData = charData.getData();
	//  println("This node's original data is: " + charData.getData());

	newData = " This is new data for this node";
	compareData = charData.getData() + newData;
	charData.appendData(newData);
	if (!compareData.equals(charData.getData()))
	{
		System.out.println("Warning!!! CharacterData's 'appendData' failed to work properly!");
		OK = false;
	}
	//	println("This node's appended data is: " + charData.getData());

	compareData = "dBodyLevel";
	charData.deleteData(10, 100);
	if (!compareData.equals(charData.getData()))
	{
		System.out.println("Warning!!! CharacterData's 'deleteData' failed to work properly!");
		OK = false;
	}
	//  println("This node's partially deleted data is: " + charData.getData());

	int length = 10;
	if (!(length == charData.getLength()))
	{
		System.out.println("Warning!!! CharacterData's 'getLength' failed to work properly!");
		OK = false;
	}
	//  println("This node's data length is: " + charData.getLength());

	compareData = "dBody' This is data inserted into this node'Level";
	charData.insertData(5, "' This is data inserted into this node'");
	if (!compareData.equals(charData.getData()))
	{
		System.out.println("Warning!!! CharacterData's 'insertData' failed to work properly!");
		OK = false;
	}
	//	println("This node's updated with insert data is: " + charData.getData());

	compareData = "dBody' This is ' replacement data'ted into this node'Level";
	charData.replaceData(15, 10, "' replacement data'");
	if (!compareData.equals(charData.getData()))
	{
		System.out.println("Warning!!! CharacterData's 'replaceData' failed to work properly!");
		OK = false;
	}
	//	println("This node's updated with replacement data is: " +charData.getData());

	compareData = "New data A123456789B123456789C123456789D123456789E123456789";
	charData.setData("New data A123456789B123456789C123456789D123456789E123456789");
	if (!compareData.equals(charData.getData()))
	{
		System.out.println("Warning!!! CharacterData's 'setData' failed to work properly!");
		OK = false;
	}
	//	println("This node's new data via setData: " + charData.getData());

	compareData = "123456789D123456789E123456789";
	if (!compareData.equals(charData.substringData(30, 30)))
	{
		System.out.println("Warning!!! CharacterData's 'substringData' failed to work properly!");
		OK = false;
	}
	//	println("Using subString 30,30 you get:" + charData.substringData(30,30));

	compareData = "New data A123456789B12345";
	if (!compareData.equals(charData.substringData(0, 25)))
	{
		System.out.println("Warning!!! CharacterData's 'substringData' failed to work properly!");
		OK = false;
	}
	//	println("Using subString 0,25 you get:" + charData.substringData(0,25));

//************************************************* ERROR TESTS
	DTest tests = new DTest();

//!! Throws INDEX_SIZE_ERR ********************
	OK &= Assertion.assert(tests.DOMExceptionsTest(charData, "deleteData", new Class[]{int.class, int.class}, 
			new Object[]{new Integer(-1),new Integer(5) }, DOMException.INDEX_SIZE_ERR ));
	OK &= Assertion.assert(tests.DOMExceptionsTest(charData, "deleteData", new Class[]{int.class, int.class}, 
			new Object[]{new Integer(2),new Integer(-1) }, DOMException.INDEX_SIZE_ERR ));
	OK &= Assertion.assert(tests.DOMExceptionsTest(charData, "deleteData", new Class[]{int.class, int.class}, 
			new Object[]{new Integer(100),new Integer(5) }, DOMException.INDEX_SIZE_ERR ));
	
	OK &= Assertion.assert(tests.DOMExceptionsTest(charData, "insertData", new Class[]{int.class, String.class}, 
			new Object[]{new Integer(-1),"Stuff inserted" }, DOMException.INDEX_SIZE_ERR ));
	OK &= Assertion.assert(tests.DOMExceptionsTest(charData, "insertData", new Class[]{int.class, String.class}, 
			new Object[]{new Integer(100),"Stuff inserted" }, DOMException.INDEX_SIZE_ERR ));
	
	OK &= Assertion.assert(tests.DOMExceptionsTest(charData, "replaceData", new Class[]{int.class, int.class, String.class}, 
			new Object[]{new Integer(-1),new Integer(5),"Replacement stuff" }, DOMException.INDEX_SIZE_ERR ));
	OK &= Assertion.assert(tests.DOMExceptionsTest(charData, "replaceData", new Class[]{int.class, int.class, String.class}, 
			new Object[]{new Integer(100),new Integer(5),"Replacement stuff" }, DOMException.INDEX_SIZE_ERR ));
	OK &= Assertion.assert(tests.DOMExceptionsTest(charData, "replaceData", new Class[]{int.class, int.class, String.class}, 
			new Object[]{new Integer(2),new Integer(-1),"Replacement stuff" }, DOMException.INDEX_SIZE_ERR ));
	
	OK &= Assertion.assert(tests.DOMExceptionsTest(charData, "substringData", new Class[]{int.class, int.class}, 
			new Object[]{new Integer(-1),new Integer(5) }, DOMException.INDEX_SIZE_ERR ));
	OK &= Assertion.assert(tests.DOMExceptionsTest(charData, "substringData", new Class[]{int.class, int.class}, 
			new Object[]{new Integer(100),new Integer(5) }, DOMException.INDEX_SIZE_ERR ));
	OK &= Assertion.assert(tests.DOMExceptionsTest(charData, "substringData", new Class[]{int.class, int.class}, 
			new Object[]{new Integer(2),new Integer(-1) }, DOMException.INDEX_SIZE_ERR ));
	

//!! Throws NO_MODIFICATION_ALLOWED_ERR ******** 
	Node node = document.getDocumentElement().getElementsByTagName("dBodyLevel24").item(0).getFirstChild().getChildNodes().item(0); // node gets ourEntityReference node's child text

	OK &= Assertion.assert(tests.DOMExceptionsTest(node, "appendData", new Class[]{String.class}, 
			new Object[]{"new data" }, DOMException.NO_MODIFICATION_ALLOWED_ERR ));
	OK &= Assertion.assert(tests.DOMExceptionsTest(node, "deleteData", new Class[]{int.class, int.class}, 
			new Object[]{new Integer(5),new Integer(10) }, DOMException.NO_MODIFICATION_ALLOWED_ERR ));
	OK &= Assertion.assert(tests.DOMExceptionsTest(node, "insertData", new Class[]{int.class, String.class}, 
			new Object[]{new Integer(5),"Stuff inserted" }, DOMException.NO_MODIFICATION_ALLOWED_ERR ));
	OK &= Assertion.assert(tests.DOMExceptionsTest(node, "replaceData", new Class[]{int.class, int.class, String.class}, 
			new Object[]{new Integer(5),new Integer(10),"Replacementstuff" }, DOMException.NO_MODIFICATION_ALLOWED_ERR ));
	OK &= Assertion.assert(tests.DOMExceptionsTest(node, "setData", new Class[]{String.class}, 
			new Object[]{"New setdata stuff"}, DOMException.NO_MODIFICATION_ALLOWED_ERR ));
	
		
// For debugging*****		println("All CharacterData method calls worked correctly.");
	if (!OK)
		System.out.println("\n*****The CharacterData method calls listed above failed, all others worked correctly.*****");
	charData.setData(resetData); // reset node to original data
//	println("");
}
/**
 * This method tests ChildNodeList methods for the XML DOM implementation
 * version 2.0 10/12/98
 * @param document org.w3c.dom.Document
 *
 * @author Philip W. Davis
 */
public void testChildNodeList(org.w3c.dom.Document document)
{
	
	Node node, node2;
	boolean OK = true;
// For debugging*****	println("\n          testChildNodeList's outputs:\n");
	node = document.getDocumentElement().getLastChild(); // node gets doc's testBody element
	
	if (!(node.getChildNodes().getLength()== 4))
		OK = false;
	node2 = node.getChildNodes().item(2);
	if (! node2.getNodeName().equals("dBodyLevel23"))
		OK = false;
	
// For debugging*****		println("All ChildNodeList method calls worked correctly.");
	if (!OK)
		System.out.println("\n*****The ChildNodeList method calls listed above failed, all others worked correctly.*****");		
//	println("");
}
/**
 * This method tests Comment methods for the XML DOM implementation
 * version 1.0 10/12/98
 * @param document org.w3c.dom.Document
 *
 * @author Philip W. Davis
 */
public void testComment(org.w3c.dom.Document document)
{
	Node node, node2;
	boolean T = true;
	boolean OK = true;
// For debugging*****	println("\n          testComment's outputs:\n");
	node = document.getDocumentElement().getElementsByTagName("dBodyLevel31").item(0).getFirstChild(); // node gets textNode11
	node2 = node.cloneNode(T);
	// Check nodes for equality, both their name and value or lack thereof
	if (!(node.getNodeName().equals(node2.getNodeName()) && 		// Compares node names for equality
	      (node.getNodeValue() != null && node2.getNodeValue() != null)     // Checks to make sure each node has a value node
	    ?  node.getNodeValue().equals(node2.getNodeValue()) 		// If both have value nodes test those value nodes for equality
	    : (node.getNodeValue() == null && node2.getNodeValue() == null)))	// If one node doesn't have a value node make sure both don't
		//println("'cloneNode' did not clone the Comment node correctly");
		OK = false;
	// Deep clone test comparison is in testNode & testDocument
	if (OK)
// For debugging*****		println("All Comment method calls worked correctly.");
	if (!OK)
		System.out.println("\n*****The Comment method calls listed above failed, all others worked correctly.*****");
//	println("");
}
/**
 * This method tests DeepNodeList methods for the XML DOM implementation
 * version 2.0 10/12/98
 * @param document org.w3c.dom.Document
 *
 * @author Philip W. Davis
 */
public void testDeepNodeList(org.w3c.dom.Document document)
{
	
	Node node, node2;
	boolean OK = true;
// For debugging*****	println("\n          testDeepNodeList's outputs:\n");
	node = document.getLastChild().getLastChild(); // node gets docBody element
	if (!(8 == ((Element) node).getElementsByTagName("*").getLength()))
		{
			System.out.println ("Warning!!! DeepNodeList's 'getLength' failed to work properly!");
			OK = false;		
		}
	node2 = ((Element) node).getElementsByTagName("*").item(2); //This also runs through 'nextMatchingElementAfter"
	if (! node2.getNodeName().equals("dBodyLevel32"))
		{
			System.out.println ("Warning!!! DeepNodeList's 'item' (or Element's 'getElementsBy TagName)failed to work properly!");
			OK = false;		
		}
	node2 = document.getLastChild();
	if (! ((Element) node2).getElementsByTagName("dTestBody").item(0).getNodeName().equals("dTestBody"))//This also runs through 'nextMatchingElementAfter"
		{
			System.out.println ("Warning!!! DeepNodeList's 'item' (or Element's 'getElementsBy TagName)failed to work properly!");
			OK = false;		
		}
		
	
// For debugging*****		println("All DeepNodeList method calls worked correctly.");
	if (!OK)
		System.out.println("\n*****The DeepNodeList method calls listed above failed, all others worked correctly.*****");
//	println("");
}
/**
 * This method tests Document methods for the XML DOM implementation
 * version 2.0 10/12/98
 * @param document org.w3c.dom.Document
 *
 * @author Philip W. Davis
 *
 **** ALL Document create methods are run in docBuilder except createAttribute which is in testAttribute**
 */
public void testDocument(org.w3c.dom.Document document)
{
	DTest make = new DTest();
	DocumentFragment docFragment, docFragment2;
	Element newElement;
	Node node, node2;
	String[] elementNames =  {"dFirstElement", "dTestBody", "dBodyLevel21","dBodyLevel31","dBodyLevel32",
				   "dBodyLevel22","dBodyLevel33","dBodyLevel34","dBodyLevel23","dBodyLevel24"};
	String[] newElementNames = {"dFirstElement", "dTestBody", "dBodyLevel22","dBodyLevel33","dBodyLevel34","dBodyLevel23"};
	boolean result;
	boolean OK = true;
// For debugging*****	println("\n          testDocument's outputs:\n ");
	
	DocumentType checkDocType =  make.createDocumentType(document,"testDocument1");
	DocumentType docType = document.getDoctype();
	if (! (checkDocType.getNodeName().equals(docType.getNodeName()) && 		// Compares node names for equality
	      (checkDocType.getNodeValue() != null && docType.getNodeValue() != null)   // Checks to make sure each node has a value node
	    ?  checkDocType.getNodeValue().equals(docType.getNodeValue()) 		// If both have value nodes test those value nodes for equality
	    : (checkDocType.getNodeValue() == null && docType.getNodeValue() == null)))	// If one node doesn't have a value node make sure both don't
	{
		System.out.println("Warning!!! Document's 'getDocType method failed!" );
		OK = false;
	}
		
	Node rootElement = document.getLastChild();
	if (! (rootElement.getNodeName().equals(document.getDocumentElement().getNodeName()) && 		// Compares node names for equality
	      (rootElement.getNodeValue() != null && document.getDocumentElement().getNodeValue() != null)   // Checks to make sure each node has a value node
	    ?  rootElement.getNodeValue().equals(document.getDocumentElement().getNodeValue()) 		// If both have value nodes test those value nodes for equality
	    : (rootElement.getNodeValue() == null && document.getDocumentElement().getNodeValue() == null)))	// If one node doesn't have a value node make sure both don't
	{
		System.out.println("Warning!!! Document's 'getDocumentElement' method failed!" );
		OK = false;
	}
	
	NodeList docElements = document.getElementsByTagName("*");
	int docSize = docElements.getLength();
	int i;
	for (i = 0; i < docSize; i++)
	{
		Node n = (Node) docElements.item(i);
		if (! (elementNames[i].equals(n.getNodeName())))
		{
			System.out.println("Comparison of this document's elements failed at element number " + i + " : " + n.getNodeName());
			OK = false;
			break;
		}
	}
	if (document.equals(document.getImplementation()))
	{
		System.out.println("Warning!!! Document's 'getImplementation' method failed!" );
		OK = false;		
	}
		
	newElement = document.createElement("NewElementTestsInsertBefore");
	//	doc.insertBefore(newElement,null);//!! Throws a HIERARCHY_REQUEST_ERR	*******	
	//	doc.removeChild(docElements.item(9));//!! Throws a NOT_FOUND_ERR  ********

	docFragment = document.createDocumentFragment();
	//Tests removeChild and stores removed branch for tree reconstruction
	docFragment.appendChild(docElements.item(1).removeChild(docElements.item(9)));
	docFragment2 = document.createDocumentFragment();
	//Tests removeChild and stores removed branch for tree reconstruction
	docFragment2.appendChild(docElements.item(1).removeChild(docElements.item(2)));
	docSize = docElements.getLength();
	for (i = 0; i < docSize; i++)
	{
		Node n = (Node) docElements.item(i);
		if (! (newElementNames[i].equals(n.getNodeName())))
		{
			System.out.println("Comparison of new document's elements failed at element number " + i + " : " + n.getNodeName());
			OK = false;
			break;
		}
	}
	docElements.item(1).insertBefore(docFragment, null); //Reattaches removed branch to restore tree to the original
	docElements.item(1).insertBefore(docFragment2, docElements.item(2)); //Reattaches removed branch to restore tree to the original

	//	println(docElements.item(2).getNodeName());

	docSize = docElements.getLength();
	for (i = 0; i < docSize; i++)
	{
		Node n = (Node) docElements.item(i);
		if (! (elementNames[i].equals(n.getNodeName())))
		{
			System.out.println("Comparison of restored document's elements failed at element number " + i + " : " + n.getNodeName());
			OK = false;
			break;
		}
	}

	DTest tests = new DTest();

	
//	Document z = tests.createDocument();
//	tests.docBuilder(z, "z");

//!! Throws WRONG_DOCUMENT_ERR **********
//	OK &= Assertion.assert(tests.DOMExceptionsTest(z, "appendChild", new Class[]{Node.class}, new Object[]{doc.createComment("Test doc d comment")}, DOMException.HIERARCHY_REQUEST_ERR )); 
		
	//	z.appendChild(d.createComment("Test doc d comment"));// Tries to append z document with document d comment
	//	d.getDocumentElement().appendChild(z.createElement("newZdocElement"));// Tries to append d document with document z Element
	//	d.getLastChild().getLastChild().insertBefore(z.createElement("newZdocElement"),d.getLastChild().getLastChild().getFirstChild());// Tries to insert into d document with document z Element
	//	d.replaceChild(z.createElement("newZdocElement"),d.getLastChild().getLastChild().getFirstChild());	// Tries to replace in d document with document z Element

	//	doc.setNodeValue("This shouldn't work");//!! Throws a NO_MODIFICATION_ALLOWED_ERR ********
	
	node = document;
	node2 = document.cloneNode(true);
	result = treeCompare(node, node2); // Deep clone test comparison of document cloneNode
	if (!result)
	{
		System.out.println("Warning!!! Deep clone of the document failed!");
		OK = false;
	}

	// check on the ownerDocument of the cloned nodes
	Document doc2 = (Document) node2;
	Assertion.assert(doc2.getDocumentElement().getOwnerDocument() == doc2);

	// Deep clone test comparison is also in testNode

	// try adding a new element to the cloned document
	node2 = doc2.createElement("foo");
	doc2.getDocumentElement().appendChild(node2);
	
// For debugging*****		println("All Document method calls worked correctly.");
	if (!OK)
		System.out.println("\n*****The Document method calls listed above failed, all others worked correctly.*****");
//	println("");
}
/**
 * This method tests DocumentFragment methods for the XML DOM implementation
 * version 2.0 10/12/98
 * @param document org.w3c.dom.Document
 *
 * @author Philip W. Davis
 *
 *
 ********This really isn't needed, only exists to throw NO_MODIFICATION_ALLOWED_ERR ********
 */
public void testDocumentFragment(org.w3c.dom.Document document)
{
	boolean OK = true;
// For debugging*****	println("\n          testDocumentFragment's outputs:\n");
	DocumentFragment testDocFragment = document.createDocumentFragment();
		
	//	testDocFragment.setNodeValue("This is a document fragment!");//!! Throws a NO_MODIFICATION_ALLOWED_ERR ********
	
// For debugging*****		println("All DocumentFragment method calls worked correctly.");
	if (!OK)
		System.out.println("\n*****The DocumentFragment method calls listed above failed, all others worked correctly.*****");
//	println("");
}
/**
 * This method tests DocumentType methods for the XML DOM implementation
 * version 2.0 10/12/98
 * @param document org.w3c.dom.Document
 *
 * @author Philip W. Davis
 */
public void testDocumentType(org.w3c.dom.Document document)
{
	DTest test = new DTest();
	DocumentType docType, holdDocType;
	NamedNodeMap docEntityMap, docNotationMap;
	Node node, node2;
	String compare;
	boolean OK = true;
// For debugging*****	println("\n          testDocumentType's outputs:\n");
	DocumentType newDocumentType =  test.createDocumentType(document, "TestDocument");
	node = document.getFirstChild(); // node gets doc's docType node
	node2 = node.cloneNode(true);
	// Check nodes for equality, both their name and value or lack thereof
	if (! (node.getNodeName().equals(node2.getNodeName()) && 	     // Compares node names for equality
	      (node.getNodeValue() != null && node2.getNodeValue() != null)  // Checks to make sure each node has a value node
	    ?  node.getNodeValue().equals(node2.getNodeValue()) 	     // If both have value nodes test those value nodes for equality
	    : (node.getNodeValue() == null && node2.getNodeValue() == null)))// If one node doesn't have a value node make sure both don't
	{	
		System.out.println("'cloneNode' did not clone the DocumentType node correctly");
		OK = false;
	}
	 // Deep clone test comparison is in testNode & testDocument

	docType = (DocumentType) document.getFirstChild();
	compare = "ourEntityNode";
	docEntityMap = docType.getEntities();
	if (! compare.equals(docEntityMap.item(0).getNodeName()))
	{
		System.out.println("Warning!!! DocumentType's 'getEntities' failed!" );
		OK = false;
	}
	docNotationMap = docType.getNotations();
	compare = "ourNotationNode";
	if (! compare.equals(docNotationMap.item(0).getNodeName()))
	{
		System.out.println("Warning!!! DocumentType's 'getNotations' failed!");
		OK = false;
	}
	//	doc.appendChild(newDocumentTypeImpl);//!! Throws a HIERARCHY_REQUEST_ERR	*******	
	holdDocType = (DocumentType) document.removeChild(document.getFirstChild()); //Tests removeChild and stores removed branch for tree reconstruction
	document.insertBefore(newDocumentType, document.getDocumentElement());
	//** Other aspects of insertBefore are tested in docBuilder through appendChild*

	document.removeChild(document.getFirstChild()); //Removes newDocumentType for tree restoral
	document.insertBefore(holdDocType, document.getFirstChild()); //Reattaches removed branch to restore tree to the original

	
// For debugging*****		println("All DocumentType method calls worked correctly.");
	if (!OK)
		System.out.println("\n*****The DocumentType method calls listed above failed, all others worked correctly.*****");
//	println("");
}
/**
 * @author Philip W. Davis
 * @param document org.w3c.dom.Document
 */
public void testDOMerrors(Document document) {

	boolean OK = true;

	DTest tests = new DTest();

	OK &= Assertion.assert(tests.DOMExceptionsTest(document, "appendChild", new Class[]{Node.class}, new Object[]{testElementNode}, DOMException.HIERARCHY_REQUEST_ERR )); 
	OK &= Assertion.assert(tests.DOMExceptionsTest(testTextNode, "appendChild", new Class[]{Node.class}, new Object[]{testTextNode}, DOMException.HIERARCHY_REQUEST_ERR )); 
//	OK &= Assertion.assert(tests.DOMExceptionsTest(document, "insertBefore", new Class[]{Node.class, Node.class}, new Object[]{document.getElementsByTagName("docEntity").item(0), document.getElementsByTagName("docFirstElement").item(0)}, DOMException.HIERARCHY_REQUEST_ERR )); 
//	OK &= Assertion.assert(tests.DOMExceptionsTest(document, "replaceChild", new Class[]{Node.class, Node.class}, new Object[]{document.getElementsByTagName("docCDATASection").item(0), document.getElementsByTagName("docFirstElement").item(0)}, DOMException.HIERARCHY_REQUEST_ERR )); 

//	OK &= Assertion.assert(tests.DOMExceptionsTest(document.getElementsByTagName("docFirstElement").item(0), "setNodeValue", new Class[]{String.class}, new Object[]{"This shouldn't work!" }, DOMException.NO_MODIFICATION_ALLOWED_ERR ));	
/*	OK &= Assertion.assert(tests.DOMExceptionsTest(docReferenceEntity, "setNodeValue", new Class[]{String.class}, new Object[]{"This shouldn't work!" }, DOMException.NO_MODIFICATION_ALLOWED_ERR ));
	OK &= Assertion.assert(tests.DOMExceptionsTest(docEntity, "setNodeValue", new Class[]{String.class}, new Object[]{"This shouldn't work!" }, DOMException.NO_MODIFICATION_ALLOWED_ERR ));
	OK &= Assertion.assert(tests.DOMExceptionsTest(document, "setNodeValue", new Class[]{String.class}, new Object[]{"This shouldn't work!" }, DOMException.NO_MODIFICATION_ALLOWED_ERR ));
	OK &= Assertion.assert(tests.DOMExceptionsTest(docDocType, "setNodeValue", new Class[]{String.class}, new Object[]{"This shouldn't work!" }, DOMException.NO_MODIFICATION_ALLOWED_ERR ));
	OK &= Assertion.assert(tests.DOMExceptionsTest(docDocFragment, "setNodeValue", new Class[]{String.class}, new Object[]{"This shouldn't work!" }, DOMException.NO_MODIFICATION_ALLOWED_ERR ));
	OK &= Assertion.assert(tests.DOMExceptionsTest(docNotation, "setNodeValue", new Class[]{String.class}, new Object[]{"This shouldn't work!" }, DOMException.NO_MODIFICATION_ALLOWED_ERR ));
	OK &= Assertion.assert(tests.DOMExceptionsTest(docReferenceEntity, "appendChild", new Class[]{Node.class}, new Object[]{entityReferenceText2 }, DOMException.NO_MODIFICATION_ALLOWED_ERR ));


	OK &= Assertion.assert(tests.DOMExceptionsTest(docBodyLevel32, "insertBefore", new Class[]{Node.class, Node.class}, new Object[]{docTextNode11,docBody }, DOMException.NOT_FOUND_ERR ));
	OK &= Assertion.assert(tests.DOMExceptionsTest(docBodyLevel32, "removeChild", new Class[]{Node.class}, new Object[]{docFirstElement}, DOMException.NOT_FOUND_ERR ));
	OK &= Assertion.assert(tests.DOMExceptionsTest(docBodyLevel32, "replaceChild", new Class[]{Node.class, Node.class}, new Object[]{docTextNode11,docFirstElement }, DOMException.NOT_FOUND_ERR ));
*/

//!! Throws a NOT_FOUND_ERR	********
	 
	 //	docBodyLevel32.getAttributes().removeNamedItem(testAttribute.getName()); 	16  // To test removeNamedItem
	 











	
}
/**
 * This method tests DOMImplementation methods for the XML DOM implementation
 * version 2.0 10/12/98
 * @param document org.w3c.dom.Document
 *
 * @author Philip W. Davis
 */
public void testDOMImplementation(org.w3c.dom.Document document)
{
	
	DOMImplementation implementation;
	boolean result = false;
	boolean OK = true;
// For debugging*****	println("\n          testDOMImplementation's outputs:\n");
	implementation = document.getImplementation(); //Uses getDOMImplementation to obtain implementation	

	result = implementation.hasFeature("XML", "1.0");
	if(!result)
	{
		System.out.println("Warning!!! DOMImplementation's 'hasFeature' that should be 'true' failed!");
		OK = false;
	}
	
	result = implementation.hasFeature("HTML", "4.0");
	if(result)
	{
		System.out.println("Warning!!! DOMImplementation's 'hasFeature' that should be 'false' failed!");
		OK = false;
	}
	
	
// For debugging*****		println("All DOMImplementation method calls worked correctly.");
	if (!OK)
		System.out.println("\n*****The DOMImplementation method calls listed above failed, all others worked correctly.*****");
//	println("");
}
/**
 * This method tests Element methods for the XML DOM implementation
 * version 2.0 10/12/98
 * @param document org.w3c.dom.Document
 *
 * @author Philip W. Davis
 */
public void testElement(org.w3c.dom.Document document)
{
	Attr attributeNode, newAttributeNode;
	Element element, element2;
	Node node, node2;
	String attribute, compare;
	String[] attributeCompare = {"AnotherFirstElementAttribute", "dFirstElement", "testAttribute"};
	String[] elementNames =  {"dFirstElement", "dTestBody", "dBodyLevel21","dBodyLevel31","dBodyLevel32",
				   "dBodyLevel22","dBodyLevel33","dBodyLevel34","dBodyLevel23","dBodyLevel24"};
	String[] textCompare = {"dBodyLevel31'sChildTextNode11", "dBodyLevel31'sChildTextNode12", "dBodyLevel31'sChildTextNode13"};
	NamedNodeMap nodeMap;
	boolean OK = true;
// For debugging*****	println("\n          testElement's outputs:\n");
	node = document.getDocumentElement(); // node gets doc's firstElement
	node2 = node.cloneNode(true);
	// Check nodes for equality, both their name and value or lack thereof
	if (!(node.getNodeName().equals(node2.getNodeName()) &&		    // Compares node names for equality
	     (node.getNodeValue() != null && node2.getNodeValue() != null)  // Checks to make sure each node has a value node
	    ? node.getNodeValue().equals(node2.getNodeValue())  	    // If both have value nodes test those value nodes for equality
	    :(node.getNodeValue() == null && node2.getNodeValue() == null)))// If one node doesn't have a value node make sure both don't
	{	
		System.out.println("'cloneNode' did not clone the Element node correctly");
		OK = false;
	}
	// Deep clone test comparison is in testNode & testDocument

	element = document.getDocumentElement(); // element gets doc's firstElement
	compare = "";
	attribute = element.getAttribute(document + "'s test attribute");
	if (! compare.equals(element.getAttribute(document + "'s test attribute")))
	{
		System.out.println("Warning!!! Element's 'getAttribute' failed!");
		OK = false;
	}
	
	attributeNode = element.getAttributeNode(document + "FirstElement");
	if(! (attributeNode == null))
	{
		System.out.println("Warning!!! Element's 'getAttributeNode' failed! It should have returned 'null' here!");
		OK = false;
	}
	
	newAttributeNode = document.createAttribute("AnotherFirstElementAttribute");
	newAttributeNode.setValue("A new attribute which helps test calls in Element");
	element.setAttributeNode(newAttributeNode);
	nodeMap = element.getAttributes();
	int size = nodeMap.getLength();
	int k;
	for (k = 0; k < size; k++)
	{
		Node n = (Node) nodeMap.item(k);
		if (! (attributeCompare[k].equals(n.getNodeName())))
		{
			System.out.println("Warning!!! Comparison of firstElement's attributes failed at attribute #"+ (k+1) +" " + n.getNodeValue());
			System.out.println("This failure can be a result of Element's 'setValue' and/or 'setAttributeNode' and/or 'getAttributes' failing.");
			OK = false;
			break;
		}
	//	println("firstElement's attribute number " + k + " : " + n.getNodeName());
	}
	NodeList docElements = document.getElementsByTagName("*");
	int docSize = docElements.getLength();
	int i;
	for (i = 0; i < docSize; i++)
	{
		Node n = (Node) docElements.item(i);
		if (! (elementNames[i].equals(n.getNodeName())))
		{
			System.out.println("Warning!!! Comparison of Element's 'getElementsByTagName' and/or 'item' failed at element number " 
						+ i + " : " + n.getNodeName());
			OK = false;
			break;
		}		
	//	println("docElement's number " + i + " is: " + n.getNodeName());
	}
	element = (Element) document.getElementsByTagName("dBodyLevel21").item(0); // element gets Element test BodyLevel21 
	element2 = (Element) document.getElementsByTagName("dBodyLevel31").item(0); // element2 gets Element test BodyLevel31 
	NodeList text = ((Node) element2).getChildNodes();
	int textSize = text.getLength();
	int j;
	for (j = 0; j < textSize; j++)
	{
		Node n = (Node) text.item(j);
		if (! (textCompare[j].equals(n.getNodeValue())))
		{
			System.out.println("Warning!!! Comparison of original text nodes via Node 'getChildNodes' & NodeList 'item'"
						+ "failed at text node: #" + j +" " + n.getNodeValue());
			OK = false;
			break;
		}
	//	println("Element testBodyLevel31's child text node " + j + " is: " + n.getNodeValue());
	}
	element = document.getDocumentElement(); // element gets doc's firstElement
	element.normalize();		// Concatenates all adjacent text nodes in this element's subtree
	NodeList text2 = ((Node) element2).getChildNodes();
	compare = "dBodyLevel31'sChildTextNode11dBodyLevel31'sChildTextNode12dBodyLevel31'sChildTextNode13";
	Node n = (Node) text2.item(0);
		if (! (compare.equals(n.getNodeValue())))
		{
			System.out.println("Warning!!! Comparison of concatenated text nodes created by Element's 'normalize' failed!");
			OK = false;
		}
	
	element.setAttribute("FirstElementLastAttribute", "More attribute stuff for firstElement!!");
	element.removeAttribute("FirstElementLastAttribute");
	element.removeAttributeNode(newAttributeNode);

	//	doc.getLastChild().setNodeValue("This shouldn't work");//!! Throws a NO_MODIFICATION_ALLOWED_ERR***
	
// For debugging*****		println("All Element method calls worked correctly.");
	if (!OK)
		System.out.println("\n*****The Element method calls listed above failed, all others worked correctly.*****");
//	println("");
}
/**
 * This method tests Entity methods for the XML DOM implementation
 * version 2.0 10/12/98
 * @param document org.w3c.dom.Document
 *
 * @author Philip W. Davis
 */
public void testEntity(org.w3c.dom.Document document)
{
	Entity entity;
	Node node, node2;
	boolean OK = true;
	String compare;
// For debugging*****	println("\n          testEntity's outputs:\n");
	entity = (Entity) document.getDoctype().getEntities().getNamedItem("ourEntityNode");
	node = entity;
	node2 = entity.cloneNode(true);
	// Check nodes for equality, both their name and value or lack thereof
	if (!(node.getNodeName().equals(node2.getNodeName()) && 		// Compares node names for equality
	     (node.getNodeValue() != null && node2.getNodeValue() != null) ?    // Checks to make sure each node has a value node
	      node.getNodeValue().equals(node2.getNodeValue()) :		// If both have value nodes test those value nodes for equality
	     (node.getNodeValue() == null && node2.getNodeValue() == null)))	// If one node doesn't have a value node make sure both don't
	{	
		System.out.println("Warning!!! 'cloneNode' did not clone the Entity node correctly");
		OK = false;
	}
	// Deep clone test comparison is in testNode & testDocument

 	((org.apache.xerces.dom.EntityImpl) entity).setNotationName("testNotationName");
	compare = "testNotationName";
 	if(! compare.equals(entity.getNotationName()))
	{
		System.out.println("Warning!!! Entity's 'setNotationName' and/or getNotationName' failed!");
		OK = false;
	}
 	((org.apache.xerces.dom.EntityImpl) entity).setPublicId("testPublicId");
	compare = "testPublicId";
 	if(! compare.equals(entity.getPublicId()))
	{
		System.out.println("Warning!!! Entity's 'setPublicId' and/or getPublicId' failed!");
		OK = false;
	}	
 	((org.apache.xerces.dom.EntityImpl) entity).setSystemId("testSystemId");
	compare = "testSystemId";
 	if(! compare.equals(entity.getSystemId()))
	{
		System.out.println("Warning!!! Entity's 'setSystemId' and/or getSystemId' failed!");
		OK = false;
	}		
	//	entity.setNodeValue("This shouldn't work");//!! Throws a NO_MODIFICATION_ALLOWED_ERR ********
	
// For debugging*****		println("All Entity method calls worked correctly.");
	if (!OK)
		System.out.println("\n*****The Entity method calls listed above failed, all others worked correctly.*****");
//	println("");
}
/**
 * This method tests EntityReference methods for the XML DOM implementation
 * version 2.0 10/12/98
 * @param document org.w3c.dom.Document
 *
 * @author Philip W. Davis
 */
public void testEntityReference(org.w3c.dom.Document document)
{
	EntityReference entityReference;
	Node node, node2;
	boolean OK = true;
// For debugging*****	println("\n          testEntityReference's outputs:\n");
	entityReference = (EntityReference) document.getLastChild().getLastChild().getLastChild().getFirstChild();
	node = entityReference;
	node2 = node.cloneNode(true);
	// Check nodes for equality, both their name and value or lack thereof
	if (!(node.getNodeName().equals(node2.getNodeName()) && 	    // Compares node names for equality
	     (node.getNodeValue() != null && node2.getNodeValue() != null)  // Checks to make sure each node has a value node
	    ? node.getNodeValue().equals(node2.getNodeValue()) 		    // If both have value nodes test those value nodes for equality
	    :(node.getNodeValue() == null && node2.getNodeValue() == null)))// If one node doesn't have a value node make sure both don't
	{	
		System.out.println("'cloneNode' did not clone the EntityReference node correctly");
		OK = false;
	}
	// Deep clone test comparison is in testNode & testDocument

	//	entityReference.setNodeValue("This shouldn't work");//!! Throws a NO_MODIFICATION_ALLOWED_ERR ********
	
// For debugging*****		println("All EntityReference method calls worked correctly.");
	if (!OK)
		System.out.println("\n*****The EntityReference method calls listed above failed, all others worked correctly.*****");
//	println("");
}
/**
 * This method tests Node methods for the XML DOM implementation
 * version 2.0 10/12/98
 * @param document org.w3c.dom.Document
 *
 * @author Philip W. Davis
 *
 *
 ********* This is only for a test of cloneNode "deep"*******
 ********* And for error tests*********
 */
public void testNode(org.w3c.dom.Document document)
{
	Node node, node2;
	boolean result;
	boolean OK = true;
// For debugging*****	println("\n          testNode's outputs:\n");
	node = document.getDocumentElement();
	node2 = node.cloneNode(true);
	result = treeCompare(node, node2); // Deep clone test of cloneNode
	if (result)
	{
		//println("'cloneNode' successfully cloned this whole node tree (deep)!");
	}
	else
	{
		System.out.println("'cloneNode' did not successfully clone this whole node tree (deep)!");
		OK = false;	
	}
	//!! The following gives a did not clone successfully message*********
	node = document.getDocumentElement();
	node2 = node.getFirstChild();
	result = treeCompare(node, node2);
	if (!result)
	{
		//println("'cloneNode' did not successfully clone this whole node tree (deep)!");
	}
	else
	{
		System.out.println("'cloneNode' was supposed to fail here, either it or 'treeCompare' failed!!!");
		OK = false;
	}
	// Deep clone test also in testDocument
	
// For debugging*****		println("All Node method calls worked correctly.");
	if (!OK)
		System.out.println("\n*****The Node method calls listed above failed, all others worked correctly.*****");	
//	println("");
}
/**
 * This method tests Notation methods for the XML DOM implementation
 * version 2.0 10/12/98
 * @param document org.w3c.dom.Document
 *
 * @author Philip W. Davis
 */
public void testNotation(org.w3c.dom.Document document)
{
	Node node, node2;
	Notation notation;
	boolean OK = true;
	String compare;
// For debugging*****	println("\n          testNotation's outputs:\n");
	notation = (Notation) document.getDoctype().getNotations().getNamedItem("ourNotationNode");
	node = notation;
	node2 = notation.cloneNode(true);//*****?
	// Check nodes for equality, both their name and value or lack thereof
	if (!(node.getNodeName().equals(node2.getNodeName()) && 	    // Compares node names for equality
	     (node.getNodeValue() != null && node2.getNodeValue() != null)  // Checks to make sure each node has a value node
	    ? node.getNodeValue().equals(node2.getNodeValue()) 		    // If both have value nodes test those value nodes for equality
	    :(node.getNodeValue() == null && node2.getNodeValue() == null)))// If one node doesn't have a value node make sure both don't
	{	
		System.out.println("'cloneNode' did not clone the Notation node correctly");
		OK = false;
	}
	// Deep clone test comparison is in testNode & testDocument

 	((org.apache.xerces.dom.NotationImpl) notation).setPublicId("testPublicId");//*****?
	compare = "testPublicId";
	if (!compare.equals(notation.getPublicId()))
	{
		System.out.println("Warning!!! Notation's 'getPublicId' failed!");
		OK = false;
	}
 	((org.apache.xerces.dom.NotationImpl) notation).setSystemId("testSystemId");//*****?
	compare = "testSystemId";
	if (! compare.equals(notation.getSystemId()))
	{
		System.out.println("Warning!!! Notation's 'getSystemId' failed!");
		OK = false;
	}
	//	notation.setNodeValue("This shouldn't work");//!! Throws a NO_MODIFICATION_ALLOWED_ERR ********
	
// For debugging*****		println("All Notation method calls worked correctly.");
	if (!OK)
		System.out.println("\n*****The Notation method calls listed above failed, all others worked correctly.*****");
//	println("");
}
/**
 * This method tests ProcessingInstruction methods for the XML DOM implementation
 * version 2.0 10/12/98
 * @param document org.w3c.dom.Document
 *
 * @author Philip W. Davis
 */
public void testPI(org.w3c.dom.Document document)
{
	Node node, node2;
	ProcessingInstruction pI, pI2;
	String compare;
	boolean OK = true;
// For debugging*****	println("\n          testPI's outputs:\n");
	pI = (ProcessingInstruction) document.getDocumentElement().getFirstChild();// Get doc's ProcessingInstruction
	pI2 = (org.apache.xerces.dom.ProcessingInstructionImpl) pI.cloneNode(true);//*****?
	// Check nodes for equality, both their name and value or lack thereof
	if (!(pI.getNodeName().equals(pI2.getNodeName()) && 		// Compares node names for equality
	     (pI.getNodeValue() != null && pI2.getNodeValue() != null)  // Checks to make sure each node has a value node
	    ? pI.getNodeValue().equals(pI2.getNodeValue()) 		// If both have value nodes test those value nodes for equality
	    :(pI.getNodeValue() == null && pI2.getNodeValue() == null)))// If one node doesn't have a value node make sure both don't
	{	
		System.out.println("'cloneNode' did not clone the Entity node correctly");
		OK = false;
	}
	// Deep clone test comparison is in testNode & testDocument
	compare = "This is [#document: null]'s processing instruction";
	if (! compare.equals(pI.getData()))
	{
		System.out.println("Warning!!! PI's 'getData' failed!");
		OK = false;
	}
	
	pI.setData("PI's reset data");
	compare = "PI's reset data";
	if (! compare.equals(pI.getData()))
	{
		System.out.println("Warning!!! PI's 'setData' failed!");
		OK = false;
	}	
	compare = "dTargetProcessorChannel";
	if (! compare.equals(pI.getTarget()))
	{
		System.out.println("Warning!!! PI's 'getTarget' failed!");
		OK = false;
	}	
	
// For debugging*****		println("All PI method calls worked correctly.");
	if (!OK)
		System.out.println("\n*****The PI method calls listed above failed, all others worked correctly.*****");
	
//	println("");
}
/**
 * This method tests Text methods for the XML DOM implementation
 * version 2.0 10/12/98
 * @param document org.w3c.dom.Document
 *
 * @author Philip W. Davis
 */
public void testText(org.w3c.dom.Document document)
{
	Node node, node2;
	Text text;
	String compare;
	boolean OK = true;
// For debugging*****	println("\n          testText's outputs:\n");
	node = document.getDocumentElement().getElementsByTagName("dBodyLevel31").item(0).getFirstChild(); // charData gets textNode11
	text = (Text) node;
	node2 = node.cloneNode(true);//*****?
	// Check nodes for equality, both their name and value or lack thereof
	if (!(node.getNodeName().equals(node2.getNodeName()) && 	    // Compares node names for equality
	     (node.getNodeValue() != null && node2.getNodeValue() != null)  // Checks to make sure each node has a value node
	    ? node.getNodeValue().equals(node2.getNodeValue()) 		    // If both have value nodes test those value nodes for equality
	    :(node.getNodeValue() == null && node2.getNodeValue() == null)))// If one node doesn't have a value node make sure both don't
	{	
		System.out.println("'cloneNode' did not clone the Text node correctly");
		OK = false;
	}
	// Deep clone test comparison is in testNode & testDocument
	text.splitText(25);
	compare = "dBodyLevel31'sChildTextNo";	// Three original text nodes were concatenated by 'normalize' in testElement
	if (! compare.equals(text.getNodeValue()))
		{
			System.out.println("First part of Text's split text failed!" );
			OK = false;
		}
	compare = "de11dBodyLevel31'sChildTextNode12dBodyLevel31'sChildTextNode13";// Three original text nodes were concatenated by 'normalize' in testElement
	if (! compare.equals(text.getNextSibling().getNodeValue()))
		{
			System.out.println("The second part of Text's split text failed!") ;
			OK = false;	
		}




//************************************************* ERROR TESTS
	DTest tests = new DTest();		
	//!! Throws INDEX_SIZE_ERR ********************
	//	text.splitText(-1);
	//	text.splitText(100);
	
// For debugging*****		println("All Text method calls worked correctly.");
	if (!OK)
		System.out.println("\n*****The Text method calls listed above failed, all others worked correctly.*****");
	
//	println("");
}
/**
 * 
 * @param node org.w3c.dom.Node
 * @param node2 org.w3c.dom.Node
 *
 * @author Philip W. Davis
 */
public boolean treeCompare(Node node, Node node2)
{
	boolean answer = true;
		
	Node kid, kid2;			// Check the subtree for equality
	kid = node.getFirstChild();
	kid2 = node2.getFirstChild();
	if (kid != null && kid2 != null)
	{
		answer = treeCompare(kid, kid2);
		if (!answer)
			return answer;
		else
			if (kid.getNextSibling() != null && kid2.getNextSibling() != null)
			{
				while (kid.getNextSibling() != null && kid2.getNextSibling() != null)
				{
					answer = treeCompare(kid.getNextSibling(), kid2.getNextSibling());
					if (!answer)
						return answer;
					else
					{
						kid = kid.getNextSibling();
						kid2 = kid2.getNextSibling();
					}
				}
			} else
				if (!(kid.getNextSibling() == null && kid2.getNextSibling() == null))
				{
					return false;
				}
	} else
		if (kid != kid2)
		{
			return false;
		}

	// Check nodes for equality, both their name and value or lack thereof
	if (!(node.getNodeName().equals(node2.getNodeName()) &&		    // Compares node names for equality
	     (node.getNodeValue() != null && node2.getNodeValue() != null)  // Checks to make sure each node has a value node
	    ? node.getNodeValue().equals(node2.getNodeValue()) 		    // If both have value nodes test those value nodes for equality
	    :(node.getNodeValue() == null && node2.getNodeValue() == null)))// If one node doesn't have a value node make sure both don't
	{
		return false;	// Return false if "any" of the above conditions are false
	}
	return answer;
}
}
