/*
 *   Copyright 2003-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.wsdl2ws.info;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import javax.wsdl.Binding;
import javax.wsdl.BindingInput;
import javax.wsdl.BindingOperation;
import javax.wsdl.Fault;
import javax.wsdl.Operation;
import javax.wsdl.Part;
import javax.wsdl.Port;
import javax.wsdl.PortType;
import javax.wsdl.Service;
import javax.wsdl.WSDLElement;
import javax.wsdl.extensions.soap.SOAPBinding;
import javax.wsdl.extensions.soap.SOAPBody;
import javax.wsdl.extensions.soap.SOAPOperation;
import javax.wsdl.extensions.soap.SOAPAddress;
import javax.xml.namespace.QName;
import javax.xml.rpc.holders.BooleanHolder;
import javax.xml.rpc.holders.IntHolder;

import org.apache.axis.Constants;
import org.apache.axis.wsdl.gen.Parser;
import org.apache.axis.wsdl.symbolTable.BindingEntry;
import org.apache.axis.wsdl.symbolTable.CContainedAttribute;
import org.apache.axis.wsdl.symbolTable.CElementDecl;
import org.apache.axis.wsdl.symbolTable.CSchemaUtils;
import org.apache.axis.wsdl.symbolTable.CollectionElement;
import org.apache.axis.wsdl.symbolTable.CollectionType;
import org.apache.axis.wsdl.symbolTable.DefinedElement;
import org.apache.axis.wsdl.symbolTable.Element;
import org.apache.axis.wsdl.symbolTable.Parameters;
import org.apache.axis.wsdl.symbolTable.SchemaUtils;
import org.apache.axis.wsdl.symbolTable.ServiceEntry;
import org.apache.axis.wsdl.symbolTable.SymTabEntry;
import org.apache.axis.wsdl.symbolTable.SymbolTable;
import org.apache.axis.wsdl.symbolTable.TypeEntry;
import org.apache.axis.wsdl.toJava.Utils;
import org.apache.axis.wsdl.wsdl2ws.CUtils;
import org.apache.axis.wsdl.wsdl2ws.WrapperFault;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


/**
 * This class initiates the collection of various bits of information needed by the 
 * wsdl2ws tool by parsing the WSDL file.
 * 
 * @author nadir amra
 *
 */
public class WSDLInfo
{
    // Private constants for retrieving extensibility elements.
    private static final int INSTANCEOF_SOAPBINDING   = 1;
    private static final int INSTANCEOF_SOAPADDRESS   = 2;
    private static final int INSTANCEOF_SOAPBODY      = 3;
    private static final int INSTANCEOF_SOAPOPERATION = 4;



    // verbose flag 
    private boolean c_verbose = false;
    
    // parser timeout value, in seconds. 0=no timeout. 
    private long c_timeout = 0;
    
    // URI to WSDL document. 
    private String c_URIToWSDLDocument = null;
    
    // Whether wrapper-style is not requested. 
    private boolean c_noWrapperStyle = false;
    
    // WSDL parser from the last time parse() was invoked. 
    private Parser c_wsdlParser = null;
    
    // Symbol table associated with the parser.
    private SymbolTable c_symbolTable = null;
    
    // Types generated as result of symbolTable
    private TypeMap c_typeMap = null;
    
    // Target name space of WSDL 
    private String c_targetNameSpaceOfWSDL = null;
    
    // Service definitions in WSDL 
    ArrayList c_services = new ArrayList();
    
    // Maps service definition to set of ports that use RPC binding style 
    ArrayList c_bindings = new ArrayList();
    
    private static boolean useCounter = false;
    private static int typeCounter = 1;
    
    /**
     * Constructor.
     */
    public WSDLInfo(String uri)
    {
        c_URIToWSDLDocument = uri;
    }
    
    /**
     * Initiates the parsing of the WSDL document. Returns the symbol table that is generated
     * by the parser. After parsing the WSDL document, various artifacts that the wsdl2ws tool needs
     * is collected for easy access.  
     * 
     * @throws Exception 
     */
    public SymbolTable parse() throws Exception
    {
        // ==================================================
        // Parse WSDL document
        // ==================================================   
        
        c_wsdlParser = new Parser();
        
        // Set verbose in WSDL parser
        c_wsdlParser.setVerbose(c_verbose);
        
        // Set timeout for parser, setTimeout method expects the time in milliseconds.
        c_wsdlParser.setTimeout(c_timeout*1000); 
        
        // Set unwrapped if requested
        c_wsdlParser.setNowrap(c_noWrapperStyle);

        // Parse the WSDL document.
        c_wsdlParser.run(c_URIToWSDLDocument);
        c_symbolTable =  c_wsdlParser.getSymbolTable();
        
        // Dump symbol table if in verbose mode.
        if (c_verbose)
            c_symbolTable.dump(System.out);
        
        // ==================================================        
        // Collect various bits of information from the document.
        // ==================================================

        // Get target name space of WSDL
        c_targetNameSpaceOfWSDL = c_symbolTable.getDefinition().getTargetNamespace();

        // Collect services and bindings.           
        Iterator it = c_symbolTable.getHashMap().values().iterator();
        while (it.hasNext())
        {
            Vector v = (Vector) it.next();
            for (int i = 0; i < v.size(); ++i)
            {
                SymTabEntry entry = (SymTabEntry) v.elementAt(i);

                if (entry instanceof org.apache.axis.wsdl.symbolTable.ServiceEntry)
                    c_services.add(((ServiceEntry) entry).getService());
                else if (entry instanceof org.apache.axis.wsdl.symbolTable.BindingEntry)
                    c_bindings.add(entry);
            }
        }
        
        // Iterate through the symbol table, generating user-defined types and
        // storing the types in a hash table.  We need to do this twice.  We need
        // to first go through the types and ensure there is no type with a suffix of 
        // _Array, which is used by this code to generate arrays.  If there is, we need to
        // generate array types with a modified suffix, such as _Array + number.
        c_typeMap = new TypeMap();
        if (c_symbolTable !=  null)
        {
            it = c_symbolTable.getTypeIndex().values().iterator();
            
            while (it.hasNext())
            {
                TypeEntry type = (TypeEntry) it.next();
                Node node = type.getNode();
                if (node != null)
                {
                    if (type.getQName().getLocalPart().endsWith("_Array"))
                        useCounter = true;
                }
            }
            
            it = c_symbolTable.getTypeIndex().values().iterator();
            while (it.hasNext())
            {
                TypeEntry type = (TypeEntry) it.next();
                Node node = type.getNode();
                if (node != null)
                {
                    if (c_verbose)
                    {
                        System.out.println( "==>getTypeInfo: Processing type...." + type.getQName());                    
                    }
                                    
                    createTypeInfo(type);
                }
            }
        }

        // ==================================================
        // Return the symbol table
        // ==================================================
        
        return c_symbolTable;
    }

    /**
     * Sets the WSDL parser timeout value. 
     * 
     * @param t  timeout value in seconds. Null implies 0 timeout (no timeout).
     */
    public void setTimeout(long t)
    {
        c_timeout = t;
    }
    
    /**
     * Sets the WSDL parser verbose mode. 
     * 
     * @param b  true=verbose; false=no verbose.
     */
    public void setVerbose(boolean b)
    {
        c_verbose = b;
    }
    
    /**
     * Indicates whether wrapper-style interfaces is allowed. 
     * 
     * @param b  true=no wrapper style; false=allow wrapper style.
     */
    public void setNoWrapperStyle(boolean b)
    {
        c_noWrapperStyle = b;
    }

    /**
     * Returns target name space of WSDL.
     * 
     * @return String representing the target name space of WSDL.
     */
    public String getTargetNameSpaceOfWSDL()
    {
        return c_targetNameSpaceOfWSDL;
    }

    /**
     * Returns array of services defined in WSDL.  The array
     * may be empty if service was not defined in WSDL.
     * 
     * @return array of java.wsdl.Service objects.
     */
    public ArrayList getServices()
    {
        return c_services;
    }
    
    /**
     * Returns end point URI for a Port by looking for the soap:address extensibility element.
     * 
     * @param port
     * @return
     */
    public static String getTargetEndPointURI(Port port)
    {
        SOAPAddress e = (SOAPAddress)getExtensibilityElement(port, INSTANCEOF_SOAPADDRESS);
        if (e != null)
            return e.getLocationURI();
        return null;
    }

    /**
     * Returns the transport URI in a soap:binding element.
     * 
     * @param binding
     * @return
     */
    public static String getTransportType(Binding binding)
    {
        SOAPBinding e = (SOAPBinding)getExtensibilityElement(binding, INSTANCEOF_SOAPBINDING);
        if (e != null)
            return e.getTransportURI();
        return null;
    }
    
    /**
     * @return the c_typeMap
     */
    public TypeMap getTypeMap()
    {
        return c_typeMap;
    }
    
    /**
     * Return the binding entry matching the local name.
     * 
     * @param name
     * @return
     */
    public BindingEntry getBindEntry(String name)
    {
        Iterator it = c_bindings.iterator();
        while (it.hasNext())
        {
            BindingEntry be = (BindingEntry)it.next();
            if (be.getBinding().getQName().getLocalPart().equals(name))
                return be;
        }
        
        return null;
    }
    
    /**
     * Returns the Port that references the specified binding entry from a service definition.
     * 
     * @param s
     * @param be
     * @return
     */
    public static Port getPort(Service s, BindingEntry be)
    {
        Iterator ports = s.getPorts().values().iterator();
        while (ports.hasNext())
        {
            Port p = (Port) ports.next();
            Binding b = p.getBinding();
            if (be.getBinding().getQName().equals(b.getQName()))
                return p;
        }
        
        return null;
    }
    
    /**
     * Checks if binding entry is SOAP 1.1 binding.
     * @param be
     * @return
     */
    public static boolean isSOAP11Binding(BindingEntry be)
    {
        return isSOAPBinding(be, Constants.URI_WSDL11_SOAP);
    }
    
    /**
     * Checks if SOAP 1.2 binding.
     * @param be
     * @return
     */
    public static boolean isSOAP12Binding(BindingEntry be)
    {
        return isSOAPBinding(be, Constants.URI_WSDL12_SOAP);
    }

    /**
     * Updates MethodInfo with information from the binding operation element.
     * 
     * @param bindingOp
     * @param method
     */
    public static void updateMethodInfoFromBinding(BindingOperation bindingOp, MethodInfo method)
    {
        // Get SOAPAction
        SOAPOperation e = (SOAPOperation)getExtensibilityElement(bindingOp, INSTANCEOF_SOAPOPERATION);
        if (e != null)
            method.setSoapAction(e.getSoapActionURI());
        
        // Get information about input operation
        BindingInput  bi = bindingOp.getBindingInput();
        SOAPBody body = (SOAPBody)getExtensibilityElement(bi, INSTANCEOF_SOAPBODY);
        if (body != null)
        {
            method.setInputNamespaceURI(body.getNamespaceURI());            
        }
    }
    
    /**
     * Generate service name given a binding.
     * 
     * @param bindingEntry
     * @return
     * @throws WrapperFault
     */
    public static String getServiceName(BindingEntry bindingEntry) throws WrapperFault
    {
        PortType portType         = bindingEntry.getBinding().getPortType();
        if (portType == null)
            throw new WrapperFault("Port type specified in binding '" + bindingEntry.getBinding().getQName().getLocalPart() + "' not found");
            
        return CUtils.getNameFromFullyQualifiedName(portType.getQName().getLocalPart());
    }
    
    /**
     * Returns list of Port objects in the specified service.  All ports in the list 
     * will have a binding style of document and uses the SOAP 1.1 binding. 
     * 
     * @param s service definition
     * @return list of ports that match the criteria described above.
     * @throws Exception
     */
    public ArrayList getPortsSOAP11Document(Service s) throws Exception
    {
        return getServicePorts(s, true, true, false, false);
    }
    
    /**
     * Returns list of Port objects in the specified service.  All ports in the list 
     * will have a binding style of rpc and uses the SOAP 1.1 binding. 
     * 
     * @param s service definition
     * @return list of ports that match the criteria described above.
     * @throws Exception
     */
    public ArrayList getPortsSOAP11RPC(Service s) throws Exception
    {
        return getServicePorts(s, false, true, false, false);
    }
    
    /**
     * Returns list of Port objects in the specified service.  All ports in the list 
     * will have a binding style of document and uses the SOAP 1.2 binding. 
     * 
     * @param s service definition
     * @return list of ports that match the criteria described above.
     * @throws Exception
     */
    public ArrayList getPortsSOAP12Document(Service s) throws Exception
    {
        return getServicePorts(s, true, false, true, false);
    }
    
    /**
     * Returns list of Port objects in the specified service.  All ports in the list 
     * will have a binding style of rpc and uses the SOAP 1.2 binding. 
     * 
     * @param s service definition
     * @return list of ports that match the criteria described above.
     * @throws Exception
     */
    public ArrayList getPortsSOAP12RPC(Service s) throws Exception
    {
        return getServicePorts(s, false, false, true, false);
    }
    
    /**
     * Returns list of Port objects in the specified service.  All ports in the list 
     * uses the HTTP binding. 
     * 
     * @param s
     * @param styleDocument
     * @return
     * @throws Exception
     */
    public ArrayList getPortsREST(Service s) throws Exception
    {
        return getServicePorts(s, true, false, false, true);
    }
    
    /**
     * Returns list of Port objects in a service definition based on selection criteria.
     * 
     * @param s              service definition.
     * @param styleDocument  true=return document style; false=return "rpc" style. 
     *                       This parameter is ignored for REST (HTTP) bindings.
     * @param soap11         true=return SOAP 1.1 bindings; false=SOAP 1.1 bindings are ignored.
     * @param soap12         true=return SOAP 1.2 bindings; false=SOAP 1.2 bindings are ignored.
     * @param rest           true=return HTTP bindings; false=ignore HTTP bindings.
     * @return               List of ports that match selection criteria.
     * @throws Exception
     */
    private ArrayList getServicePorts(Service s, 
                                      boolean styleDocument, 
                                      boolean soap11, 
                                      boolean soap12, 
                                      boolean rest) throws Exception
    {        
        ArrayList a = new ArrayList();
        
        if (s == null)
            return a;

        Iterator ports = s.getPorts().values().iterator();
        while (ports.hasNext())
        {
            Port p = (Port) ports.next();
            Binding b = p.getBinding();
            BindingEntry be = c_symbolTable.getBindingEntry(b.getQName());
            if (b == null || be == null)
                throw new WrapperFault("No binding exists for port '" + p.getName() + "'.");
            
            if ((be.getBindingType() == BindingEntry.TYPE_SOAP) && (soap11 || soap12))
            {
                String style = be.getBindingStyle().getName();
                if (style == null)
                    style = "document";
                
                if ((styleDocument && style.equalsIgnoreCase("document"))
                        || (!styleDocument && style.equalsIgnoreCase("rpc")))
                {
                    String ns = Constants.URI_WSDL11_SOAP;
                    SOAPBinding soapbinding = (SOAPBinding)getExtensibilityElement(b, INSTANCEOF_SOAPBINDING);
                    if (soapbinding != null && null != soapbinding.getElementType().getNamespaceURI())
                        ns = soapbinding.getElementType().getNamespaceURI();
                        
                    if ((soap11 && ns.equals(Constants.URI_WSDL11_SOAP))
                            || (soap12 && ns.equals(Constants.URI_WSDL12_SOAP)))
                            a.add(p);
                }
            }
            else if (rest && (be.getBindingType() == BindingEntry.TYPE_HTTP_GET 
                                || be.getBindingType() == BindingEntry.TYPE_HTTP_POST))
            {
                a.add(p);
            }
        }
        
        return a;
    }
    
    /**
     * Helper function that returns requested extensibility element.
     * 
     * @param e element to retrieve extensibility elements from.
     * @param clazz instance of class
     * @return extensibility element.
     */
    private static Object getExtensibilityElement(WSDLElement e, int clazz)
    {
        if (e != null)
        {
            List extElems = e.getExtensibilityElements();
            if (extElems != null)
            {
                Iterator it = extElems.iterator();
                
                while (it.hasNext())
                {
                    Object o = it.next();
                    if ((clazz == INSTANCEOF_SOAPBINDING && (o instanceof javax.wsdl.extensions.soap.SOAPBinding))
                       || (clazz == INSTANCEOF_SOAPADDRESS && (o instanceof javax.wsdl.extensions.soap.SOAPAddress))
                       || (clazz == INSTANCEOF_SOAPOPERATION && (o instanceof javax.wsdl.extensions.soap.SOAPOperation))
                       || (clazz == INSTANCEOF_SOAPBODY && (o instanceof javax.wsdl.extensions.soap.SOAPBody)))
                        return o;
                }
            }
        }
        
        return null;
    }
    

    /**
     * Generate a type for the specified QName.
     * 
     * @param typename
     * @return
     * @throws WrapperFault
     */
    private Type createTypeInfo(QName typename)  throws WrapperFault
    {
        TypeEntry type = c_symbolTable.getType(typename);
        if (type == null)
        {
            type = c_symbolTable.getElement(typename);
            if (type == null)
                throw new WrapperFault("[" + typename + "]unexpected condition occurred. ");
        }
        
        return createTypeInfo(type);
    }
    
    /**
     * Creates a type map entry from a symbol table typeentry. 
     * 
     * @param type
     * @return
     * @throws WrapperFault
     */
    private Type createTypeInfo(TypeEntry type) throws WrapperFault
    {
        Type typedata = null;
        Type newSecondaryType = null;
        
        // Do not add types which are not used in the WSDL
        if (!type.isReferenced())
            return null;
        
        if (c_verbose && !CUtils.isPrimitiveType(type.getQName()))
            System.out.println("Attempting to create type: " + type.getQName());
        
        if (type instanceof CollectionElement)
        { //an array
        }
        else if (type instanceof DefinedElement)
        { 
            // if element references another type, process the referenced type
            if (type.getRefType() != null)
            {
                if (c_verbose)
                    System.out.println("Attempting to create new type from element-ref: " + type.getRefType().getQName());
                
                return createTypeInfo(type.getRefType());
            }

            return null;
        }
        
        if (-1 != type.getQName().getLocalPart().indexOf('['))
        { 
            // An array...
            
            // Get referenced type
            if (null == type.getRefType() || null == type.getRefType().getQName())
                throw new WrapperFault("Array type found without a Ref type: " + type.getQName());
            
            
            // TODO not sure what we should do if array references an element following commented code is not correct 
	        //  if (type.getRefType().getRefType() != null) 	 
	        //     qn = type.getRefType().getRefType().getQName();
            QName qn = type.getRefType().getQName();
            
            // If referenced type is primitive, we are done...
            if (CUtils.isPrimitiveType(qn))
                return null;
            
            // Create array 
            QName newqn;
            if (useCounter)
            {
                newqn = CUtils.getArrayQNameForType(qn);
                if (newqn == null)
                    newqn = new QName(type.getQName().getNamespaceURI(), CUtils.sanitizeString(qn.getLocalPart()) + "_Array" + typeCounter++);      
            }
            else
                newqn = new QName(type.getQName().getNamespaceURI(), CUtils.sanitizeString(qn.getLocalPart()) + "_Array");
            
            // type is a inbuilt type or an already created type?
            typedata = c_typeMap.getType(newqn);
            if (typedata != null)
            {
                if (typedata.isArray())
                {
                    if (c_verbose && !CUtils.isPrimitiveType(type.getQName()))
                        System.out.println("Type not created, already exists: " + type.getQName());
                    
                    return typedata;
                }
                else
                {
                    // There is a type with the _Array suffix in WSDL that was already processed.
                    // If an array type was not already created, create one with different name.
                    QName arrayQName = CUtils.getArrayQNameForType(qn);
                    if (arrayQName == null)
                    {
                        do 
                        {
                            newqn = new QName(type.getQName().getNamespaceURI(), CUtils.sanitizeString(qn.getLocalPart())  + "_Array" + typeCounter++);
                            typedata = c_typeMap.getType(newqn);
                        }
                        while (typedata != null && !typedata.isArray());
                        
                        if (typedata == null)
                        {
                            if (c_verbose)
                                System.out.println("Type clash, change type name to : " + newqn);
                        }
                        else 
                        {
                            if (c_verbose && !CUtils.isPrimitiveType(type.getQName()))
                                System.out.println("Type not created, already exists: " + type.getQName());
                            
                            return typedata;                            
                        }
                    }
                    else
                    {
                        if (c_verbose)
                            System.out.println("Type not created, already exists: " + type.getQName());
                        
                        return c_typeMap.getType(arrayQName);
                    }
                }
            }            
            
            typedata = new Type(newqn, newqn.getLocalPart());
            CUtils.addArrayType(qn, newqn);
            
            if (type.getRefType().getRefType() != null)
                typedata.setElementType(type.getRefType().getRefType().getQName().getLocalPart());
            else
                typedata.setElementType(type.getRefType().getQName().getLocalPart());     
        }
        else
        {
            // type is a inbuilt type or a already created type?
            typedata = c_typeMap.getType(type.getQName());
            if (typedata != null)
            {
                if (!typedata.isArray())
                {                
                    if (c_verbose && !CUtils.isPrimitiveType(type.getQName()))
                        System.out.println("Type not created, already exists: " + type.getQName());
                }
                
                return typedata;
            }
            
            typedata = new Type(type.getQName(), type.getQName().getLocalPart());
        }
        
        // Add type to type map
        if (c_verbose)
            System.out.println("Created new type: " + typedata.getName());
        
        c_typeMap.addType(typedata.getName(), typedata);
        
        // TODO revisit...work out whether this type will be generated or not 
        typedata.externalize(isTypeGenerated(type, typedata));

        Node node = type.getNode();

        if (type.isSimpleType())
        {            
            //check for extended types
            TypeEntry base = CSchemaUtils.getComplexElementExtensionBase(type.getNode(), c_symbolTable);
            if (base != null)
            {
                String localpart = type.getQName().getLocalPart() + "_value";
                QName typeName =  new QName(type.getQName().getNamespaceURI(), localpart);
                newSecondaryType = createTypeInfo(base.getQName());
                typedata.addRelatedType(newSecondaryType);
                typedata.setExtensionBaseType(new CElementDecl(newSecondaryType, typeName));
                if (c_verbose)
                    System.out.print(
                        "=====complexType with simpleContent is found : "
                            + type.getQName().getLocalPart() + "=====\n");
            }
            else
                setRestrictionBaseAndValues(typedata, node);
            
            // There can be attributes in this extended basic type
            Vector attributes = CSchemaUtils.getContainedAttributeTypes(type.getNode(), c_symbolTable);
            if (attributes != null)
            {
                for (int j = 0; j < attributes.size(); j++)
                {
                    CContainedAttribute attr = (CContainedAttribute)attributes.get(j);
                    newSecondaryType = createTypeInfo(attr.getTypeEntry().getQName());
                    attr.setType(newSecondaryType);
                    typedata.addRelatedType(newSecondaryType);
                }
                typedata.addAttributes(attributes);
            }
        }
        else if (type instanceof CollectionType)
        {
            typedata.setArray(true);

            newSecondaryType = createTypeInfo(type.getRefType().getQName());
            typedata.addRelatedType(newSecondaryType);
            typedata.setTypeNameForElementName(new CElementDecl(newSecondaryType, type.getQName()));
        }
        else
        {
            //is this a SOAPEnc array type    
            QName arrayType = CSchemaUtils.getArrayComponentQName(node,new IntHolder(0),c_symbolTable);
            if (arrayType != null)
            {
                typedata.setArray(true);

                newSecondaryType = createTypeInfo(arrayType);
                typedata.addRelatedType(newSecondaryType);
                typedata.setTypeNameForElementName(new CElementDecl(newSecondaryType, new QName("item")));
            }
            else if ((arrayType = CSchemaUtils.getCollectionComponentQName(node)) != null)
            {
                typedata.setArray(true);

                newSecondaryType = createTypeInfo(arrayType);
                typedata.addRelatedType(newSecondaryType);
                typedata.setTypeNameForElementName(new CElementDecl(newSecondaryType, new QName("item")));
            }
            //Note in a array the parameter type is stored as under the name item all the time  
            else
            {
                // get all extended types
                Vector extendList = new Vector();
                extendList.add(type);
                
                TypeEntry parent = CSchemaUtils.getComplexElementExtensionBase(type.getNode(), c_symbolTable);
                while (parent != null)
                {
                    extendList.add(parent);
                    parent = CSchemaUtils.getComplexElementExtensionBase(parent.getNode(), c_symbolTable);
                }

                // Now generate a list of names and types starting with
                // the oldest parent.  (Attrs are considered before elements).
                for (int i = extendList.size() - 1; i >= 0; i--)
                {
                    TypeEntry te = (TypeEntry) extendList.elementAt(i);

                    //TODO the code require the attributes name at extension base types
                    //different, the WSDL2Ws do not support it having same name at up and below.

                    // Process the attributes
                    if (c_verbose)
                        System.out.println("Processing attributes for type: " + type.getQName());

                    // TODO Need to handle whether attributes are qualified?
                    Vector attributes = CSchemaUtils.getContainedAttributeTypes(te.getNode(), c_symbolTable);
                    if (attributes != null)
                    {
                        for (int j = 0; j < attributes.size(); j++)
                        {
                            CContainedAttribute attr = (CContainedAttribute)attributes.get(j);
                            newSecondaryType = createTypeInfo(attr.getTypeEntry().getQName());
                            attr.setType(newSecondaryType);
                            typedata.addRelatedType(newSecondaryType);
                        }
                        typedata.addAttributes(attributes);
                    }                        
                    
                    // Process the elements
                    if (c_verbose)
                        System.out.println("Processing elements for type: " + type.getQName());
                    
                    Vector elements =  CSchemaUtils.getContainedElementDeclarations(te.getNode(), c_symbolTable);
                    if (elements != null)
                    {
                        // The following will get elementFormDefault for the schema the element is in.
                        boolean nsQualifyElementDefault = CSchemaUtils.isElementFormDefaultQualified(te.getNode());
                        
                        // Now process the elements.
                        for (int j = 0; j < elements.size(); j++)
                        {   
                            CElementDecl elem = (CElementDecl) elements.get(j);
                            
                            // Set whether to namespace qualify or not. We only process if not set.
                            if (!elem.getNsQualified())
                            {
                                boolean nsQualifyElement = 
                                    CSchemaUtils.shouldWeNamespaceQualifyNode(elem.getTypeEntry().getNode(), 
                                                                              nsQualifyElementDefault);
                                elem.setNsQualified(nsQualifyElement);
                            }
                            
                            if (elem.getAnyElement())
                            {
                                newSecondaryType =  new Type();
                            }
                            else
                            {
                                QName typeName = elem.getTypeEntry().getQName();
                                if (typeName.getLocalPart().indexOf('[') > 0)
                                {
                                    String localpart =
                                        typeName.getLocalPart().substring(0, typeName.getLocalPart().indexOf('['));
                                    
                                    typeName = new QName(typeName.getNamespaceURI(), localpart);
                                    
                                    if (CUtils.isPrimitiveType(typeName))
                                        newSecondaryType = createTypeInfo(typeName);
                                    else
                                        newSecondaryType = createTypeInfo(elem.getTypeEntry());
                                }
                                else
                                    newSecondaryType = createTypeInfo(typeName);
                            }
                            
                            typedata.addRelatedType(newSecondaryType);
                            elem.setType(newSecondaryType);
                                                       
                            typedata.setTypeNameForElementName(elem);
                        }
                    }
                } // for-loop
            }
        }
        return typedata;
    }    
    
    /**
     * Returns the actual referenced type (i.e. a defined type or base type)
     *  
     * @param type
     * @return
     */
    private TypeEntry getActualRefType(TypeEntry type)
    {
        if (type == null)
            return null;
        
        TypeEntry rt = type.getRefType();
        
        if (rt != null)
        {
            if (rt instanceof org.apache.axis.wsdl.symbolTable.DefinedType 
                    || rt instanceof org.apache.axis.wsdl.symbolTable.BaseType)
                return rt;
        }
        
        return getActualRefType(rt);
    }

    /**
     * If the specified node represents a supported JAX-RPC restriction,
     * a Vector is returned which contains the base type and the values (enumerations etc).
     * The first element in the vector is the base type (an TypeEntry).
     * Subsequent elements are QNames.
     * NEEDS WORK - CURRENTLY THE ONLY THING WE DO IS GENERATE ENUMERATOR CONSTANTS AND CREATE
     * AN EMPTY RESTRICTOR FUNCTION WHEN DOING CODE GENERATION STEP.
     */
    private void setRestrictionBaseAndValues(Type typedata, Node node) 
    {
        if (node == null)
            return;

        // If the node kind is an element, dive into it.
        QName nodeKind = Utils.getNodeQName(node);
        if (nodeKind != null &&
            nodeKind.getLocalPart().equals("element") &&
            Constants.isSchemaXSD(nodeKind.getNamespaceURI())) 
        {
            NodeList children = node.getChildNodes();
            Node simpleNode = null;
            for (int j = 0; j < children.getLength() && simpleNode == null; j++) 
            {
                QName simpleKind = Utils.getNodeQName(children.item(j));
                if (simpleKind != null &&
                    simpleKind.getLocalPart().equals("simpleType") &&
                    Constants.isSchemaXSD(simpleKind.getNamespaceURI())) 
                {
                    simpleNode = children.item(j);
                    node = simpleNode;
                }
            }
        }
        
        // Get the node kind, expecting a schema simpleType
        nodeKind = Utils.getNodeQName(node);
        if (nodeKind != null &&
            nodeKind.getLocalPart().equals("simpleType") &&
            Constants.isSchemaXSD(nodeKind.getNamespaceURI())) 
        {
             
            // Under the simpleType there may be a restriction, list, or union.
            // (There may be other #text nodes, which we will ignore).            
            // We do something special for unions and lists.  We treat them
            // as strings and ignore the processing of restriction nodes.
            Node restrictionNode = null;
            boolean isListOrUnionNode = false;
            restrictionNode = CSchemaUtils.getListOrUnionNode(node);
            
            if (restrictionNode != null)
                isListOrUnionNode = true;

            if (!isListOrUnionNode)
            {
                NodeList children = node.getChildNodes();
                for (int j = 0; j < children.getLength() && restrictionNode == null; j++) 
                {
                    QName restrictionKind = Utils.getNodeQName(children.item(j));
                    if (restrictionKind != null &&
                        restrictionKind.getLocalPart().equals("restriction") &&
                        Constants.isSchemaXSD(restrictionKind.getNamespaceURI()))
                        restrictionNode = children.item(j);
                }
            }
            
            // If no restriction or union or list node, just return
            if (restrictionNode == null)
                return;

            // The restriction node indicates the type being restricted
            // (the base attribute contains this type). For list or union types, 
            // treat as xsd:string.
            QName baseType;
            
            if (!isListOrUnionNode)
                baseType = Utils.getTypeQName(restrictionNode, new BooleanHolder(), false);
            else
                baseType = new QName("http://www.w3.org/2001/XMLSchema", "string");
            
            TypeEntry baseEType = c_symbolTable.getType(baseType);
            
            if (baseEType != null) 
            {
                QName  typedataQName     = typedata.getName();
                String typedataLocalpart = typedataQName.getLocalPart();
                String baseTypeLocalpart = baseEType.getQName().getLocalPart();
                
                QName  typedataQNameSanitized     = null;
                String typedataLocalpartSanitized = null;
                String baseTypeLocalpartSanitized = null;
                
                String methodSuffix = null;
                
                String primitiveXSDType          = null;
                String initValueForType          = null;
                String classForPrimitiveType     = null;
                
                if (TypeMap.isAnonymousType(typedataLocalpart))
                {
                    typedataQNameSanitized     = new QName(typedataQName.getNamespaceURI(), CUtils.sanitizeString(typedataLocalpart));
                    typedataLocalpartSanitized =  CUtils.sanitizeString(typedataLocalpart);
                }
                
                if (TypeMap.isAnonymousType(baseTypeLocalpart))
                    baseTypeLocalpartSanitized =  CUtils.sanitizeString(baseTypeLocalpart);
                
                String class4qname          = null;
                String class4qnameSanitized = null;
                
                String javaName = CUtils.getPrimitiveType(baseEType.getQName());
                boolean isBaseTypePrimitive = javaName != null;
                
                QName primitiveBaseTypeQName = null;
                
                if (javaName == null)
                {
                    // No mapping - ensure that the base type is simple - if it is, then this 
                    // must be a user-defined simple type that is based on another user-defined
                    // simple type.
                    if (!baseEType.isSimpleType()
                            && !SchemaUtils.isSimpleSchemaType(baseEType.getQName())) 
                        return;

                    // Get the primitive base type
                    TypeEntry primitiveBaseType = CSchemaUtils.getBaseType(baseEType, c_symbolTable);
                    primitiveBaseTypeQName      = primitiveBaseType.getQName();
                }
                else if (javaName.equals("boolean"))
                    return;
                else
                    primitiveBaseTypeQName = baseEType.getQName();
                
                classForPrimitiveType =  CUtils.getSimpleType(primitiveBaseTypeQName);
                initValueForType      =  CUtils.getInitValueForType(classForPrimitiveType);
                
                // Set the base type for Type
                typedata.setBaseType(primitiveBaseTypeQName);
                
                // We will map the user-defined type to the user-defined type, so set
                // mapping for the type.
                class4qname          = typedataLocalpart;
                class4qnameSanitized = typedataLocalpartSanitized;
                
                // Update some commonly-used mapping tables to reflect the user-defined
                // simple type. If anonymous type, we need to update mapping tables twice: once
                // with the anonymous names, and once with the sanitized names. 
                
                boolean isPointerType = CUtils.isPointerType(primitiveBaseTypeQName);
                primitiveXSDType = CUtils.getXSDEnumeratorForType(classForPrimitiveType);

                if (!isBaseTypePrimitive)
                {
                    typedata.setRestrictionBaseType(baseTypeLocalpart);
                    if (isPointerType)
                        CUtils.addPointerType(baseTypeLocalpart);
                }
                if (isPointerType)
                    CUtils.addPointerType(typedataLocalpart);                    

                methodSuffix = (String)CUtils.getDeserializerMethodSuffixForType(classForPrimitiveType);
                CUtils.addXSDEnumeratorForType(typedataLocalpart, primitiveXSDType);

                if (initValueForType != null)
                    CUtils.addInitValueForType(typedataLocalpart, initValueForType);
                CUtils.addDeserializerMethodSuffixForType(typedataLocalpart, methodSuffix);
                
                if (!isBaseTypePrimitive)
                {
                    CUtils.addXSDEnumeratorForType(baseTypeLocalpart, primitiveXSDType);
                    if (initValueForType != null)
                        CUtils.addInitValueForType(baseTypeLocalpart, initValueForType);
                    CUtils.addDeserializerMethodSuffixForType(baseTypeLocalpart, methodSuffix);
                }

                if (typedataQNameSanitized != null)
                {
                    if (isPointerType)
                        CUtils.addPointerType(typedataLocalpartSanitized); 
                    CUtils.addXSDEnumeratorForType(typedataLocalpartSanitized, primitiveXSDType);
                    if (initValueForType != null)
                        CUtils.addInitValueForType(typedataLocalpartSanitized, initValueForType);
                    CUtils.addDeserializerMethodSuffixForType(typedataLocalpartSanitized, methodSuffix);
                }
                
                if (baseTypeLocalpartSanitized != null)
                {
                    if (isPointerType)
                        CUtils.addPointerType(baseTypeLocalpartSanitized);
                    CUtils.addXSDEnumeratorForType(baseTypeLocalpartSanitized, primitiveXSDType);
                    if (initValueForType != null)
                        CUtils.addInitValueForType(baseTypeLocalpartSanitized, initValueForType);
                    CUtils.addDeserializerMethodSuffixForType(baseTypeLocalpartSanitized, methodSuffix);
                }         
                
                // Process the enumeration elements underneath the restriction node
                Vector v = new Vector();  
                if (!isListOrUnionNode)
                {
                    NodeList enums = restrictionNode.getChildNodes();
                    for (int i=0; i < enums.getLength(); i++) 
                    {
                        QName enumKind = Utils.getNodeQName(enums.item(i));
                        if (enumKind != null && Constants.isSchemaXSD(enumKind.getNamespaceURI())) 
                        {
                            Node enumNode = enums.item(i);
                            String value = Utils.getAttribute(enumNode, "value");
        
                            if (value.indexOf(':')>0)                                                        
                                    value=value.substring(value.indexOf(':')+1,value.length());
                            v.add(new QName(value, enumKind.getLocalPart()));
                        }
                    }
                }
                
                // The first element in the vector is a TypeEntry.
                v.add(0,baseEType);
                typedata.setRestrictiondata(v);
                typedata.setRestriction(true);
                
                // Add schema-defined simple type to mapping table - TODO: not sure we need this anymore.
                CUtils.addSchemaDefinedSimpleType(typedataQName, class4qname);
                if (typedataQNameSanitized != null)
                    CUtils.addSchemaDefinedSimpleType(typedataQNameSanitized, class4qnameSanitized);
            }
        }
        return;
    }      
    
    /**
     * Work out the various conditions that dictate whether this type will be generated into a new
     * file or not.
     * This method is only very partially implemented. 
     *   
     * @param type
     * @param typedata
     * @return true if the type will not be generated. False otherwise
     */
    private boolean isTypeGenerated(TypeEntry type, Type typedata)
    {
        // If the referenced type is actually a type that will not get generated because it's
        //     a base type array then tell other people of this case. Do this to two levels of indirection
        
        if(type.getRefType()!=null)
            if(type.getRefType().getRefType()!=null && type.getRefType().getRefType().isBaseType())
                return false;
            
        if (typedata.isAnonymous())
            return false;
        else
            return true;
    }
    
    
    /**
     * Process service operations, generating information about each operation.
     *
     * @param bindingEntry
     * @return               array of MethodInfo objects.
     * @throws WrapperFault
     */
    public ArrayList processServiceMethods(BindingEntry bindingEntry, 
                                           boolean wsdlWrappingStyle,
                                           boolean userRequestedWSDLWrappingStyle) throws WrapperFault
    {
        PortType portType         = bindingEntry.getBinding().getPortType();
        if (portType == null)
            throw new WrapperFault("Port type specified in binding '" + bindingEntry.getBinding().getQName().getLocalPart() + "' not found");
        
        ArrayList serviceMethods = new ArrayList();
        
        //get operation list
        Iterator oplist = portType.getOperations().iterator();
        while (oplist.hasNext())
        {
            Operation op     = (Operation) oplist.next();
            MethodInfo minfo = new MethodInfo(op.getName());
            
            // This chunk of code is new and we hope to use it more in the future to replace some of the 
            // things we do to process parameters.
            // When getOperationParameters() is called, the code, assuming user did not request unwrapped,
            // will determine whether the operation is eligible for wrapped-style.   The bad thing is that
            // isWrapped() is a method on the SymbolTable class.  So before processing an operation, 
            // we call setWrapped(false) before calling getOperationParameters() so that we can determine 
            // on a per-operation basis whether the operation is eligible for wrapped-style processing.
            c_symbolTable.setWrapped(false);
            Parameters opParams=null;
            try
            {
                opParams = c_symbolTable.getOperationParameters(op, "", bindingEntry);
                minfo.setOperationParameters(opParams);
                minfo.setEligibleForWrapped(c_symbolTable.isWrapped());
                
                // mark the method as wrapped or unwrapped.
                if (!wsdlWrappingStyle || !minfo.isEligibleForWrapped())
                {
                    minfo.setIsUnwrapped(true);
                    minfo.setConsumeBodyOnMessageValidation(false);
                }
            }
            catch (IOException e)
            {
                throw new WrapperFault(e);
            }

            if (c_verbose)
            {
                System.out.println("\n\n-----------------------------------------------");
                System.out.println("Parameters for operation: " + op.getName()); 
                System.out.println("-----------------------------------------------");
                System.out.println(opParams);
                System.out.println("-----------------------------------------------");
            }
            
            //setting the faults
            addFaultInfo(op.getFaults(), minfo);
            
            // process input and response messages 
            if ("document".equals(bindingEntry.getBindingStyle().getName()))
            {
                if (userRequestedWSDLWrappingStyle && !minfo.isEligibleForWrapped())
                    System.out.println("INFORMATIONAL: Operation '" + op.getName() + "' is not eligible for wrapper-style, generating non-wrapper style.");
               
                addDocumentStyleInputMessageToMethodInfo(bindingEntry, op, minfo);
                addDocumentStyleOutputMessageToMethodInfo(bindingEntry, op, minfo);
            }
            else
            {
                addRPCStyleInputMessageToMethodInfo(bindingEntry, op, minfo);
                addRPCStyleOutputMessageToMethodInfo(bindingEntry, op, minfo);
            }
            
            //add operation to operation List
            serviceMethods.add(minfo); 
        }
        
        // Need to get some stuff from binding element such as SOAPAction and namespace for 
        // each operation - we store the information in the method. 
        List operations = bindingEntry.getBinding().getBindingOperations();
        if (operations != null)
        {
            for (int i = 0; i < operations.size(); i++)
            {
                //for the each binding operation found
                if (operations.get(i) instanceof javax.wsdl.BindingOperation)
                {
                    javax.wsdl.BindingOperation bindinop = (javax.wsdl.BindingOperation) operations.get(i);
                    
                    String name = bindinop.getName();
                    MethodInfo method = null;
                    
                    for (int ii = 0; ii < serviceMethods.size(); ii++)
                        if (((MethodInfo) serviceMethods.get(ii)).getMethodname().equals(name))
                            method = (MethodInfo) serviceMethods.get(ii);
                    
                    if (method == null)
                        throw new WrapperFault("The binding and portType elements do not match.");                    
                    
                    // Get binding operation information and store in method for later use.
                    WSDLInfo.updateMethodInfoFromBinding(bindinop, method);
                }
            }
        }
        
        return serviceMethods;
    }

    /**
     * @param op
     * @param minfo MethodInfo object into which output message and it's elements are to be added
     * @throws WrapperFault
     */
    private void addRPCStyleOutputMessageToMethodInfo(BindingEntry bindingEntry, Operation op, MethodInfo minfo) throws WrapperFault
    {
        if (op.getOutput() == null)
            return;
        
        ParameterInfo pinfo;
        Iterator returnlist;

        minfo.setInputMessage(op.getInput().getMessage().getQName());
        minfo.setOutputMessage(op.getOutput().getMessage().getQName());

        if (op.getParameterOrdering() != null)
        {
            for (int ix = 0; ix < op.getParameterOrdering().size(); ix++)
            {
                Part p = (Part) (op.getOutput().getMessage().getParts().get((String) op.getParameterOrdering().get(ix)));
                if (p == null)
                    continue;
                pinfo = createParameterInfo(p);
                if (null != pinfo)
                    minfo.addOutputParameter(pinfo);
            }
            
            // TODO recheck parameter ordering logic....
            // there can be more output parameters than in parameterOrder list (partial parameter ordering)
            returnlist = op.getOutput().getMessage().getParts().values().iterator();
            while (returnlist.hasNext())
            { 
                //RPC style messages can have multiple parts
                Part p = (Part) returnlist.next();
                if (op.getParameterOrdering().contains(p.getName()) 
                        || (bindingEntry.isOutHeaderPart(op.getName(), p.getName())))
                    continue;
                pinfo = createParameterInfo(p);
                if (null != pinfo)
                    minfo.addOutputParameter(pinfo);
            }
        }
        else
        {
            returnlist = op.getOutput().getMessage().getParts().values().iterator();
            while (returnlist.hasNext())
            { 
                //RPC style messages can have multiple parts
                Part p = ((Part) returnlist.next());
                if (bindingEntry.isOutHeaderPart(op.getName(), p.getName()))
                    continue;
                pinfo = createParameterInfo(p);
                if (null != pinfo)
                    minfo.addOutputParameter(pinfo);
            }
        }
    }

    /**
     * @param minfo MethodInfo object into which output message and it's elements are to be added
     * @param part
     * @throws WrapperFault
     */
    private void addDocumentStyleOutputMessageToMethodInfo(BindingEntry bindingEntry, Operation op, MethodInfo minfo) throws WrapperFault
    {
        if (op.getOutput() == null)
            return;

        Part part = null;

        // For now, skip over soap header parts
        Iterator returnlist = op.getOutput().getMessage().getParts().values().iterator();
        while (returnlist.hasNext())
        {
            part = (Part) returnlist.next();
            if (bindingEntry.isOutHeaderPart(op.getName(), part.getName()))
                part = null;
            else 
                break;
        }        
        
        // If no output parameter, simply return.
        if (part == null)
            return;

        
        QName qname;
        QName minfoqname;
        TypeEntry elementTypeEntry;
        
        Element element = c_symbolTable.getElement(part.getElementName());

        if (element == null)
        {
            elementTypeEntry = c_symbolTable.getType(part.getTypeName());
            qname            = elementTypeEntry.getQName();
            minfoqname       = elementTypeEntry.getQName();
        }
        else
        {
            elementTypeEntry = element.getRefType();
            qname            = elementTypeEntry.getQName();
            minfoqname       = element.getQName();
        }
        
        minfo.setOutputMessage(minfoqname);

        if (qname == null)
            return;
        
        Type type = c_typeMap.getType(qname);
        if (type == null)
            throw new WrapperFault("Unregistered type " + qname + " referenced!");

        // TODO - need to look into this more.
        // For wrapped style, inner attributes and elements are added as parameters.
        // For unwrapped style, objects are used for the parameters (i.e. classes or structures).
        
        Iterator elementNames = type.getElementnames();
        Iterator attributes   = type.getAttributes();
        if (!minfo.isUnwrapped())
        {
            if (!elementNames.hasNext())
            {
                // Type must be simple or primitive...we do a check just to make sure.
                if (type.isSimpleType() || type.isPrimitiveType())
                {
                    String elementName = (String) element.getQName().getLocalPart();
                    ParameterInfo pinfo = new ParameterInfo();
                    pinfo.setType(type);
                    pinfo.setParamName(elementName, c_typeMap);
                    pinfo.setElementName(element.getQName());
                    pinfo.setAnyElement(type.isAnyElement());
                    minfo.addOutputParameter(pinfo);                    
                    minfo.setConsumeBodyOnMessageValidation(false);
                }
            }
            else
            {
                while (elementNames.hasNext())
                {
                    String elementname  = (String) elementNames.next();
                    CElementDecl eleinfo = type.getElementForElementName(elementname);
                    Type innerType      = eleinfo.getType();
                    
                    ParameterInfo pinfo = new ParameterInfo();
                    pinfo.setType(innerType);
                    pinfo.setParamName(elementname, c_typeMap);
                    pinfo.setArray(eleinfo.getMaxOccurs() > 1);
                    pinfo.setNillable(eleinfo.isNillable());
                    pinfo.setOptional(eleinfo.getMinOccurs() == 0);
                    pinfo.setElementName(type.getElementForElementName(elementname).getName());
                    pinfo.setAnyElement(innerType.isAnyElement());
    
                    minfo.addOutputParameter(pinfo);
                }
            }
        }
        else
        { 
            // Ensure there is a response, if not, then operation is a one-way operation.
            if (type.isSimpleType() 
                    || type.isPrimitiveType()
                    || elementNames.hasNext() 
                    || (attributes != null && attributes.hasNext()))
            {
                String elementName = (String) element.getQName().getLocalPart();
                
                ParameterInfo pinfo = new ParameterInfo();
                pinfo.setType(type);
                type.setIsUnwrappedOutputType(true);
                pinfo.setParamName(elementName, c_typeMap);
                
                if (element != null)
                    pinfo.setElementName(element.getQName());
                else
                    pinfo.setElementName(type.getName());
                
                pinfo.setAnyElement(type.isAnyElement());
                
                // Let us be nice and uppercase the first character in type name, 
                // in addition to resolving method name/type conflicts.
                type.setLanguageSpecificName(generateNewTypeName(type, minfo));
                
                minfo.addOutputParameter(pinfo);
            }
            else if (!elementNames.hasNext())
            {
                // empty element....check message response but no deserialization necessary
                minfo.setConsumeBodyOnMessageValidation(true);
            }
        }
    }

    /**
     * @param op
     * @param minfo
     * @throws WrapperFault
     */
    private void addRPCStyleInputMessageToMethodInfo(BindingEntry bindingEntry, Operation op, MethodInfo minfo)
        throws WrapperFault
    {
        ParameterInfo pinfo;
        Iterator paramlist;

        minfo.setInputMessage(op.getInput().getMessage().getQName());
        if (op.getParameterOrdering() != null)
        {
            for (int ix = 0; ix < op.getParameterOrdering().size(); ix++)
            {
                Part p = (Part) (op.getInput()
                                   .getMessage()
                                   .getParts()
                                   .get((String) op.getParameterOrdering().get(ix)));
                if (p == null
                        || bindingEntry.isInHeaderPart(op.getName(), p.getName()))
                    continue;

                pinfo = createParameterInfo(p);
                if (null != pinfo)
                    minfo.addInputParameter(pinfo);
            }
        }
        else
        {
            paramlist = op.getInput().getMessage().getParts().values().iterator();
            while (paramlist.hasNext())
            { 
                //RPC style messages can have multiple parts
                Part p = (Part) paramlist.next();
                if (bindingEntry.isInHeaderPart(op.getName(), p.getName()))
                    continue;

                pinfo = createParameterInfo(p);
                if (null != pinfo)
                    minfo.addInputParameter(pinfo);
            }
        }
    }

    /**
     * @param op
     * @param minfo
     * @throws WrapperFault
     */
    private void addDocumentStyleInputMessageToMethodInfo(BindingEntry bindingEntry, Operation op, MethodInfo minfo)
        throws WrapperFault
    {   
        Part part = null;
        
        // For now, skip over soap header parts.
        Iterator paramlist = op.getInput().getMessage().getParts().values().iterator();
        while (paramlist.hasNext())
        {
            part = (Part) paramlist.next();
            if (bindingEntry.isInHeaderPart(op.getName(), part.getName()))
                part = null;
            else
                break;
        }        
        
        // If no input parameter, simply return.
        if (part == null)
            return;       
            
        QName minfoqname;
        QName qname;
        
        Element element = c_symbolTable.getElement(part.getElementName());
        
        if (element == null)
        {
            // the part reference a type.
            qname = c_symbolTable.getType(part.getTypeName()).getQName();
            minfoqname = c_symbolTable.getType(part.getTypeName()).getQName();
        }
        else
        {
            qname = element.getRefType().getQName();
            minfoqname = element.getQName();
        }
        
        minfo.setInputMessage(minfoqname);

        if (qname == null)
            return;
        
        Type type = c_typeMap.getType(qname);
        if (type == null)
            throw new WrapperFault("unregistered type " + qname + " referenced");

        // For wrapped style, inner attributes and elements are added as parameters.
        // For unwrapped style, objects are used for the parameters (i.e. classes or structures).
        Iterator elementNames = type.getElementnames();
        Iterator attributes   = type.getAttributes();
        if (!minfo.isUnwrapped())
        {
            // Add input elements to method info
            while (elementNames.hasNext())
            {
                String elementname = (String) elementNames.next();
                CElementDecl eleinfo = type.getElementForElementName(elementname);
                Type innerType = eleinfo.getType();
                
                ParameterInfo pinfo = new ParameterInfo();
                pinfo.setType(innerType);
                pinfo.setParamName(elementname, c_typeMap);     
                pinfo.setArray(eleinfo.getMaxOccurs() > 1);
                pinfo.setElementName(type.getElementForElementName(elementname).getName());
                pinfo.setAnyElement(innerType.isAnyElement());
                pinfo.setNillable(eleinfo.isNillable());
                pinfo.setOptional(eleinfo.getMinOccurs() == 0);

                minfo.addInputParameter(pinfo);
            }
            
            // add input attributes to method info - TODO probably can remove this chunk of code.
            if (attributes != null)
            {
                while (attributes.hasNext())
                {
                    CContainedAttribute attr = (CContainedAttribute)attributes.next();
    
                    ParameterInfo pinfo = new ParameterInfo();
    
                    pinfo.setType(attr.getType());
                    pinfo.setParamName(attr.getName(), c_typeMap);
                    pinfo.setElementName(attr.getType().getName());
                    pinfo.setAttribute(true);
                    
                    minfo.addInputParameter(pinfo);
                }
            }
        }
        else
        { 
            // If input element is complex and does not contain any sub-elements or attributes, we ignore.
            if (type.isSimpleType() 
                    || type.isPrimitiveType()
                    || elementNames.hasNext() 
                    || (attributes != null && attributes.hasNext()))
            {
                String elementName;
                
                if (element != null)
                    elementName = element.getQName().getLocalPart();
                else
                    elementName = type.getName().getLocalPart();
                
                ParameterInfo pinfo = new ParameterInfo();
                
                pinfo.setType(type);
                type.setIsUnwrappedInputType(true);
                pinfo.setParamName(elementName, c_typeMap);
                
                if (element != null)
                    pinfo.setElementName(element.getQName());
                else
                    pinfo.setElementName(type.getName());
                
                pinfo.setAnyElement(type.isAnyElement());
    
                // Let us be nice and uppercase the first character in type name, 
                // in addition to resolving method name/type conflicts.
                type.setLanguageSpecificName(generateNewTypeName(type, minfo));
                
                minfo.addInputParameter(pinfo);
            }
        }
    }

    /**
     * Adds faults.
     * 
     * @param faults
     * @param methodinfo
     * @throws WrapperFault
     */
    private void addFaultInfo(Map faults, MethodInfo methodinfo)
        throws WrapperFault
    {
        if (faults == null)
            return;
        
        Iterator faultIt = faults.values().iterator();
        while (faultIt.hasNext())
        {
            Fault fault = (Fault) faultIt.next();
            FaultInfo faultinfo = new FaultInfo(fault.getName());

            Map parts = fault.getMessage().getParts();
            Iterator partIt = parts.values().iterator();
            while (partIt.hasNext())
            {
                ParameterInfo pinfo = createParameterInfo((Part) partIt.next());
                pinfo.getType().setAsFault(true);
                faultinfo.addParam(pinfo);
            }
            
            methodinfo.addFaultType(faultinfo);
        }
    }

    /**
     * 
     * @param part
     * @return
     * @throws WrapperFault
     */
    private ParameterInfo createParameterInfo(Part part) throws WrapperFault
    {
        QName qname = part.getTypeName();
        if (qname == null)
        {
            Element element = c_symbolTable.getElement(part.getElementName());
            qname = element.getRefType().getQName();
        }

        Type type = c_typeMap.getType(qname);
        if (type == null)
            throw new WrapperFault("unregistered type " + qname + " referred");
        
        ParameterInfo pinfo = new ParameterInfo();
        pinfo.setType(type);
        pinfo.setParamName(part.getName(), c_typeMap);
        pinfo.setElementName(part.getElementName());
        return pinfo;
    }
    
    /**
     * Resolves name conflict between a method name and a type name. 
     * When doing document-literal, usually the name of the wrapper element is same as the 
     * operation name. 
     * 
     * @param type
     * @param minfo
     * @return the new type name that does not conflict with the operation name.
     */
    private String generateNewTypeName(Type type, MethodInfo minfo)
    {
        String minfo_nm = minfo.getMethodname();
        String type_nm  = type.getLanguageSpecificName();
        
        if (CUtils.isPrimitiveType(type_nm))
            return type_nm;
        
        String newName = CUtils.capitalizeFirstCharacter(type_nm);

        if (!minfo_nm.equals(newName))
            return newName;

        return newName + "_t";
    }
    
    /**
     * Checks if binding entry is SOAP and specified version.
     * @param be
     * @return
     */
    private static boolean isSOAPBinding(BindingEntry be, String soapNamespace)
    {
        Binding b = be.getBinding();        
        if ((be.getBindingType() == BindingEntry.TYPE_SOAP))
        {            
            String ns = soapNamespace;
            SOAPBinding soapbinding = (SOAPBinding)getExtensibilityElement(b, INSTANCEOF_SOAPBINDING);
            if (soapbinding != null && null != soapbinding.getElementType().getNamespaceURI())
                ns = soapbinding.getElementType().getNamespaceURI();
                
            return ns.equals(soapNamespace);
        }
        
        return false;
    }
}
