/*******************************************************************************
 * 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 {
		try
		{
		  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;
		ClassLoader currentLoader = Thread.currentThread().getContextClassLoader();   
		try
		{
    	  Thread.currentThread().setContextClassLoader(XMLUtils.class.getClassLoader());   

  		  // 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(false);

 		  // 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);
		}
	    finally
	    { 
	      Thread.currentThread().setContextClassLoader(currentLoader);
	    }    

		// 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());   
		
		  // 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(false);

		  // 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(false);
			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;
		ClassLoader currentLoader = Thread.currentThread().getContextClassLoader();   
		try
		{
    	  Thread.currentThread().setContextClassLoader(XMLUtils.class.getClassLoader());   
 		  // 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(false);
		  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));

          // 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);
		}
	    finally
	    { 
	      Thread.currentThread().setContextClassLoader(currentLoader);
	    }    

		// 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;
		ClassLoader currentLoader = Thread.currentThread().getContextClassLoader();   
		try
		{
    	  Thread.currentThread().setContextClassLoader(XMLUtils.class.getClassLoader());   

		  // 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(false);
		  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));

		  // 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);
		}
	    finally
	    { 
	      Thread.currentThread().setContextClassLoader(currentLoader);
	    }    

		// 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;
		ClassLoader currentLoader = Thread.currentThread().getContextClassLoader();   
		try
		{
    	  Thread.currentThread().setContextClassLoader(XMLUtils.class.getClassLoader());   

		  // 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(false);
		  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);

		  // 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);
		}
	    finally
	    { 
	      Thread.currentThread().setContextClassLoader(currentLoader);
	    }    

		// 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");

		attributeName.getNamespaceURI();
		attributeName.getLocalPart();
		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]);
		  parseXMLDocument(args[0], args[1]);
		  System.out.println("Done.");
		}

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

		System.exit(0);
	}
}
