/*******************************************************************************
 * Copyright (c) 2008 Standards for Technology in Automotive Retail
 * 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:
 *     David Carver - STAR - bug 224197 - initial API and implementation
 *                    based on work from Apache Xalan 2.7.0
 *******************************************************************************/
/*
 * Copyright 1999-2005 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * $Id: ElemLiteralResult.java,v 1.4 2008/03/28 02:38:15 dacarver Exp $
 */
package org.eclipse.wst.xsl.core.internal.compiler.xslt10.templates;

import java.util.Enumeration;
import java.util.Vector;

import javax.xml.transform.TransformerException;

import org.eclipse.wst.xsl.core.compiler.xslt10.res.Messages;
import org.eclipse.wst.xsl.core.compiler.xslt10.res.XSLTErrorResources;
import org.eclipse.wst.xsl.core.internal.compiler.xslt10.transformer.TransformerImpl;
import org.apache.xml.serializer.SerializationHandler;
import org.apache.xml.utils.StringVector;
import org.apache.xpath.XPathContext;
import org.xml.sax.SAXException;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.DOMException;
import org.w3c.dom.TypeInfo;
import org.w3c.dom.UserDataHandler;

/**
 * Implement a Literal Result Element.
 * 
 * @see <a
 *      href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element
 *      in XSLT Specification</a>
 * @xsl.usage advanced
 */
public class ElemLiteralResult extends ElemUse {
	public static final long serialVersionUID = -8703409074421657260L;

	/** The return value as Empty String. */
	private static final String EMPTYSTRING = "";

	/**
	 * Tells if this element represents a root element that is also the
	 * stylesheet element. TODO: This should be a derived class.
	 * 
	 * @serial
	 */
	private boolean isLiteralResultAsStylesheet = false;

	/**
	 * Set whether this element represents a root element that is also the
	 * stylesheet element.
	 * 
	 * 
	 * @param b
	 *            boolean flag indicating whether this element represents a root
	 *            element that is also the stylesheet element.
	 */
	public void setIsLiteralResultAsStylesheet(boolean b) {
		isLiteralResultAsStylesheet = b;
	}

	/**
	 * Return whether this element represents a root element that is also the
	 * stylesheet element.
	 * 
	 * 
	 * @return boolean flag indicating whether this element represents a root
	 *         element that is also the stylesheet element.
	 */
	public boolean getIsLiteralResultAsStylesheet() {
		return isLiteralResultAsStylesheet;
	}

	/**
	 * This function is called after everything else has been recomposed, and
	 * allows the template to set remaining values that may be based on some
	 * other property that depends on recomposition.
	 */
	@Override
	public void compose(StylesheetRoot sroot) throws TransformerException {
		super.compose(sroot);
		StylesheetRoot.ComposeState cstate = sroot.getComposeState();
		java.util.Vector vnames = cstate.getVariableNames();
		if (null != m_avts) {
			int nAttrs = m_avts.size();

			for (int i = (nAttrs - 1); i >= 0; i--) {
				AVT avt = (AVT) m_avts.elementAt(i);
				avt.fixupVariables(vnames, cstate.getGlobalsSize());
			}
		}
	}

	/**
	 * The created element node will have the attribute nodes that were present
	 * on the element node in the stylesheet tree, other than attributes with
	 * names in the XSLT namespace.
	 * 
	 * @serial
	 */
	private Vector m_avts = null;

	/**
	 * List of attributes with the XSLT namespace.
	 * 
	 * @serial
	 */
	private Vector m_xslAttr = null;

	/**
	 * Set a literal result attribute (AVTs only).
	 * 
	 * @param avt
	 *            literal result attribute to add (AVT only)
	 */
	public void addLiteralResultAttribute(AVT avt) {

		if (null == m_avts)
			m_avts = new Vector();

		m_avts.addElement(avt);
	}

	/**
	 * Set a literal result attribute (used for xsl attributes).
	 * 
	 * @param att
	 *            literal result attribute to add
	 */
	public void addLiteralResultAttribute(String att) {

		if (null == m_xslAttr)
			m_xslAttr = new Vector();

		m_xslAttr.addElement(att);
	}

	/**
	 * Set the "xml:space" attribute. A text node is preserved if an ancestor
	 * element of the text node has an xml:space attribute with a value of
	 * preserve, and no closer ancestor element has xml:space with a value of
	 * default.
	 * 
	 * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT
	 *      Specification</a>
	 * @see <a
	 *      href="http://www.w3.org/TR/xslt#section-Creating-Text">section-Creating-Text
	 *      in XSLT Specification</a>
	 * 
	 * @param avt
	 *            Enumerated value, either Constants.ATTRVAL_PRESERVE or
	 *            Constants.ATTRVAL_STRIP.
	 */
	public void setXmlSpace(AVT avt) {
		// This function is a bit-o-hack, I guess...
		addLiteralResultAttribute(avt);
		String val = avt.getSimpleString();
		if (val.equals("default")) {
			super.setXmlSpace(Constants.ATTRVAL_STRIP);
		} else if (val.equals("preserve")) {
			super.setXmlSpace(Constants.ATTRVAL_PRESERVE);
		}
		// else maybe it's a real AVT, so we can't resolve it at this time.
	}

	/**
	 * Get a literal result attribute by name.
	 * 
	 * @param namespaceURI
	 *            Namespace URI of attribute node to get
	 * @param localName
	 *            Local part of qualified name of attribute node to get
	 * 
	 * @return literal result attribute (AVT)
	 */
	public AVT getLiteralResultAttributeNS(String namespaceURI, String localName) {

		if (null != m_avts) {
			int nAttrs = m_avts.size();

			for (int i = (nAttrs - 1); i >= 0; i--) {
				AVT avt = (AVT) m_avts.elementAt(i);

				if (avt.getName().equals(localName)
						&& avt.getURI().equals(namespaceURI)) {
					return avt;
				}
			} // end for
		}

		return null;
	}

	/**
	 * Return the raw value of the attribute.
	 * 
	 * @param namespaceURI
	 *            Namespace URI of attribute node to get
	 * @param localName
	 *            Local part of qualified name of attribute node to get
	 * 
	 * @return The Attr value as a string, or the empty string if that attribute
	 *         does not have a specified or default value
	 */
	@Override
	public String getAttributeNS(String namespaceURI, String localName) {

		AVT avt = getLiteralResultAttributeNS(namespaceURI, localName);

		if ((null != avt)) {
			return avt.getSimpleString();
		}

		return EMPTYSTRING;
	}

	/**
	 * Get a literal result attribute by name. The name is
	 * namespaceURI:localname if namespace is not null.
	 * 
	 * @param name
	 *            Name of literal result attribute to get
	 * 
	 * @return literal result attribute (AVT)
	 */
	public AVT getLiteralResultAttribute(String name) {

		if (null != m_avts) {
			int nAttrs = m_avts.size();
			String namespace = null;
			for (int i = (nAttrs - 1); i >= 0; i--) {
				AVT avt = (AVT) m_avts.elementAt(i);
				namespace = avt.getURI();

				if ((namespace != null && (!namespace.equals("")) && (namespace
						+ ":" + avt.getName()).equals(name))
						|| ((namespace == null || namespace.equals("")) && avt
								.getRawName().equals(name))) {
					return avt;
				}
			} // end for
		}

		return null;
	}

	/**
	 * Return the raw value of the attribute.
	 * 
	 * @param namespaceURI:localName
	 *            or localName if the namespaceURI is null of the attribute to
	 *            get
	 * 
	 * @return The Attr value as a string, or the empty string if that attribute
	 *         does not have a specified or default value
	 */
	@Override
	public String getAttribute(String rawName) {

		AVT avt = getLiteralResultAttribute(rawName);

		if ((null != avt)) {
			return avt.getSimpleString();
		}

		return EMPTYSTRING;
	}

	/**
	 * Get whether or not the passed URL is flagged by the
	 * "extension-element-prefixes" or "exclude-result-prefixes" properties.
	 * 
	 * @see <a
	 *      href="http://www.w3.org/TR/xslt#extension-element">extension-element
	 *      in XSLT Specification</a>
	 * 
	 * @param prefix
	 *            non-null reference to prefix that might be excluded.(not
	 *            currently used)
	 * @param uri
	 *            reference to namespace that prefix maps to
	 * 
	 * @return true if the prefix should normally be excluded.
	 */
	@Override
	public boolean containsExcludeResultPrefix(String prefix, String uri) {
		if (uri == null
				|| (null == m_excludeResultPrefixes && null == m_ExtensionElementURIs))
			return super.containsExcludeResultPrefix(prefix, uri);

		if (prefix.length() == 0)
			prefix = Constants.ATTRVAL_DEFAULT_PREFIX;

		// This loop is ok here because this code only runs during
		// stylesheet compile time.
		if (m_excludeResultPrefixes != null)
			for (int i = 0; i < m_excludeResultPrefixes.size(); i++) {
				if (uri.equals(getNamespaceForPrefix(m_excludeResultPrefixes
						.elementAt(i))))
					return true;
			}

		// JJK Bugzilla 1133: Also check locally-scoped extensions
		if (m_ExtensionElementURIs != null
				&& m_ExtensionElementURIs.contains(uri))
			return true;

		return super.containsExcludeResultPrefix(prefix, uri);
	}

	/**
	 * Augment resolvePrefixTables, resolving the namespace aliases once the
	 * superclass has resolved the tables.
	 * 
	 * @throws TransformerException
	 */
	@Override
	public void resolvePrefixTables() throws TransformerException {

		super.resolvePrefixTables();

		StylesheetRoot stylesheet = getStylesheetRoot();

		if ((null != m_namespace) && (m_namespace.length() > 0)) {
			NamespaceAlias nsa = stylesheet
					.getNamespaceAliasComposed(m_namespace);

			if (null != nsa) {
				m_namespace = nsa.getResultNamespace();

				// String resultPrefix = nsa.getResultPrefix();
				String resultPrefix = nsa.getStylesheetPrefix(); // As per
																	// xsl WG,
																	// Mike Kay

				if ((null != resultPrefix) && (resultPrefix.length() > 0))
					m_rawName = resultPrefix + ":" + m_localName;
				else
					m_rawName = m_localName;
			}
		}

		if (null != m_avts) {
			int n = m_avts.size();

			for (int i = 0; i < n; i++) {
				AVT avt = (AVT) m_avts.elementAt(i);

				// Should this stuff be a method on AVT?
				String ns = avt.getURI();

				if ((null != ns) && (ns.length() > 0)) {
					NamespaceAlias nsa = stylesheet
							.getNamespaceAliasComposed(m_namespace); // %REVIEW%
																		// ns?

					if (null != nsa) {
						String namespace = nsa.getResultNamespace();

						// String resultPrefix = nsa.getResultPrefix();
						String resultPrefix = nsa.getStylesheetPrefix(); // As
																			// per
																			// XSL
																			// WG
						String rawName = avt.getName();

						if ((null != resultPrefix)
								&& (resultPrefix.length() > 0))
							rawName = resultPrefix + ":" + rawName;

						avt.setURI(namespace);
						avt.setRawName(rawName);
					}
				}
			}
		}
	}

	/**
	 * Return whether we need to check namespace prefixes against the exclude
	 * result prefixes or extensions lists. Note that this will create a new
	 * prefix table if one has not been created already.
	 * 
	 * NEEDSDOC ($objectName$)
	 * 
	 * @return
	 */
	@Override
	public boolean needToCheckExclude() {
		if (null == m_excludeResultPrefixes && null == m_prefixTable
				&& m_ExtensionElementURIs == null // JJK Bugzilla 1133
		)
			return false;
		else {

			// Create a new prefix table if one has not already been created.
			if (null == m_prefixTable)
				m_prefixTable = new Vector();

			return true;
		}
	}

	/**
	 * The namespace of the element to be created.
	 * 
	 * @serial
	 */
	private String m_namespace;

	/**
	 * Set the namespace URI of the result element to be created. Note that
	 * after resolvePrefixTables has been called, this will return the aliased
	 * result namespace, not the original stylesheet namespace.
	 * 
	 * @param ns
	 *            The Namespace URI, or the empty string if the element has no
	 *            Namespace URI.
	 */
	public void setNamespace(String ns) {
		if (null == ns) // defensive, shouldn't have to do this.
			ns = "";
		m_namespace = ns;
	}

	/**
	 * Get the original namespace of the Literal Result Element.
	 * 
	 * %REVIEW% Why isn't this overriding the getNamespaceURI method rather than
	 * introducing a new one?
	 * 
	 * @return The Namespace URI, or the empty string if the element has no
	 *         Namespace URI.
	 */
	public String getNamespace() {
		return m_namespace;
	}

	/**
	 * The local name of the element to be created.
	 * 
	 * @serial
	 */
	private String m_localName;

	/**
	 * Set the local name of the LRE.
	 * 
	 * @param localName
	 *            The local name (without prefix) of the result element to be
	 *            created.
	 */
	public void setLocalName(String localName) {
		m_localName = localName;
	}

	/**
	 * Get the local name of the Literal Result Element. Note that after
	 * resolvePrefixTables has been called, this will return the aliased name
	 * prefix, not the original stylesheet namespace prefix.
	 * 
	 * @return The local name (without prefix) of the result element to be
	 *         created.
	 */
	@Override
	public String getLocalName() {
		return m_localName;
	}

	/**
	 * The raw name of the element to be created.
	 * 
	 * @serial
	 */
	private String m_rawName;

	/**
	 * Set the raw name of the LRE.
	 * 
	 * @param rawName
	 *            The qualified name (with prefix), or the empty string if
	 *            qualified names are not available.
	 */
	public void setRawName(String rawName) {
		m_rawName = rawName;
	}

	/**
	 * Get the raw name of the Literal Result Element.
	 * 
	 * @return The qualified name (with prefix), or the empty string if
	 *         qualified names are not available.
	 */
	public String getRawName() {
		return m_rawName;
	}

	/**
	 * Get the prefix part of the raw name of the Literal Result Element.
	 * 
	 * @return The prefix, or the empty string if noprefix was provided.
	 */
	@Override
	public String getPrefix() {
		int len = m_rawName.length() - m_localName.length() - 1;
		return (len > 0) ? m_rawName.substring(0, len) : "";
	}

	/**
	 * The "extension-element-prefixes" property, actually contains URIs.
	 * 
	 * @serial
	 */
	private StringVector m_ExtensionElementURIs;

	/**
	 * Set the "extension-element-prefixes" property.
	 * 
	 * @see <a
	 *      href="http://www.w3.org/TR/xslt#extension-element">extension-element
	 *      in XSLT Specification</a>
	 * 
	 * @param v
	 *            Vector of URIs (not prefixes) to set as the
	 *            "extension-element-prefixes" property
	 */
	public void setExtensionElementPrefixes(StringVector v) {
		m_ExtensionElementURIs = v;
	}

	/**
	 * @see org.w3c.dom.Node
	 * 
	 * @return NamedNodeMap
	 */
	@Override
	public NamedNodeMap getAttributes() {
		return new LiteralElementAttributes();
	}

	public class LiteralElementAttributes implements NamedNodeMap {
		private int m_count = -1;

		/**
		 * Construct a NameNodeMap.
		 * 
		 */
		public LiteralElementAttributes() {
		}

		/**
		 * Return the number of Attributes on this Element
		 * 
		 * @return The number of nodes in this map. The range of valid child
		 *         node indices is <code>0</code> to <code>length-1</code>
		 *         inclusive
		 */
		public int getLength() {
			if (m_count == -1) {
				if (null != m_avts)
					m_count = m_avts.size();
				else
					m_count = 0;
			}
			return m_count;
		}

		/**
		 * Retrieves a node specified by name.
		 * 
		 * @param name
		 *            The <code>nodeName</code> of a node to retrieve.
		 * @return A <code>Node</code> (of any type) with the specified
		 *         <code>nodeName</code>, or <code>null</code> if it does
		 *         not identify any node in this map.
		 */
		public Node getNamedItem(String name) {
			if (getLength() == 0)
				return null;
			String uri = null;
			String localName = name;
			int index = name.indexOf(":");
			if (-1 != index) {
				uri = name.substring(0, index);
				localName = name.substring(index + 1);
			}
			Node retNode = null;
			Enumeration eum = m_avts.elements();
			while (eum.hasMoreElements()) {
				AVT avt = (AVT) eum.nextElement();
				if (localName.equals(avt.getName())) {
					String nsURI = avt.getURI();
					if ((uri == null && nsURI == null)
							|| (uri != null && uri.equals(nsURI))) {
						retNode = new Attribute(avt, ElemLiteralResult.this);
						break;
					}
				}
			}
			return retNode;
		}

		/**
		 * Retrieves a node specified by local name and namespace URI.
		 * 
		 * @param namespaceURI
		 *            Namespace URI of attribute node to get
		 * @param localName
		 *            Local part of qualified name of attribute node to get
		 * @return A <code>Node</code> (of any type) with the specified
		 *         <code>nodeName</code>, or <code>null</code> if it does
		 *         not identify any node in this map.
		 */
		public Node getNamedItemNS(String namespaceURI, String localName) {
			if (getLength() == 0)
				return null;
			Node retNode = null;
			Enumeration eum = m_avts.elements();
			while (eum.hasMoreElements()) {
				AVT avt = (AVT) eum.nextElement();
				if (localName.equals(avt.getName())) {
					String nsURI = avt.getURI();
					if ((namespaceURI == null && nsURI == null)
							|| (namespaceURI != null && namespaceURI
									.equals(nsURI))) {
						retNode = new Attribute(avt, ElemLiteralResult.this);
						break;
					}
				}
			}
			return retNode;
		}

		/**
		 * Returns the <code>index</code>th item in the map. If <code>index
		 * </code>
		 * is greater than or equal to the number of nodes in this map, this
		 * returns <code>null</code>.
		 * 
		 * @param i
		 *            The index of the requested item.
		 * @return The node at the <code>index</code>th position in the map,
		 *         or <code>null</code> if that is not a valid index.
		 */
		public Node item(int i) {
			if (getLength() == 0 || i >= m_avts.size())
				return null;
			else
				return new Attribute(((AVT) m_avts.elementAt(i)),
						ElemLiteralResult.this);
		}

		/**
		 * @see org.w3c.dom.NamedNodeMap
		 * 
		 * @param name
		 *            of the node to remove
		 * 
		 * @return The node removed from this map if a node with such a name
		 *         exists.
		 * 
		 * @throws DOMException
		 */
		public Node removeNamedItem(String name) throws DOMException {
			throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
					XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR);
			return null;
		}

		/**
		 * @see org.w3c.dom.NamedNodeMap
		 * 
		 * @param namespaceURI
		 *            Namespace URI of the node to remove
		 * @param localName
		 *            Local part of qualified name of the node to remove
		 * 
		 * @return The node removed from this map if a node with such a local
		 *         name and namespace URI exists
		 * 
		 * @throws DOMException
		 */
		public Node removeNamedItemNS(String namespaceURI, String localName)
				throws DOMException {
			throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
					XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR);
			return null;
		}

		/**
		 * Unimplemented. See org.w3c.dom.NamedNodeMap
		 * 
		 * @param A
		 *            node to store in this map
		 * 
		 * @return If the new Node replaces an existing node the replaced Node
		 *         is returned, otherwise null is returned
		 * 
		 * @throws DOMException
		 */
		public Node setNamedItem(Node arg) throws DOMException {
			throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
					XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR);
			return null;
		}

		/**
		 * Unimplemented. See org.w3c.dom.NamedNodeMap
		 * 
		 * @param A
		 *            node to store in this map
		 * 
		 * @return If the new Node replaces an existing node the replaced Node
		 *         is returned, otherwise null is returned
		 * 
		 * @throws DOMException
		 */
		public Node setNamedItemNS(Node arg) throws DOMException {
			throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
					XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR);
			return null;
		}
	}

	public class Attribute implements Attr {
		private AVT m_attribute;
		private Element m_owner = null;

		/**
		 * Construct a Attr.
		 * 
		 */
		public Attribute(AVT avt, Element elem) {
			m_attribute = avt;
			m_owner = elem;
		}

		/**
		 * @see org.w3c.dom.Node
		 * 
		 * @param newChild
		 *            New node to append to the list of this node's children
		 * 
		 * 
		 * @throws DOMException
		 */
		public Node appendChild(Node newChild) throws DOMException {
			throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
					XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR);
			return null;
		}

		/**
		 * @see org.w3c.dom.Node
		 * 
		 * @param deep
		 *            Flag indicating whether to clone deep (clone member
		 *            variables)
		 * 
		 * @return Returns a duplicate of this node
		 */
		public Node cloneNode(boolean deep) {
			return new Attribute(m_attribute, m_owner);
		}

		/**
		 * @see org.w3c.dom.Node
		 * 
		 * @return null
		 */
		public NamedNodeMap getAttributes() {
			return null;
		}

		/**
		 * @see org.w3c.dom.Node
		 * 
		 * @return a NodeList containing no nodes.
		 */
		public NodeList getChildNodes() {
			return new NodeList() {
				public int getLength() {
					return 0;
				}

				public Node item(int index) {
					return null;
				}
			};
		}

		/**
		 * @see org.w3c.dom.Node
		 * 
		 * @return null
		 */
		public Node getFirstChild() {
			return null;
		}

		/**
		 * @see org.w3c.dom.Node
		 * 
		 * @return null
		 */
		public Node getLastChild() {
			return null;
		}

		/**
		 * @see org.w3c.dom.Node
		 * 
		 * @return the local part of the qualified name of this node
		 */
		public String getLocalName() {
			return m_attribute.getName();
		}

		/**
		 * @see org.w3c.dom.Node
		 * 
		 * @return The namespace URI of this node, or null if it is unspecified
		 */
		public String getNamespaceURI() {
			String uri = m_attribute.getURI();
			return (uri.equals("")) ? null : uri;
		}

		/**
		 * @see org.w3c.dom.Node
		 * 
		 * @return null
		 */
		public Node getNextSibling() {
			return null;
		}

		/**
		 * @see org.w3c.dom.Node
		 * 
		 * @return The name of the attribute
		 */
		public String getNodeName() {
			String uri = m_attribute.getURI();
			String localName = getLocalName();
			return (uri.equals("")) ? localName : uri + ":" + localName;
		}

		/**
		 * @see org.w3c.dom.Node
		 * 
		 * @return The node is an Attr
		 */
		public short getNodeType() {
			return ATTRIBUTE_NODE;
		}

		/**
		 * @see org.w3c.dom.Node
		 * 
		 * @return The value of the attribute
		 * 
		 * @throws DOMException
		 */
		public String getNodeValue() throws DOMException {
			return m_attribute.getSimpleString();
		}

		/**
		 * @see org.w3c.dom.Node
		 * 
		 * @return null
		 */
		public Document getOwnerDocument() {
			return m_owner.getOwnerDocument();
		}

		/**
		 * @see org.w3c.dom.Node
		 * 
		 * @return the containing element node
		 */
		public Node getParentNode() {
			return m_owner;
		}

		/**
		 * @see org.w3c.dom.Node
		 * 
		 * @return The namespace prefix of this node, or null if it is
		 *         unspecified
		 */
		public String getPrefix() {
			String uri = m_attribute.getURI();
			String rawName = m_attribute.getRawName();
			return (uri.equals("")) ? null : rawName.substring(0, rawName
					.indexOf(":"));
		}

		/**
		 * @see org.w3c.dom.Node
		 * 
		 * @return null
		 */
		public Node getPreviousSibling() {
			return null;
		}

		/**
		 * @see org.w3c.dom.Node
		 * 
		 * @return false
		 */
		public boolean hasAttributes() {
			return false;
		}

		/**
		 * @see org.w3c.dom.Node
		 * 
		 * @return false
		 */
		public boolean hasChildNodes() {
			return false;
		}

		/**
		 * @see org.w3c.dom.Node
		 * 
		 * @param newChild
		 *            New child node to insert
		 * @param refChild
		 *            Insert in front of this child
		 * 
		 * @return null
		 * 
		 * @throws DOMException
		 */
		public Node insertBefore(Node newChild, Node refChild)
				throws DOMException {
			throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
					XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR);
			return null;
		}

		/**
		 * @see org.w3c.dom.Node
		 * 
		 * @return Returns <code>false</code>
		 * @since DOM Level 2
		 */
		public boolean isSupported(String feature, String version) {
			return false;
		}

		/** @see org.w3c.dom.Node */
		public void normalize() {
		}

		/**
		 * @see org.w3c.dom.Node
		 * 
		 * @param oldChild
		 *            Child to be removed
		 * 
		 * @return null
		 * 
		 * @throws DOMException
		 */
		public Node removeChild(Node oldChild) throws DOMException {
			throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
					XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR);
			return null;
		}

		/**
		 * @see org.w3c.dom.Node
		 * 
		 * @param newChild
		 *            Replace existing child with this one
		 * @param oldChild
		 *            Existing child to be replaced
		 * 
		 * @return null
		 * 
		 * @throws DOMException
		 */
		public Node replaceChild(Node newChild, Node oldChild)
				throws DOMException {
			throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
					XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR);
			return null;
		}

		/**
		 * @see org.w3c.dom.Node
		 * 
		 * @param nodeValue
		 *            Value to set this node to
		 * 
		 * @throws DOMException
		 */
		public void setNodeValue(String nodeValue) throws DOMException {
			throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
					XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR);
		}

		/**
		 * @see org.w3c.dom.Node
		 * 
		 * @param prefix
		 *            Prefix to set for this node
		 * 
		 * @throws DOMException
		 */
		public void setPrefix(String prefix) throws DOMException {
			throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
					XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR);
		}

		/**
		 * 
		 * @return The name of this attribute
		 */
		public String getName() {
			return m_attribute.getName();
		}

		/**
		 * 
		 * @return The value of this attribute returned as string
		 */
		public String getValue() {
			return m_attribute.getSimpleString();
		}

		/**
		 * 
		 * @return The Element node this attribute is attached to or null if
		 *         this attribute is not in use
		 */
		public Element getOwnerElement() {
			return m_owner;
		}

		/**
		 * 
		 * @return true
		 */
		public boolean getSpecified() {
			return true;
		}

		/**
		 * @see org.w3c.dom.Attr
		 * 
		 * @param value
		 *            Value to set this node to
		 * 
		 * @throws DOMException
		 */
		public void setValue(String value) throws DOMException {
			throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
					XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR);
		}

		public TypeInfo getSchemaTypeInfo() {
			return null;
		}

		public boolean isId() {
			return false;
		}

		public Object setUserData(String key, Object data,
				UserDataHandler handler) {
			return getOwnerDocument().setUserData(key, data, handler);
		}

		public Object getUserData(String key) {
			return getOwnerDocument().getUserData(key);
		}

		public Object getFeature(String feature, String version) {
			return isSupported(feature, version) ? this : null;
		}

		public boolean isEqualNode(Node arg) {
			return arg == this;
		}

		public String lookupNamespaceURI(String specifiedPrefix) {
			return null;
		}

		public boolean isDefaultNamespace(String namespaceURI) {
			return false;
		}

		public String lookupPrefix(String namespaceURI) {
			return null;
		}

		public boolean isSameNode(Node other) {
			// we do not use any wrapper so the answer is obvious
			return this == other;
		}

		public void setTextContent(String textContent) throws DOMException {
			setNodeValue(textContent);
		}

		public String getTextContent() throws DOMException {
			return getNodeValue(); // overriden in some subclasses
		}

		public short compareDocumentPosition(Node other) throws DOMException {
			return 0;
		}

		public String getBaseURI() {
			return null;
		}
	}

	/**
	 * Get an "extension-element-prefix" property.
	 * 
	 * @see <a
	 *      href="http://www.w3.org/TR/xslt#extension-element">extension-element
	 *      in XSLT Specification</a>
	 * 
	 * @param i
	 *            Index of URI ("extension-element-prefix" property) to get
	 * 
	 * @return URI at given index ("extension-element-prefix" property)
	 * 
	 * @throws ArrayIndexOutOfBoundsException
	 */
	public String getExtensionElementPrefix(int i)
			throws ArrayIndexOutOfBoundsException {

		if (null == m_ExtensionElementURIs)
			throw new ArrayIndexOutOfBoundsException();

		return m_ExtensionElementURIs.elementAt(i);
	}

	/**
	 * Get the number of "extension-element-prefixes" Strings.
	 * 
	 * @see <a
	 *      href="http://www.w3.org/TR/xslt#extension-element">extension-element
	 *      in XSLT Specification</a>
	 * 
	 * @return the number of "extension-element-prefixes" Strings
	 */
	public int getExtensionElementPrefixCount() {
		return (null != m_ExtensionElementURIs) ? m_ExtensionElementURIs.size()
				: 0;
	}

	/**
	 * Find out if the given "extension-element-prefix" property is defined.
	 * 
	 * @see <a
	 *      href="http://www.w3.org/TR/xslt#extension-element">extension-element
	 *      in XSLT Specification</a>
	 * 
	 * @param uri
	 *            The URI to find
	 * 
	 * @return True if the given URI is found
	 */
	public boolean containsExtensionElementURI(String uri) {

		if (null == m_ExtensionElementURIs)
			return false;

		return m_ExtensionElementURIs.contains(uri);
	}

	/**
	 * Get an int constant identifying the type of element.
	 * 
	 * @see org.apache.xalan.templates.Constants
	 * 
	 * @return The token ID for this element
	 */
	@Override
	public int getXSLToken() {
		return Constants.ELEMNAME_LITERALRESULT;
	}

	/**
	 * Return the node name.
	 * 
	 * @return The element's name
	 */
	@Override
	public String getNodeName() {

		// TODO: Need prefix.
		return m_rawName;
	}

	/**
	 * The XSLT version as specified by this element.
	 * 
	 * @serial
	 */
	private String m_version;

	/**
	 * Set the "version" property.
	 * 
	 * @see <a href="http://www.w3.org/TR/xslt#forwards">forwards in XSLT
	 *      Specification</a>
	 * 
	 * @param v
	 *            Version property value to set
	 */
	public void setVersion(String v) {
		m_version = v;
	}

	/**
	 * Get the "version" property.
	 * 
	 * @see <a href="http://www.w3.org/TR/xslt#forwards">forwards in XSLT
	 *      Specification</a>
	 * 
	 * @return Version property value
	 */
	public String getVersion() {
		return m_version;
	}

	/**
	 * The "exclude-result-prefixes" property.
	 * 
	 * @serial
	 */
	private StringVector m_excludeResultPrefixes;

	/**
	 * Set the "exclude-result-prefixes" property. The designation of a
	 * namespace as an excluded namespace is effective within the subtree of the
	 * stylesheet rooted at the element bearing the exclude-result-prefixes or
	 * xsl:exclude-result-prefixes attribute; a subtree rooted at an
	 * xsl:stylesheet element does not include any stylesheets imported or
	 * included by children of that xsl:stylesheet element.
	 * 
	 * @see <a
	 *      href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element
	 *      in XSLT Specification</a>
	 * 
	 * @param v
	 *            vector of prefixes that are resolvable to strings.
	 */
	public void setExcludeResultPrefixes(StringVector v) {
		m_excludeResultPrefixes = v;
	}

	/**
	 * Tell if the result namespace decl should be excluded. Should be called
	 * before namespace aliasing (I think).
	 * 
	 * @param prefix
	 *            Prefix of namespace to check
	 * @param uri
	 *            URI of namespace to check
	 * 
	 * @return True if the given namespace should be excluded
	 * 
	 * @throws TransformerException
	 */
	private boolean excludeResultNSDecl(String prefix, String uri)
			throws TransformerException {

		if (null != m_excludeResultPrefixes) {
			return containsExcludeResultPrefix(prefix, uri);
		}

		return false;
	}

	/**
	 * Copy a Literal Result Element into the Result tree, copy the non-excluded
	 * namespace attributes, copy the attributes not of the XSLT namespace, and
	 * execute the children of the LRE.
	 * 
	 * @see <a
	 *      href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element
	 *      in XSLT Specification</a>
	 * 
	 * @param transformer
	 *            non-null reference to the the current transform-time state.
	 * 
	 * @throws TransformerException
	 */
	@Override
	public void execute(TransformerImpl transformer)
			throws TransformerException {
		SerializationHandler rhandler = transformer.getSerializationHandler();

		try {
			if (transformer.getDebug()) {
				// flush any buffered pending processing before
				// the trace event.
				rhandler.flushPending();
				transformer.getTraceManager().fireTraceEvent(this);
			}

			// JJK Bugzilla 3464, test namespace85 -- make sure LRE's
			// namespace is asserted even if default, since xsl:element
			// may have changed the context.
			rhandler.startPrefixMapping(getPrefix(), getNamespace());

			// Add namespace declarations.
			executeNSDecls(transformer);
			rhandler.startElement(getNamespace(), getLocalName(), getRawName());
		} catch (SAXException se) {
			throw new TransformerException(se);
		}

		/*
		 * If we make it to here we have done a successful startElement() we
		 * will do an endElement() call for balance, no matter what happens in
		 * the middle.
		 */

		// tException remembers if we had an exception "in the middle"
		TransformerException tException = null;
		try {

			// Process any possible attributes from xsl:use-attribute-sets first
			super.execute(transformer);

			// xsl:version, excludeResultPrefixes???
			// Process the list of avts next
			if (null != m_avts) {
				int nAttrs = m_avts.size();

				for (int i = (nAttrs - 1); i >= 0; i--) {
					AVT avt = (AVT) m_avts.elementAt(i);
					XPathContext xctxt = transformer.getXPathContext();
					int sourceNode = xctxt.getCurrentNode();
					String stringedValue = avt
							.evaluate(xctxt, sourceNode, this);

					if (null != stringedValue) {

						// Important Note: I'm not going to check for excluded
						// namespace
						// prefixes here. It seems like it's too expensive, and
						// I'm not
						// even sure this is right. But I could be wrong, so
						// this needs
						// to be tested against other implementations.

						rhandler.addAttribute(avt.getURI(), avt.getName(), avt
								.getRawName(), "CDATA", stringedValue, false);
					}
				} // end for
			}

			// Now process all the elements in this subtree
			// TODO: Process m_extensionElementPrefixes && m_attributeSetsNames
			transformer.executeChildTemplates(this, true);
		} catch (TransformerException te) {
			// thrown in finally to prevent original exception consumed by
			// subsequent exceptions
			tException = te;
		} catch (SAXException se) {
			tException = new TransformerException(se);
		}

		try {
			/*
			 * we need to do this endElement() to balance the successful
			 * startElement() call even if there was an exception in the middle.
			 * Otherwise an exception in the middle could cause a system to
			 * hang.
			 */
			if (transformer.getDebug()) {
				// flush any buffered pending processing before
				// the trace event.
				// rhandler.flushPending();
				transformer.getTraceManager().fireTraceEndEvent(this);
			}
			rhandler.endElement(getNamespace(), getLocalName(), getRawName());
		} catch (SAXException se) {
			/*
			 * we did call endElement(). If thee was an exception in the middle
			 * throw that one, otherwise if there was an exception from
			 * endElement() throw that one.
			 */
			if (tException != null)
				throw tException;
			else
				throw new TransformerException(se);
		}

		/*
		 * If an exception was thrown in the middle but not with startElement()
		 * or or endElement() then its time to let it percolate.
		 */
		if (tException != null)
			throw tException;

		unexecuteNSDecls(transformer);

		// JJK Bugzilla 3464, test namespace85 -- balance explicit start.
		try {
			rhandler.endPrefixMapping(getPrefix());
		} catch (SAXException se) {
			throw new TransformerException(se);
		}
	}

	/**
	 * Compiling templates requires that we be able to list the AVTs ADDED
	 * 9/5/2000 to support compilation experiment
	 * 
	 * @return an Enumeration of the literal result attributes associated with
	 *         this element.
	 */
	public Enumeration enumerateLiteralResultAttributes() {
		return (null == m_avts) ? null : m_avts.elements();
	}

	/**
	 * Accept a visitor and call the appropriate method for this class.
	 * 
	 * @param visitor
	 *            The visitor whose appropriate method will be called.
	 * @return true if the children of the object should be visited.
	 */
	@Override
	protected boolean accept(XSLTVisitor visitor) {
		return visitor.visitLiteralResultElement(this);
	}

	/**
	 * Call the children visitors.
	 * 
	 * @param visitor
	 *            The visitor whose appropriate method will be called.
	 */
	@Override
	protected void callChildVisitors(XSLTVisitor visitor, boolean callAttrs) {
		if (callAttrs && null != m_avts) {
			int nAttrs = m_avts.size();

			for (int i = (nAttrs - 1); i >= 0; i--) {
				AVT avt = (AVT) m_avts.elementAt(i);
				avt.callVisitors(visitor);
			}
		}
		super.callChildVisitors(visitor, callAttrs);
	}

	/**
	 * Throw a DOMException
	 * 
	 * @param msg
	 *            key of the error that occured.
	 */
	public void throwDOMException(short code, String msg) {

		String themsg = Messages.createMessage(msg, null);

		throw new DOMException(code, themsg);
	}

}
