/*******************************************************************************
 * 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-2004 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: XSLTElementDef.java,v 1.2 2008/03/28 02:38:16 dacarver Exp $
 */
package org.eclipse.wst.xsl.core.internal.compiler.xslt10.processor;

import java.util.Enumeration;
import java.util.Hashtable;

import org.apache.xalan.templates.Constants;
import org.apache.xml.utils.QName;

/**
 * This class defines the allowed structure for an element in a XSLT stylesheet,
 * is meant to reflect the structure defined in http://www.w3.org/TR/xslt#dtd,
 * and the mapping between Xalan classes and the markup elements in the XSLT
 * instance. This actually represents both text nodes and elements.
 */
public class XSLTElementDef {

	/**
	 * Construct an instance of XSLTElementDef. This must be followed by a call
	 * to build().
	 */
	public XSLTElementDef() {
	}

	/**
	 * Construct an instance of XSLTElementDef.
	 * 
	 * @param namespace
	 *            The Namespace URI, "*", or null.
	 * @param name
	 *            The local name (without prefix), "*", or null.
	 * @param nameAlias
	 *            A potential alias for the name, or null.
	 * @param elements
	 *            An array of allowed child element defs, or null.
	 * @param attributes
	 *            An array of allowed attribute defs, or null.
	 * @param contentHandler
	 *            The element processor for this element.
	 * @param classObject
	 *            The class of the object that this element def should produce.
	 */
	public XSLTElementDef(XSLTSchema schema, String namespace, String name,
			String nameAlias, XSLTElementDef[] elements,
			XSLTAttributeDef[] attributes, XSLTElementProcessor contentHandler,
			Class classObject) {
		build(namespace, name, nameAlias, elements, attributes, contentHandler,
				classObject);
		if ((null != namespace)
				&& (namespace
						.equals(org.apache.xml.utils.Constants.S_XSLNAMESPACEURL)
						|| namespace
								.equals(org.apache.xml.utils.Constants.S_BUILTIN_EXTENSIONS_URL) || namespace
						.equals(org.apache.xml.utils.Constants.S_BUILTIN_OLD_EXTENSIONS_URL))) {
			schema.addAvailableElement(new QName(namespace, name));
			if (null != nameAlias)
				schema.addAvailableElement(new QName(namespace, nameAlias));
		}
	}

	/**
	 * Construct an instance of XSLTElementDef.
	 * 
	 * @param namespace
	 *            The Namespace URI, "*", or null.
	 * @param name
	 *            The local name (without prefix), "*", or null.
	 * @param nameAlias
	 *            A potential alias for the name, or null.
	 * @param elements
	 *            An array of allowed child element defs, or null.
	 * @param attributes
	 *            An array of allowed attribute defs, or null.
	 * @param contentHandler
	 *            The element processor for this element.
	 * @param classObject
	 *            The class of the object that this element def should produce.
	 * @param has_required
	 *            true if this element has required elements by the XSLT
	 *            specification.
	 */
	public XSLTElementDef(XSLTSchema schema, String namespace, String name,
			String nameAlias, XSLTElementDef[] elements,
			XSLTAttributeDef[] attributes, XSLTElementProcessor contentHandler,
			Class classObject, boolean has_required) {
		this.m_has_required = has_required;
		build(namespace, name, nameAlias, elements, attributes, contentHandler,
				classObject);
		if ((null != namespace)
				&& (namespace
						.equals(org.apache.xml.utils.Constants.S_XSLNAMESPACEURL)
						|| namespace
								.equals(org.apache.xml.utils.Constants.S_BUILTIN_EXTENSIONS_URL) || namespace
						.equals(org.apache.xml.utils.Constants.S_BUILTIN_OLD_EXTENSIONS_URL))) {
			schema.addAvailableElement(new QName(namespace, name));
			if (null != nameAlias)
				schema.addAvailableElement(new QName(namespace, nameAlias));
		}

	}

	/**
	 * Construct an instance of XSLTElementDef.
	 * 
	 * @param namespace
	 *            The Namespace URI, "*", or null.
	 * @param name
	 *            The local name (without prefix), "*", or null.
	 * @param nameAlias
	 *            A potential alias for the name, or null.
	 * @param elements
	 *            An array of allowed child element defs, or null.
	 * @param attributes
	 *            An array of allowed attribute defs, or null.
	 * @param contentHandler
	 *            The element processor for this element.
	 * @param classObject
	 *            The class of the object that this element def should produce.
	 * @param has_required
	 *            true if this element has required elements by the XSLT
	 *            specification.
	 * @param required
	 *            true if this element is required by the XSLT specification.
	 */
	public XSLTElementDef(XSLTSchema schema, String namespace, String name,
			String nameAlias, XSLTElementDef[] elements,
			XSLTAttributeDef[] attributes, XSLTElementProcessor contentHandler,
			Class classObject, boolean has_required, boolean required) {
		this(schema, namespace, name, nameAlias, elements, attributes,
				contentHandler, classObject, has_required);
		this.m_required = required;
	}

	/**
	 * Construct an instance of XSLTElementDef.
	 * 
	 * @param namespace
	 *            The Namespace URI, "*", or null.
	 * @param name
	 *            The local name (without prefix), "*", or null.
	 * @param nameAlias
	 *            A potential alias for the name, or null.
	 * @param elements
	 *            An array of allowed child element defs, or null.
	 * @param attributes
	 *            An array of allowed attribute defs, or null.
	 * @param contentHandler
	 *            The element processor for this element.
	 * @param classObject
	 *            The class of the object that this element def should produce.
	 * @param has_required
	 *            true if this element has required elements by the XSLT
	 *            specification.
	 * @param required
	 *            true if this element is required by the XSLT specification.
	 * @param order
	 *            the order this element should appear according to the XSLT
	 *            specification.
	 * @param multiAllowed
	 *            whether this element is allowed more than once
	 */
	public XSLTElementDef(XSLTSchema schema, String namespace, String name,
			String nameAlias, XSLTElementDef[] elements,
			XSLTAttributeDef[] attributes, XSLTElementProcessor contentHandler,
			Class classObject, boolean has_required, boolean required,
			int order, boolean multiAllowed) {
		this(schema, namespace, name, nameAlias, elements, attributes,
				contentHandler, classObject, has_required, required);
		this.m_order = order;
		this.m_multiAllowed = multiAllowed;
	}

	/**
	 * Construct an instance of XSLTElementDef.
	 * 
	 * @param namespace
	 *            The Namespace URI, "*", or null.
	 * @param name
	 *            The local name (without prefix), "*", or null.
	 * @param nameAlias
	 *            A potential alias for the name, or null.
	 * @param elements
	 *            An array of allowed child element defs, or null.
	 * @param attributes
	 *            An array of allowed attribute defs, or null.
	 * @param contentHandler
	 *            The element processor for this element.
	 * @param classObject
	 *            The class of the object that this element def should produce.
	 * @param has_required
	 *            true if this element has required elements by the XSLT
	 *            specification.
	 * @param required
	 *            true if this element is required by the XSLT specification.
	 * @param has_order
	 *            whether this element has ordered child elements
	 * @param order
	 *            the order this element should appear according to the XSLT
	 *            specification.
	 * @param multiAllowed
	 *            whether this element is allowed more than once
	 */
	public XSLTElementDef(XSLTSchema schema, String namespace, String name,
			String nameAlias, XSLTElementDef[] elements,
			XSLTAttributeDef[] attributes, XSLTElementProcessor contentHandler,
			Class classObject, boolean has_required, boolean required,
			boolean has_order, int order, boolean multiAllowed) {
		this(schema, namespace, name, nameAlias, elements, attributes,
				contentHandler, classObject, has_required, required);
		this.m_order = order;
		this.m_multiAllowed = multiAllowed;
		this.m_isOrdered = has_order;
	}

	/**
	 * Construct an instance of XSLTElementDef.
	 * 
	 * @param namespace
	 *            The Namespace URI, "*", or null.
	 * @param name
	 *            The local name (without prefix), "*", or null.
	 * @param nameAlias
	 *            A potential alias for the name, or null.
	 * @param elements
	 *            An array of allowed child element defs, or null.
	 * @param attributes
	 *            An array of allowed attribute defs, or null.
	 * @param contentHandler
	 *            The element processor for this element.
	 * @param classObject
	 *            The class of the object that this element def should produce.
	 * @param has_order
	 *            whether this element has ordered child elements
	 * @param order
	 *            the order this element should appear according to the XSLT
	 *            specification.
	 * @param multiAllowed
	 *            whether this element is allowed more than once
	 */
	public XSLTElementDef(XSLTSchema schema, String namespace, String name,
			String nameAlias, XSLTElementDef[] elements,
			XSLTAttributeDef[] attributes, XSLTElementProcessor contentHandler,
			Class classObject, boolean has_order, int order,
			boolean multiAllowed) {
		this(schema, namespace, name, nameAlias, elements, attributes,
				contentHandler, classObject, order, multiAllowed);
		this.m_isOrdered = has_order;
	}

	/**
	 * Construct an instance of XSLTElementDef.
	 * 
	 * @param namespace
	 *            The Namespace URI, "*", or null.
	 * @param name
	 *            The local name (without prefix), "*", or null.
	 * @param nameAlias
	 *            A potential alias for the name, or null.
	 * @param elements
	 *            An array of allowed child element defs, or null.
	 * @param attributes
	 *            An array of allowed attribute defs, or null.
	 * @param contentHandler
	 *            The element processor for this element.
	 * @param classObject
	 *            The class of the object that this element def should produce.
	 * @param order
	 *            the order this element should appear according to the XSLT
	 *            specification.
	 * @param multiAllowed
	 *            whether this element is allowed more than once
	 */
	public XSLTElementDef(XSLTSchema schema, String namespace, String name,
			String nameAlias, XSLTElementDef[] elements,
			XSLTAttributeDef[] attributes, XSLTElementProcessor contentHandler,
			Class classObject, int order, boolean multiAllowed) {
		this(schema, namespace, name, nameAlias, elements, attributes,
				contentHandler, classObject);
		this.m_order = order;
		this.m_multiAllowed = multiAllowed;
	}

	/**
	 * Construct an instance of XSLTElementDef that represents text.
	 * 
	 * @param classObject
	 *            The class of the object that this element def should produce.
	 * @param contentHandler
	 *            The element processor for this element.
	 * @param type
	 *            Content type, one of T_ELEMENT, T_PCDATA, or T_ANY.
	 */
	public XSLTElementDef(Class classObject,
			XSLTElementProcessor contentHandler, int type) {

		this.m_classObject = classObject;
		this.m_type = type;

		setElementProcessor(contentHandler);
	}

	/**
	 * Construct an instance of XSLTElementDef.
	 * 
	 * @param namespace
	 *            The Namespace URI, "*", or null.
	 * @param name
	 *            The local name (without prefix), "*", or null.
	 * @param nameAlias
	 *            A potential alias for the name, or null.
	 * @param elements
	 *            An array of allowed child element defs, or null.
	 * @param attributes
	 *            An array of allowed attribute defs, or null.
	 * @param contentHandler
	 *            The element processor for this element.
	 * @param classObject
	 *            The class of the object that this element def should produce.
	 */
	public void build(String namespace, String name, String nameAlias,
			XSLTElementDef[] elements, XSLTAttributeDef[] attributes,
			XSLTElementProcessor contentHandler, Class classObject) {

		this.m_namespace = namespace;
		this.m_name = name;
		this.m_nameAlias = nameAlias;
		this.m_elements = elements;
		this.m_attributes = attributes;

		setElementProcessor(contentHandler);

		this.m_classObject = classObject;

		if (hasRequired() && m_elements != null) {
			int n = m_elements.length;
			for (int i = 0; i < n; i++) {
				XSLTElementDef def = m_elements[i];

				if (def != null && def.getRequired()) {
					if (m_requiredFound == null)
						m_requiredFound = new Hashtable();
					m_requiredFound.put(def.getName(), "xsl:" + def.getName());
				}
			}
		}
	}

	/**
	 * Tell if two objects are equal, when either one may be null. If both are
	 * null, they are considered equal.
	 * 
	 * @param obj1
	 *            A reference to the first object, or null.
	 * @param obj2
	 *            A reference to the second object, or null.
	 * 
	 * @return true if the to objects are equal by both being null or because
	 *         obj2.equals(obj1) returns true.
	 */
	private static boolean equalsMayBeNull(Object obj1, Object obj2) {
		return (obj2 == obj1)
				|| ((null != obj1) && (null != obj2) && obj2.equals(obj1));
	}

	/**
	 * Tell if the two string refs are equal, equality being defined as: 1) Both
	 * strings are null. 2) One string is null and the other is empty. 3) Both
	 * strings are non-null, and equal.
	 * 
	 * @param s1
	 *            A reference to the first string, or null.
	 * @param s2
	 *            A reference to the second string, or null.
	 * 
	 * @return true if Both strings are null, or if one string is null and the
	 *         other is empty, or if both strings are non-null, and equal
	 *         because s1.equals(s2) returns true.
	 */
	private static boolean equalsMayBeNullOrZeroLen(String s1, String s2) {

		int len1 = (s1 == null) ? 0 : s1.length();
		int len2 = (s2 == null) ? 0 : s2.length();

		return (len1 != len2) ? false : (len1 == 0) ? true : s1.equals(s2);
	}

	/** Content type enumerations */
	public static final int T_ELEMENT = 1, T_PCDATA = 2, T_ANY = 3;

	/**
	 * The type of this element.
	 */
	private int m_type = T_ELEMENT;

	/**
	 * Get the type of this element.
	 * 
	 * @return Content type, one of T_ELEMENT, T_PCDATA, or T_ANY.
	 */
	public int getType() {
		return m_type;
	}

	/**
	 * Set the type of this element.
	 * 
	 * @param t
	 *            Content type, one of T_ELEMENT, T_PCDATA, or T_ANY.
	 */
	public void setType(int t) {
		m_type = t;
	}

	/**
	 * The allowed namespace for this element.
	 */
	private String m_namespace;

	/**
	 * Get the allowed namespace for this element.
	 * 
	 * @return The Namespace URI, "*", or null.
	 */
	public String getNamespace() {
		return m_namespace;
	}

	/**
	 * The name of this element.
	 */
	private String m_name;

	/**
	 * Get the local name of this element.
	 * 
	 * @return The local name of this element, "*", or null.
	 */
	public String getName() {
		return m_name;
	}

	/**
	 * The name of this element.
	 */
	private String m_nameAlias;

	/**
	 * Get the name of this element.
	 * 
	 * @return A potential alias for the name, or null.
	 */
	public String getNameAlias() {
		return m_nameAlias;
	}

	/**
	 * The allowed elements for this type.
	 */
	private XSLTElementDef[] m_elements;

	/**
	 * Get the allowed elements for this type.
	 * 
	 * @return An array of allowed child element defs, or null.
	 * @xsl.usage internal
	 */
	public XSLTElementDef[] getElements() {
		return m_elements;
	}

	/**
	 * Set the allowed elements for this type.
	 * 
	 * @param defs
	 *            An array of allowed child element defs, or null.
	 */
	public void setElements(XSLTElementDef[] defs) {
		m_elements = defs;
	}

	/**
	 * Tell if the namespace URI and local name match this element.
	 * 
	 * @param uri
	 *            The namespace uri, which may be null.
	 * @param localName
	 *            The local name of an element, which may be null.
	 * 
	 * @return true if the uri and local name arguments are considered to match
	 *         the uri and local name of this element def.
	 */
	private boolean QNameEquals(String uri, String localName) {

		return (equalsMayBeNullOrZeroLen(m_namespace, uri) && (equalsMayBeNullOrZeroLen(
				m_name, localName) || equalsMayBeNullOrZeroLen(m_nameAlias,
				localName)));
	}

	/**
	 * Given a namespace URI, and a local name, get the processor for the
	 * element, or return null if not allowed.
	 * 
	 * @param uri
	 *            The Namespace URI, or an empty string.
	 * @param localName
	 *            The local name (without prefix), or empty string if not
	 *            namespace processing.
	 * 
	 * @return The element processor that matches the arguments, or null.
	 */
	public XSLTElementProcessor getProcessorFor(String uri, String localName) {

		XSLTElementProcessor elemDef = null; // return value

		if (null == m_elements)
			return null;

		int n = m_elements.length;
		int order = -1;
		boolean multiAllowed = true;
		for (int i = 0; i < n; i++) {
			XSLTElementDef def = m_elements[i];

			// A "*" signals that the element allows literal result
			// elements, so just assign the def, and continue to
			// see if anything else matches.
			if (def.m_name.equals("*")) {

				// Don't allow xsl elements
				if (!equalsMayBeNullOrZeroLen(uri,
						org.apache.xml.utils.Constants.S_XSLNAMESPACEURL)) {
					elemDef = def.m_elementProcessor;
					order = def.getOrder();
					multiAllowed = def.getMultiAllowed();
				}
			} else if (def.QNameEquals(uri, localName)) {
				if (def.getRequired())
					this.setRequiredFound(def.getName(), true);
				order = def.getOrder();
				multiAllowed = def.getMultiAllowed();
				elemDef = def.m_elementProcessor;
				break;
			}
		}

		if (elemDef != null && this.isOrdered()) {
			int lastOrder = getLastOrder();
			if (order > lastOrder)
				setLastOrder(order);
			else if (order == lastOrder && !multiAllowed) {
				return null;
			} else if (order < lastOrder && order > 0) {
				return null;
			}
		}

		return elemDef;
	}

	/**
	 * Given an unknown element, get the processor for the element.
	 * 
	 * @param uri
	 *            The Namespace URI, or an empty string.
	 * @param localName
	 *            The local name (without prefix), or empty string if not
	 *            namespace processing.
	 * 
	 * @return normally a {@link ProcessorUnknown} reference.
	 * @see ProcessorUnknown
	 */
	public XSLTElementProcessor getProcessorForUnknown(String uri,
			String localName) {

		// XSLTElementProcessor lreDef = null; // return value
		if (null == m_elements)
			return null;

		int n = m_elements.length;

		for (int i = 0; i < n; i++) {
			XSLTElementDef def = m_elements[i];

			if (def.m_name.equals("unknown") && uri.length() > 0) {
				return def.m_elementProcessor;
			}
		}

		return null;
	}

	/**
	 * The allowed attributes for this type.
	 */
	private XSLTAttributeDef[] m_attributes;

	/**
	 * Get the allowed attributes for this type.
	 * 
	 * @return An array of allowed attribute defs, or null.
	 */
	public XSLTAttributeDef[] getAttributes() {
		return m_attributes;
	}

	/**
	 * Given a namespace URI, and a local name, return the element's attribute
	 * definition, if it has one.
	 * 
	 * @param uri
	 *            The Namespace URI, or an empty string.
	 * @param localName
	 *            The local name (without prefix), or empty string if not
	 *            namespace processing.
	 * 
	 * @return The attribute def that matches the arguments, or null.
	 */
	public XSLTAttributeDef getAttributeDef(String uri, String localName) {

		XSLTAttributeDef defaultDef = null;
		XSLTAttributeDef[] attrDefs = getAttributes();
		int nAttrDefs = attrDefs.length;

		for (int k = 0; k < nAttrDefs; k++) {
			XSLTAttributeDef attrDef = attrDefs[k];
			String uriDef = attrDef.getNamespace();
			String nameDef = attrDef.getName();

			if (nameDef.equals("*")
					&& (equalsMayBeNullOrZeroLen(uri, uriDef) || (uriDef != null
							&& uriDef.equals("*") && uri != null && uri
							.length() > 0))) {
				return attrDef;
			} else if (nameDef.equals("*") && (uriDef == null)) {

				// In this case, all attributes are legal, so return
				// this as the last resort.
				defaultDef = attrDef;
			} else if (equalsMayBeNullOrZeroLen(uri, uriDef)
					&& localName.equals(nameDef)) {
				return attrDef;
			}
		}

		if (null == defaultDef) {
			if (uri.length() > 0
					&& !equalsMayBeNullOrZeroLen(uri,
							org.apache.xml.utils.Constants.S_XSLNAMESPACEURL)) {
				return XSLTAttributeDef.m_foreignAttr;
			}
		}

		return defaultDef;
	}

	/**
	 * If non-null, the ContentHandler/TransformerFactory for this element.
	 */
	private XSLTElementProcessor m_elementProcessor;

	/**
	 * Return the XSLTElementProcessor for this element.
	 * 
	 * @return The element processor for this element.
	 * @xsl.usage internal
	 */
	public XSLTElementProcessor getElementProcessor() {
		return m_elementProcessor;
	}

	/**
	 * Set the XSLTElementProcessor for this element.
	 * 
	 * @param handler
	 *            The element processor for this element.
	 * @xsl.usage internal
	 */
	public void setElementProcessor(XSLTElementProcessor handler) {

		if (handler != null) {
			m_elementProcessor = handler;

			m_elementProcessor.setElemDef(this);
		}
	}

	/**
	 * If non-null, the class object that should in instantiated for a Xalan
	 * instance of this element.
	 */
	private Class m_classObject;

	/**
	 * Return the class object that should in instantiated for a Xalan instance
	 * of this element.
	 * 
	 * @return The class of the object that this element def should produce, or
	 *         null.
	 */
	public Class getClassObject() {
		return m_classObject;
	}

	/**
	 * If true, this has a required element.
	 */
	private boolean m_has_required = false;

	/**
	 * Get whether or not this has a required element.
	 * 
	 * @return true if this this has a required element.
	 */
	public boolean hasRequired() {
		return m_has_required;
	}

	/**
	 * If true, this is a required element.
	 */
	private boolean m_required = false;

	/**
	 * Get whether or not this is a required element.
	 * 
	 * @return true if this is a required element.
	 */
	public boolean getRequired() {
		return m_required;
	}

	private Hashtable m_requiredFound;

	/**
	 * Set this required element found.
	 * 
	 */
	public void setRequiredFound(String elem, boolean found) {
		if (m_requiredFound.get(elem) != null)
			m_requiredFound.remove(elem);
	}

	/**
	 * Get whether all required elements were found.
	 * 
	 * @return true if all required elements were found.
	 */
	public boolean getRequiredFound() {
		if (m_requiredFound == null)
			return true;
		return m_requiredFound.isEmpty();
	}

	/**
	 * Get required elements that were not found.
	 * 
	 * @return required elements that were not found.
	 */
	public String getRequiredElem() {
		if (m_requiredFound == null)
			return null;
		Enumeration elems = m_requiredFound.elements();
		String s = "";
		boolean first = true;
		while (elems.hasMoreElements()) {
			if (first)
				first = false;
			else
				s = s + ", ";
			s = s + (String) elems.nextElement();
		}
		return s;
	}

	boolean m_isOrdered = false;

	/**
	 * Get whether this element requires ordered children.
	 * 
	 * @return true if this element requires ordered children.
	 */
	public boolean isOrdered() {
		/*
		 * if (!m_CheckedOrdered) { m_CheckedOrdered = true; m_isOrdered =
		 * false; if (null == m_elements) return false;
		 * 
		 * int n = m_elements.length;
		 * 
		 * for (int i = 0; i < n; i++) { if (m_elements[i].getOrder() > 0) {
		 * m_isOrdered = true; return true; } } return false; } else
		 */
		return m_isOrdered;
	}

	/**
	 * the order that this element should appear, or -1 if not ordered
	 */
	private int m_order = -1;

	/**
	 * Get the order that this element should appear .
	 * 
	 * @return the order that this element should appear.
	 */
	public int getOrder() {
		return m_order;
	}

	/**
	 * the highest order of child elements have appeared so far, or -1 if not
	 * ordered
	 */
	private int m_lastOrder = -1;

	/**
	 * Get the highest order of child elements have appeared so far .
	 * 
	 * @return the highest order of child elements have appeared so far.
	 */
	public int getLastOrder() {
		return m_lastOrder;
	}

	/**
	 * Set the highest order of child elements have appeared so far .
	 * 
	 * @param order
	 *            the highest order of child elements have appeared so far.
	 */
	public void setLastOrder(int order) {
		m_lastOrder = order;
	}

	/**
	 * True if this element can appear multiple times
	 */
	private boolean m_multiAllowed = true;

	/**
	 * Get whether this element can appear multiple times
	 * 
	 * @return true if this element can appear multiple times
	 */
	public boolean getMultiAllowed() {
		return m_multiAllowed;
	}
}
