/*******************************************************************************
 * Copyright (c) 2002-2005 IBM Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   IBM - Initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.wsi.internal.core.xml;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import org.eclipse.wst.wsi.internal.core.WSIException;
import org.eclipse.wst.wsi.internal.core.WSITag;
import org.eclipse.wst.wsi.internal.core.util.NullUtil;
import org.w3c.dom.Attr;
import org.w3c.dom.CharacterData;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;

import com.ibm.wsdl.util.StringUtils;

/**
 * Set of XML related utilities.
 * 
 * @version 1.0.1
 * @author Peter Brittenham
 */
public final class XMLUtils
{
	/**
	 * Some sax features that need to be set.
	 */
	public static final String FEATURE_NAMESPACE_PREFIXES = "http://xml.org/sax/features/namespace-prefixes";
	public static final String FEATURE_NAMESPACES = "http://xml.org/sax/features/namespaces";
	public static final String FEATURE_VALIDATION_SCHEMA = "http://apache.org/xml/features/validation/schema";
	public static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
	public static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
	public static final String W3C_SOAP_12_SCHEMA = "http://schemas.xmlsoap.org/soap/envelope/";
	public static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";
	public static final String PROPERTY_EXTERNAL_SCHEMA_LOCATION = "http://apache.org/xml/properties/schema/external-schemaLocation";

	public static final String SOAP_ELEM_ENVELOPE = "Envelope";
	public static final String SOAP_ELEM_HEADER = "Header";
	public static final String SOAP_ELEM_BODY = "Body";
	public static final String SOAP_ELEM_FAULT = "Fault";
	public static final String SOAP_ELEM_FAULT_CODE = "faultcode";
	public static final String SOAP_ELEM_FAULT_STRING = "faultstring";
	public static final String SOAP_ELEM_FAULT_DETAIL = "detail";
	public static final String SOAP_ELEM_FAULT_ACTOR = "faultactor";
	public static final String SOAP_ATTR_MUST_UNDERSTAND = "mustUnderstand";
	public static final String SOAP_ATTR_ACTOR = "actor";

	/**
	 * Get XMLReader.
	 * 
	 * @return the XMLReader value
	 * @throws WSIException if there are problems getting the XMLReader
	 *           implementation.
	 */
	public static XMLReader getXMLReader() throws WSIException {
		XMLReader xmlReader = null;

		try
		{
			xmlReader = (new org.apache.xerces.jaxp.SAXParserFactoryImpl())
					.newSAXParser().getXMLReader();

			// Set namespace aware
			xmlReader.setFeature(FEATURE_NAMESPACE_PREFIXES, true);
			xmlReader.setFeature(FEATURE_NAMESPACES, true);
		}

		catch (Exception e)
		{
			throw new WSIException("Could not get XMLReader implementation.", e);
		}

		return xmlReader;
	}

	/**
	 * Parse text string as an XML document and return the document element.
	 * 
	 * @param text XML document text.
	 * @param validate true if the document will be validate, false otherwise
	 * @return a Document object.
	 * @throws WSIException if there is a problem parsing the XML document.
	 */
	public static Document parseXML(String text, boolean validate)
			throws WSIException {
		return parseXML(new StringReader(text), validate);
	}

	/**
	 * Parse text string as an XML document and return the document element.
	 * 
	 * @param text XML document text.
	 * @return a Document object.
	 * @throws WSIException if there is a problem parsing the XML document.
	 */
	public static Document parseXML(String text) throws WSIException {
		return parseXML(new StringReader(text));
	}

	/**
	 * Parse the XML document and return the document element.
	 * 
	 * @param uri the location of the XML document.
	 * @return a Document object.
	 * @throws WSIException if there is a problem parsing the XML document.
	 * @throws IOException if an I/O exception of some sort has occurred.
	 */
	public static Document parseXMLDocument(String uri) 
	throws WSIException, IOException 
	{
		return parseXMLDocument(uri, null);
	}

	/**
	 * Parse the XML document and return the document element.
	 * 
	 * @param uri the location of the XML document.
	 * @param schema a String identifying related schema document.
	 * @return a Document object.
	 * @throws WSIException if there is a problem parsing the XML document.
	 * @throws IOException if an I/O exception of some sort has occurred.
	 */
	public static Document parseXMLDocument(String uri, String schema)
	throws WSIException, IOException 
	{
	      URL url = StringUtils.getURL(null, uri);
	      InputStream inputStream = (InputStream)url.getContent();
	      InputSource inputSource = new InputSource(inputStream);
	      inputSource.setSystemId(url.toString());
	      
	      if (schema == null)
	      	return parseXML(inputSource, false);
	      else
            return parseXML(inputSource, schema);
	}

	/**
	 * Parses an XML document from a reader and returns the document object.
	 * 
	 * @param url a String locating the XML document.
	 * @param schema a String identifying related schema document.
	 * @param baseURI a base url to assist in locating the XML document.
	 * @return Document.
	 * @throws WSIException if there is a problem parsing the XML document.
	 */
	public static Document parseXMLDocumentURL(String url, String schema,
			String baseURI) throws WSIException {
		Document document = null;

		try
		{
			document = parseXMLDocumentURL(createURL(url, baseURI), schema);
		}

		catch (Exception e)
		{
			throw new WSIException(e.getMessage(), e);
		}

		return parseXMLDocumentURL(url, schema);
	}

	/**
	 * Parses an XML document from a reader and returns the document object.
	 * 
	 * @param url a URL object identifying the XML document.
	 * @param schema a String identifying related schema document.
	 * @return Document.
	 * @throws WSIException if there is a problem parsing the XML document.
	 */
	public static Document parseXMLDocumentURL(URL url, String schema)
			throws WSIException {
		try
		{
	      InputStream inputStream = (InputStream)url.getContent();
	      InputSource inputSource = new InputSource(inputStream);
	      inputSource.setSystemId(url.toString());

			Document doc = null;

			if (schema == null)
				doc = parseXML(inputSource);
			else
				doc = parseXML(inputSource, schema);

			inputStream.close();
			return doc;
		}

		catch (WSIException e)
		{
			throw e;
		}

		catch (Throwable t)
		{
			throw new WSIException(t.getMessage());
		}
	}

	/**
	 * Parses an XML document from a reader and returns the document object.
	 * 
	 * @param urlString a String locating the XML document.
	 * @param baseURI a base url to assist in locating the XML document.
	 * @return Document object.
	 * @throws WSIException if there is a problem parsing the XML document.
	 */
	public static Document parseXMLDocumentURL(String urlString, String baseURI)
			throws WSIException {
		Document document = null;

		try
		{
			URL url = createURL(urlString, baseURI);

			document = parseXMLDocumentURL(url);
		}

		catch (WSIException we)
		{
			throw we;
		}

		catch (Exception e)
		{
			throw new WSIException(e.getMessage(), e);
		}

		return document;
	}

	/**
	 * Parses an XML document from a reader and returns the document object.
	 * 
	 * @param url a URL object identifying the XML document.
	 * @return Document.
	 * @throws WSIException if there is a problem parsing the XML document.
	 */
	public static Document parseXMLDocumentURL(URL url) throws WSIException {
		Document document = null;

		try
		{
			Reader reader = new InputStreamReader(url.openStream());
			InputSource source = new InputSource(reader);
			source.setSystemId(url.toString());
			document = parseXML(source);

			reader.close();
		}

		catch (Exception e)
		{
			throw new WSIException(e.getMessage(), e);
		}

		return document;
	}

	/**
	 * Parse an XML document from a reader and return the document object.
	 * 
	 * @param reader a Reader object.
	 * @param validate true if the document will be validate, false otherwise
	 * @return a Document object.
	 * @throws WSIException if there is a problem parsing the XML document.
	 */
	public static Document parseXML(InputSource source, boolean validate)
			throws WSIException {
		Document doc = null;

		// Get the document factory
		DocumentBuilderFactory factory = new org.eclipse.wst.wsi.internal.core.xml.jaxp.DocumentBuilderFactoryImpl();

		// Set namespace aware, but for now do not validate
		factory.setNamespaceAware(true);
		factory.setIgnoringElementContentWhitespace(true);

		// ADD: This should be set to true when we have access to the schema
		// document
		factory.setValidating(validate);

		try
		{
			// Parse the document
			DocumentBuilder builder = factory.newDocumentBuilder();
			doc = builder.parse(source);
			// workaround for compatibility Xerces 2.2.1 with Xerces 2.6.2,
			// Xerces 2.6.2 supported XML 1.1 but WSI-tool and Xerces 2.2.1
			// supported only XML 1.0
			if (doc instanceof org.apache.xerces.dom.DocumentImpl)
			{
				if (((org.apache.xerces.dom.DocumentImpl) doc).getXmlVersion().equals(
						"1.1"))
				{
					throw new WSIException("Fatal Error: XML version &quot;1.1&quot; "
							+ "is not supported, only XML 1.0 is supported.");
				}
			}
		}

		catch (Exception e)
		{
			throw new WSIException("Could not parse XML document.", e);
		}

		// Return document
		return doc;
	}

	/**
	 * Parse an XML document from a reader and return the document object.
	 * 
	 * @param reader a Reader object.
	 * @param validate true if the document will be validate, false otherwise
	 * @return a Document object.
	 * @throws WSIException if there is a problem parsing the XML document.
	 */
	public static Document parseXML(Reader reader, boolean validate)
			throws WSIException {
		Document doc = null;
		ClassLoader currentLoader = Thread.currentThread().getContextClassLoader();   
		try
		{
		  Thread.currentThread().setContextClassLoader(XMLUtils.class.getClassLoader());   
		  ClassLoader tempLoader = Thread.currentThread().getContextClassLoader();
		
		  // Create input source
		  InputSource inputSource = new InputSource(reader);

		  // Get the document factory
		  DocumentBuilderFactory factory = new org.eclipse.wst.wsi.internal.core.xml.jaxp.DocumentBuilderFactoryImpl();

		  // Set namespace aware, but for now do not validate
		  factory.setNamespaceAware(true);
		  factory.setIgnoringElementContentWhitespace(true);

		  // ADD: This should be set to true when we have access to the schema
		  // document
		  factory.setValidating(validate);

		  // Parse the document
		  DocumentBuilder builder = factory.newDocumentBuilder();
		  doc = builder.parse(inputSource);
	   	  // workaround for compatibility Xerces 2.2.1 with Xerces 2.6.2,
		  // Xerces 2.6.2 supported XML 1.1 but WSI-tool and Xerces 2.2.1
		  // supported only XML 1.0
		  if (doc instanceof org.apache.xerces.dom.DocumentImpl)
		  {
			if (((org.apache.xerces.dom.DocumentImpl) doc).getXmlVersion().equals(
						"1.1"))
			{
			  throw new WSIException("Fatal Error: XML version &quot;1.1&quot; "
							+ "is not supported, only XML 1.0 is supported.");
			}
	      }
		}
		catch (Exception e)
		{
			throw new WSIException("Could not parse XML document.", e);
		}
	    finally
	    { 
	      Thread.currentThread().setContextClassLoader(currentLoader);
	    }    

		// Return document
		return doc;
	}

	/**
	 * Parse an XML document from a input source and return the document object.
	 * 
	 * @param source a InputSource object.
	 * @return a Document object.
	 * @throws WSIException if there is a problem parsing the XML document.
	 */
	public static Document parseXML(Reader reader) throws WSIException {
		return parseXML(reader, false);
	}

	/**
	 * Parse an XML document from a input source and return the document object.
	 * 
	 * @param source a InputSource object.
	 * @return a Document object.
	 * @throws WSIException if there is a problem parsing the XML document.
	 */
	public static Document parseXML(InputSource source) throws WSIException {
		return parseXML(source, false);
	}

	/**
	 * Parse text string as an XML document and return the document element.
	 * 
	 * @param text XML document text.
	 * @param schema a String identifying related schema document.
	 * @return a Document object.
	 * @throws WSIException if there is a problem parsing the XML document.
	 */
	public static Document parseXML(String text, String schema)
			throws WSIException {
		return parseXML(new StringReader(text), schema);
	}

	/**
	 * Parse text string as an XML document and return the document element.
	 * 
	 * @param text XML document text.
	 * @param schemas a collection of related schema documents.
	 * @return a Document object.
	 * @throws WSIException if there is a problem parsing the XML document.
	 */
	public static Document parseXML(String text, Collection schemas)
			throws WSIException {
		return parseXML(new StringReader(text), schemas);
	}


	/**
	 * Parse the XML document and return the document element.
	 * 
	 * @param text XML document text.
	 * @param schemaString a StringReader object.
	 * @return a Document object.
	 * @throws WSIException if there is a problem parsing the XML document.
	 * @throws IOException if an I/O exception of some sort has occurred.
	 */
	public static Document parseXML(String text, StringReader schemaString)
			throws WSIException, IOException {
		return parseXML(new StringReader(text), schemaString);
	}

	/**
	 * Parse the XML document and return the document element.
	 * 
	 * @param reader a Reader object.
	 * @param schema a String identifying related schema document.
	 * @return a Document object.
	 * @throws WSIException if there is a problem parsing the XML document.
	 */
	public static Document parseXML(Reader reader, String schema)
			throws WSIException {
		Document doc = null;
		ClassLoader currentLoader = Thread.currentThread().getContextClassLoader();   
		try
		{
    	  Thread.currentThread().setContextClassLoader(XMLUtils.class.getClassLoader());   
		  // Create input source
		  InputSource inputSource = new InputSource(reader);

		  // Get the document factory
		  DocumentBuilderFactory factory = new org.eclipse.wst.wsi.internal.core.xml.jaxp.DocumentBuilderFactoryImpl();

		  // Set namespace aware, but for now do not validate
		  factory.setNamespaceAware(true);
		  factory.setIgnoringElementContentWhitespace(true);

		  try
		  {
		    factory.setValidating(true);
			factory.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
 		  }
   		  catch (IllegalArgumentException e)
		  {
			String errMessage = "Error: JAXP DocumentBuilderFactory attribute not recognized: "
					+ JAXP_SCHEMA_LANGUAGE
					+ "\n"
					+ "Check to see if parser conforms to JAXP 1.2 spec.";
			throw new WSIException(errMessage, e);
		  }
		  factory.setAttribute(JAXP_SCHEMA_SOURCE, new InputSource(schema));

		  // Parse the document
		  DocumentBuilder builder = factory.newDocumentBuilder();
		  builder.setErrorHandler(new ErrHandler());
		  doc = builder.parse(inputSource);

		  // workaround for compatibility Xerces 2.2.1 with Xerces 2.6.2,
		  // Xerces 2.6.2 supported XML 1.1 but WSI-tool and Xerces 2.2.1
		  // supported only XML 1.0
		  if (doc instanceof org.apache.xerces.dom.DocumentImpl)
		  {
			if (((org.apache.xerces.dom.DocumentImpl) doc).getXmlVersion().equals("1.1"))
			{
		 	  throw new WSIException("Fatal Error: XML version &quot;1.1&quot; "
							+ "is not supported, only XML 1.0 is supported.");
			}
		  }
	    }
		catch (Exception e)
		{
			throw new WSIException("Could not parse XML document.", e);
		}
	    finally
	    { 
	      Thread.currentThread().setContextClassLoader(currentLoader);
	    }    
		// Return document
    	return doc;
	}

	/**
	 * Parse the XML document and return the document element.
	 * 
	 * @param reader a Reader object.
	 * @param schema a String identifying related schema document.
	 * @return a Document object.
	 * @throws WSIException if there is a problem parsing the XML document.
	 */
	public static Document parseXML(InputSource source, String schema)
			throws WSIException {
		Document doc = null;
		// Get the document factory
		DocumentBuilderFactory factory = new org.eclipse.wst.wsi.internal.core.xml.jaxp.DocumentBuilderFactoryImpl();

		// Set namespace aware, but for now do not validate
		factory.setNamespaceAware(true);
		factory.setIgnoringElementContentWhitespace(true);

		factory.setValidating(true);
		try
		{
			factory.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
		}

		catch (IllegalArgumentException e)
		{
			String errMessage = "Error: JAXP DocumentBuilderFactory attribute not recognized: "
					+ JAXP_SCHEMA_LANGUAGE
					+ "\n"
					+ "Check to see if parser conforms to JAXP 1.2 spec.";
			throw new WSIException(errMessage, e);
		}
		factory.setAttribute(JAXP_SCHEMA_SOURCE, new InputSource(schema));

		try
		{
			// Parse the document
			DocumentBuilder builder = factory.newDocumentBuilder();
			builder.setErrorHandler(new ErrHandler());
			doc = builder.parse(source);

			// workaround for compatibility Xerces 2.2.1 with Xerces 2.6.2,
			// Xerces 2.6.2 supported XML 1.1 but WSI-tool and Xerces 2.2.1
			// supported only XML 1.0
			if (doc instanceof org.apache.xerces.dom.DocumentImpl)
			{
				if (((org.apache.xerces.dom.DocumentImpl) doc).getXmlVersion().equals(
						"1.1"))
				{
					throw new WSIException("Fatal Error: XML version &quot;1.1&quot; "
							+ "is not supported, only XML 1.0 is supported.");
				}
			}
		}

		catch (Exception e)
		{
			throw new WSIException("Could not parse XML document.", e);
		}

		// Return document
		return doc;

	}

	/**
	 * Parse the XML document and return the document element.
	 * 
	 * @param filename a Reader object.
	 * @param schemaString a StringReader object.
	 * @return a Document object.
	 * @throws WSIException if there is a problem parsing the XML document.
	 */
	public static Document parseXML(Reader filename, StringReader schemaString)
			throws WSIException {

		Document doc = null;

		// Create input source
		InputSource inputSource = new InputSource(filename);

		// Get the document factory
		DocumentBuilderFactory factory = new org.eclipse.wst.wsi.internal.core.xml.jaxp.DocumentBuilderFactoryImpl();

		// Set namespace aware, but for now do not validate
		factory.setNamespaceAware(true);
		factory.setIgnoringElementContentWhitespace(true);

		factory.setValidating(true);
		try
		{
			factory.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
		} catch (IllegalArgumentException e)
		{
			String errMessage = "Error: JAXP DocumentBuilderFactory attribute not recognized: "
					+ JAXP_SCHEMA_LANGUAGE
					+ "\n"
					+ "Check to see if parser conforms to JAXP 1.2 spec.";
			throw new WSIException(errMessage, e);
		}
		factory.setAttribute(JAXP_SCHEMA_SOURCE, new InputSource(schemaString));
		try
		{
			// Parse the document
			DocumentBuilder builder = factory.newDocumentBuilder();
			builder.setErrorHandler(new ErrHandler());
			doc = builder.parse(inputSource);
		} catch (Exception e)
		{
			throw new WSIException("Could not parse XML document.", e);
		}

		// Return document
		return doc;

	}

	/**
	 * Parse the XML document and return the document element.
	 * 
	 * @param filename a Reader object
	 * @param schemaStrings a collection of related schema documents.
	 * @return a Document object.
	 * @throws WSIException if there is a problem parsing the XML document.
	 */
	public static Document parseXML(Reader filename, Collection schemaStrings)
			throws WSIException {

		Document doc = null;

		// Create input source
		InputSource inputSource = new InputSource(filename);

		// Get the document factory
		DocumentBuilderFactory factory = new org.eclipse.wst.wsi.internal.core.xml.jaxp.DocumentBuilderFactoryImpl();

		// Set namespace aware, but for now do not validate
		factory.setNamespaceAware(true);
		factory.setIgnoringElementContentWhitespace(true);

		factory.setValidating(true);
		try
		{
			factory.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
		} catch (IllegalArgumentException e)
		{
			String errMessage = "Error: JAXP DocumentBuilderFactory attribute not recognized: "
					+ JAXP_SCHEMA_LANGUAGE
					+ "\n"
					+ "Check to see if parser conforms to JAXP 1.2 spec.";
			throw new WSIException(errMessage, e);
		}
		// convert schema strings to array of InputSources
		Iterator i = schemaStrings.iterator();
		Vector readers = new Vector();
		while (i.hasNext())
		{
			String nextSchema = (String) i.next();
			readers.add(new InputSource(new StringReader(nextSchema)));
		}
		InputSource[] inputSources = (InputSource[]) readers
				.toArray(new InputSource[]{});
		// pass an array of schema strings (each of which contains a schema)
		factory.setAttribute(JAXP_SCHEMA_SOURCE, inputSources);

		try
		{
			// Parse the document
			DocumentBuilder builder = factory.newDocumentBuilder();
			builder.setErrorHandler(new ErrHandler());
			doc = builder.parse(inputSource);
		} catch (Exception e)
		{
			throw new WSIException("Could not parse XML document.", e);
		}

		// Return document
		return doc;

	}

	/**
	 * Get attribute value with the given name defined for the specified element.
	 * 
	 * @param element an Element object.
	 * @param attrName a name of an attribute
	 * @return the attribute value.
	 */
	public static String getAttributeValue(Element element, String attrName) {
		String attrValue = null;
		Attr attr = null;

		// Get the attribute using its name
		if ((attr = element.getAttributeNode(attrName)) != null)
		{
			attrValue = attr.getValue().trim();
		}

		// Return attribute value
		return attrValue;
	}

	/**
	 * Get attribute value.
	 * 
	 * @param element an Element object.
	 * @param attrName a name of an attribute
	 * @param defaultValue a default value for the specified attribute.
	 * @return the attribute value if found. Otherwise the specified default
	 *         value.
	 */
	public static String getAttributeValue(Element element, String attrName,
			String defaultValue) {
		String returnValue = defaultValue;
		String attrValue = null;

		if ((attrValue = getAttributeValue(element, attrName)) != null)
			returnValue = attrValue;

		return returnValue;
	}

	/**
	 * Get attribute value.
	 * 
	 * @param element an Element object.
	 * @param namespace a namespace.
	 * @param attrName a name of an attribute
	 * @return the attribute value.
	 */
	public static String getAttributeValueNS(Element element, String namespace,
			String attrName) {
		String attrValue = null;
		Attr attr = null;

		// Get the attribute using its name
		if ((attr = element.getAttributeNodeNS(namespace, attrName)) != null)
		{
			attrValue = attr.getValue().trim();
		}

		// Return attribute value
		return attrValue;
	}

	/**
	 * Get the first child element from the input elment.
	 * 
	 * @param element an Element object.
	 * @return the firstchild element.
	 */
	public static Element getFirstChild(Element element) {
		// Return the first child element
		return findNextSibling(element.getFirstChild());
	}

	/**
	 * Get the next sibling element.
	 * 
	 * @param element - an Element object.
	 * @return the next sibling element.
	 */
	public static Element getNextSibling(Element element) {
		// Return next sibling element
		return findNextSibling(element.getNextSibling());
	}

	/**
	 * Find the next sibling element.
	 * 
	 * @param startNode XML start node.
	 * @return the next sibling element.
	 */
	protected static Element findNextSibling(Node startNode) {
		Node node = null;
		Element returnElement = null;

		// Find the next sibling element
		for (node = startNode; node != null && returnElement == null; node = node
				.getNextSibling())
		{
			// If this node is an element node, then return it
			if (node.getNodeType() == Node.ELEMENT_NODE)
			{
				returnElement = (Element) node;
			}
		}

		// Return next sibling element
		return (Element) returnElement;
	}

	/**
	 * Find the previous sibling element.
	 * 
	 * @param startNode XML start node.
	 * @return the previous sibling element.
	 */
	public static Element findPreviousSibling(Node startNode) {
		if (startNode == null)
			return null;

		while (startNode != null)
		{
			startNode = startNode.getPreviousSibling();
			if (startNode == null)
				return null;
			if (startNode.getNodeType() == Node.ELEMENT_NODE)
				return (Element) startNode;
		}

		return null;
	}

	/**
	 * Get the text that is associated with this element.
	 * 
	 * @param element an Element object.
	 * @return the text that is associated with this element.
	 */
	public static String getText(Element element) {
		String text = null;

		// Get first child element
		Node node = element.getFirstChild();

		// NodeList nodeList = element.getChildNodes();

		// int length = nodeList.getLength();

		// Process while there are nodes and the text hasn't been found
		while ((node != null) && (text == null))
		{
			// If a text node or cdata section is found, then get text
			if ((node.getNodeType() == Node.TEXT_NODE)
					|| (node.getNodeType() == Node.CDATA_SECTION_NODE))
			{
				text = ((CharacterData) node).getData();
			}

			// Get next sibling
			node = node.getNextSibling();
		}

		if (text != null)
			text = text.trim();

		return text;
	}

	/**
	 * Determine if an element is represented by the QName.
	 * 
	 * @param qname a QName object.
	 * @param element an Element object.
	 * @return true if an element is represented by the QName.
	 */
	public static boolean equals(QName qname, Element element) {
		boolean equals = false;

		// If both the namespace URI and local name are the same, then they are
		// equal
		if ((qname.getNamespaceURI().equals(element.getNamespaceURI()))
				&& (qname.getLocalPart().equals(element.getLocalName())))
		{
			equals = true;
		}

		return equals;
	}

	/**
	 * XML encode a text string.
	 * 
	 * @param text - a String.
	 * @return an XML encoded text string.
	 */
	public static String xmlEscapedString(String text) 
	{
	  if (text == null) return text;
	  else
	  {
	    StringBuffer sb = new StringBuffer(text.length()*2);
	    int size = text.length();
	    for (int i=0; i<size; i++)
	    {
	      char c = text.charAt(i);
	      switch (c)
		  {
             case '<': 
               sb.append("&lt;");
               break;
             case '>': 
             	sb.append("&gt;");
                break;
             case '&': 
             	sb.append("&amp;");
                break;
             case '"': 
             	sb.append("&quot;");
                break;
             case '\'': 
             	sb.append("&apos;");
                break;
             case '\r': 
             	sb.append("&#xd;");
                break;
             default:
             	sb.append(c);
		  }
		}
	    return  sb.toString();
	  }
	}

	/**
	 * XML encode a text string.
	 * 
	 * @param text - a String.
	 * @return an XML encoded text string.
	 */
	public static String xmlRemoveEscapedString(String text) 
	{
	  if (text == null) return text;
	  else
	  {
        StringBuffer sb = new StringBuffer(text);
      
	    int i = sb.indexOf("&#xd;");
	    while(i != -1)
	    {
	      sb.replace(i, i+5, "\r");
	      i = sb.indexOf("&#xd;");
	    }
	    
	    i = sb.indexOf("&lt;");
	    while(i != -1)
	    {
	      sb.replace(i, i+4, "<");
	      i = sb.indexOf("&lt;");
	    }

	    i = sb.indexOf("&gt;");
	    while(i != -1)
	    {
	      sb.replace(i, i+4, ">");
	      i = sb.indexOf("&gt;");
	    }

	    i = sb.indexOf("&quot;");
	    while(i != -1)
	    {
	      sb.replace(i, i+6, "\"");
	      i = sb.indexOf("&quot;");
	    }

	    i = sb.indexOf("&apos;");
	    while(i != -1)
	    {
	      sb.replace(i, i+6, "\'");
	      i = sb.indexOf("&apos;");
	    }

	    i = sb.indexOf("&amp;");
	    while(i != -1)
	    {
	      sb.replace(i, i+5, "&");
	      i = sb.indexOf("&amp;");
	    }
 	    return  sb.toString();
	  }
	}
	/**
	 * Get the specified element from a parent element.
	 * 
	 * @param elementName the element tag to serach for.
	 * @param parentElement the parent element.
	 * @return an element given the name and the parent element.
	 */
	public static Element getElement(String elementName, Element parentElement) {
		Element returnElement = null;
		NodeList nl;

		// Get the list of elements
		if ((nl = parentElement.getElementsByTagName(elementName)) != null)
		{
			// Return first element found
			returnElement = (Element) nl.item(0);
		}

		// Return element
		return returnElement;
	}

	/**
	 * Determine if this element matches specified local name in the specified
	 * namespace.
	 * 
	 * @param element an Element object.
	 * @param namespaceURI a namespace.
	 * @param localName a local name.
	 * @return true if this element matches specified local name in the specified
	 *         namespace.
	 */
	public static boolean isElement(Element element, String namespaceURI,
			String localName) {
		boolean isElement = false;

		if (element != null)
		{
			// Check is
			if (element.getNamespaceURI().equals(namespaceURI)
					&& element.getLocalName().equals(localName))
			{
				isElement = true;
			}
		}

		return isElement;
	}

	/**
	 * Determine if this element matches specified local name in the specified
	 * namespace.
	 * 
	 * @param element an Element object.
	 * @param namespaceURIs a list of valid namespaces.
	 * @param localName a local name.
	 * @return true if this element matches specified local name in the specified
	 *         namespace.
	 */
	public static boolean isElement(Element element, List namespaceURIs,
			String localName) {
		boolean isElement = false;

		if (element != null)
		{
			// Check is
			if (namespaceURIs.contains(element.getNamespaceURI())
					&& element.getLocalName().equals(localName))
			{
				isElement = true;
			}
		}

		return isElement;
	}

	/**
	 * Get element text as a boolean.
	 * 
	 * @param element an Element object.
	 * @param defaultValue a boolean to be used as a default value.
	 * @return element text as a boolean value.
	 */
	public static boolean getBooleanValue(Element element, boolean defaultValue) {
		boolean returnValue = defaultValue;
		String booleanValue = null;

		// Get value as a string
		if ((booleanValue = XMLUtils.getText(element)) != null)
		{
			returnValue = Boolean.valueOf(booleanValue).booleanValue();
		}

		// Return boolean
		return returnValue;
	}

	/**
	 * Get attribute value as a boolean.
	 * 
	 * @param element an Element object.
	 * @param attrName a name of an attribute.
	 * @param defaultValue a boolean to be used as a default value.
	 * @return attribute value as a boolean.
	 */
	public static boolean getBooleanValue(Element element, String attrName,
			boolean defaultValue) {
		boolean returnValue = defaultValue;
		String booleanValue = null;

		// Get value as a string
		if ((booleanValue = XMLUtils.getAttributeValue(element, attrName)) != null)
		{
			returnValue = Boolean.valueOf(booleanValue).booleanValue();
		}

		// Return boolean
		return returnValue;
	}

	/**
	 * Create QName.
	 * 
	 * @param qnameString a qualified name.
	 * @return a QName object.
	 */
	public static QName createQName(String qnameString) {
		QName qname = null;

		// Locate local part
		int index = qnameString.lastIndexOf(":");

		// Create new QName
		if (index != -1)
		{
			qname = new QName(qnameString.substring(0, index), qnameString
					.substring(index + 1));
		}

		else
		{
			qname = new QName(qnameString);
		}

		return qname;
	}

	/**
	 * Error Handler
	 */
	private static class ErrHandler implements ErrorHandler
	{
		/**
		 * Warning
		 */
		public void warning(SAXParseException spe) throws SAXException {
			String message = "Warning: " + spe.getMessage();
			throw new SAXException(message);
		}

		/**
		 * Error
		 */
		public void error(SAXParseException spe) throws SAXException {
			String message = "Error: " + spe.getMessage();
			throw new SAXException(message);
		}

		/**
		 * Fatal Error
		 */
		public void fatalError(SAXParseException spe) throws SAXException {
			String message = "Fatal Error: " + spe.getMessage();
			throw new SAXException(message);
		}
	}

	/**
	 * Determine if the string is a NMTOKEN data type.
	 * 
	 * @param text a string value.
	 * @return true if the string is a NMTOKEN data type.
	 */
	public static boolean isNmtoken(String text) {
		boolean nmtoken = true;

		// ADD: Need to find a utility function that does this or write it from
		// scratch

		return nmtoken;
	}

	/**
	 * The method searches the first direct descendant element with the given
	 * qname.
	 * 
	 * @param parent parent DOM element.
	 * @param elementName QName of the element to be searched.
	 * @return DOM element if the required element found, and null otherwise.
	 */
	static public Element findChildElement(Element parent, QName elementName) {
		if (parent == null)
			throw new IllegalArgumentException("Parent element can not be NULL");
		if (elementName == null)
			throw new IllegalArgumentException("Element name can not be NULL");
		if (elementName.getLocalPart() == null)
			throw new IllegalArgumentException(
					"Local part of the element name can not be NULL");

		Node n = parent.getFirstChild();
		String local = elementName.getLocalPart();
		String ns = elementName.getNamespaceURI();
		while (n != null)
		{
			if (Node.ELEMENT_NODE == n.getNodeType()
					&& local.equals(n.getLocalName())
					&& NullUtil.equals(ns, n.getNamespaceURI()))
				return (Element) n;
			n = n.getNextSibling();
		}

		return null;
	}

	/**
	 * The method searches the first sibling element with the given qname.
	 * 
	 * @param active DOM element.
	 * @param elementName QName of the element to be searched.
	 * @return DOM element if the required element found, and null otherwise.
	 */
	static public Element findElement(Element active, QName elementName) {
		if (active == null)
			throw new IllegalArgumentException("Active element can not be NULL");
		if (elementName == null)
			throw new IllegalArgumentException("Element name can not be NULL");
		if (elementName.getLocalPart() == null)
			throw new IllegalArgumentException(
					"Local part of the element name can not be NULL");

		Node n = active.getNextSibling();
		String local = elementName.getLocalPart();
		String ns = elementName.getNamespaceURI();
		while (n != null)
		{
			if (Node.ELEMENT_NODE == n.getNodeType()
					&& local.equals(n.getLocalName())
					&& NullUtil.equals(ns, n.getNamespaceURI()))
				return (Element) n;
			n = n.getNextSibling();
		}

		return null;
	}

	/**
	 * The method returns attribute node by the given qname.
	 * 
	 * @param el owner element.
	 * @param attributeName QName of the attribute node to be searched.
	 * @return attribute node by the given qname.
	 */
	static public Attr getAttribute(Element el, QName attributeName) {
		if (el == null)
			throw new IllegalArgumentException("Element can not be NULL");
		if (attributeName == null)
			throw new IllegalArgumentException("Attribute name can not be NULL");
		if (attributeName.getLocalPart() == null)
			throw new IllegalArgumentException(
					"Local part of the attribute name can not be NULL");

		Attr a = el.getAttributeNodeNS(attributeName.getNamespaceURI(),
				attributeName.getLocalPart());
		if (a == null)
			// try to get with null namespace
			a = el.getAttributeNodeNS(null, attributeName.getLocalPart());
		return a;
	}

	/**
	 * The method compares node's name to the given qname.
	 * 
	 * @param n a node.
	 * @param name a QName object.
	 * @return true if the node's name is the same as the given qname.
	 */
	static public boolean equals(Node n, QName name) {
		if (n == null || name == null)
			return false;
		return (NullUtil.equals(name.getLocalPart(), n.getLocalName()) && NullUtil
				.equals(name.getNamespaceURI(), n.getNamespaceURI()));
	}

	/**
	 * The method searches namespace URI for the given prefix. The searching
	 * mechanism is implemented according to the "XML Namespaces resolution"
	 * algorithm ('http://www.w3.org/TR/2003/WD-DOM-Level-3-
	 * Core-20030226/namespaces-algorithms.html').
	 * 
	 * @param n a node.
	 * @param prefix a prefix.
	 * @return the namespace URI for the given prefix.
	 */
	static public String findNamespaceURI(Node n, String prefix) {
		if (prefix == null)
			return null;

		while (n != null)
		{
			if (prefix.equals(n.getPrefix()))
				return n.getNamespaceURI();

			if (Node.ELEMENT_NODE == n.getNodeType())
			{
				NamedNodeMap m = n.getAttributes();
				if (m != null)
					for (int i = 0; i < m.getLength(); i++)
					{
						Node a = m.item(i);
						if (WSITag.NS_URI_XMLNS.equals(a.getNamespaceURI())
								&& prefix.equals(a.getLocalName()))
							return a.getNodeValue();
					}
			}

			n = n.getParentNode();
		}

		return null;
	}

	/**
	 * Serializes element.
	 * 
	 * @param n a DOM element.
	 * @return the serialized element.
	 */
	public static String serialize(Element n) {
		String value = null;
		try
		{
			StringWriter writer = new StringWriter();
			XMLSerializer s = new XMLSerializer(writer, new OutputFormat("xml",
					"UTF-8", true));
			s.serialize(n);
			value = writer.toString();
			writer.close();
		} catch (Throwable t)
		{
			// nothing
			value = "EXCEPTION : " + t.getMessage();
		}

		return value;
	}

	/**
	 * The method return list of child elements.
	 * 
	 * @param parent an org.w3c.dom.Element object.
	 * @return list of child elements.
	 */
	static public Vector getChildElements(Element parent) {
		if (parent == null)
			throw new IllegalArgumentException("Element can not be NULL");

		Vector vect = new Vector();
		Element elem = getFirstChild(parent);
		while (elem != null)
		{
			vect.add(elem);
			elem = getNextSibling(elem);
		}
		return vect;
	}

	/**
	 * Serializes document.
	 * 
	 * @param doc an org.w3c.dom.Document object.
	 * @param writer a java.io.Writer object.
	 * @throws Exception if unable to serialize the document.
	 */
	public static void serializeDoc(Document doc, Writer writer)
			throws java.lang.Exception {
		XMLSerializer s = new XMLSerializer(writer, new OutputFormat("xml",
				"UTF-8", true));
		s.serialize(doc);
	}

	/**
	 * Serealizes element.
	 * 
	 * @param elem an org.w3c.dom.Element object.
	 * @param writer a java.io.Writer object.
	 * @throws Exception if unable to serialize the DOM element.
	 */
	public static void serializeElement(Element elem, Writer writer)
			throws java.lang.Exception {
		XMLSerializer s = new XMLSerializer(writer, new OutputFormat("xml",
				"UTF-8", true));
		s.serialize(elem);
	}

	/**
	 * Remove all elements from list without namespace.
	 * 
	 * @param vect a list of elements.
	 */
	public static void removeAllElementsWithoutNS(Vector vect) {
		for (int i = 0; i < vect.size();)
		{
			if (((Element) vect.get(i)).getNamespaceURI() == null
					|| ((Element) vect.get(i)).getNamespaceURI().equals(""))
				vect.remove(i);
			else
				i++;
		}
	}

	/**
	 * Create URL using base URI.
	 * 
	 * @param url a URL string.
	 * @param baseURI a base url string to assist in creating a URL.
	 * @return newly created URL.
	 * @throws MalformedURLException if a malformed URL has occurred.
	 */
	public static URL createURL(String url, String baseURI)
			throws MalformedURLException {
		URL returnURL = null;
		URI uri = null;
		try
		{
            returnURL = new URL(url);
			uri = new URI(url);
			uri = uri.normalize();
			returnURL =  new URL(uri.toString());
		}

		catch (Exception mue)
		{
			int i = baseURI.lastIndexOf('/');
			int j = baseURI.lastIndexOf('\\');
			if (j > i)
				i = j;
			try
			{
			  uri = new URI(baseURI.substring(0, i + 1) + url);
			  uri = uri.normalize();
			  returnURL = uri.toURL();
			}
			catch (Exception e)
			{
			  return new URL(baseURI.substring(0, i + 1) + url);
			}
		}
		return returnURL;
	}

	/**
	 * Create URL using base URI.
	 * 
	 * @param url a URL string.
	 * @param baseURI a base url string to assist in creating a URL.
	 * @return newly created URL string.
	 * @throws MalformedURLException if a malformed URL has occurred.
	 */
	public static String createURLString(String url, String baseURI)
			throws MalformedURLException {
		return createURL(url, baseURI).toExternalForm();
	}

	/**
	 * This method is used only for unit testing.
	 * 
	 * @param args arguments for main.
	 */
	public static void main(String[] args) {
		try
		{
			System.out.println("Filename: " + args[0] + ", schema: " + args[1]);
			Document doc = parseXMLDocument(args[0], args[1]);
			System.out.println("Done.");
		}

		catch (Exception e)
		{
			System.err.println(e.toString());
		}

		System.exit(0);
	}
}
