/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package dom;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.w3c.dom.Attr;
import org.w3c.dom.CDATASection;
import org.w3c.dom.CharacterData;
import org.w3c.dom.Comment;
import org.w3c.dom.DOMException;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.Entity;
import org.w3c.dom.EntityReference;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Notation;
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.Text;

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.verify(DTest.DOMExceptionsTest(document, "appendChild", new Class[]{Node.class}, new Object[]{docBody}, DOMException.HIERARCHY_REQUEST_ERR )); 
	OK &= Assertion.verify(DTest.DOMExceptionsTest(docNode3, "appendChild", new Class[]{Node.class}, new Object[]{docNode4}, DOMException.HIERARCHY_REQUEST_ERR )); 
	OK &= Assertion.verify(DTest.DOMExceptionsTest(doc, "insertBefore", new Class[]{Node.class, Node.class}, new Object[]{docEntity, docFirstElement}, DOMException.HIERARCHY_REQUEST_ERR )); 
	OK &= Assertion.verify(DTest.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.verify(docFirstElement.getNodeValue() == null);
        docReferenceEntity.setNodeValue("This shouldn't do anything!");
	OK &= Assertion.verify(docReferenceEntity.getNodeValue() == null);
        docEntity.setNodeValue("This shouldn't do anything!");
	OK &= Assertion.verify(docEntity.getNodeValue() == null);
        doc.setNodeValue("This shouldn't do anything!");
	OK &= Assertion.verify(doc.getNodeValue() == null);
        docType.setNodeValue("This shouldn't do anything!");
	OK &= Assertion.verify(docType.getNodeValue() == null);
        docDocFragment.setNodeValue("This shouldn't do anything!");
	OK &= Assertion.verify(docDocFragment.getNodeValue() == null);
        docNotation.setNodeValue("This shouldn't do anything!");
	OK &= Assertion.verify(docNotation.getNodeValue() == null);

	OK &= Assertion.verify(DTest.DOMExceptionsTest(docReferenceEntity, "appendChild", new Class[]{Node.class}, new Object[]{entityReferenceText2 }, DOMException.NO_MODIFICATION_ALLOWED_ERR ));
	OK &= Assertion.verify(DTest.DOMExceptionsTest(docBodyLevel32, "insertBefore", new Class[]{Node.class, Node.class}, new Object[]{docTextNode11,docBody }, DOMException.NOT_FOUND_ERR ));
	OK &= Assertion.verify(DTest.DOMExceptionsTest(docBodyLevel32, "removeChild", new Class[]{Node.class}, new Object[]{docFirstElement}, DOMException.NOT_FOUND_ERR ));
	OK &= Assertion.verify(DTest.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.verify(
          DTest.DOMExceptionsTest(document.getDocumentElement(),
                                  "appendChild",
                                  new Class[]{Node.class},
                                  new Object[]{attributeNode},
                                  DOMException.HIERARCHY_REQUEST_ERR));

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

        Element element = (Element)document.getLastChild().getLastChild();
        // Tests setNamedItem
        Assertion.verify(
          DTest.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.verify(DTest.DOMExceptionsTest(charData, "deleteData", new Class[]{int.class, int.class}, 
			new Object[]{new Integer(-1),new Integer(5) }, DOMException.INDEX_SIZE_ERR ));
	OK &= Assertion.verify(DTest.DOMExceptionsTest(charData, "deleteData", new Class[]{int.class, int.class}, 
			new Object[]{new Integer(2),new Integer(-1) }, DOMException.INDEX_SIZE_ERR ));
	OK &= Assertion.verify(DTest.DOMExceptionsTest(charData, "deleteData", new Class[]{int.class, int.class}, 
			new Object[]{new Integer(100),new Integer(5) }, DOMException.INDEX_SIZE_ERR ));
	
	OK &= Assertion.verify(DTest.DOMExceptionsTest(charData, "insertData", new Class[]{int.class, String.class}, 
			new Object[]{new Integer(-1),"Stuff inserted" }, DOMException.INDEX_SIZE_ERR ));
	OK &= Assertion.verify(DTest.DOMExceptionsTest(charData, "insertData", new Class[]{int.class, String.class}, 
			new Object[]{new Integer(100),"Stuff inserted" }, DOMException.INDEX_SIZE_ERR ));
	
	OK &= Assertion.verify(DTest.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.verify(DTest.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.verify(DTest.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.verify(DTest.DOMExceptionsTest(charData, "substringData", new Class[]{int.class, int.class}, 
			new Object[]{new Integer(-1),new Integer(5) }, DOMException.INDEX_SIZE_ERR ));
	OK &= Assertion.verify(DTest.DOMExceptionsTest(charData, "substringData", new Class[]{int.class, int.class}, 
			new Object[]{new Integer(100),new Integer(5) }, DOMException.INDEX_SIZE_ERR ));
	OK &= Assertion.verify(DTest.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.verify(DTest.DOMExceptionsTest(node, "appendData", new Class[]{String.class}, 
			new Object[]{"new data" }, DOMException.NO_MODIFICATION_ALLOWED_ERR ));
	OK &= Assertion.verify(DTest.DOMExceptionsTest(node, "deleteData", new Class[]{int.class, int.class}, 
			new Object[]{new Integer(5),new Integer(10) }, DOMException.NO_MODIFICATION_ALLOWED_ERR ));
	OK &= Assertion.verify(DTest.DOMExceptionsTest(node, "insertData", new Class[]{int.class, String.class}, 
			new Object[]{new Integer(5),"Stuff inserted" }, DOMException.NO_MODIFICATION_ALLOWED_ERR ));
	OK &= Assertion.verify(DTest.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.verify(DTest.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.verify(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.verify(DTest.DOMExceptionsTest(document, "appendChild", new Class[]{Node.class}, new Object[]{testElementNode}, DOMException.HIERARCHY_REQUEST_ERR )); 
	OK &= Assertion.verify(DTest.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;
}
}
