/*******************************************************************************
 * 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;
		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());   
		  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(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]);
			Document doc = parseXMLDocument(args[0], args[1]);
			System.out.println("Done.");
		}

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

		System.exit(0);
	}
}
