/*
 * Copyright 2001-2004 The Apache Software Foundation.
// (c) Copyright IBM Corp. 2004, 2005 All Rights Reserved
 * 
 * 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.
 */
package org.apache.axis.wsdl.symbolTable;

import org.apache.axis.Constants;
import org.apache.axis.utils.JavaUtils;
import org.w3c.dom.DOMException;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.namespace.QName;
import javax.xml.rpc.holders.BooleanHolder;
import javax.xml.rpc.holders.IntHolder;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.Vector;
/**
 * This class contains static utility methods specifically for schema type queries.
 * 
 * @author Rich Scheuerle  (scheu@us.ibm.com)
 */
public class CSchemaUtils extends SchemaUtils
{

    /** Field VALUE_QNAME */
    static final QName VALUE_QNAME = Utils.findQName("", "value");

    /**
     * This method checks mixed=true attribute is set either on
     * complexType or complexContent element.
     */
    public static boolean isMixed(Node node)
    {
        // Expecting a schema complexType
        if (isXSDNode(node, "complexType"))
        {
            String mixed = ((Element) node).getAttribute("mixed");
            if (mixed != null && mixed.length() > 0)
            {
                return ("true".equalsIgnoreCase(mixed) || "1".equals(mixed));
            }
            // Under the complexType there could be complexContent with
            // mixed="true"
            NodeList children = node.getChildNodes();

            for (int j = 0; j < children.getLength(); j++)
            {
                Node kid = children.item(j);
                if (isXSDNode(kid, "complexContent"))
                {
                    mixed = ((Element) kid).getAttribute("mixed");
                    return ("true".equalsIgnoreCase(mixed) || "1".equals(mixed));
                }
            }
        }
        return false;
    }

    public static Node getListOrUnionNode(Node node) 
    {
        // Expecting a schema complexType
        if (isXSDNode(node, "simpleType")) 
        {
            // Under the simpleType there could be union or list
            NodeList children = node.getChildNodes();
            for (int j = 0; j < children.getLength(); j++) 
            {
                Node kid = children.item(j);
                if (isXSDNode(kid, "union") || isXSDNode(kid, "list")) 
                    return kid;
                else if (isXSDNode(kid, "restriction"))
                {
                    NodeList rchildren = kid.getChildNodes();
                    for (int i = 0; i < rchildren.getLength(); i++) 
                    {
                        Node rkid = rchildren.item(i);
                        if (isXSDNode(rkid, "simpleType"))
                        {
                            Node unode = getListOrUnionNode(rkid);
                            if (unode != null)
                                return unode;
                        }
                    }
                }
            }
        }
        return null;
    }
    
    /**
     * This method checks out if the given node satisfies the 3rd condition
     * of the "wrapper" style:
     * such an element (a wrapper) must be of a complex type defined using the
     * xsd:sequence compositor and containing only elements declarations.
     * (excerpt from JAX-RPC spec 1.1 Maintenanace Review 2 Chapter 6 Section 4.1.)
     * 
     * @param node        
     * @return 
     */
    public static boolean isWrappedType(Node node)
    {

        if (node == null)
            return false;

        // If the node kind is an element, dive into it.
        if (isXSDNode(node, "element"))
        {
            NodeList children = node.getChildNodes();
            boolean hasComplexType = false;
            for (int j = 0; j < children.getLength(); j++)
            {
                Node kid = children.item(j);
                if (isXSDNode(kid, "complexType"))
                {
                    node = kid;
                    hasComplexType = true;
                    break;
                }
            }
            
            if (!hasComplexType)
                return false;
        }

        // Expecting a schema complexType
        if (isXSDNode(node, "complexType"))
        {
            // Under the complexType there could be complexContent/simpleContent
            // and extension elements if this is a derived type.
            // A wrapper element must be complex-typed.

            NodeList children = node.getChildNodes();

            for (int j = 0; j < children.getLength(); j++)
            {
                Node kid = children.item(j);

                if (isXSDNode(kid, "complexContent"))
                    return false;
                else if (isXSDNode(kid, "simpleContent"))
                    return false;
            }

            // Under the complexType there may be choice, sequence, group and/or all nodes.
            // (There may be other #text nodes, which we will ignore).
            // The complex type of a wrapper element must have only sequence 
            // and again element declarations in the sequence. 
            children = node.getChildNodes();
            int len =  children.getLength();
            for (int j = 0; j < len; j++)
            {
                Node kid = children.item(j);
          		String localName = kid.getLocalName();
          		if (localName != null && Constants.isSchemaXSD(kid.getNamespaceURI())) 
                {
                  	if (localName.equals("sequence")) 
                    {
                        Node sequenceNode = kid;
                        NodeList sequenceChildren = sequenceNode.getChildNodes();
                        int sequenceLen = sequenceChildren.getLength();
                        for (int k = 0; k < sequenceLen; k++) 
                        {
                            Node sequenceKid = sequenceChildren.item(k);
                            String sequenceLocalName = sequenceKid.getLocalName();
                            if (sequenceLocalName != null &&
                                    Constants.isSchemaXSD(sequenceKid.getNamespaceURI())) 
                            {
                                // allow choice with element children
                                if (sequenceLocalName.equals("choice")) 
                                {
                                    Node choiceNode = sequenceKid;
                                    NodeList choiceChildren = choiceNode.getChildNodes();
                                    int choiceLen = choiceChildren.getLength();
                                    for (int l = 0; l < choiceLen; l++) 
                                    {
                                        Node choiceKid = choiceChildren.item(l);
                                        String choiceLocalName = choiceKid.getLocalName();
                                        if (choiceLocalName != null &&
                                                Constants.isSchemaXSD(choiceKid.getNamespaceURI())) 
                                        {
                                            if (!choiceLocalName.equals("element")) 
                                                return false;
                                        }
                                    }
                                }
                                else if (!sequenceLocalName.equals("element")) 
                                    return false;
                            }
                        }
                        return true;
                    }
                    else
                        return false;
                }
            }
        }
        // allows void type
        return true;
    }

    /**
     * If the specified node represents a supported JAX-RPC complexType or
     * simpleType, a Vector is returned which contains ElementDecls for the
     * child element names.
     * If the element is a simpleType, an ElementDecls is built representing
     * the restricted type with the special name "value".
     * If the element is a complexType which has simpleContent, an ElementDecl
     * is built representing the extended type with the special name "value".
     * This method does not return attribute names and types
     * (use the getContainedAttributeTypes)
     * If the specified node is not a supported
     * JAX-RPC complexType/simpleType/element null is returned.
     * 
     * @param node        
     * @param symbolTable 
     * @return 
     */
    public static Vector getContainedElementDeclarations(Node node, 
                                                         SymbolTable symbolTable) {
        if (node == null)
            return null;

        // If the node kind is an element, dive into it.
        if (isXSDNode(node, "element"))
        {
            NodeList children = node.getChildNodes();

            for (int j = 0; j < children.getLength(); j++)
            {
                Node kid = children.item(j);

                if (isXSDNode(kid, "complexType"))
                {
                    node = kid;
                    break;
                }
            }
        }

        // Expecting a schema complexType or simpleType
        if (isXSDNode(node, "complexType"))
        {

            // Under the complexType there could be complexContent/simpleContent
            // and extension elements if this is a derived type.  Skip over these.
            NodeList children = node.getChildNodes();
            Node complexContent = null;
            Node simpleContent = null;
            Node extension = null;

            for (int j = 0; j < children.getLength(); j++)
            {
                Node kid = children.item(j);

                if (isXSDNode(kid, "complexContent"))
                {
                    complexContent = kid;
                    break; // REMIND: should this be here or on either branch?
                }
                else if (isXSDNode(kid, "simpleContent"))
                    simpleContent = kid;
            }

            if (complexContent != null)
            {
                children = complexContent.getChildNodes();

                for (int j = 0; (j < children.getLength()) && (extension == null); j++)
                {
                    Node kid = children.item(j);

                    if (isXSDNode(kid, "extension") || isXSDNode(kid, "restriction"))
                        extension = kid;
                }
            }

            if (simpleContent != null)
            {
                children = simpleContent.getChildNodes();

                int len =  children.getLength();
                for (int j = 0; (j < len) && (extension == null); j++) 
                {
                    Node kid = children.item(j);
                    String localName = kid.getLocalName();

                    if ((localName != null)
                        && (localName.equals("extension") || localName.equals("restriction"))
                        && Constants.isSchemaXSD(kid.getNamespaceURI())) 
                    {

                        // get the type of the extension/restriction from the "base" attribute
                        QName extendsOrRestrictsTypeName =
                            Utils.getTypeQName(children.item(j), new BooleanHolder(), false);

                        TypeEntry extendsOrRestrictsType =
                            symbolTable.getTypeEntry(extendsOrRestrictsTypeName, false);

                        // If this type extends a simple type, then add the
                        // special "value" ElementDecl, else this type is
                        // extending another simpleContent type and will
                        // already have a "value".

                        if (extendsOrRestrictsType == null || extendsOrRestrictsType.isBaseType())
                        {
                            // Return an element declaration with a fixed name
                            // ("value") and the correct type.
                            Vector v = new Vector();
                            CElementDecl elem = new CElementDecl(extendsOrRestrictsType, VALUE_QNAME);
                            v.add(elem);
    
                            return v;
                        }
                        else
                        {
                            // There can't be any other elements in a
                            // simpleContent node.
                            return null;
                        }
                    }
                }
            }

            if (extension != null)
                node = extension; // Skip over complexContent and extension

            // Under the complexType there may be choice, sequence, group and/or all nodes.
            // (There may be other #text nodes, which we will ignore).
            children = node.getChildNodes();

            Vector v = new Vector();
            int len = children.getLength();
            for (int j = 0; j < len; j++) 
            {
                Node kid = children.item(j);
                String localName = kid.getLocalName();
                if (localName != null && Constants.isSchemaXSD(kid.getNamespaceURI())) 
                {
                    if (localName.equals("sequence")) 
                        v.addAll(processSequenceNode(kid, symbolTable));
                    else if (localName.equals("all")) 
                        v.addAll(processAllNode(kid, symbolTable));
                    else if (localName.equals("choice")) 
                        v.addAll(processChoiceNode(kid, symbolTable));
                    else if (localName.equals("group")) 
                        v.addAll(processGroupNode(kid, symbolTable));
                }
            }

            return v;
        }
        else if (isXSDNode(node, "group"))
        {
            /*
            * Does this else clause make any sense anymore if
            * we're treating refs to xs:groups like a macro inclusion
            * into the referencing type?
            * Maybe this else clause should never be possible?
            *
            NodeList children = node.getChildNodes();
            Vector v = new Vector();
            int len = children.getLength();
            for (int j = 0; j < len; j++) {
                Node kid = children.item(j);
                String localName = kid.getLocalName();
                if (localName != null &&
                    Constants.isSchemaXSD(kid.getNamespaceURI())) {
                    if (localName.equals("sequence")) {
                        v.addAll(processSequenceNode(kid, symbolTable));
                    } else if (localName.equals("all")) {
                        v.addAll(processAllNode(kid, symbolTable));
                    } else if (localName.equals("choice")) {
                        v.addAll(processChoiceNode(kid, symbolTable));
                    }
                }
            }
            return v;
            */
            return null;
        }
        else
        {
            // This may be a simpleType, return the type with the name "value"
            QName[] simpleQName = getContainedSimpleTypes(node);

            if (simpleQName != null)
            {
                Vector v = null;

                for (int i = 0; i < simpleQName.length; i++)
                {
                    TypeEntry simpleType = symbolTable.getType(simpleQName[i]);

                    if (simpleType != null)
                    {
                        if (v == null)
                            v = new Vector();

                        QName qname = null;
                        if (simpleQName.length > 1)
                            qname = new QName("", simpleQName[i].getLocalPart() + "Value");
                        else
                            qname = new QName("", "value");

                        v.add(new CElementDecl(simpleType, qname));
                    }
                }

                return v;
            }
        }

        return null;
    }

    /**
     * Invoked by getContainedElementDeclarations to get the child element types
     * and child element names underneath a Choice Node
     * 
     * @param choiceNode  
     * @param symbolTable 
     * @return 
     */
    private static Vector processChoiceNode(Node choiceNode, SymbolTable symbolTable)
    {
        Vector v = new Vector();
        NodeList children = choiceNode.getChildNodes();
        int len = children.getLength();
        for (int j = 0; j < len; j++) 
        {
            Node kid = children.item(j);
            String localName = kid.getLocalName();

            if (localName != null && Constants.isSchemaXSD(kid.getNamespaceURI())) 
            {
                if (localName.equals("choice")) 
                    v.addAll(processChoiceNode(kid, symbolTable));
                else if (localName.equals("sequence")) 
                    v.addAll(processSequenceNode(kid, symbolTable));
                else if (localName.equals("group")) 
                    v.addAll(processGroupNode(kid, symbolTable));
                else if (localName.equals("element")) 
                {
                    CElementDecl elem = processChildElementNode(kid, symbolTable);

                    if (elem != null)
                    {
                        elem.setChoiceElement(true); 
                        v.add(elem);
                    }
                }
                else if (localName.equals("any")) 
                {
                    // Represent this as an element named any of type any type.
                    // This will cause it to be serialized with the element
                    // serializer.
                    TypeEntry type = symbolTable.getType(Constants.XSD_ANY);
                    CElementDecl elem = new CElementDecl(type, Utils.findQName("", "any"));

                    elem.setAnyElement(true);
                    v.add(elem);
                }
            }
        }

        return v;
    }

    /**
     * Returns named child node.
     * 
     * @param parentNode Parent node.
     * @param name Element name of child node to return.
     */
    private static Node getChildByName(Node parentNode, String name) throws DOMException
    {
        if (parentNode == null)
            return null;
        
        NodeList children = parentNode.getChildNodes();
        if (children != null)
        {
            for (int i = 0; i < children.getLength(); i++)
            {
                Node child = children.item(i);
                if (child != null)
                {
                    if ((child.getNodeName() != null && (name.equals(child.getNodeName()))) ||
                        (child.getLocalName() != null && (name.equals(child.getLocalName())))) 
                        return child;
                }
            }
        }
        return null;
    }

    /**
     * Returns all textual nodes of a subnode defined by a parent node
     * and a path of element names to that subnode.
     * 
     * @param root Parent node.
     * @param path Path of element names to text of interest, delimited by "/". 
     */
    public static String getTextByPath(Node root, String path) throws DOMException
    {
        StringTokenizer st = new StringTokenizer(path, "/");
        Node node = root;
        while (st.hasMoreTokens())
        {
            String elementName = st.nextToken();
            Node child = getChildByName(node, elementName);
            if (child == null)
                throw new DOMException(DOMException.NOT_FOUND_ERR, "could not find " + elementName);
            node = child;
        }

        // should have found the node
        String text = "";
        NodeList children = node.getChildNodes();
        if (children != null)
        {
            for (int i = 0; i < children.getLength(); i++)
            {
                Node child = children.item(i);
                if (child != null)
                {
                    if (child.getNodeName() != null
                        && (child.getNodeName().equals("#text")
                            || child.getNodeName().equals("#cdata-section")))
                    {
                        text += child.getNodeValue();
                    }
                }
            }
        }
        return text;
    }

    /**
     * Returns the complete text of the child xsd:annotation/xsd:documentation 
     * element from the provided node.  Only the first annotation element and 
     * the first documentation element in the annotation element will be used.
     * 
     * @param typeNode Parent node.
     */
    public static String getAnnotationDocumentation(Node typeNode)
    {
        Node annotationNode = typeNode.getFirstChild();
        while (annotationNode != null)
        {
            if (isXSDNode(annotationNode, "annotation"))
                break;
            annotationNode = annotationNode.getNextSibling();
        }
        Node documentationNode;
        if (annotationNode != null)
        {
            documentationNode = annotationNode.getFirstChild();
            while (documentationNode != null)
            {
                if (isXSDNode(documentationNode, "documentation"))
                    break;
                documentationNode = documentationNode.getNextSibling();
            }
        }
        else
            documentationNode = null;

        // should have found the node if it exists
        String text = "";
        if (documentationNode != null)
        {
            NodeList children = documentationNode.getChildNodes();
            if (children != null)
            {
                for (int i = 0; i < children.getLength(); i++)
                {
                    Node child = children.item(i);
                    if (child != null)
                    {
                        if (child.getNodeName() != null
                            && (child.getNodeName().equals("#text")
                                || child.getNodeName().equals("#cdata-section")))
                        {
                            text += child.getNodeValue();
                        }
                    }
                }
            }
        }
        return text;
    }

    /**
     * Invoked by getContainedElementDeclarations to get the child element types
     * and child element names underneath a Sequence Node
     * 
     * @param sequenceNode 
     * @param symbolTable  
     * @return 
     */
    private static Vector processSequenceNode(Node sequenceNode, 
                                              SymbolTable symbolTable)
    {
        Vector v = new Vector();
        NodeList children = sequenceNode.getChildNodes();
        int len = children.getLength();
        for (int j = 0; j < len; j++) 
        {
            Node kid = children.item(j);
            String localName = kid.getLocalName();

            if (localName != null && Constants.isSchemaXSD(kid.getNamespaceURI())) 
            {
                if (localName.equals("choice")) 
                    v.addAll(processChoiceNode(kid, symbolTable));
                else if (localName.equals("sequence")) 
                    v.addAll(processSequenceNode(kid, symbolTable));
                else if (localName.equals("group")) 
                    v.addAll(processGroupNode(kid, symbolTable));
                else if (localName.equals("any")) 
                {
                    // Represent this as an element named any of type any type.
                    // This will cause it to be serialized with the element
                    // serializer.
                    TypeEntry type = symbolTable.getType(Constants.XSD_ANY);
                    CElementDecl elem = new CElementDecl(type, Utils.findQName("", "any"));

                    elem.setAnyElement(true);
                    v.add(elem);
                }
                else if (localName.equals("element")) 
                {
                    CElementDecl elem = processChildElementNode(kid, symbolTable);
                    
                    if (elem != null)
                        v.add(elem);
                }
            }
        }

        return v;
    }

    /**
     * Invoked by getContainedElementDeclarations to get the child element types
     * and child element names underneath a group node. If a ref attribute is 
     * specified, only the referenced group element is returned.
     * 
     * @param groupNode   
     * @param symbolTable 
     * @return 
     */
    private static Vector processGroupNode(Node groupNode, SymbolTable symbolTable)
    {
        Vector v = new Vector();
        if (groupNode.getAttributes().getNamedItem("ref") == null)
        {
            NodeList children = groupNode.getChildNodes();
            int len = children.getLength();
            for (int j = 0; j < len; j++) 
            {
                Node kid = children.item(j);
                String localName = kid.getLocalName();
                if (localName != null && Constants.isSchemaXSD(kid.getNamespaceURI())) 
                {
                    if (localName.equals("choice")) 
                        v.addAll(processChoiceNode(kid, symbolTable));
                    else if (localName.equals("sequence")) 
                        v.addAll(processSequenceNode(kid, symbolTable));
                    else if (localName.equals("all")) 
                        v.addAll(processAllNode(kid, symbolTable));
                }
            }
        } 
        else 
        {
            QName nodeType = Utils.getTypeQName(groupNode, new BooleanHolder(), false);
            
            // The value of the second argument is 'false' since global model group
            // definitions are always represented by objects whose type is
            // assignment compatible with 'org.apache.axis.wsdl.symbolTable.Type'.
            TypeEntry type = symbolTable.getTypeEntry(nodeType, false);

            if (type != null && type.getNode() != null) 
            {
                Node node = type.getNode();
                NodeList children = node.getChildNodes();
            	for (int j = 0; j < children.getLength(); j++)
            	{
                	QName subNodeKind = Utils.getNodeQName(children.item(j));
                	if ((subNodeKind != null)
                    		&& Constants.isSchemaXSD(subNodeKind.getNamespaceURI()))
                	{
                    	if (subNodeKind.getLocalPart().equals("sequence")) 
                        	v.addAll(processSequenceNode(children.item(j), symbolTable));
                    	else if (subNodeKind.getLocalPart().equals("all"))
                        	v.addAll(processAllNode(children.item(j), symbolTable));
                    	else if (subNodeKind.getLocalPart().equals("choice")) 
                        	v.addAll(processChoiceNode(children.item(j), symbolTable));
                	}
            	}
            }
        }
        return v;
    }

    /**
     * Invoked by getContainedElementDeclarations to get the child element types
     * and child element names underneath an all node.
     * 
     * @param allNode     
     * @param symbolTable 
     * @return 
     */
    private static Vector processAllNode(Node allNode, SymbolTable symbolTable)
    {

        Vector v = new Vector();
        NodeList children = allNode.getChildNodes();

        for (int j = 0; j < children.getLength(); j++)
        {
            Node kid = children.item(j);

            if (isXSDNode(kid, "element"))
            {
                CElementDecl elem = processChildElementNode(kid, symbolTable);

                if (elem != null)
                {
                    elem.setAllElement(true); 
                    v.add(elem);
                }
            }
        }

        return v;
    }

    /**
     * Invoked by getContainedElementDeclarations to get the child element type
     * and child element name for a child element node.
     * <p/>
     * If the specified node represents a supported JAX-RPC child element,
     * we return an ElementDecl containing the child element name and type.
     * 
     * @param elementNode 
     * @param symbolTable 
     * @return 
     */
    private static CElementDecl processChildElementNode(Node elementNode,
                                                       SymbolTable symbolTable) 
    {
        // Get the name qnames.
        QName nodeName = Utils.getNodeNameQName(elementNode);
        BooleanHolder forElement = new BooleanHolder();
        String comments = null;
        comments = getAnnotationDocumentation(elementNode);

        // The type qname is used to locate the TypeEntry, which is then
        // used to retrieve the proper java name of the type.
        QName nodeType = Utils.getTypeQName(elementNode, forElement, false);        
        TypeEntry type = symbolTable.getTypeEntry(nodeType, forElement.value);
        
        // We want to treat schema references same way we treat anyType. 
        if (type == null 
                && nodeType.getLocalPart().equals("schema") 
                && nodeType.getNamespaceURI().equals("http://www.w3.org/2001/XMLSchema"))
        {
            forElement.value = false;
            type = symbolTable.getTypeEntry(nodeType, forElement.value);
        }
        
        //The boolean field 'qualified' is set to true 
        //if the element is namespace qualified.
        //The default value is unqualified.
        boolean qualified = false;
        
        // An element inside a complex type is either qualified or unqualified.
        // If the ref= attribute is used, the name of the ref'd element is used
        // (which must be a root element).  If the ref= attribute is not
        // used, the name of the element is unqualified.
        if (!forElement.value)
        {
            // check the Form (or elementFormDefault) attribute of this node to
            // determine if it should be namespace quailfied or not.
            String form = Utils.getAttribute(elementNode, "form");
            
            if ((form != null) && form.equals("unqualified"))
                nodeName = Utils.findQName("", nodeName.getLocalPart());
            else if ((form != null) && form.equals("qualified"))             
                qualified = true;
            else if (form == null)
            {
                // check elementFormDefault on schema element
                String def = Utils.getScopedAttribute(elementNode, "elementFormDefault");

                if ((def == null) || def.equals("unqualified"))
                    nodeName = Utils.findQName("", nodeName.getLocalPart());
                else if ((def == null) || def.equals("qualified"))
                    qualified = true;
            }
        }

        if (type != null)
        {
            CElementDecl elem = new CElementDecl(type, nodeName);
            elem.setDocumentation(comments);
            
            String minOccurs = Utils.getAttribute(elementNode, "minOccurs");
            if (minOccurs != null) {
                elem.setMinOccurs(Integer.parseInt(minOccurs));
			}
			
            String maxOccurs = Utils.getAttribute(elementNode, "maxOccurs");
            if (maxOccurs != null) {
                if (maxOccurs.equals("unbounded")) {
                    elem.setMaxOccurs(CElementDecl.UNBOUNDED);
                }
                else
                    elem.setMaxOccurs(Integer.parseInt(maxOccurs));
            }

            elem.setNillable(JavaUtils.isTrueExplicitly(Utils.getAttribute(elementNode, "nillable")));

            String useValue = Utils.getAttribute(elementNode, "use");

            if (useValue != null) 
                elem.setOptional(useValue.equalsIgnoreCase("optional"));

            elem.setNsQualified(qualified);
            
            return elem;
        }

        return null;
    }

    /**
     * Returns the WSDL2Java QName for the anonymous type of the element
     * or null.
     * 
     * @param node 
     * @return 
     */
    public static QName getElementAnonQName(Node node)
    {

        if (isXSDNode(node, "element"))
        {
            NodeList children = node.getChildNodes();

            for (int j = 0; j < children.getLength(); j++)
            {
                Node kid = children.item(j);

                if (isXSDNode(kid, "complexType") || isXSDNode(kid, "simpleType"))
                    return Utils.getNodeNameQName(kid);
            }
        }

        return null;
    }

    /**
     * Returns the WSDL2Java QName for the anonymous type of the attribute
     * or null.
     * 
     * @param node 
     * @return 
     */
    public static QName getAttributeAnonQName(Node node)
    {

        if (isXSDNode(node, "attribute"))
        {
            NodeList children = node.getChildNodes();

            for (int j = 0; j < children.getLength(); j++)
            {
                Node kid = children.item(j);

                if (isXSDNode(kid, "complexType") || isXSDNode(kid, "simpleType"))
                    return Utils.getNodeNameQName(kid);
            }
        }

        return null;
    }

    /**
     * If the specified node is a simple type or contains simpleContent, return true
     * 
     * @param node 
     * @return 
     */
    public static boolean isSimpleTypeOrSimpleContent(Node node) {

        if (node == null)
            return false;

        // If the node kind is an element, dive into it.
        if (isXSDNode(node, "element"))
        {
            NodeList children = node.getChildNodes();

            for (int j = 0; j < children.getLength(); j++)
            {
                Node kid = children.item(j);

                if (isXSDNode(kid, "complexType"))
                {
                    node = kid;
                    break;
                }
                else if (isXSDNode(kid, "simpleType"))
                    return true;
            }
        }

        // Expecting a schema complexType or simpleType
        if (isXSDNode(node, "simpleType"))
            return true;

        if (isXSDNode(node, "complexType"))
        {
            // Under the complexType there could be complexContent/simpleContent
            // and extension elements if this is a derived type.  Skip over these.
            NodeList children = node.getChildNodes();
            Node complexContent = null;
            Node simpleContent = null;

            for (int j = 0; j < children.getLength(); j++)
            {
                Node kid = children.item(j);

                if (isXSDNode(kid, "complexContent"))
                {
                    complexContent = kid;
                    break;
                }
                else if (isXSDNode(kid, "simpleContent"))
                    simpleContent = kid;
            }

            if (complexContent != null)
                return false;

            if (simpleContent != null)
                return true;
        }

        return false;
    }

    /**
     * Test whether <tt>node</tt> is not null, belongs to the XML
     * Schema namespace, and has a localName that matches
     * <tt>schemaLocalName</tt>
     * <p/>
     * This can be used to determine that a given Node defines a
     * schema "complexType" "element" and so forth.
     * 
     * @param node            a <code>Node</code> value
     * @param schemaLocalName a <code>String</code> value
     * @return true if the node is matches the name in the schema namespace.
     */
    private static boolean isXSDNode(Node node, String schemaLocalName)
    {
        if (node == null) 
            return false;

        String localName = node.getLocalName();
        if (localName == null) 
            return false;

        return (localName.equals(schemaLocalName) &&
                Constants.isSchemaXSD(node.getNamespaceURI()));
    }

    /**
     * Look for the base type of node iff node is a complex type that has been
     * derived by restriction; otherwise return null.
     * 
     * @param node        
     * @param symbolTable 
     * @return 
     */
    public static TypeEntry getComplexElementRestrictionBase(Node node, 
                                                             SymbolTable symbolTable)
    {
        if (node == null)
            return null;

        // If the node kind is an element, dive into it.
        if (isXSDNode(node, "element"))
        {
            NodeList children = node.getChildNodes();
            Node complexNode = null;

            for (int j = 0; (j < children.getLength()) && (complexNode == null); j++)
            {
                if (isXSDNode(children.item(j), "complexType"))
                {
                    complexNode = children.item(j);
                    node = complexNode;
                }
            }
        }

        // Expecting a schema complexType
        if (isXSDNode(node, "complexType"))
        {
            // Under the complexType there could be should be a complexContent &
            // restriction elements if this is a derived type.
            NodeList children = node.getChildNodes();
            Node content = null;
            Node restriction = null;

            for (int j = 0; (j < children.getLength()) && (content == null); j++)
            {
                Node kid = children.item(j);

                if (isXSDNode(kid, "complexContent") || isXSDNode(kid, "simpleContent")) 
                    content = kid;
            }

            if (content != null)
            {
                children = content.getChildNodes();

                for (int j = 0; (j < children.getLength()) && (restriction == null); j++)
                {
                    Node kid = children.item(j);

                    if (isXSDNode(kid, "restriction"))
                        restriction = kid;
                }
            }

            if (restriction == null)
                return null;
            else
            {
                // Get the QName of the extension base
                QName restrictionType =
                    Utils.getTypeQName(restriction, new BooleanHolder(), false);

                if (restrictionType == null)
                    return null;
                else
                {
                    // Return associated Type
                    return symbolTable.getType(restrictionType);
                }
            }
        }
        else
            return null;
    }

    /**
     * If the specified node represents a supported JAX-RPC complexType/element
     * which extends another complexType.  The Type of the base is returned.
     * 
     * @param node        
     * @param symbolTable 
     * @return 
     */
    public static TypeEntry getComplexElementExtensionBase(Node node,  
                                                           SymbolTable symbolTable)
    {
        if (node == null)
            return null;

        TypeEntry cached = (TypeEntry) symbolTable.node2ExtensionBase.get(node);

        if (cached != null)
            return cached; // cache hit

        // If the node kind is an element, dive into it.
        if (isXSDNode(node, "element"))
        {
            NodeList children = node.getChildNodes();
            Node complexNode = null;

            for (int j = 0; (j < children.getLength()) && (complexNode == null); j++)
            {
                if (isXSDNode(children.item(j), "complexType"))
                {
                    complexNode = children.item(j);
                    node = complexNode;
                }
            }
        }

        // Expecting a schema complexType
        if (isXSDNode(node, "complexType"))
        {
            // Under the complexType there could be should be a complexContent &
            // extension elements if this is a derived type.
            NodeList children = node.getChildNodes();
            Node content = null;
            Node extension = null;

            for (int j = 0; (j < children.getLength()) && (content == null); j++)
            {
                Node kid = children.item(j);

                if (isXSDNode(kid, "complexContent") || isXSDNode(kid, "simpleContent"))
                    content = kid;
            }

            if (content != null)
            {
                children = content.getChildNodes();

                for (int j = 0; (j < children.getLength()) && (extension == null); j++)
                {
                    Node kid = children.item(j);

                    if (isXSDNode(kid, "extension"))
                        extension = kid;
                }
            }

            if (extension == null)
                cached = null;
            else
            {
                // Get the QName of the extension base
                QName extendsType = 
                    Utils.getTypeQName(extension, new BooleanHolder(), false);

                if (extendsType == null)
                    cached = null;
                else
                {
                    // Return associated Type
                    cached = symbolTable.getType(extendsType);
                }
            }
        }

        symbolTable.node2ExtensionBase.put(node, cached);

        return cached;
    }

    /**
     * If the specified node represents a 'normal' non-enumeration simpleType,
     * the QName of the simpleType base is returned.
     * 
     * @param node 
     * @return 
     */
    public static QName getSimpleTypeBase(Node node)
    {

        QName[] qname = getContainedSimpleTypes(node);

        if ((qname != null) && (qname.length > 0))
            return qname[0];

        return null;
    }

    /**
     * Method getContainedSimpleTypes
     * 
     * @param node 
     * @return 
     */
    public static QName[] getContainedSimpleTypes(Node node)
    {

        QName[] baseQNames = null;

        if (node == null)
            return null;

        // If the node kind is an element, dive into it.
        if (isXSDNode(node, "element"))
        {
            NodeList children = node.getChildNodes();

            for (int j = 0; j < children.getLength(); j++)
            {
                if (isXSDNode(children.item(j), "simpleType"))
                {
                    node = children.item(j);
                    break;
                }
            }
        }

        // Get the node kind, expecting a schema simpleType
        if (isXSDNode(node, "simpleType"))
        {
            // Under the simpleType there should be a restriction.
            // (There may be other #text nodes, which we will ignore).
            NodeList children = node.getChildNodes();
            Node restrictionNode = null;
            Node unionNode = null;

            for (int j = 0;
                 (j < children.getLength()) && (restrictionNode == null);
                 j++) 
            {
                if (isXSDNode(children.item(j), "restriction"))
                    restrictionNode = children.item(j);
                else if (isXSDNode(children.item(j), "union"))
                    unionNode = children.item(j);
            }

            // The restriction node indicates the type being restricted
            // (the base attribute contains this type).
            if (restrictionNode != null)
            {
                baseQNames = new QName[1];
                baseQNames[0] = 
                    Utils.getTypeQName(restrictionNode, new BooleanHolder(), false);
            }

            if (unionNode != null)
                baseQNames = Utils.getMemberTypeQNames(unionNode);

            // Look for enumeration elements underneath the restriction node
            if ((baseQNames != null) && (restrictionNode != null) && (unionNode != null)) 
            {
                NodeList enums = restrictionNode.getChildNodes();

                for (int i = 0; i < enums.getLength(); i++)
                {
                    if (isXSDNode(enums.item(i), "enumeration"))
                    {
                        // Found an enumeration, this isn't a
                        // 'normal' simple type.
                        return null;
                    }
                }
            }
        }

        return baseQNames;
    }

    /**
     * Returns the contained restriction or extension node underneath
     * the specified node.  Returns null if not found
     * 
     * @param node 
     * @return 
     */
    public static Node getRestrictionOrExtensionNode(Node node)
    {

        Node re = null;

        if (node == null)
            return re;

        // If the node kind is an element, dive into it.
        if (isXSDNode(node, "element"))
        {
            NodeList children = node.getChildNodes();

            for (int j = 0; j < children.getLength(); j++)
            {
                Node n = children.item(j);

                if (isXSDNode(n, "simpleType") || isXSDNode(n, "complexType")
                    || isXSDNode(n, "simpleContent"))
                {
                    node = n;
                    break;
                }
            }
        }

        // Get the node kind, expecting a schema simpleType
        if (isXSDNode(node, "simpleType") || isXSDNode(node, "complexType"))
        {
            // Under the complexType there could be a complexContent.
            NodeList children = node.getChildNodes();
            Node complexContent = null;

            if (node.getLocalName().equals("complexType"))
            {
                for (int j = 0; (j < children.getLength()) && (complexContent == null); j++)
                {
                    Node kid = children.item(j);

                    if (isXSDNode(kid, "complexContent") || isXSDNode(kid, "simpleContent"))
                        complexContent = kid;
                }

                node = complexContent;
            }

            // Now get the extension or restriction node
            if (node != null)
            {
                children = node.getChildNodes();

                for (int j = 0;(j < children.getLength()) && (re == null); j++)
                {
                    Node kid = children.item(j);

                    if (isXSDNode(kid, "extension") || isXSDNode(kid, "restriction"))
                        re = kid;
                }
            }
        }

        return re;
    }

    /**
     * If the specified node represents an array encoding of one of the following
     * forms, then return the qname repesenting the element type of the array.
     * 
     * @param node is the node
     * @param dims is the output value that contains the number of dimensions if return is not null
     * @param itemQName will end up containing the "inner" QName for a
     *                       wrapped literal array
     * @return QName or null
     */
    public static QName getArrayComponentQName(Node node, 
                                               IntHolder dims, 
                                               SymbolTable symbolTable)
    {
        dims.value = 1; // assume 1 dimension

        QName qName = getCollectionComponentQName(node);

        if (qName == null)
            qName = getArrayComponentQName_JAXRPC(node, dims, symbolTable);

        return qName;
    }

    /**
     * If the specified node represents an element that references a collection
     * then return the qname repesenting the component of the collection.
     * <p/>
     * <xsd:element name="alias" type="xsd:string" maxOccurs="unbounded"/>
     * returns qname for"xsd:string"
     * <p/>
     * <xsd:complexType>
     *  <xsd:sequence>
     *   <xsd:element name="alias" type="xsd:string" maxOccurs="unbounded"/>
     *  </xsd:sequence>
     * </xsd:complexType>
     * returns qname for"xsd:string"
     * <p/>
     * <xsd:element ref="alias"  maxOccurs="unbounded"/>
     * returns qname for "alias"
     * 
     * @param node is the Node
     * @return QName of the compoent of the collection
     */
    public static QName getCollectionComponentQName(Node node)
    {
        if (node == null)
            return null;

        // If the node kind is an element, dive get its type.
        if (isXSDNode(node, "element"))
        {
            // Compare the componentQName with the name of the
            // full name.  If different, return componentQName
            BooleanHolder forElement = new BooleanHolder();
            QName componentQName = Utils.getTypeQName(node, forElement, true);

            if (componentQName != null)
            {
                QName fullQName = Utils.getTypeQName(node, forElement, false);

                if (!componentQName.equals(fullQName))
                    return componentQName;
            }
        }

        return null;
    }

    /**
     * If the specified node represents an array encoding of one of the following
     * forms, then return the qname repesenting the element type of the array.
     * 
     * @param node is the node
     * @param dims is the output value that contains the number of dimensions if return is not null
     * @return QName or null
     *         <p/>
     *         JAX-RPC Style 2:
     *         <xsd:complexType name="hobbyArray">
     *         <xsd:complexContent>
     *         <xsd:restriction base="soapenc:Array">
     *         <xsd:attribute ref="soapenc:arrayType" wsdl:arrayType="xsd:string[]"/>
     *         </xsd:restriction>
     *         </xsd:complexContent>
     *         </xsd:complexType>
     *         <p/>
     *         JAX-RPC Style 3:
     *         <xsd:complexType name="petArray">
     *         <xsd:complexContent>
     *         <xsd:restriction base="soapenc:Array">
     *         <xsd:sequence>
     *         <xsd:element name="alias" type="xsd:string" maxOccurs="unbounded"/>
     *         </xsd:sequence>
     *         </xsd:restriction>
     *         </xsd:complexContent>
     *         </xsd:complexType>
     */
    private static QName getArrayComponentQName_JAXRPC(Node node, 
                                                       IntHolder dims, 
                                                       SymbolTable symbolTable)
    {

        dims.value = 0; // Assume 0

        if (node == null)
            return null;

        // If the node kind is an element, dive into it.
        if (isXSDNode(node, "element"))
        {
            NodeList children = node.getChildNodes();

            for (int j = 0; j < children.getLength(); j++)
            {
                Node kid = children.item(j);

                if (isXSDNode(kid, "complexType"))
                {
                    node = kid;
                    break;
                }
            }
        }

        // Get the node kind, expecting a schema complexType
        if (isXSDNode(node, "complexType"))
        {
            // Under the complexType there should be a complexContent.
            // (There may be other #text nodes, which we will ignore).
            NodeList children = node.getChildNodes();
            Node complexContentNode = null;

            for (int j = 0; j < children.getLength(); j++)
            {
                Node kid = children.item(j);

                if (isXSDNode(kid, "complexContent") || isXSDNode(kid, "simpleContent"))
                {
                    complexContentNode = kid;
                    break;
                }
            }

            // Under the complexContent there should be a restriction.
            // (There may be other #text nodes, which we will ignore).
            Node restrictionNode = null;

            if (complexContentNode != null)
            {
                children = complexContentNode.getChildNodes();

                for (int j = 0; j < children.getLength(); j++)
                {
                    Node kid = children.item(j);

                    if (isXSDNode(kid, "restriction"))
                    {
                        restrictionNode = kid;
                        break;
                    }
                }
            }

            // The restriction node must have a base of soapenc:Array.
            QName baseType = null;

            if (restrictionNode != null)
            {
                baseType = Utils.getTypeQName(restrictionNode, new BooleanHolder(), false);

                if (baseType != null)
                {
                    if (!baseType.getLocalPart().equals("Array") || 
                            !Constants.isSOAP_ENC(baseType.getNamespaceURI()))
                    {
                        if (!symbolTable.arrayTypeQNames.contains(baseType))
                            baseType = null; // Did not find base=soapenc:Array
                    }
                }
            }

            // Under the restriction there should be an attribute OR a sequence/all group node.
            // (There may be other #text nodes, which we will ignore).
            Node groupNode = null;
            Node attributeNode = null;

            if (baseType != null)
            {
                children = restrictionNode.getChildNodes();

                for (int j = 0; (j < children.getLength())
                        && (groupNode == null)
                        && (attributeNode == null); j++) 
                {
                    Node kid = children.item(j);

                    if (isXSDNode(kid, "sequence") || isXSDNode(kid, "all"))
                    {
                        groupNode = kid;

                        if (groupNode.getChildNodes().getLength() == 0)
                        {

                            // This covers the rather odd but legal empty sequence.
                            // <complexType name="ArrayOfString">
                            // <complexContent>
                            // <restriction base="soapenc:Array">
                            // <sequence/>
                            // <attribute ref="soapenc:arrayType" wsdl:arrayType="string[]"/>
                            // </restriction>
                            // </complexContent>
                            // </complexType>
                            groupNode = null;
                        }
                    }

                    if (isXSDNode(kid, "attribute"))
                    {
                        // If the attribute node does not have ref="soapenc:arrayType"
                        // then keep looking.
                        BooleanHolder isRef = new BooleanHolder();
                        QName refQName = Utils.getTypeQName(kid, isRef, false);

                        if ((refQName != null) && isRef.value
                                && refQName.getLocalPart().equals("arrayType")
                                && Constants.isSOAP_ENC(refQName.getNamespaceURI()))
                            attributeNode = kid;
                    }
                }
            }

            // If there is an attribute node, look at wsdl:arrayType to get the element type
            if (attributeNode != null)
            {
                String wsdlArrayTypeValue = null;
                Vector attrs = Utils.getAttributesWithLocalName(attributeNode, "arrayType");

                for (int i = 0;
                     (i < attrs.size()) && (wsdlArrayTypeValue == null);
                     i++) 
                {
                    Node attrNode = (Node) attrs.elementAt(i);
                    String attrName = attrNode.getNodeName();
                    QName attrQName = Utils.getQNameFromPrefixedName(attributeNode, attrName);

                    if (Constants.isWSDL(attrQName.getNamespaceURI()))
                        wsdlArrayTypeValue = attrNode.getNodeValue();
                }

                // The value could have any number of [] or [,] on the end
                // Strip these off to get the prefixed name.
                // The convert the prefixed name into a qname.
                // Count the number of [ and , to get the dim information.
                if (wsdlArrayTypeValue != null)
                {
                    int i = wsdlArrayTypeValue.indexOf('[');

                    if (i > 0)
                    {
                        String prefixedName = wsdlArrayTypeValue.substring(0, i);
                        String mangledString = wsdlArrayTypeValue.replace(',', '[');

                        dims.value = 0;

                        int index = mangledString.indexOf('[');

                        while (index > 0)
                        {
                            dims.value++;
                            index = mangledString.indexOf('[', index + 1);
                        }

                        return Utils.getQNameFromPrefixedName(restrictionNode, prefixedName);
                    }
                }
            }
            else if (groupNode != null)
            {
                // Get the first element node under the group node.
                NodeList elements = groupNode.getChildNodes();
                Node elementNode = null;

                for (int i = 0; (i < elements.getLength()) && (elementNode == null); i++)
                {
                    Node kid = elements.item(i);

                    if (isXSDNode(kid, "element"))
                    {
                        elementNode = elements.item(i);
                        break;
                    }
                }

                // The element node should have maxOccurs="unbounded" and
                // a type
                if (elementNode != null)
                {
                    String maxOccursValue = Utils.getAttribute(elementNode, "maxOccurs");

                    if ((maxOccursValue != null) && maxOccursValue.equalsIgnoreCase("unbounded")) 
                    {
                        // Get the QName of the type without considering maxOccurs
                        dims.value = 1;

                        return Utils.getTypeQName(elementNode, new BooleanHolder(), true);
                    }
                }
            }
        }

        return null;
    }

    /**
     * adds an attribute node's type and name to the vector
     * helper used by getContainedAttributeTypes
     * 
     * @param v           
     * @param child       
     * @param symbolTable 
     */
    private static void addAttributeToVector(Vector v, Node child, 
                                             SymbolTable symbolTable)
    {
        // Get the name and type qnames.
        // The type qname is used to locate the TypeEntry, which is then
        // used to retrieve the proper java name of the type.
        QName attributeName = Utils.getNodeNameQName(child);
        BooleanHolder forElement = new BooleanHolder();
        QName attributeType = Utils.getTypeQName(child, forElement, false);

        // An attribute is either qualified or unqualified.
        // If the ref= attribute is used, the name of the ref'd element is used
        // (which must be a root element).  If the ref= attribute is not
        // used, the name of the attribute is unqualified.
        if (!forElement.value)
        {
            // check the Form (or attributeFormDefault) attribute of
            // this node to determine if it should be namespace
            // quailfied or not.
            String form = Utils.getAttribute(child, "form");

            if ((form != null) && form.equals("unqualified"))
            {
                // Unqualified nodeName
                attributeName = Utils.findQName("", attributeName.getLocalPart());
            }
            else if (form == null)
            {
                // check attributeFormDefault on schema element
                String def = Utils.getScopedAttribute(child, "attributeFormDefault");

                if ((def == null) || def.equals("unqualified"))
                    attributeName = Utils.findQName("", attributeName.getLocalPart());
            }
        }
        else
            attributeName = attributeType;

        // Get the corresponding TypeEntry from the symbol table
        TypeEntry type = symbolTable.getTypeEntry(attributeType, forElement.value);

        // Try to get the corresponding global attribute ElementEntry
        // from the symbol table.
        if (type instanceof org.apache.axis.wsdl.symbolTable.Element) 
            type = ((org.apache.axis.wsdl.symbolTable.Element) type).getRefType();
 
        // add type and name to vector, skip it if we couldn't parse it
        // XXX - this may need to be revisited.
        if ((type != null) && (attributeName != null))
        {
            CContainedAttribute attr = new CContainedAttribute(type, attributeName);

            String useValue = Utils.getAttribute(child, "use");
            if (useValue != null) 
                attr.setOptional(useValue.equalsIgnoreCase("optional"));
            
            String fixedValue = Utils.getAttribute(child, "fixed");
            if (fixedValue != null)
                attr.setFixedValue(fixedValue);
            
            String defaultValue = Utils.getAttribute(child, "default");
            if (defaultValue != null)
                attr.setDefaultValue(defaultValue);

            v.add(attr);
        }
    }

    /**
     * adds an attribute to the vector
     * helper used by addAttributeGroupToVector
     * 
     * @param v           
     * @param symbolTable 
     * @param type        
     * @param name        
     */
    private static void addAttributeToVector(Vector v, SymbolTable symbolTable, 
                                             QName type, QName name)
    {
        TypeEntry typeEnt = symbolTable.getTypeEntry(type, false);
                 
        if (typeEnt != null)
            v.add(new CContainedAttribute(typeEnt, name));
    }

    /**
     * adds each attribute group's attribute node to the vector
     * helper used by getContainedAttributeTypes
     * 
     * @param v           
     * @param attrGrpnode 
     * @param symbolTable 
     */
    private static void addAttributeGroupToVector(Vector v, Node attrGrpnode, 
                                                  SymbolTable symbolTable)
    {
        // get the type of the attributeGroup
        QName attributeGroupType = Utils.getTypeQName(attrGrpnode, new BooleanHolder(), false);
        TypeEntry type = symbolTable.getTypeEntry(attributeGroupType, false);
        
        if (type != null) 
        {
            if (type.getNode() != null)
            {
                // for each attribute or attributeGroup defined in the attributeGroup...
                NodeList children = type.getNode().getChildNodes();
    
                for (int j = 0; j < children.getLength(); j++)
                {
                    Node kid = children.item(j);
    
                    if (isXSDNode(kid, "attribute"))
                        addAttributeToVector(v, kid, symbolTable);
                    else if (isXSDNode(kid, "attributeGroup"))
                        addAttributeGroupToVector(v, kid, symbolTable);
                }
            }
            else if (type.isBaseType())
            {
                // soap/encoding is treated as a "known" schema
                // so let's act like we know it
                if (type.getQName().equals(Constants.SOAP_COMMON_ATTRS11))
                {
                    // 1.1 commonAttributes contains two attributes
                    addAttributeToVector(v,  symbolTable, Constants.XSD_ID,
                        new QName(Constants.URI_SOAP11_ENC, "id"));
                    addAttributeToVector(v,  symbolTable, Constants.XSD_ANYURI,
                        new QName(Constants.URI_SOAP11_ENC, "href"));
                }
                else if (type.getQName().equals(Constants.SOAP_COMMON_ATTRS12))
                {
                    // 1.2 commonAttributes contains one attribute
                    addAttributeToVector(v,  symbolTable, Constants.XSD_ID,
                        new QName(Constants.URI_SOAP12_ENC, "id"));
                }
                else if (type.getQName().equals(Constants.SOAP_ARRAY_ATTRS11))
                {
                    // 1.1 arrayAttributes contains two attributes
                    addAttributeToVector(v, symbolTable, Constants.XSD_STRING,
                        new QName(Constants.URI_SOAP12_ENC, "arrayType"));
                    addAttributeToVector(v, symbolTable, Constants.XSD_STRING,
                        new QName(Constants.URI_SOAP12_ENC, "offset"));
                }
                else if (type.getQName().equals(Constants.SOAP_ARRAY_ATTRS12))
                {
                    // 1.2 arrayAttributes contains two attributes
                    // the type of "arraySize" is really "2003soapenc:arraySize"
                    // which is rather of a hairy beast that is not yet supported
                    // in Axis, so let's just use string; nobody should care for
                    // now because arraySize wasn't used at all up until this
                    // bug 23145 was fixed, which had nothing to do, per se, with
                    // adding support for arraySize
                    addAttributeToVector(v, symbolTable, Constants.XSD_STRING,
                        new QName(Constants.URI_SOAP12_ENC, "arraySize"));
                    addAttributeToVector(v, symbolTable, Constants.XSD_QNAME,
                        new QName(Constants.URI_SOAP12_ENC, "itemType"));
                }
            }
        }
    }

    /**
     * Return the attribute names and types if any in the node
     * The even indices are the attribute types (TypeEntry) and
     * the odd indices are the corresponding names (Strings).
     * <p/>
     * Example:
     * <complexType name="Person">
     * <sequence>
     * <element minOccurs="1" maxOccurs="1" name="Age" type="double" />
     * <element minOccurs="1" maxOccurs="1" name="ID" type="xsd:float" />
     * </sequence>
     * <attribute name="Name" type="string" />
     * <attribute name="Male" type="boolean" />
     * <attributeGroup ref="s0:MyAttrSet" />
     * </complexType>
     * 
     * @param node        
     * @param symbolTable 
     * @return 
     */
    public static Vector getContainedAttributeTypes(Node node, 
                                                    SymbolTable symbolTable)
    {

        Vector v = null; // return value

        if (node == null)
            return null;

        // Check for SimpleContent
        // If the node kind is an element, dive into it.
        if (isXSDNode(node, "element"))
        {
            NodeList children = node.getChildNodes();
            int len = children.getLength();
            for (int j = 0; j < len; j++) 
            {
                Node kid = children.item(j);

                if (isXSDNode(kid, "complexType"))
                {
                    node = kid;
                    break;
                }
            }
        }

        // Expecting a schema complexType
        if (isXSDNode(node, "complexType"))
        {
            // Under the complexType there could be complexContent/simpleContent
            // and extension elements if this is a derived type.  Skip over these.
            NodeList children = node.getChildNodes();
            Node content = null;
            int len = children.getLength();
            for (int j = 0; j < len; j++) 
            {
                Node kid = children.item(j);

                if (isXSDNode(kid, "complexContent") || isXSDNode(kid, "simpleContent"))
                {
                    content = kid;
                    break;
                }
            }

            // Check for extensions or restrictions
            if (content != null)
            {
                children = content.getChildNodes();
                len = children.getLength();
                for (int j = 0; j < len; j++) 
                {
                    Node kid = children.item(j);

                    if (isXSDNode(kid, "extension") || isXSDNode(kid, "restriction"))
                    {
                        node = kid;
                        break;
                    }
                }
            }

            // examine children of the node for <attribute> elements
            children = node.getChildNodes();
            len = children.getLength();
            for (int i = 0; i < len; i++) 
            {
                Node child = children.item(i);

                if (isXSDNode(child, "attributeGroup")) 
                {
                	if (v == null)
                    	v = new Vector();

                    addAttributeGroupToVector(v, child, symbolTable);
                } 
                else if (isXSDNode(child, "anyAttribute")) 
                {
                    // do nothing right now
                    if (v == null) 
                        v = new Vector();
                } 
                else if (isXSDNode(child, "attribute")) 
                {
                    if (v == null) 
                        v = new Vector();

                    addAttributeToVector(v, child, symbolTable);
                }
            }
        }

        return v;
    }

    // list of all of the XSD types in Schema 2001

    /** Field schemaTypes[] */
    private static String schemaTypes[] = {
            "string", "normalizedString", "token", "byte", "unsignedByte",
            "base64Binary", "hexBinary", "integer", "positiveInteger",
            "negativeInteger", "nonNegativeInteger", "nonPositiveInteger", "int",
            "unsignedInt", "long", "unsignedLong", "short", "unsignedShort",
            "decimal", "float", "double", "boolean", "time", "dateTime", "duration",
            "date", "gMonth", "gYear", "gYearMonth", "gDay", "gMonthDay", "Name",
            "QName", "NCName", "anyURI", "language", "ID", "IDREF", "IDREFS",
            "ENTITY", "ENTITIES", "NOTATION", "NMTOKEN", "NMTOKENS",
            "anySimpleType"
    };

    /** Field schemaTypeSet */
    private static final Set schemaTypeSet =  new HashSet(Arrays.asList(schemaTypes));

    /**
     * Determine if a string is a simple XML Schema type
     * 
     * @param s 
     * @return 
     */
    private static boolean isSimpleSchemaType(String s) {
        if (s == null)
            return false;

        return schemaTypeSet.contains(s);
    }

    /**
     * Determine if a QName is a simple XML Schema type
     * 
     * @param qname 
     * @return 
     */
    public static boolean isSimpleSchemaType(QName qname)
    {

        if ((qname == null) || !Constants.isSchemaXSD(qname.getNamespaceURI()))
            return false;

        return isSimpleSchemaType(qname.getLocalPart());
    }

    /**
     * Returns the base type of a given type with its symbol table.
     * This logic is extracted from JavaTypeWriter's constructor() method
     * for reusing.
     * 
     * @param type 
     * @param symbolTable 
     * @return 
     */
    public static TypeEntry getBaseType(TypeEntry type, SymbolTable symbolTable) {
        Node node = type.getNode();
        TypeEntry base = getComplexElementExtensionBase(node, symbolTable);
        if (base == null)
            base = getComplexElementRestrictionBase(node, symbolTable);

        if (base == null)
        {
            QName baseQName = getSimpleTypeBase(node);
            if (baseQName != null)
                base = symbolTable.getType(baseQName);
        }
        return base;
    }

    /**
     * Returns whether the specified node represents a <xsd:simpleType> 
     * with a nested <xsd:list itemType="...">.
     * @param node 
     * @return 
     */
    public static boolean isListWithItemType(Node node)
    {
        return getListItemType(node) != null;
    }

    /**
     * Returns the value of itemType attribute of <xsd:list> in <xsd:simpleType> 
     * @param node 
     * @return 
     */
    public static QName getListItemType(Node node)
    {

        if (node == null)
            return null;

        // If the node kind is an element, dive into it.
        if (isXSDNode(node, "element"))
        {
            NodeList children = node.getChildNodes();
            for (int j = 0; j < children.getLength(); j++)
            {
                if (isXSDNode(children.item(j), "simpleType"))
                {
                    node = children.item(j);
                    break;
                }
            }
        }
        
        // Get the node kind, expecting a schema simpleType
        if (isXSDNode(node, "simpleType"))
        {
            NodeList children = node.getChildNodes();
            for (int j = 0; j < children.getLength(); j++)
            {
                if (isXSDNode(children.item(j), "list"))
                {
                    Node listNode = children.item(j);
                    org.w3c.dom.Element listElement = (org.w3c.dom.Element) listNode;
                    String type = listElement.getAttribute("itemType");
                    if (type.equals(""))
                    {
                        Node localType = null;
                        children = listNode.getChildNodes();
                        for (j = 0; j < children.getLength() && localType == null; j++)
                        {
                            if (isXSDNode(children.item(j), "simpleType")) 
                                localType = children.item(j);
                        }

                        if (localType != null)
                            return getSimpleTypeBase(localType);

                        return null;
                    }
                    //int colonIndex = type.lastIndexOf(":");
                    //if (colonIndex > 0) {
                        //type = type.substring(colonIndex + 1);
                    //}
                    //return new QName(Constants.URI_2001_SCHEMA_XSD, type + "[]");
                    return Utils.getQNameFromPrefixedName(node, type);
                }
            }
        }       
        return null;
    }
    
    /*
     * check whether node should be namespace qualified or not by checking for "form"
     * attribute. If "form" attribute not specified, the defaultAnswer is returned.
     */
    public static boolean shouldWeNamespaceQualifyNode(Node elementNode, boolean defaultAnswer)
    {
        if (null == elementNode || elementNode.getNodeType() != Node.ELEMENT_NODE)
            return defaultAnswer;
        
        // Ensure node represents an "element" node.  If not, get the parent.
        if (!elementNode.getLocalName().equals("element"))
            return shouldWeNamespaceQualifyNode(elementNode.getParentNode(), defaultAnswer);
        
        String form = Utils.getAttribute(elementNode, "form");
        if (form != null)
        {
            if (form.equals("qualified"))
                return true;
            else 
                return false;
        }
        else
            return defaultAnswer;
    }
    
    /*
     * Find out whether schema's elementFormDefault is "qualified" or not.  This is done by 
     * recursively interrogating parent nodes until it is found or not. 
     */
    public static boolean isElementFormDefaultQualified(Node elementNode)
    {
        if (elementNode != null)
        {
            String def = Utils.getScopedAttribute(elementNode, "elementFormDefault");
            if ((def != null) && def.equals("qualified"))
                return true;
        }
        
        return false;
    }
    
    /*
     * Find out whether schema's attributeFormDefault is "qualified" or not.  This is done by 
     * recursively interrogating parent nodes until it is found or not. 
     */
    public static boolean isAttributeFormDefaultQualified(Node attributeNode)
    {
        if (attributeNode != null)
        {
            String def = Utils.getScopedAttribute(attributeNode, "attributeFormDefault");
            if ((def != null) && def.equals("qualified"))
                return true;
        }
        
        return false;
    }
    
}
