/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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.axis2.description;

import org.apache.axiom.om.OMElement;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.addressing.AddressingConstants;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.context.ServiceContext;
import org.apache.axis2.dataretrieval.AxisDataLocator;
import org.apache.axis2.dataretrieval.AxisDataLocatorImpl;
import org.apache.axis2.dataretrieval.DRConstants;
import org.apache.axis2.dataretrieval.Data;
import org.apache.axis2.dataretrieval.DataRetrievalException;
import org.apache.axis2.dataretrieval.DataRetrievalRequest;
import org.apache.axis2.dataretrieval.LocatorType;
import org.apache.axis2.dataretrieval.OutputForm;
import org.apache.axis2.dataretrieval.SchemaSupplier;
import org.apache.axis2.dataretrieval.WSDL11SupplierTemplate;
import org.apache.axis2.dataretrieval.WSDL20SupplierTemplate;
import org.apache.axis2.dataretrieval.WSDLSupplier;
import org.apache.axis2.deployment.DeploymentConstants;
import org.apache.axis2.deployment.util.ExcludeInfo;
import org.apache.axis2.deployment.util.PhasesInfo;
import org.apache.axis2.deployment.util.Utils;
import org.apache.axis2.description.java2wsdl.DefaultSchemaGenerator;
import org.apache.axis2.description.java2wsdl.DocLitBareSchemaGenerator;
import org.apache.axis2.description.java2wsdl.Java2WSDLConstants;
import org.apache.axis2.description.java2wsdl.SchemaGenerator;
import org.apache.axis2.description.java2wsdl.TypeTable;
import org.apache.axis2.engine.AxisConfiguration;
import org.apache.axis2.engine.DefaultObjectSupplier;
import org.apache.axis2.engine.MessageReceiver;
import org.apache.axis2.engine.ObjectSupplier;
import org.apache.axis2.engine.ServiceLifeCycle;
import org.apache.axis2.i18n.Messages;
import org.apache.axis2.phaseresolver.PhaseResolver;
import org.apache.axis2.transport.TransportListener;
import org.apache.axis2.util.IOUtils;
import org.apache.axis2.util.JavaUtils;
import org.apache.axis2.util.Loader;
import org.apache.axis2.util.LoggingControl;
import org.apache.axis2.util.XMLPrettyPrinter;
import org.apache.axis2.util.XMLUtils;
import org.apache.axis2.wsdl.WSDLConstants;
import org.apache.axis2.wsdl.WSDLUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.neethi.Policy;
import org.apache.woden.WSDLSource;
import org.apache.woden.wsdl20.Description;
import org.apache.ws.commons.schema.XmlSchema;
import org.apache.ws.commons.schema.XmlSchemaElement;
import org.apache.ws.commons.schema.XmlSchemaExternal;
import org.apache.ws.commons.schema.utils.NamespaceMap;
import org.apache.ws.commons.schema.utils.NamespacePrefixList;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;


import javax.wsdl.Definition;
import javax.wsdl.Import;
import javax.wsdl.Port;
import javax.wsdl.Service;
import javax.wsdl.Types;
import javax.wsdl.WSDLException;
import javax.wsdl.extensions.http.HTTPAddress;
import javax.wsdl.extensions.schema.Schema;
import javax.wsdl.extensions.soap.SOAPAddress;
import javax.wsdl.extensions.soap12.SOAP12Address;
import javax.wsdl.extensions.UnknownExtensibilityElement;
import javax.wsdl.factory.WSDLFactory;
import javax.wsdl.xml.WSDLReader;
import javax.wsdl.xml.WSDLWriter;
import javax.xml.namespace.QName;
import javax.xml.parsers.ParserConfigurationException;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.net.SocketException;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * Class AxisService
 */
public class AxisService extends AxisDescription {

    // ////////////////////////////////////////////////////////////////
    // Standard Parameter names

    /**
     * If this param is true, and the service has exactly one AxisOperation,
     * normal operation dispatch (via URI/soapAction/etc) will not be necessary,
     * and we'll just default to funneling all messages to that op. This is
     * useful for passthrough/ESB/embedded applications.
     */
    public static final String SUPPORT_SINGLE_OP = "supportSingleOperation";
    // ////////////////////////////////////////////////////////////////

    public static final String IMPORT_TAG = "import";
    public static final String INCLUDE_TAG = "include";
    public static final String SCHEMA_LOCATION = "schemaLocation";

    private Map<String, AxisEndpoint> endpointMap = new HashMap<String, AxisEndpoint>();

    /*
     * This is a map between the QName of the element of a message specified in
     * the WSDL and an Operation. It enables SOAP Body-based dispatching for
     * doc-literal bindings.
     */
    private Map<QName, AxisOperation> messageElementQNameToOperationMap = new HashMap<QName, AxisOperation>();

    private int nsCount = 0;
    private static final Log log = LogFactory.getLog(AxisService.class);
    private URL fileName;

    // Maps httpLocations to corresponding operations. Used to dispatch rest
    // messages.
    private HashMap<String, AxisOperation> httpLocationDispatcherMap = null;

    // A map of (String alias, AxisOperation operation). The aliases might
    // include: SOAPAction,
    // WS-Addressing action, the operation name, the AxisInputMessage name. See:
    // - invalidOperationsAliases
    // - mapActionToOperatoin()
    // - getOperationByAction()
    // REVIEW: This really should be seperate maps for the different types of
    // aliases so they don't
    // conflict with each other. For example, so that an identical operation
    // name and soap action
    // on different operatoins don't cause a collision; the following can't be
    // routed because
    // "foo" is not unique across different operations:
    // operation 1: action = foo, name = bar
    // operation 2: action = bar, name = foo
    private HashMap<String, AxisOperation> operationsAliasesMap = null;

    // Collection of aliases that are invalid for this service because they are
    // duplicated across
    // multiple operations under this service.
    private List<String> invalidOperationsAliases = null;
    // private HashMap operations = new HashMap();

    // to store module ref at deploy time parsing
    private ArrayList<String> moduleRefs = null;

    // to keep the time that last update time of the service
    private long lastupdate;
    private HashMap<String, ModuleConfiguration> moduleConfigmap;
    private String name;
    private ClassLoader serviceClassLoader;

    // to keep the XMLScheam getting either from WSDL or java2wsdl
    private ArrayList<XmlSchema> schemaList;
    // private XmlSchema schema;

    // wsdl is there for this service or not (in side META-INF)
    private boolean wsdlFound = false;

    // to store the scope of the service
    private String scope;

    // to store default message receivers
    private HashMap<String, MessageReceiver> messageReceivers;

    // to set the handler chain available in phase info
    private boolean useDefaultChains = true;

    // to keep the status of the service , since service can stop at the run
    // time
    private boolean active = true;

    private boolean elementFormDefault = true;

    // to keep the service target name space
    private String targetNamespace = Java2WSDLConstants.DEFAULT_TARGET_NAMESPACE;
    private String targetNamespacePrefix = Java2WSDLConstants.TARGETNAMESPACE_PREFIX;

    // to store the target namespace for the schema
    private String schematargetNamespace;// = Java2WSDLConstants.AXIS2_XSD;
    private String schematargetNamespacePrefix = Java2WSDLConstants.SCHEMA_NAMESPACE_PRFIX;

    private boolean enableAllTransports = true;
    private List<String> exposedTransports = new ArrayList<String>();

    // To keep reference to ServiceLifeCycle instance , if the user has
    // specified in services.xml
    private ServiceLifeCycle serviceLifeCycle;

    /**
     * Keeps track whether the schema locations are adjusted
     */
    private boolean schemaLocationsAdjusted = false;

    private boolean wsdlImportLocationAdjusted = false;

    /**
     * A table that keeps a mapping of unique xsd names (Strings) against the
     * schema objects. This is populated in the first instance the schemas are
     * asked for and then used to serve the subsequent requests
     */
    private Map schemaMappingTable = null;

    /**
     * counter variable for naming the schemas
     */
    private int count = 0;
    /**
     * A custom schema Name prefix. if set this will be used to modify the
     * schema names
     */
    private String customSchemaNamePrefix = null;

    /**
     * A custom schema name suffix. will be attached to the schema file name
     * when the files are uniquely named. A good place to add a file extension
     * if needed
     */
    private String customSchemaNameSuffix = null;

    // ///////////////////////////////////////
    // WSDL related stuff ////////////////////
    // //////////////////////////////////////

    /** Map of prefix -> namespaceURI */
    private NamespaceMap namespaceMap;

    private String soapNsUri;
    private String endpointName;
    private String endpointURL;
    
    private List importedNamespaces;

    private boolean clientSide = false;

    // To keep a ref to ObjectSupplier instance
    private ObjectSupplier objectSupplier;

    // package to namespace mapping
    private Map p2nMap;

    // to keep the exclude property details
    private ExcludeInfo excludeInfo;

    private TypeTable typeTable;

    // Data Locators for WS-Mex Support
    private HashMap dataLocators;
    private HashMap<String, String> dataLocatorClassNames;
    private AxisDataLocatorImpl defaultDataLocator;
    // Define search sequence for datalocator based on Data Locator types.
    LocatorType[] availableDataLocatorTypes = new LocatorType[] {
            LocatorType.SERVICE_DIALECT, LocatorType.SERVICE_LEVEL,
            LocatorType.GLOBAL_DIALECT, LocatorType.GLOBAL_LEVEL,
            LocatorType.DEFAULT_AXIS };

    // name of the binding used : use in codegeneration
    private String bindingName;
        
    // List of MessageContextListeners that listen for events on the MessageContext
        private CopyOnWriteArrayList<MessageContextListener> messageContextListeners = 
            new CopyOnWriteArrayList<MessageContextListener>();

    // names list keep to preserve the parameter order
    private List operationsNameList;
    
    // Excluded operations name list to know which operations to exclude.
    private List excludeOperationsNameList;

    private String[] eprs;
    private boolean customWsdl = false;

    private HashMap policyMap = new HashMap();

    public AxisEndpoint getEndpoint(String key) {
        return (AxisEndpoint) endpointMap.get(key);
    }

    public void addEndpoint(String key, AxisEndpoint axisEndpoint) {
        this.endpointMap.put(key, axisEndpoint);
    }

    public boolean isSchemaLocationsAdjusted() {
        return schemaLocationsAdjusted;
    }

    public void setSchemaLocationsAdjusted(boolean schemaLocationsAdjusted) {
        this.schemaLocationsAdjusted = schemaLocationsAdjusted;
    }

    public Map getSchemaMappingTable() {
        return schemaMappingTable;
    }

    public void setSchemaMappingTable(Map schemaMappingTable) {
        this.schemaMappingTable = schemaMappingTable;
    }

    public String getCustomSchemaNamePrefix() {
        return customSchemaNamePrefix;
    }

    public void setCustomSchemaNamePrefix(String customSchemaNamePrefix) {
        this.customSchemaNamePrefix = customSchemaNamePrefix;
    }

    public String getCustomSchemaNameSuffix() {
        return customSchemaNameSuffix;
    }

    public void setCustomSchemaNameSuffix(String customSchemaNameSuffix) {
        this.customSchemaNameSuffix = customSchemaNameSuffix;
    }

    /**
     * Constructor AxisService.
     */
    public AxisService() {
        super();
        this.operationsAliasesMap = new HashMap();
        this.invalidOperationsAliases = new ArrayList();
        this.excludeOperationsNameList = new ArrayList();
        moduleConfigmap = new HashMap();
        // by default service scope is for the request
        scope = Constants.SCOPE_REQUEST;
        httpLocationDispatcherMap = new HashMap();
        messageReceivers = new HashMap();
        moduleRefs = new ArrayList();
        schemaList = new ArrayList();
        serviceClassLoader = (ClassLoader) org.apache.axis2.java.security.AccessController
                .doPrivileged(new PrivilegedAction<ClassLoader>() {
                    public ClassLoader run() {
                        return Thread.currentThread().getContextClassLoader();
                    }
                });
        objectSupplier = new DefaultObjectSupplier();
        dataLocators = new HashMap();
        dataLocatorClassNames = new HashMap();
    }

    public String getBindingName() {
        return bindingName;
    }

    public void setBindingName(String bindingName) {
        this.bindingName = bindingName;
    }

    /**
     * get the SOAPVersion
     */
    public String getSoapNsUri() {
        return soapNsUri;
    }

    public void setSoapNsUri(String soapNsUri) {
        this.soapNsUri = soapNsUri;
    }

    /**
     * get the endpointName
     */
    public String getEndpointName() {
        return endpointName;
    }

    public void setEndpointName(String endpoint) {
        this.endpointName = endpoint;
    }

    /**
     * Constructor AxisService.
     */
    public AxisService(String name) {
        this();
        this.name = name;
    }

    @SuppressWarnings("deprecation")
    public void addMessageReceiver(String mepURI,
            MessageReceiver messageReceiver) {
        if (WSDL2Constants.MEP_URI_IN_ONLY.equals(mepURI)
                || WSDL2Constants.MEP_URI_IN_ONLY
                        .equals(mepURI)
                || WSDL2Constants.MEP_URI_IN_ONLY
                        .equals(mepURI)) {
            messageReceivers.put(WSDL2Constants.MEP_URI_IN_ONLY,
                    messageReceiver);
            messageReceivers.put(
                    WSDL2Constants.MEP_URI_IN_ONLY,
                    messageReceiver);
            messageReceivers.put(
                    WSDL2Constants.MEP_URI_IN_ONLY,
                    messageReceiver);
        } else if (WSDL2Constants.MEP_URI_OUT_ONLY.equals(mepURI)
                || WSDL2Constants.MEP_URI_OUT_ONLY
                        .equals(mepURI)
                || WSDL2Constants.MEP_URI_OUT_ONLY
                        .equals(mepURI)) {
            messageReceivers.put(WSDL2Constants.MEP_URI_OUT_ONLY,
                    messageReceiver);
            messageReceivers.put(
                    WSDL2Constants.MEP_URI_OUT_ONLY,
                    messageReceiver);
            messageReceivers.put(
                    WSDL2Constants.MEP_URI_OUT_ONLY,
                    messageReceiver);
        } else if (WSDL2Constants.MEP_URI_IN_OUT.equals(mepURI)
                || WSDL2Constants.MEP_URI_IN_OUT
                        .equals(mepURI)
                || WSDL2Constants.MEP_URI_IN_OUT
                        .equals(mepURI)) {
            messageReceivers
                    .put(WSDL2Constants.MEP_URI_IN_OUT, messageReceiver);
            messageReceivers.put(
                    WSDL2Constants.MEP_URI_IN_OUT,
                    messageReceiver);
            messageReceivers.put(
                    WSDL2Constants.MEP_URI_IN_OUT,
                    messageReceiver);
        } else if (WSDL2Constants.MEP_URI_IN_OPTIONAL_OUT.equals(mepURI)
                || WSDL2Constants.MEP_URI_IN_OPTIONAL_OUT
                        .equals(mepURI)
                || WSDL2Constants.MEP_URI_IN_OPTIONAL_OUT
                        .equals(mepURI)) {
            messageReceivers.put(WSDL2Constants.MEP_URI_IN_OPTIONAL_OUT,
                    messageReceiver);
            messageReceivers.put(
                    WSDL2Constants.MEP_URI_IN_OPTIONAL_OUT,
                    messageReceiver);
            messageReceivers
                    .put(
                            WSDL2Constants.MEP_URI_IN_OPTIONAL_OUT,
                            messageReceiver);
        } else if (WSDL2Constants.MEP_URI_OUT_IN.equals(mepURI)
                || WSDL2Constants.MEP_URI_OUT_IN
                        .equals(mepURI)
                || WSDL2Constants.MEP_URI_OUT_IN
                        .equals(mepURI)) {
            messageReceivers
                    .put(WSDL2Constants.MEP_URI_OUT_IN, messageReceiver);
            messageReceivers.put(
                    WSDL2Constants.MEP_URI_OUT_IN,
                    messageReceiver);
            messageReceivers.put(
                    WSDL2Constants.MEP_URI_OUT_IN,
                    messageReceiver);
        } else if (WSDL2Constants.MEP_URI_OUT_OPTIONAL_IN.equals(mepURI)
                || WSDL2Constants.MEP_URI_OUT_OPTIONAL_IN
                        .equals(mepURI)
                || WSDL2Constants.MEP_URI_OUT_OPTIONAL_IN
                        .equals(mepURI)) {
            messageReceivers.put(WSDL2Constants.MEP_URI_OUT_OPTIONAL_IN,
                    messageReceiver);
            messageReceivers.put(
                    WSDL2Constants.MEP_URI_OUT_OPTIONAL_IN,
                    messageReceiver);
            messageReceivers
                    .put(
                            WSDL2Constants.MEP_URI_OUT_OPTIONAL_IN,
                            messageReceiver);
        } else if (WSDL2Constants.MEP_URI_ROBUST_OUT_ONLY.equals(mepURI)
                || WSDL2Constants.MEP_URI_ROBUST_OUT_ONLY
                        .equals(mepURI)
                || WSDL2Constants.MEP_URI_ROBUST_OUT_ONLY
                        .equals(mepURI)) {
            messageReceivers.put(WSDL2Constants.MEP_URI_ROBUST_OUT_ONLY,
                    messageReceiver);
            messageReceivers.put(
                    WSDL2Constants.MEP_URI_ROBUST_OUT_ONLY,
                    messageReceiver);
            messageReceivers
                    .put(
                            WSDL2Constants.MEP_URI_ROBUST_OUT_ONLY,
                            messageReceiver);
        } else if (WSDL2Constants.MEP_URI_ROBUST_IN_ONLY.equals(mepURI)
                || WSDL2Constants.MEP_URI_ROBUST_IN_ONLY
                        .equals(mepURI)
                || WSDL2Constants.MEP_URI_ROBUST_IN_ONLY
                        .equals(mepURI)) {
            messageReceivers.put(WSDL2Constants.MEP_URI_ROBUST_IN_ONLY,
                    messageReceiver);
            messageReceivers.put(
                    WSDL2Constants.MEP_URI_ROBUST_IN_ONLY,
                    messageReceiver);
            messageReceivers.put(
                    WSDL2Constants.MEP_URI_ROBUST_IN_ONLY,
                    messageReceiver);
        } else {
            messageReceivers.put(mepURI, messageReceiver);
        }
    }

    public MessageReceiver getMessageReceiver(String mepURL) {
        return messageReceivers.get(mepURL);
    }

    /**
     * Adds module configuration , if there is moduleConfig tag in service.
     * 
     * @param moduleConfiguration
     */
    public void addModuleConfig(ModuleConfiguration moduleConfiguration) {
        moduleConfigmap.put(moduleConfiguration.getModuleName(),
                moduleConfiguration);
    }

    /**
     * Add any control operations defined by a Module to this service.
     * 
     * @param module
     *            the AxisModule which has just been engaged
     * @throws AxisFault
     *             if a problem occurs
     */
    void addModuleOperations(AxisModule module) throws AxisFault {
        HashMap<QName, AxisOperation> map = module.getOperations();
        Collection<AxisOperation> col = map.values();
        PhaseResolver phaseResolver = new PhaseResolver(getAxisConfiguration());
        for (Iterator<AxisOperation> iterator = col.iterator(); iterator.hasNext();) {
            AxisOperation axisOperation = copyOperation((AxisOperation) iterator
                    .next());
            if (this.getOperation(axisOperation.getName()) == null) {
                ArrayList<String> wsamappings = axisOperation.getWSAMappingList();
                if (wsamappings != null) {
                    for (int j = 0, size = wsamappings.size(); j < size; j++) {
                        String mapping = (String) wsamappings.get(j);
                        //If there is already an operation with this action
                        //mapping (e.g. if the service has a matching operation)
                        //then we're going to check to see if the module's
                        //operation says that it's OK to be overridden and
                        //if so, we'll simply ignore the mapping, otherwise
                        //we continue as before
                        AxisOperation mappedOperation = getOperationByAction(mapping);
                        if ((mappedOperation != null)
                            && (axisOperation.isParameterTrue(DeploymentConstants.TAG_ALLOWOVERRIDE))) {
                          if (log.isDebugEnabled()) {
                            log
                            .debug("addModuleOperations: Mapping already exists for action: "
                                   + mapping
                                   + " to operation: "
                                   + axisOperation
                                   + " named: "
                                   + axisOperation.getName()
                                   + " and an override is allowed, so the module mapping for module: "
                                   + module.getName()
                                   + " is being ignored.");
                            log.debug(JavaUtils.callStackToString());
                          }
                        } else {
                          mapActionToOperation(mapping, axisOperation);
                        }
                    }
                }
                // If we've set the "expose" parameter for this operation, it's
                // normal (non-
                // control) and therefore it will appear in generated WSDL. If
                // we haven't,
                // it's a control operation and will be ignored at WSDL-gen
                // time.
                if (axisOperation
                        .isParameterTrue(DeploymentConstants.TAG_EXPOSE)) {
                    axisOperation.setControlOperation(false);
                } else {
                    axisOperation.setControlOperation(true);
                }

                phaseResolver.engageModuleToOperation(axisOperation, module);

                this.addOperation(axisOperation);
            }
        }
    }

    public void addModuleref(String moduleref) {
        moduleRefs.add(moduleref);
    }

    /**
     * Adds operation name to exclude list.
     * 
     * @param operation operation name to add to exclude list
     * 
     */
    public void addExcludeOperationName(String operation){        
        excludeOperationsNameList.add(operation);       
    }
    
    /**
     * Removes operation name from exclude list.
     * 
     * @param operation operation name to remove from exclude list
     * 
     */
    public void removeExcludeOperationName(String operation){        
        excludeOperationsNameList.remove(operation);       
    }
    
    /**
     * Returns whether operation name is in exclude list. 
     * 
     * @param operation name to check if operation is in the exlude list.
     * @return boolean indicating whether operation name is in exlude list. 
     */
    public boolean isExcludedOperation(String operation){        
        return excludeOperationsNameList.contains(operation);       
    }
    
    /*
     * (non-Javadoc)
     * 
     * @see org.apache.axis2.description.AxisService#addOperation(org.apache.axis2.description.AxisOperation)
     */

    /**
     * Method addOperation.
     * 
     * @param axisOperation
     */
    public void addOperation(AxisOperation axisOperation) {
        axisOperation.setParent(this);
        
        if (log.isDebugEnabled()) {
            if (axisOperation.getName().equals(ServiceClient.ANON_OUT_ONLY_OP)
                    || (axisOperation.getName().equals(ServiceClient.ANON_OUT_ONLY_OP))
                    || (axisOperation.getName().equals(ServiceClient.ANON_OUT_ONLY_OP))) {
                log.debug("Client-defined operation name matches default operation name. "
                        + "this may cause interoperability issues.  Name is: " + axisOperation.getName().toString());
            }
        }

        Iterator<AxisModule> modules = getEngagedModules().iterator();

        while (modules.hasNext()) {
            AxisModule module = (AxisModule) modules.next();
            try {
                axisOperation.engageModule(module);
            } catch (AxisFault axisFault) {
                log.info(Messages.getMessage("modulealredyengagetoservice",
                        module.getName()));
            }
        }
        if (axisOperation.getMessageReceiver() == null) {
            axisOperation.setMessageReceiver(loadDefaultMessageReceiver(
                    axisOperation.getMessageExchangePattern(), this));
        }
        if (axisOperation.getInputAction() == null) {
            axisOperation.setSoapAction("urn:"
                    + axisOperation.getName().getLocalPart());
        }

        if (axisOperation.getOutputAction() == null) {
            axisOperation.setOutputAction("urn:"
                    + axisOperation.getName().getLocalPart()
                    + Java2WSDLConstants.RESPONSE);
        }
        addChild(axisOperation);

        String operationName = axisOperation.getName().getLocalPart();

        /*
         * Some times name of the operation can be different from the name of
         * the first child of the SOAPBody. This will put the correct mapping
         * associating that name with the operation. This will be useful
         * especially for the SOAPBodyBasedDispatcher
         */

        Iterator axisMessageIter = axisOperation.getChildren();

        while (axisMessageIter.hasNext()) {
            AxisMessage axisMessage = (AxisMessage) axisMessageIter.next();
            String messageName = axisMessage.getName();
            if (messageName != null && !messageName.equals(operationName)) {
                mapActionToOperation(messageName, axisOperation);
            }
        }

        mapActionToOperation(operationName, axisOperation);

        String action = axisOperation.getInputAction();
        if (action.length() > 0) {
            mapActionToOperation(action, axisOperation);
        }

        ArrayList<String> wsamappings = axisOperation.getWSAMappingList();
        if (wsamappings != null) {
            for (int j = 0, size = wsamappings.size(); j < size; j++) {
                String mapping = (String) wsamappings.get(j);
                mapActionToOperation(mapping, axisOperation);
            }
        }

        if (axisOperation.getMessageReceiver() == null) {
            axisOperation.setMessageReceiver(loadDefaultMessageReceiver(
                    axisOperation.getMessageExchangePattern(), this));
        }
    }

    private MessageReceiver loadDefaultMessageReceiver(String mepURL,
            AxisService service) {
        MessageReceiver messageReceiver;
        if (mepURL == null) {
            mepURL = WSDL2Constants.MEP_URI_IN_OUT;
        }
        if (service != null) {
            messageReceiver = service.getMessageReceiver(mepURL);
            if (messageReceiver != null) {
                return messageReceiver;
            }
        }
        if (getAxisConfiguration() != null) {
            return getAxisConfiguration().getMessageReceiver(mepURL);
        }
        return null;
    }

    /**
     * Gets a copy from module operation.
     * 
     * @param axisOperation
     * @return Returns AxisOperation.
     * @throws AxisFault
     */
    private AxisOperation copyOperation(AxisOperation axisOperation)
            throws AxisFault {
        AxisOperation operation = AxisOperationFactory
                .getOperationDescription(axisOperation
                        .getMessageExchangePattern());

        operation.setMessageReceiver(axisOperation.getMessageReceiver());
        operation.setName(axisOperation.getName());

        Iterator<Parameter> parameters = axisOperation.getParameters().iterator();

        while (parameters.hasNext()) {
            Parameter parameter = (Parameter) parameters.next();

            operation.addParameter(parameter);
        }

        PolicyInclude policyInclude = new PolicyInclude(operation);
        PolicyInclude axisOperationPolicyInclude = axisOperation
                .getPolicyInclude();

        if (axisOperationPolicyInclude != null) {
            Policy policy = axisOperationPolicyInclude.getPolicy();
            if (policy != null) {
                policyInclude.setPolicy(axisOperationPolicyInclude.getPolicy());
            }
        }
        operation.setPolicyInclude(policyInclude);

        operation.setWsamappingList(axisOperation.getWSAMappingList());
        operation.setRemainingPhasesInFlow(axisOperation
                .getRemainingPhasesInFlow());
        operation.setPhasesInFaultFlow(axisOperation.getPhasesInFaultFlow());
        operation.setPhasesOutFaultFlow(axisOperation.getPhasesOutFaultFlow());
        operation.setPhasesOutFlow(axisOperation.getPhasesOutFlow());

        operation.setOutputAction(axisOperation.getOutputAction());
        String[] faultActionNames = axisOperation.getFaultActionNames();
        for (int i = 0; i < faultActionNames.length; i++) {
            operation.addFaultAction(faultActionNames[i], axisOperation
                    .getFaultAction(faultActionNames[i]));
        }

        return operation;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.apache.axis2.description.AxisService#addToengagedModules(javax.xml.namespace.QName)
     */

    /**
     * Engages a module. It is required to use this method.
     * 
     * @param axisModule
     * @param engager
     */
    public void onEngage(AxisModule axisModule, AxisDescription engager)
            throws AxisFault {
        // adding module operations
        addModuleOperations(axisModule);

        Iterator<AxisOperation> operations = getOperations();
        while (operations.hasNext()) {
            AxisOperation axisOperation = (AxisOperation) operations.next();
            axisOperation.engageModule(axisModule, engager);
        }
    }

    /**
     * Maps an alias (such as a SOAPAction, WSA action, or an operation name) to
     * the given AxisOperation. This is used by dispatching (both SOAPAction-
     * and WSAddressing- based dispatching) to figure out which operation a
     * given message is for. Some notes on restrictions of "action" - A null or
     * empty action will be ignored - An action that is a duplicate and
     * references an idential operation is allowed - An acton that is a
     * duplicate and references a different operation is NOT allowed. In this
     * case, the action for the original operation is removed from the alias
     * table, thus removing the ability to route based on this action. This is
     * necessary to prevent mis-directing incoming message to the wrong
     * operation based on SOAPAction.
     * 
     * Note that an alias could be a SOAPAction, WS-Addressing Action, the
     * operation name, or some other alias.
     * 
     * @see #getOperationByAction(String)
     * 
     * @param action
     *            the alias key
     * @param axisOperation
     *            the operation to map to
     */
    public void mapActionToOperation(String action, AxisOperation axisOperation) {
        if (action == null || "".equals(action)) {
            if (log.isDebugEnabled()) {
                log
                        .debug("mapActionToOperation: A null or empty action cannot be used to map to an operation.");
            }
            return;
        }
        if (log.isDebugEnabled()) {
            log
                    .debug("mapActionToOperation: Mapping Action to Operation: action: "
                            + action
                            + "; operation: "
                            + axisOperation
                            + "named: " + axisOperation.getName());
              log.debug(JavaUtils.callStackToString());
        }
                      
        //If there is already an operation with this action
        //mapping then we're going to check to see if the
        //operation says that it's OK to be overridden and
        //if so, we'll simply ignore the mapping, otherwise
        //we continue as before
        AxisOperation mappedOperation = getOperationByAction(action);
        if ((mappedOperation != null)
            && (axisOperation.isParameterTrue(DeploymentConstants.TAG_ALLOWOVERRIDE))) {
          if (log.isDebugEnabled()) {
            log
            .debug("addModuleOperations: Mapping already exists for action: "
                   + action
                   + " to operation: "
                   + axisOperation
                   + " named: "
                   + axisOperation.getName()
                   + " and an override is allowed, so the mapping is being ignored.");
            log.debug(JavaUtils.callStackToString());
          }
          return;        
        }

        // First check if this action has already been flagged as invalid
        // because it is a duplicate.
        if (invalidOperationsAliases.contains(action)) {
            // This SOAPAction has already been determined to be invalid; log a
            // message
            // and do not add it to the operation alias map.
            if (log.isDebugEnabled()) {
                log
                        .debug("mapActionToOperation: The action: "
                                + action
                                + " can not be used for operation: "
                                + axisOperation
                                + " with operation name: "
                                + axisOperation.getName()
                                + " because that SOAPAction is not unique for this service.");
            }
            return;
        }

        // Check if the action is currently mapping to an operation.
        AxisOperation currentlyMappedOperation = getOperationByAction(action);
        if (currentlyMappedOperation != null) {
            if (currentlyMappedOperation == axisOperation) {
                // This maps to the same operation, then it is already in the
                // alias table, so
                // just silently ignore this mapping request.
                if (log.isDebugEnabled()) {
                    log
                            .debug("mapActionToOperation: This operation is already mapped to this action: "
                                    + action
                                    + "; AxisOperation: "
                                    + currentlyMappedOperation
                                    + " named: "
                                    + currentlyMappedOperation.getName());
                }
            } else {
                // This action is already mapped, but it is to a different
                // operation. Remove
                // the action mapping from the alias table and add it to the
                // list of invalid mappings
                operationsAliasesMap.remove(action);
                invalidOperationsAliases.add(action);
                if (log.isDebugEnabled()) {
                    log
                            .debug("mapActionToOperation: The action is already mapped to a different "
                                    + "operation.  The mapping of the action to any operations will be "
                                    + "removed.  Action: "
                                    + action
                                    + "; original operation: "
                                    + currentlyMappedOperation
                                    + " named "
                                    + currentlyMappedOperation.getName()
                                    + "; new operation: "
                                    + axisOperation
                                    + " named " + axisOperation.getName());
                }
            }
        } else {
            operationsAliasesMap.put(action, axisOperation);
            // Adding operation name to the mapping table
            // operationsAliasesMap.put(axisOperation.getName().getLocalPart(),
            // axisOperation);
        }
    }

    /**
     * Maps an constant string in the whttp:location to the given operation.
     * This is used by RequestURIOperationDispatcher based dispatching to figure
     * out which operation it is that a given message is for.
     * 
     * @param string
     *            the constant drawn from whttp:location
     * @param axisOperation
     *            the operation to map to
     */
    public void addHttpLocationDispatcherString(String string,
            AxisOperation axisOperation) {
        httpLocationDispatcherMap.put(string, axisOperation);
    }

    /**
     * Prints the schema to the given output stream.
     * @param out The output stream for the data to be written. NOTE: the stream is not closed after the operation, 
     *            it is the responsibility of the caller to close the stream after usage.
     * @throws AxisFault
     */
    public void printSchema(OutputStream out) throws AxisFault {
        for (int i = 0; i < schemaList.size(); i++) {
            XmlSchema schema = addNameSpaces(i);
            try {
                schema.write(out);
            } catch (UnsupportedEncodingException e) {
                log.error("Error while printing schema ", e);
                throw new AxisFault(e.getMessage(), e);
            }
        }
    }

    public XmlSchema getSchema(int index) {
        return addNameSpaces(index);
    }

    /**
     * Release the list of schema objects. <p/> In some environments, this can
     * provide significant relief of memory consumption in the java heap, as
     * long as the need for the schema list has completed.
     */
    public void releaseSchemaList() {
        if (schemaList != null) {
            // release the schema list
            schemaList.clear();
        }

        if (log.isDebugEnabled()) {
            log.debug("releaseSchemaList: schema list has been released.");
        }
    }

    private XmlSchema addNameSpaces(int i) {
        XmlSchema schema = (XmlSchema) schemaList.get(i);
        NamespaceMap map = (NamespaceMap) namespaceMap.clone();
        NamespacePrefixList namespaceContext = schema.getNamespaceContext();
        String prefixes[] = namespaceContext.getDeclaredPrefixes();
        for (int j = 0; j < prefixes.length; j++) {
            String prefix = prefixes[j];
            map.add(prefix, namespaceContext.getNamespaceURI(prefix));
        }
        schema.setNamespaceContext(map);
        return schema;
    }

    public void setEPRs(String[] eprs) {
        this.eprs = eprs;
    }

    public String[] getEPRs() {
        if (eprs != null && eprs.length != 0) {
            return eprs;
        }
        eprs = calculateEPRs();
        return eprs;
    }

    private String[] calculateEPRs() {
        try {
            String requestIP = org.apache.axis2.util.Utils.getIpAddress(getAxisConfiguration());
            return calculateEPRs(requestIP);
        } catch (SocketException e) {
            log.error("Cannot get local IP address", e);
        }
        return new String[0];
    }

    private String[] calculateEPRs(String requestIP) {
        AxisConfiguration axisConfig = getAxisConfiguration();
        if (axisConfig == null) {
            return null;
        }
        ArrayList<String> eprList = new ArrayList<String>();
        if (enableAllTransports) {
            for (Iterator<TransportInDescription> transports = axisConfig.getTransportsIn().values()
                    .iterator(); transports.hasNext();) {
                TransportInDescription transportIn = (TransportInDescription) transports
                        .next();
                TransportListener listener = transportIn.getReceiver();
                if (listener != null) {
                    try {
                        EndpointReference[] eprsForService = listener
                                .getEPRsForService(this.name, requestIP);
                        if (eprsForService != null) {
                            for (int i = 0; i < eprsForService.length; i++) {
                                EndpointReference endpointReference = eprsForService[i];
                                if (endpointReference != null) {
                                    String address = endpointReference
                                            .getAddress();
                                    if (address != null) {
                                        eprList.add(address);
                                    }
                                }
                            }
                        }
                    } catch (AxisFault axisFault) {
                        log.warn(axisFault.getMessage());
                    }
                }
            }
        } else {
            List<String> trs = this.exposedTransports;
            for (int i = 0; i < trs.size(); i++) {
                String trsName = (String) trs.get(i);
                TransportInDescription transportIn = axisConfig
                        .getTransportIn(trsName);
                if (transportIn != null) {
                    TransportListener listener = transportIn.getReceiver();
                    if (listener != null) {
                        try {
                            EndpointReference[] eprsForService = listener
                                    .getEPRsForService(this.name, requestIP);
                            if (eprsForService != null) {
                                for (int j = 0; j < eprsForService.length; j++) {
                                    EndpointReference endpointReference = eprsForService[j];
                                    if (endpointReference != null) {
                                        String address = endpointReference
                                                .getAddress();
                                        if (address != null) {
                                            eprList.add(address);
                                        }
                                    }
                                }
                            }
                        } catch (AxisFault axisFault) {
                            log.warn(axisFault.getMessage());
                        }
                    }
                }
            }
        }
        eprs = (String[]) eprList.toArray(new String[eprList.size()]);
        return eprs;
    }

    /**
     * Prints the given definition object.
     * @param definition The definition.
     * @param out The output stream the data to be written to. NOTE: the stream is not closed after the operation, 
     *            it is the responsibility of the caller to close the stream after usage.
     * @param requestIP The host IP address.
     * @throws AxisFault
     * @throws WSDLException
     */
    private synchronized void printDefinitionObject(Definition definition, OutputStream out,
            String requestIP) throws AxisFault, WSDLException {
        // Synchronized this method to fix the NullPointer exception occurred when load is high.
        // This error happens because wsdl4j is not thread safe and we are using same WSDL Definition for printing the
        // WSDL.
        // Please refer AXIS2-4511,AXIS2-4517,AXIS2-3276.
        if (isModifyUserWSDLPortAddress()) {
            setPortAddress(definition, requestIP);
        }
        if (!wsdlImportLocationAdjusted) {
            changeImportAndIncludeLocations(definition);
            wsdlImportLocationAdjusted = true;
        }
        WSDLWriter writer = WSDLFactory.newInstance().newWSDLWriter();
        writer.writeWSDL(definition, out);
    }

    public void printUserWSDL(OutputStream out, String wsdlName)
            throws AxisFault {
            printUserWSDL(out, wsdlName, null);
    }

    /**
     * Prints the user WSDL.
     * @param out The output stream for the data to be written. NOTE: the stream is not closed after the operation, 
     *            it is the responsibility of the caller to close the stream after usage.
     * @param wsdlName The name of the WSDL.
     * @param ip The host IP address.
     * @throws AxisFault
     */
    public void printUserWSDL(OutputStream out, String wsdlName, String ip)
            throws AxisFault {
        Definition definition = null;
        // first find the correct wsdl definition
        Parameter wsdlParameter = getParameter(WSDLConstants.WSDL_4_J_DEFINITION);
        if (wsdlParameter != null) {
            definition = (Definition) wsdlParameter.getValue();
        }

        if (definition != null) {
            try {
                printDefinitionObject(getWSDLDefinition(definition, wsdlName),
                        out, ip);
            } catch (WSDLException e) {
                throw AxisFault.makeFault(e);
            }
        } else {
            printWSDLError(out);
        }

    }
    
    public void printUserWSDL2(OutputStream out, String wsdlName, String ip) throws AxisFault {
        Description description = null;
        // first find the correct wsdl definition
        Parameter wsdlParameter = getParameter(WSDLConstants.WSDL_20_DESCRIPTION);
        if (wsdlParameter != null) {
            description = (Description) wsdlParameter.getValue();
            try {
                org.apache.woden.WSDLFactory factory = org.apache.woden.WSDLFactory.newInstance();
                org.apache.woden.WSDLWriter writer = factory.newWSDLWriter();
                writer.writeWSDL(description.toElement(), out);
            } catch (org.apache.woden.WSDLException e) {
                throw AxisFault.makeFault(e);
            }
        }

}

    /**
     * find the defintion object for given name
     * 
     * @param parentDefinition
     * @param name
     * @return wsdl definition
     */
    private Definition getWSDLDefinition(Definition parentDefinition,
            String name) {

        if (name == null)
            return parentDefinition;

        Definition importedDefinition = null;
        Iterator iter = parentDefinition.getImports().values().iterator();
        Vector values = null;
        Import wsdlImport = null;
        for (; iter.hasNext();) {
            values = (Vector) iter.next();
            for (Iterator valuesIter = values.iterator(); valuesIter.hasNext();) {
                wsdlImport = (Import) valuesIter.next();
                if (wsdlImport.getLocationURI().endsWith(name)) {
                    importedDefinition = wsdlImport.getDefinition();
                    break;
                } else {
                    importedDefinition = getWSDLDefinition(wsdlImport
                            .getDefinition(), name);
                }
                if (importedDefinition != null) {
                    break;
                }
            }
            if (importedDefinition != null) {
                break;
            }
        }
        return importedDefinition;
    }

    /**
     * this procesdue recursively adjust the wsdl imports locations and the
     * schmea import and include locations.
     * 
     * @param definition
     */
    private void changeImportAndIncludeLocations(Definition definition) throws AxisFault {

        // adjust the schema locations in types section
        Types types = definition.getTypes();
        if (types != null) {
            List extensibilityElements = types.getExtensibilityElements();
            Object extensibilityElement = null;
            Schema schema = null;
            for (Iterator iter = extensibilityElements.iterator(); iter.hasNext();) {
                extensibilityElement = iter.next();
                if (extensibilityElement instanceof Schema) {
                    schema = (Schema) extensibilityElement;
                    changeLocations(schema.getElement());
                }
            }
        }

        Iterator iter = definition.getImports().values().iterator();
        Vector values = null;
        Import wsdlImport = null;
        String originalImprotString = null;
        for (; iter.hasNext();) {
            values = (Vector) iter.next();
            for (Iterator valuesIter = values.iterator(); valuesIter.hasNext();) {
                wsdlImport = (Import) valuesIter.next();
                originalImprotString = wsdlImport.getLocationURI();
                if (originalImprotString.indexOf("://") == -1 && originalImprotString.indexOf("?wsdl=") == -1){
                    wsdlImport.setLocationURI(this.getServiceEPR() + "?wsdl=" + originalImprotString);
                }
                changeImportAndIncludeLocations(wsdlImport.getDefinition());
            }
        }

    }

    /**
     * change the schema Location in the elemment
     * 
     * @param element
     */

    private void changeLocations(Element element) throws AxisFault {
        NodeList nodeList = element.getChildNodes();
        String tagName;
        for (int i = 0; i < nodeList.getLength(); i++) {
            tagName = nodeList.item(i).getLocalName();
            if (IMPORT_TAG.equals(tagName) || INCLUDE_TAG.equals(tagName)) {
                processImport(nodeList.item(i));
            }
        }
    }

    private void updateSchemaLocation(XmlSchema schema) throws AxisFault {
        for (XmlSchemaExternal xmlSchemaExternal : schema.getExternals()) {
            XmlSchema s = xmlSchemaExternal.getSchema();
            updateSchemaLocation(s, xmlSchemaExternal);
        }
    }

    private void updateSchemaLocation(XmlSchema s, XmlSchemaExternal xmlSchemaExternal) throws AxisFault {
        if (s != null) {
            String schemaLocation = xmlSchemaExternal.getSchemaLocation();

            if (schemaLocation.indexOf("://") == -1 && schemaLocation.indexOf("?xsd=") == -1) {
                String newscheamlocation = this.getServiceEPR() + "?xsd=" + schemaLocation;
                xmlSchemaExternal.setSchemaLocation(newscheamlocation);
            }
        }
    }
       
    private void processImport(Node importNode) throws AxisFault {
        NamedNodeMap nodeMap = importNode.getAttributes();
        Node attribute;
        String attributeValue;
        for (int i = 0; i < nodeMap.getLength(); i++) {
            attribute = nodeMap.item(i);
            if (attribute.getNodeName().equals("schemaLocation")) {
                attributeValue = attribute.getNodeValue();
                if (attributeValue.indexOf("://") == -1 && attributeValue.indexOf("?xsd=") == -1) {
                    attribute.setNodeValue(this.getServiceEPR() + "?xsd=" + attributeValue);
                }
            }
        }
    }

    private String getServiceEPR() {
        String serviceEPR = null;
        Parameter parameter = this.getParameter(Constants.Configuration.GENERATE_ABSOLUTE_LOCATION_URIS);
        if ((parameter != null) && JavaUtils.isTrueExplicitly(parameter.getValue())) {
            String[] eprs = this.getEPRs();
            for (int i = 0; i < eprs.length; i++) {
                if ((eprs[i] != null) && (eprs[i].startsWith("http:"))){
                    serviceEPR = eprs[i];
                    break;
                }
            }
            if (serviceEPR == null){
                serviceEPR = eprs[0];
            }
        } else {
            serviceEPR = this.name;
        }
        if (serviceEPR.endsWith("/")){
            serviceEPR = serviceEPR.substring(0, serviceEPR.lastIndexOf("/"));
        }
        return serviceEPR;
    }

    /**
     * Produces a XSD for this AxisService and prints it to the specified
     * OutputStream.
     * 
     * @param out
     *            destination stream, NOTE: the stream is not closed after the operation, 
     *            it is the responsibility of the caller to close the stream after usage.
     * @param xsd
     *            schema name
     * @return -1 implies not found, 0 implies redirect to root, 1 implies
     *         found/printed a schema
     * @throws IOException
     */
    public int printXSD(OutputStream out, String xsd) throws IOException {

        // If we find a SchemaSupplier, use that
        SchemaSupplier supplier = (SchemaSupplier) getParameterValue("SchemaSupplier");
        if (supplier != null) {
            XmlSchema schema = supplier.getSchema(this, xsd);
            if (schema != null) {
                updateSchemaLocation(schema);
                schema.write(new OutputStreamWriter(out, "UTF8"));
                out.flush();
                return 1;
            }
        }

        // call the populator
        populateSchemaMappings();
        Map schemaMappingtable = getSchemaMappingTable();
        ArrayList<XmlSchema> schemas = getSchema();

        // a name is present - try to pump the requested schema
        if ((xsd != null) && (!"".equals(xsd))) {
            XmlSchema schema = (XmlSchema) schemaMappingtable.get(xsd);
            if (schema == null) {
                int dotIndex = xsd.lastIndexOf('.');
                if (dotIndex > 0) {
                    String schemaKey = xsd.substring(0, dotIndex);
                    schemaKey = schemaKey.replace("./" , "");
                    schema = (XmlSchema) schemaMappingtable.get(schemaKey);
                }
            }
            if (schema != null) {
                // schema is there - pump it outs
                schema.write(new OutputStreamWriter(out, "UTF8"));
                out.flush();
            } else {
                // make sure we are only serving .xsd files and ignore requests with
                // ".." in the name.
                if (xsd.endsWith(".xsd") && xsd.indexOf("..") == -1) {
                    InputStream in = getClassLoader().getResourceAsStream(
                            DeploymentConstants.META_INF + "/" + xsd);
                    if (in != null) {
                        IOUtils.copy(in, out, true);
                    } else {
                        // Can't find the schema
                        return -1;
                    }
                } else {
                    // bad schema request
                    return -1;
                }
            }
        } else if (schemas.size() > 1) {
            // multiple schemas are present and the user specified
            // no name - in this case we cannot possibly pump a schema
            // so redirect to the service root
            return 0;
        } else {
            // user specified no name and there is only one schema
            // so pump that out
            ArrayList<XmlSchema> list = getSchema();
            if (list.size() > 0) {
                XmlSchema schema = getSchema(0);
                if (schema != null) {
                    schema.write(new OutputStreamWriter(out, "UTF8"));
                    out.flush();
                }
            } else {
                String xsdNotFound = "<error>"
                        + "<description>Unable to access schema for this service</description>"
                        + "</error>";
                out.write(xsdNotFound.getBytes());
                out.flush();
            }
        }
        return 1;
    }

    /**
     * Produces a WSDL for this AxisService and prints it to the specified
     * OutputStream.
     * 
     * @param out
     *            destination stream. The WSDL will be sent here. NOTE: the stream is not closed after the operation, 
     *            it is the responsibility of the caller to close the stream after usage.
     * @param requestIP
     *            the hostname the WSDL request was directed at. This should be
     *            the address that appears in the generated WSDL.
     * @throws AxisFault
     *             if an error occurs
     */
    public void printWSDL(OutputStream out, String requestIP) throws AxisFault {
        // If we're looking for pre-existing WSDL, use that.
        if (isUseUserWSDL()) {
            printUserWSDL(out, null, requestIP);
            return;
        }

        // If we find a WSDLSupplier with WSDL 1.1 content, use that
        WSDLSupplier supplier = getUserDefinedWSDLSupplier("wsdl");
        if(supplier == null){
            supplier = (WSDLSupplier) getParameterValue(Constants.WSDL_SUPPLIER_PARAM);    
            if(supplier instanceof WSDL11SupplierTemplate){
                ((WSDL11SupplierTemplate)supplier).init(this);
            }
        }            
        if (supplier != null) {
            Object wsdlContent = supplier.getWSDL(this);
            if( wsdlContent instanceof Definition){
                try {
                    Definition definition = (Definition) wsdlContent;
                    if (definition != null) {
                        changeImportAndIncludeLocations(definition);
                        printDefinitionObject(getWSDLDefinition(definition, null),
                                out, requestIP);
                    }
                } catch (Exception e) {
                    printWSDLError(out, e);
                }
            // wsdlContent can be a OMElement            
            } else if (wsdlContent instanceof OMElement) {
                OMElement wsdlElement = (OMElement) wsdlContent;
                QName wsdlName = wsdlElement.getQName();
                if (wsdlName != null
                        && wsdlName.getLocalPart().equals("definitions")
                        && wsdlName.getNamespaceURI().equals("http://schemas.xmlsoap.org/wsdl/")) {
                    // TODO How to address port number/ ip name customization
                    // here ?
                    try {
                        XMLPrettyPrinter.prettify(wsdlElement, out);
                        out.flush();
                    } catch (Exception e) {
                        throw AxisFault.makeFault(e);
                    }
                }
            }
            return;
        }

        if (isSetEndpointsToAllUsedBindings()) {
            Utils.setEndpointsToAllUsedBindings(this);
        }

        // Otherwise, generate WSDL ourselves
        String[] eprArray = requestIP == null ? new String[] { this.endpointName }
                : calculateEPRs(requestIP);
        getWSDL(out, eprArray);
    }

    /**
     * users can use this parameter when they supply a wsdl file with the .aar file
     * but wants to generate the endpoints for all available transports. here it assume
     * that the user has not set the useOriginalwsdl
     * @return
     */
    public boolean isSetEndpointsToAllUsedBindings() {
        Parameter parameter = getParameter("setEndpointsToAllUsedBindings");
        if (parameter != null) {
            String value = (String) parameter.getValue();
            if ("true".equals(value)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Print the WSDL with a default URL. This will be called only during
     * codegen time.
     * 
     * @param out The output stream for the data to be written. NOTE: the stream is not closed after the operation, 
     *            it is the responsibility of the caller to close the stream after usage.
     * @throws AxisFault
     */
    public void printWSDL(OutputStream out) throws AxisFault {
        printWSDL(out, null);
    }

        private AxisEndpoint getAxisEndpoint(String port) {
            // if service has a single endpoint, this will cause the [serviceName] address
            // to be used in wsdl instead of the [serviceName].[endpointName]
            if (endpointMap.size() == 1 && endpointMap.containsKey(getEndpointName())) {
                return null;
            } else {
                return (AxisEndpoint)endpointMap.get(port);
            }
        }

    private void setPortAddress(Definition definition, String requestIP)
            throws AxisFault {
        Iterator serviceItr = definition.getServices().values().iterator();
        while (serviceItr.hasNext()) {
            Service serviceElement = (Service) serviceItr.next();
            Iterator portItr = serviceElement.getPorts().values().iterator();
            while (portItr.hasNext()) {
                Port port = (Port) portItr.next();
                AxisEndpoint endpoint = getAxisEndpoint(port.getName());
                List list = port.getExtensibilityElements();
                for (int i = 0; i < list.size(); i++) {
                    Object extensibilityEle = list.get(i);
                    if (extensibilityEle instanceof SOAPAddress) {
                        SOAPAddress soapAddress = (SOAPAddress) extensibilityEle;
                        String existingAddress = soapAddress.getLocationURI();
                        if (existingAddress == null
                                || existingAddress
                                        .equals("REPLACE_WITH_ACTUAL_URL")) {
                            if (endpoint != null) {
                                ((SOAPAddress) extensibilityEle)
                                        .setLocationURI(endpoint
                                                .calculateEndpointURL(requestIP));
                            } else {
                                ((SOAPAddress) extensibilityEle)
                                        .setLocationURI(getEPRs()[0]);
                            }
                        } else {
                            if (requestIP == null) {
                                if (endpoint != null) {
                                    ((SOAPAddress) extensibilityEle)
                                            .setLocationURI(endpoint
                                                    .calculateEndpointURL());
                                } else {
                                    ((SOAPAddress) extensibilityEle)
                                            .setLocationURI(getLocationURI(
                                                    getEPRs(), existingAddress));
                                }
                            } else {
                                if (endpoint != null) {
                                    ((SOAPAddress) extensibilityEle)
                                            .setLocationURI(endpoint
                                                    .calculateEndpointURL(requestIP));
                                } else {
                                    ((SOAPAddress) extensibilityEle)
                                            .setLocationURI(getLocationURI(
                                                    calculateEPRs(requestIP),
                                                    existingAddress));
                                }
                            }
                        }
                    } else if (extensibilityEle instanceof SOAP12Address) {
                        SOAP12Address soapAddress = (SOAP12Address) extensibilityEle;
                        String exsistingAddress = soapAddress.getLocationURI();
                        if (requestIP == null) {
                            if (endpoint != null) {
                                ((SOAP12Address) extensibilityEle)
                                        .setLocationURI(endpoint
                                                .calculateEndpointURL());

                            } else {
                                ((SOAP12Address) extensibilityEle)
                                        .setLocationURI(getLocationURI(
                                                getEPRs(), exsistingAddress));
                            }
                        } else {
                            if (endpoint != null) {
                                ((SOAP12Address) extensibilityEle)
                                        .setLocationURI(endpoint
                                                .calculateEndpointURL(requestIP));
                            } else {
                                ((SOAP12Address) extensibilityEle)
                                        .setLocationURI(getLocationURI(
                                                calculateEPRs(requestIP),
                                                exsistingAddress));

                            }
                        }
                    } else if (extensibilityEle instanceof HTTPAddress) {
                        HTTPAddress httpAddress = (HTTPAddress) extensibilityEle;
                        String exsistingAddress = httpAddress.getLocationURI();
                        if (requestIP == null) {
                            if (endpoint != null) {
                                ((HTTPAddress) extensibilityEle)
                                        .setLocationURI(endpoint
                                                .calculateEndpointURL());
                            } else {
                                ((HTTPAddress) extensibilityEle)
                                        .setLocationURI(getLocationURI(
                                                getEPRs(), exsistingAddress));
                            }
                        } else {
                            if (endpoint != null) {
                                ((HTTPAddress) extensibilityEle)
                                        .setLocationURI(endpoint
                                                .calculateEndpointURL(requestIP));
                            } else {
                                ((HTTPAddress) extensibilityEle)
                                        .setLocationURI(getLocationURI(
                                                calculateEPRs(requestIP),
                                                exsistingAddress));
                            }
                        }
                    } else if (extensibilityEle instanceof UnknownExtensibilityElement){
                        UnknownExtensibilityElement unknownExtensibilityElement = (UnknownExtensibilityElement) extensibilityEle;
                        Element element = unknownExtensibilityElement.getElement();
                        if (AddressingConstants.ENDPOINT_REFERENCE.equals(element.getLocalName())){
                            NodeList nodeList = element.getChildNodes();
                            Node node = null;
                            Element currentElement = null;
                            for (int j = 0; j < nodeList.getLength(); j++) {
                                node = nodeList.item(j);
                                if (node instanceof Element){
                                    currentElement = (Element) node;
                                    if (AddressingConstants.EPR_ADDRESS.equals(currentElement.getLocalName())) {
                                        String exsistingAddress = currentElement.getTextContent();
                                        if (requestIP == null) {
                                            if (endpoint != null) {
                                                currentElement.setTextContent(endpoint.calculateEndpointURL());
                                            } else {
                                                currentElement.setTextContent(getLocationURI(getEPRs(), exsistingAddress));
                                            }
                                        } else {
                                            if (endpoint != null) {
                                                currentElement.setTextContent(endpoint.calculateEndpointURL(requestIP));
                                            } else {
                                                currentElement.setTextContent(getLocationURI(calculateEPRs(requestIP),exsistingAddress));
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * this method returns the new IP address corresponding to the already
     * existing ip
     * 
     * @param eprs
     * @param epr
     * @return corresponding Ip address
     */
    private String getLocationURI(String[] eprs, String epr) throws AxisFault {
        String returnIP = null;
        if (epr != null) {
            String existingProtocol = org.apache.axis2.util.Utils.getURIScheme(epr);
            if (existingProtocol != null) {
                for (int i = 0; i < eprs.length; i++) {
                    if (existingProtocol.equals(org.apache.axis2.util.Utils.getURIScheme(eprs[i]))) {
                        returnIP = eprs[i];
                        break;
                    }
                }
                if (returnIP != null) {
                    return returnIP;
                } else {
                    throw new AxisFault(
                            "Server does not have an epr for the wsdl epr==>"
                                    + epr);
                }
            } else {
                throw new AxisFault("invalid epr is given epr ==> " + epr);
            }
        } else {
            throw new AxisFault("No epr is given in the wsdl port");
        }
    }

    /**
     * Retrieves the WSDL data associated with the given serviceURL.
     * @param out The output stream for the WSDL data to be written, NOTE: the stream is not closed after the operation, 
     *            it is the responsibility of the caller to close the stream after usage.
     * @param serviceURL The fist element of this array i.e. serviceURL[0] is taken in retrieving the target service.
     */
    private void getWSDL(OutputStream out, String[] serviceURL)
            throws AxisFault {
        // Retrieve WSDL using the same data retrieval path for GetMetadata
        // request.
        DataRetrievalRequest request = new DataRetrievalRequest();
        request.putDialect(DRConstants.SPEC.DIALECT_TYPE_WSDL);
        request.putOutputForm(OutputForm.INLINE_FORM);

        MessageContext context = new MessageContext();
        context.setAxisService(this);
        context.setTo(new EndpointReference(serviceURL[0]));

        Data[] result = getData(request, context);
        OMElement wsdlElement;
        if (result != null && result.length > 0) {
            wsdlElement = (OMElement) (result[0].getData());
            try {
                XMLPrettyPrinter.prettify(wsdlElement, out);
                out.flush();
            } catch (Exception e) {
                throw AxisFault.makeFault(e);
            }
        }
    }

    /**
     * Prints generic WSDL error to the given output stream.
     * @param out The output stream the data to be written to. NOTE: the stream is not closed after the operation, 
     *            it is the responsibility of the caller to close the stream after usage.
     * @throws AxisFault
     */
    private void printWSDLError(OutputStream out) throws AxisFault {
        printWSDLError(out, null);
    }

    /**
     * Prints WSDL error condition that is given in the exception.
     * @param out The output stream for the error message to be written. NOTE: the stream is not closed after the operation, 
     *            it is the responsibility of the caller to close the stream after usage.
     * @param e The exception describing the error condition.
     * @throws AxisFault
     */
    private void printWSDLError(OutputStream out, Exception e) throws AxisFault {
        try {
            String wsdlntfound = "<error>"
                    + "<description>Unable to generate WSDL 1.1 for this service</description>"
                    + "<reason>If you wish Axis2 to automatically generate the WSDL 1.1, then please "
                    + "set useOriginalwsdl as false in your services.xml</reason>";
            out.write(wsdlntfound.getBytes());
            if (e != null) {
                PrintWriter pw = new PrintWriter(out);
                e.printStackTrace(pw);
                pw.flush();
            }
            out.write("</error>".getBytes());
            out.flush();
        } catch (IOException ex) {
            throw AxisFault.makeFault(ex);
        }
    }

    /**
     * Print the WSDL2.0 with a default URL. This will be called only during
     * codegen time.
     * 
     * @param out The output stream for the data to be written for. NOTE: the stream is not closed after the operation, 
     *            it is the responsibility of the caller to close the stream after usage.
     * @throws AxisFault
     */
    public void printWSDL2(OutputStream out) throws AxisFault {
        printWSDL2(out, null);
    }

    /**
     * Prints WSDL2.0 data for the service with the given host IP address.
     * @param out The output stream for the data to be written for. NOTE: the stream is not closed after the operation, 
     *            it is the responsibility of the caller to close the stream after usage.
     * @param requestIP The host IP address.
     * @throws AxisFault
     */
    public void printWSDL2(OutputStream out, String requestIP) throws AxisFault {
     // If we're looking for pre-existing WSDL, use that.
        if (isUseUserWSDL()) {
            printUserWSDL2(out, null, requestIP);
            return;
        }
        AxisService2WSDL20 axisService2WSDL2 = new AxisService2WSDL20(this);
        
        // If we find a WSDLSupplier with WSDL 2.0 content, use that
        WSDLSupplier supplier = getUserDefinedWSDLSupplier("wsdl2");
        if(supplier == null){
            supplier = (WSDLSupplier) getParameterValue(Constants.WSDL_SUPPLIER_PARAM);    
            if(supplier instanceof WSDL20SupplierTemplate){
                ((WSDL20SupplierTemplate)supplier).init(this);
            }
        }                
        if (supplier != null) {
            Object wsdlContent = supplier.getWSDL(this);
            if( wsdlContent instanceof Description){
                try {
                    Description definition = (Description) wsdlContent;
                    if (definition != null) {
                        //TODO  -- Need to implement this method for WSDL 2.0
                        //changeImportAndIncludeLocations(definition);
                        printDescriptionObject(definition, out, requestIP);
                    }
                } catch (Exception e) {
                    printWSDLError(out, e);
                }
                
            // wsdlContent can be a OMElement           
            } else if (wsdlContent instanceof OMElement) {
                OMElement wsdlElement = (OMElement) wsdlContent;
                QName wsdlName = wsdlElement.getQName();
                if (wsdlName != null
                        && wsdlName.getLocalPart().equals("description")
                        && wsdlName.getNamespaceURI().equals("http://www.w3.org/ns/wsdl")) {
                    // TODO How to address port number/ ip name customization
                    // here ?
                    try {
                        XMLPrettyPrinter.prettify(wsdlElement, out);
                        out.flush();
                    } catch (Exception e) {
                        throw AxisFault.makeFault(e);
                    }
                }
            }            
            return;
        }
        
        try {
            if (requestIP != null) {
                axisService2WSDL2.setEPRs(calculateEPRs(requestIP));
            }
            OMElement wsdlElement = axisService2WSDL2.generateOM();
            wsdlElement.serialize(out);
            out.flush();
        } catch (Exception e) {
            throw AxisFault.makeFault(e);
        }
    }

    /**
     * Produces a WSDL2 for this AxisService and prints it to the specified
     * OutputStream.
     * 
     * @param out
     *            destination stream. NOTE: the stream is not closed after the operation, 
     *            it is the responsibility of the caller to close the stream after usage.
     * @param wsdl
     *            wsdl name
     * @return -1 implies not found, 0 implies redirect to root, 1 implies
     *         found/printed wsdl
     * @throws IOException
     */
    public int printWSDL2(OutputStream out, String requestIP, String wsdl) 
        throws IOException, AxisFault {    
        // if the wsdl2 parameter is not empty or null in the requested URL, get the wsdl  from the META-INF and serve.
        //else construct the wsdl out of axis service and serve.
        if ((wsdl != null ) && (!"".equals(wsdl))) {
            // make sure we are only serving .wsdl files and ignore requests with
            // ".." in the name.
            if (wsdl.endsWith(".wsdl") && wsdl.indexOf("..") == -1) {
                InputStream in = getClassLoader().getResourceAsStream(
                                    DeploymentConstants.META_INF + "/" + wsdl);
                if (in != null) {
                    IOUtils.copy(in, out, true);
                } else {
                    // can't find the wsdl
                    return -1;
                }
            } else {
                // bad wsdl2 request
                return -1;
            }
        } else {
            printWSDL2(out, requestIP);
        }
        
        return 1;
    }
    

    /**
     * Method getClassLoader.
     * 
     * @return Returns ClassLoader.
     */
    public ClassLoader getClassLoader() {
        return this.serviceClassLoader;
    }

    /**
     * Gets the control operation which are added by module like RM.
     */
    public ArrayList<AxisOperation> getControlOperations() {
        Iterator<AxisOperation> op_itr = getOperations();
        ArrayList<AxisOperation> operationList = new ArrayList<AxisOperation>();

        while (op_itr.hasNext()) {
            AxisOperation operation = (AxisOperation) op_itr.next();

            if (operation.isControlOperation()) {
                operationList.add(operation);
            }
        }

        return operationList;
    }

    public URL getFileName() {
        return fileName;
    }

    public long getLastUpdate() {
        return lastupdate;
    }

    public ModuleConfiguration getModuleConfig(String moduleName) {
        return (ModuleConfiguration) moduleConfigmap.get(moduleName);
    }

    public ArrayList<String> getModules() {
        return moduleRefs;
    }

    public String getName() {
        return name;
    }

    /**
     * Method getOperation.
     * 
     * @param operationName
     * @return Returns AxisOperation.
     */
    public AxisOperation getOperation(QName operationName) {
        if (LoggingControl.debugLoggingAllowed && log.isDebugEnabled())
            log.debug("Get operation for " + operationName);
                
        AxisOperation axisOperation = (AxisOperation) getChild(operationName);
        
        if (axisOperation == null) {
            axisOperation = (AxisOperation) getChild(new QName(
                    getTargetNamespace(), operationName.getLocalPart()));
            
            if (LoggingControl.debugLoggingAllowed && log.isDebugEnabled())
                log.debug("Target namespace: " + getTargetNamespace());
        }
        
        if (axisOperation == null) {
            axisOperation = (AxisOperation) operationsAliasesMap
                    .get(operationName.getLocalPart());
            
            if (LoggingControl.debugLoggingAllowed && log.isDebugEnabled())
                log.debug("Operations aliases map: " + operationsAliasesMap);
        }
        
        //The operation may be associated with a namespace other than the
        //target namespace, e.g. if the operation is from an imported wsdl.
        if (axisOperation == null) {            
            List namespaces = getImportedNamespaces();
            
            if (LoggingControl.debugLoggingAllowed && log.isDebugEnabled())
                log.debug("Imported namespaces: " + namespaces);

            if (namespaces != null) {
                Iterator iterator = namespaces.iterator();
                
                while (iterator.hasNext()) {
                    String namespace = (String) iterator.next();
                    axisOperation = (AxisOperation) getChild(new QName(
                            namespace, operationName.getLocalPart()));
                    
                    if (axisOperation != null)
                        break;
                }
            }
        }

        if (LoggingControl.debugLoggingAllowed && log.isDebugEnabled())
            log.debug("Found axis operation:  " + axisOperation);

        return axisOperation;
    }

    /**
     * Returns the AxisOperation which has been mapped to the given alias.
     * 
     * @see #mapActionToOperation(String, AxisOperation)
     * 
     * @param action
     *            the alias key
     * @return Returns the corresponding AxisOperation or null if it isn't
     *         found.
     */
    public AxisOperation getOperationByAction(String action) {
        return (AxisOperation) operationsAliasesMap.get(action);
    }

    /**
     * Returns the operation given a SOAP Action. This method should be called
     * if only one Endpoint is defined for this Service. If more than one
     * Endpoint exists, one of them will be picked. If more than one Operation
     * is found with the given SOAP Action; null will be returned. If no
     * particular Operation is found with the given SOAP Action; null will be
     * returned. If the action is in the list of invaliad aliases, which means
     * it did not uniquely identify an operation, a null will be returned.
     * 
     * @param soapAction
     *            SOAP Action defined for the particular Operation
     * @return Returns an AxisOperation if a unique Operation can be found with
     *         the given SOAP Action otherwise will return null.
     */
    public AxisOperation getOperationBySOAPAction(String soapAction) {

        // Check for illegal soapActions
        if ((soapAction == null) || soapAction.length() == 0) {
            if (log.isDebugEnabled()) {
                log.debug("getOperationBySOAPAction: " + soapAction
                        + " is null or ''. Returning null.");
            }
            return null;
        }

        // If the action maps to an alais that is not unique, then it can't be
        // used to map to
        // an operation.
        if (invalidOperationsAliases.contains(soapAction)) {
            if (log.isDebugEnabled()) {
                log.debug("getOperationBySOAPAction: " + soapAction
                        + " is an invalid operation alias. Returning null.");
            }
            return null;
        }

        // Get the operation from the action->operation map
        AxisOperation operation = (AxisOperation) operationsAliasesMap
                .get(soapAction);

        if (operation != null) {
            if (log.isDebugEnabled()) {
                log.debug("getOperationBySOAPAction: Operation (" + operation
                        + "," + operation.getName() + ") for soapAction: "
                        + soapAction + " found in action map.");
            }
            return operation;
        }

        // The final fallback is to check the operations for a matching name.

        Iterator children = getChildren();
        // I could not find any spec statement that explicitly forbids using a
        // short name in the SOAPAction header or wsa:Action element,
        // so I believe this to be valid. There may be customers using the
        // shortname as the SOAPAction in their client code that would
        // also require this support.
        while (children.hasNext() && (operation == null)) {
            AxisOperation op = (AxisOperation) children.next();
            if (op.getName().getLocalPart().equals(soapAction)) {
                operation = op;
            }
        }

        if (operation != null) {
            if (log.isDebugEnabled()) {
                log.debug("getOperationBySOAPAction: Operation (" + operation
                        + "," + operation.getName() + ") for soapAction: "
                        + soapAction + " found as child.");
            }
        }

        return operation;
    }

    /**
     * Method getOperations.
     * 
     * @return Returns HashMap
     */
    public Iterator<AxisOperation> getOperations() {
        return (Iterator<AxisOperation>) getChildren();
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.apache.axis2.description.ParameterInclude#getParameter(java.lang.String)
     */

    /**
     * Gets only the published operations.
     */
    public ArrayList<AxisOperation> getPublishedOperations() {
        Iterator<AxisOperation> op_itr = getOperations();
        ArrayList<AxisOperation> operationList = new ArrayList<AxisOperation>();

        while (op_itr.hasNext()) {
            AxisOperation operation = (AxisOperation) op_itr.next();

            if (!operation.isControlOperation()) {
                operationList.add(operation);
            }
        }

        return operationList;
    }    

    /**
     * Method setClassLoader.
     * 
     * @param classLoader
     */
    public void setClassLoader(ClassLoader classLoader) {
        this.serviceClassLoader = classLoader;
    }

    public void setFileName(URL fileName) {
        this.fileName = fileName;
    }

    /**
     * Sets the current time as last update time of the service.
     */
    public void setLastUpdate() {
        lastupdate = new Date().getTime();
    }

    public void setName(String name) {
        this.name = name;
    }

    public ArrayList<XmlSchema> getSchema() {
        return schemaList;
    }

    public void addSchema(XmlSchema schema) {
        if (schema != null) {
            schemaList.add(schema);
            if (schema.getTargetNamespace() != null) {
                addSchemaNameSpace(schema);
            }
        }
    }

    public void addSchema(Collection<XmlSchema> schemas) {
        Iterator<XmlSchema> iterator = schemas.iterator();
        while (iterator.hasNext()) {
            XmlSchema schema = iterator.next();
            addSchema(schema);
        }
    }

    public boolean isWsdlFound() {
        return wsdlFound;
    }

    public void setWsdlFound(boolean wsdlFound) {
        this.wsdlFound = wsdlFound;
    }

    public String getScope() {
        return scope;
    }

    /**
     * @param scope -
     *            Available scopes : Constants.SCOPE_APPLICATION
     *            Constants.SCOPE_TRANSPORT_SESSION Constants.SCOPE_SOAP_SESSION
     *            Constants.SCOPE_REQUEST.equals
     */
    public void setScope(String scope) {
        if (Constants.SCOPE_APPLICATION.equals(scope)
                || Constants.SCOPE_TRANSPORT_SESSION.equals(scope)
                || Constants.SCOPE_SOAP_SESSION.equals(scope)
                || Constants.SCOPE_REQUEST.equals(scope)) {
            this.scope = scope;
        }
    }

    public boolean isUseDefaultChains() {
        return useDefaultChains;
    }

    public void setUseDefaultChains(boolean useDefaultChains) {
        this.useDefaultChains = useDefaultChains;
    }

    public Object getKey() {
        return this.name;
    }

    public boolean isActive() {
        return active;
    }

    public void setActive(boolean active) {
        this.active = active;
    }

    public String getSchemaTargetNamespace() {
        return schematargetNamespace;
    }

    public void setSchemaTargetNamespace(String schematargetNamespace) {
        this.schematargetNamespace = schematargetNamespace;
    }

    public String getSchemaTargetNamespacePrefix() {
        return schematargetNamespacePrefix;
    }

    public void setSchemaTargetNamespacePrefix(
            String schematargetNamespacePrefix) {
        this.schematargetNamespacePrefix = schematargetNamespacePrefix;
    }

    public String getTargetNamespace() {
        return targetNamespace;
    }

    public void setTargetNamespace(String targetNamespace) {
        this.targetNamespace = targetNamespace;
    }

    public String getTargetNamespacePrefix() {
        return targetNamespacePrefix;
    }

    public void setTargetNamespacePrefix(String targetNamespacePrefix) {
        this.targetNamespacePrefix = targetNamespacePrefix;
    }

    public XmlSchemaElement getSchemaElement(QName elementQName) {
        XmlSchemaElement element;
        for (int i = 0; i < schemaList.size(); i++) {
            XmlSchema schema = (XmlSchema) schemaList.get(i);
            if (schema != null) {
                element = schema.getElementByName(elementQName);
                if (element != null) {
                    return element;
                }
            }
        }
        return null;
    }

    public boolean isEnableAllTransports() {
        return enableAllTransports;
    }

    /**
     * To eneble service to be expose in all the transport
     * 
     * @param enableAllTransports
     */
    public void setEnableAllTransports(boolean enableAllTransports) {
        this.enableAllTransports = enableAllTransports;
        eprs = calculateEPRs();
    }

    public List<String> getExposedTransports() {
        return this.exposedTransports;
    }

    public void setExposedTransports(List transports) {
        enableAllTransports = false;
        this.exposedTransports = transports;
        eprs = null; // Do not remove this. We need to force EPR
                        // recalculation.
    }

    public void addExposedTransport(String transport) {
        enableAllTransports = false;
        if (!this.exposedTransports.contains(transport)) {
            this.exposedTransports.add(transport);
            try {
                eprs = calculateEPRs();
            } catch (Exception e) {
                eprs = null;
            }
        }
    }

    public void removeExposedTransport(String transport) {
        enableAllTransports = false;
        this.exposedTransports.remove(transport);
        try {
            eprs = calculateEPRs();
        } catch (Exception e) {
            eprs = null;
        }
    }

    public boolean isExposedTransport(String transport) {
        return exposedTransports.contains(transport);
    }

    public void onDisengage(AxisModule module) throws AxisFault {
        removeModuleOperations(module);
        for (Iterator operations = getChildren(); operations.hasNext();) {
            AxisOperation axisOperation = (AxisOperation) operations.next();
            axisOperation.disengageModule(module);
        }
        AxisConfiguration config = getAxisConfiguration();
        if (!config.isEngaged(module.getName())) {
            PhaseResolver phaseResolver = new PhaseResolver(config);
            phaseResolver.disengageModuleFromGlobalChains(module);
        }
    }

    /**
     * Remove any operations which were added by a given module.
     * 
     * @param module
     *            the module in question
     */
    private void removeModuleOperations(AxisModule module) {
        HashMap<QName, AxisOperation> moduleOperations = module.getOperations();
        if (moduleOperations != null) {
            for (Iterator<AxisOperation> modOpsIter = moduleOperations.values().iterator(); modOpsIter
                    .hasNext();) {
                AxisOperation operation = (AxisOperation) modOpsIter.next();
                removeOperation(operation.getName());
            }
        }
    }

    // #######################################################################################
    // APIs to create AxisService

    //

    /**
     * To create a AxisService for a given WSDL and the created client is most
     * suitable for client side invocation not for server side invocation. Since
     * all the soap action and wsa action is added to operations
     * 
     * @param wsdlURL
     *            location of the WSDL
     * @param wsdlServiceName
     *            name of the service to be invoke , if it is null then the
     *            first one will be selected if there are more than one
     * @param portName
     *            name of the port , if there are more than one , if it is null
     *            then the first one in the iterator will be selected
     * @param options
     *            Service client options, to set the target EPR
     * @return AxisService , the created service will be return
     */
    public static AxisService createClientSideAxisService(URL wsdlURL,
            QName wsdlServiceName, String portName, Options options)
            throws AxisFault {
        try {
            InputStream in = wsdlURL.openConnection().getInputStream();
            Document doc = XMLUtils.newDocument(in);
            String namespaceURI = doc.getDocumentElement().getNamespaceURI();
            if (Constants.NS_URI_WSDL11.equals(namespaceURI)) {
                WSDLReader reader = WSDLUtil.newWSDLReaderWithPopulatedExtensionRegistry();
                reader.setFeature("javax.wsdl.importDocuments", true);
                Definition wsdlDefinition = reader.readWSDL(getBaseURI(wsdlURL.toString()), doc);
                if (wsdlDefinition != null) {
                    wsdlDefinition.setDocumentBaseURI(getDocumentURI(wsdlURL.toString()));
                }
                return createClientSideAxisService(wsdlDefinition, wsdlServiceName, portName,
                        options);
            } else if (Constants.NS_URI_WSDL20.equals(namespaceURI)) {
                org.apache.woden.WSDLReader reader = org.apache.woden.WSDLFactory.newInstance()
                        .newWSDLReader();
                WSDLSource source = reader.createWSDLSource();
                source.setSource(doc);
                source.setBaseURI(wsdlURL.toURI());
                Description description = reader.readWSDL(source);
                return createClientSideAxisService(description, wsdlServiceName, portName, options);
            } else {
                throw new AxisFault("No namespace found : Invalid WSDL");
            }
            
        } catch (IOException e) {
            log.error(e.getMessage(), e);
            throw AxisFault.makeFault(e);
        } catch (ParserConfigurationException e) {
            log.error(e.getMessage(), e);
            throw AxisFault.makeFault(e);
        } catch (SAXException e) {
            log.error(e.getMessage(), e);
            throw AxisFault.makeFault(e);
        } catch (WSDLException e) {
            log.error(e.getMessage(), e);
            throw AxisFault.makeFault(e);
        } catch (org.apache.woden.WSDLException e) {
            log.error(e.getMessage(), e);
            throw AxisFault.makeFault(e);
        } catch (URISyntaxException e) {
            log.error(e.getMessage(), e);
            throw AxisFault.makeFault(e);
        }
    }

    private static String getBaseURI(String currentURI) {
        try {
            File file = new File(currentURI);
            if (file.exists()) {
                return file.getCanonicalFile().getParentFile().toURI()
                        .toString();
            }
            String uriFragment = currentURI.substring(0, currentURI
                    .lastIndexOf("/"));
            return uriFragment + (uriFragment.endsWith("/") ? "" : "/");
        } catch (IOException e) {
            return null;
        }
    }

    private static String getDocumentURI(String currentURI) {
        try {
            File file = new File(currentURI);
            return file.getCanonicalFile().toURI().toString();
        } catch (IOException e) {
            return null;
        }
    }

    public static AxisService createClientSideAxisService(
            Definition wsdlDefinition, QName wsdlServiceName, String portName,
            Options options) throws AxisFault {
        WSDL11ToAxisServiceBuilder serviceBuilder = new WSDL11ToAxisServiceBuilder(
                wsdlDefinition, wsdlServiceName, portName);
        serviceBuilder.setServerSide(false);
        AxisService axisService = serviceBuilder.populateService();
        AxisEndpoint axisEndpoint = (AxisEndpoint) axisService.getEndpoints()
                .get(axisService.getEndpointName());

        if (axisEndpoint != null) {
            options.setTo(new EndpointReference(axisEndpoint.getEndpointURL()));
            options.setSoapVersionURI((String) axisEndpoint.getBinding()
                    .getProperty(WSDL2Constants.ATTR_WSOAP_VERSION));
        }
        return axisService;
    }

    /**
     * To create an AxisService using given service impl class name first
     * generate schema corresponding to the given java class , next for each
     * methods AxisOperation will be created. If the method is in-out it will
     * uses RPCMessageReceiver else RPCInOnlyMessageReceiver <p/> Note : Inorder
     * to work this properly RPCMessageReceiver should be available in the class
     * path otherewise operation can not continue
     * 
     * @param implClass
     *            Service implementation class
     * @param axisConfig
     *            Current AxisConfiguration
     * @return return created AxisSrevice the creted service , it can either be
     *         null or valid service
     */
    public static AxisService createService(String implClass,
            AxisConfiguration axisConfig) throws AxisFault {

        try {
            HashMap<String, MessageReceiver> messageReciverMap = new HashMap<String, MessageReceiver>();
            Class inOnlyMessageReceiver = Loader
                    .loadClass("org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver");
            MessageReceiver messageReceiver = (MessageReceiver) inOnlyMessageReceiver
                    .newInstance();
            messageReciverMap.put(WSDL2Constants.MEP_URI_IN_ONLY,
                    messageReceiver);
            Class inoutMessageReceiver = Loader
                    .loadClass("org.apache.axis2.rpc.receivers.RPCMessageReceiver");
            MessageReceiver inOutmessageReceiver = (MessageReceiver) inoutMessageReceiver
                    .newInstance();
            messageReciverMap.put(WSDL2Constants.MEP_URI_IN_OUT,
                    inOutmessageReceiver);
            messageReciverMap.put(WSDL2Constants.MEP_URI_ROBUST_IN_ONLY,
                    inOutmessageReceiver);

            return createService(implClass, axisConfig, messageReciverMap,
                    null, null, axisConfig.getSystemClassLoader());
        } catch (Exception e) {
            throw AxisFault.makeFault(e);
        }
    }

    /**
     * messageReceiverClassMap will hold the MessageReceivers for given meps.
     * Key will be the mep and value will be the instance of the MessageReceiver
     * class. Ex: Map mrMap = new HashMap();
     * mrMap.put("http://www.w3.org/ns/wsdl/in-only",
     * RPCInOnlyMessageReceiver.class.newInstance());
     * mrMap.put("http://www.w3.org/ns/wsdl/in-out",
     * RPCMessageReceiver.class.newInstance());
     * 
     * @param implClass
     * @param axisConfiguration
     * @param messageReceiverClassMap
     * @param targetNamespace
     * @param schemaNamespace
     * @throws AxisFault
     */
    public static AxisService createService(String implClass,
            AxisConfiguration axisConfiguration, Map messageReceiverClassMap,
            String targetNamespace, String schemaNamespace, ClassLoader loader)
            throws AxisFault {
        int index = implClass.lastIndexOf(".");
        String serviceName;
        if (index > 0) {
            serviceName = implClass.substring(index + 1, implClass.length());
        } else {
            serviceName = implClass;
        }

        SchemaGenerator schemaGenerator;
        ArrayList excludeOpeartion = new ArrayList();
        AxisService service = new AxisService();
        service.setParent(axisConfiguration);
        service.setName(serviceName);

        try {
            Parameter generateBare = service
                    .getParameter(Java2WSDLConstants.DOC_LIT_BARE_PARAMETER);
            if (generateBare != null && "true".equals(generateBare.getValue())) {
                schemaGenerator = new DocLitBareSchemaGenerator(loader,
                        implClass, schemaNamespace,
                        Java2WSDLConstants.SCHEMA_NAMESPACE_PRFIX, service);
            } else {
                schemaGenerator = new DefaultSchemaGenerator(loader, implClass,
                        schemaNamespace,
                        Java2WSDLConstants.SCHEMA_NAMESPACE_PRFIX, service);
            }
            schemaGenerator
                    .setElementFormDefault(Java2WSDLConstants.FORM_DEFAULT_UNQUALIFIED);
            Utils.addExcludeMethods(excludeOpeartion);
            schemaGenerator.setExcludeMethods(excludeOpeartion);
        } catch (Exception e) {
            throw AxisFault.makeFault(e);
        }

        return createService(implClass, serviceName, axisConfiguration,
                messageReceiverClassMap, targetNamespace, loader,
                schemaGenerator, service);
    }

    /**
     * messageReceiverClassMap will hold the MessageReceivers for given meps.
     * Key will be the mep and value will be the instance of the MessageReceiver
     * class. Ex: Map mrMap = new HashMap();
     * mrMap.put("http://www.w3.org/ns/wsdl/in-only",
     * RPCInOnlyMessageReceiver.class.newInstance());
     * mrMap.put("http://www.w3.org/ns/wsdl/in-out",
     * RPCMessageReceiver.class.newInstance());
     * 
     * @param implClass
     * @param axisConfiguration
     * @param messageReceiverClassMap
     * @param targetNamespace
     * @throws AxisFault
     */
    public static AxisService createService(String implClass,
            String serviceName, AxisConfiguration axisConfiguration,
            Map<String, MessageReceiver> messageReceiverClassMap, String targetNamespace,
            ClassLoader loader, SchemaGenerator schemaGenerator,
            AxisService axisService) throws AxisFault {
        Parameter parameter = new Parameter(Constants.SERVICE_CLASS, implClass);
        OMElement paraElement = Utils.getParameter(Constants.SERVICE_CLASS,
                implClass, false);
        parameter.setParameterElement(paraElement);
        axisService.setUseDefaultChains(false);
        axisService.addParameter(parameter);
        axisService.setName(serviceName);
        axisService.setClassLoader(loader);

        NamespaceMap map = new NamespaceMap();
        map.put(Java2WSDLConstants.AXIS2_NAMESPACE_PREFIX,
                Java2WSDLConstants.AXIS2_XSD);
        map.put(Java2WSDLConstants.DEFAULT_SCHEMA_NAMESPACE_PREFIX,
                Java2WSDLConstants.URI_2001_SCHEMA_XSD);
        axisService.setNamespaceMap(map);
        Utils.processBeanPropertyExclude(axisService);
        axisService.setElementFormDefault(false);
        try {
            axisService.addSchema(schemaGenerator.generateSchema());
        } catch (Exception e) {
            throw AxisFault.makeFault(e);
        }
        axisService.setSchemaTargetNamespace(schemaGenerator
                .getSchemaTargetNameSpace());
        axisService.setTypeTable(schemaGenerator.getTypeTable());
        if (targetNamespace == null) {
            targetNamespace = schemaGenerator.getSchemaTargetNameSpace();
        }
        if (targetNamespace != null && !"".equals(targetNamespace)) {
            axisService.setTargetNamespace(targetNamespace);
        }
        Method[] method = schemaGenerator.getMethods();
        PhasesInfo pinfo = axisConfiguration.getPhasesInfo();
        for (int i = 0; i < method.length; i++) {
            Method jmethod = method[i];

            String methodName = jmethod.getName();         
            
            AxisOperation operation = axisService.getOperation(new QName(methodName));

            String mep = operation.getMessageExchangePattern();
            MessageReceiver mr;
            if (messageReceiverClassMap != null) {

                if (messageReceiverClassMap.get(mep) != null) {
                    Object obj = messageReceiverClassMap.get(mep);
                    if (obj instanceof MessageReceiver) {
                        mr = (MessageReceiver) obj;
                        operation.setMessageReceiver(mr);
                    } else {
                        log
                                .error("Object is not an instance of MessageReceiver, thus, default MessageReceiver has been set");
                        mr = axisConfiguration.getMessageReceiver(operation
                                .getMessageExchangePattern());
                        operation.setMessageReceiver(mr);
                    }
                } else {
                    log
                            .error("Required MessageReceiver couldn't be found, thus, default MessageReceiver has been used");
                    mr = axisConfiguration.getMessageReceiver(operation
                            .getMessageExchangePattern());
                    operation.setMessageReceiver(mr);
                }
            } else {
                log
                        .error("MessageRecevierClassMap couldn't be found, thus, default MessageReceiver has been used");
                mr = axisConfiguration.getMessageReceiver(operation
                        .getMessageExchangePattern());
                operation.setMessageReceiver(mr);
            }
            pinfo.setOperationPhases(operation);
            axisService.addOperation(operation);
        }

        String endpointName = axisService.getEndpointName();
        if ((endpointName == null || endpointName.length() == 0)
                && axisService.getAxisConfiguration() != null) {
            Utils.addEndpointsToService(axisService, axisService.getAxisConfiguration());
        }

        return axisService;

    }

    public void removeOperation(QName opName) {
        AxisOperation operation = getOperation(opName);
        if (operation != null) {
            removeChild(opName);
            ArrayList<String> mappingList = operation.getWSAMappingList();
            if (mappingList != null) {
                for (int i = 0; i < mappingList.size(); i++) {
                    String actionMapping = (String) mappingList.get(i);
                    operationsAliasesMap.remove(actionMapping);
                    invalidOperationsAliases.remove(actionMapping);
                }
            }
            operationsAliasesMap.remove(operation.getName().getLocalPart());
            invalidOperationsAliases.remove(operation.getName().getLocalPart());
        }
    }

    /**
     * Get the namespace map for this service.
     * 
     * @return a Map of prefix (String) to namespace URI (String)
     */
    public Map getNamespaceMap() {
        return namespaceMap;
    }
    
    /**
     * Get the namespaces associated with imported WSDLs
     * 
     * @return a <code>List</code> of namespace URIs (String)
     */
    public List getImportedNamespaces() {
        return importedNamespaces;
    }

    /**
     * Set the namespaces associated with imported WSDLs
     * 
     * @param importedNamespaces
     */
    public void setImportedNamespaces(List importedNamespaces) {
        this.importedNamespaces = importedNamespaces;
    }
    

    public void setNamespaceMap(NamespaceMap namespaceMap) {
        this.namespaceMap = namespaceMap;
    }

    private void addSchemaNameSpace(XmlSchema schema) {
        String targetNameSpace = schema.getTargetNamespace();
        String prefix = schema.getNamespaceContext().getPrefix(targetNameSpace);

        if (namespaceMap == null) {
            namespaceMap = new NamespaceMap();
        }

        if (!namespaceMap.values().contains(targetNameSpace)) {
            // i.e this target namespace not exists in the namesapce map
            // find a non exists prefix to add this target namesapce
            while ((prefix == null) || namespaceMap.keySet().contains(prefix)) {
                prefix = "ns" + nsCount++;
            }
            namespaceMap.put(prefix, targetNameSpace);
        }

    }

    public Map populateSchemaMappings() {
        // when calling from other than codegen. i.e from deployment
        // engine we don't have to override the absolute http locations.
        return populateSchemaMappings(false);
    }

    /**
     * runs the schema mappings if it has not been run previously it is best
     * that this logic be in the axis service since one can call the axis
     * service to populate the schema mappings
     */
    public Map populateSchemaMappings(boolean overrideAbsoluteAddress) {

        // populate the axis service with the necessary schema references
        ArrayList schema = this.schemaList;
        Map changedSchemaLocations = null;
        if (!this.schemaLocationsAdjusted) {
            Hashtable nameTable = new Hashtable();
            Hashtable sourceURIToNewLocationMap = new Hashtable();
            // calculate unique names for the schemas
            calculateSchemaNames(schema, nameTable, sourceURIToNewLocationMap,
                    overrideAbsoluteAddress);
            // adjust the schema locations as per the calculated names
            changedSchemaLocations = adjustSchemaNames(schema, nameTable,
                    sourceURIToNewLocationMap);
            // reverse the nametable so that there is a mapping from the
            // name to the schemaObject
            setSchemaMappingTable(swapMappingTable(nameTable));
            setSchemaLocationsAdjusted(true);
        }
        return changedSchemaLocations;
    }

    /**
     * run 1 -calcualte unique names
     * 
     * @param schemas
     */
    private void calculateSchemaNames(List schemas, Hashtable nameTable,
            Hashtable sourceURIToNewLocationMap, boolean overrideAbsoluteAddress) {
        // first traversal - fill the hashtable
        for (int i = 0; i < schemas.size(); i++) {
            XmlSchema schema = (XmlSchema) schemas.get(i);
            for (XmlSchemaExternal externalSchema : schema.getExternals()) {
                if (externalSchema != null) {
                    XmlSchema s = externalSchema.getSchema();
                    if (s != null
                            && getScheamLocationWithDot(
                                    sourceURIToNewLocationMap, s) == null) {
                        // insert the name into the table
                        insertIntoNameTable(nameTable, s,
                                sourceURIToNewLocationMap,
                                overrideAbsoluteAddress);
                        // recursively call the same procedure
                        calculateSchemaNames(Arrays
                                .asList(new XmlSchema[] { s }), nameTable,
                                sourceURIToNewLocationMap,
                                overrideAbsoluteAddress);
                    }
                }
            }
        }
    }

    /**
     * A quick private sub routine to insert the names
     * 
     * @param nameTable
     * @param s
     */
    private void insertIntoNameTable(Hashtable nameTable, XmlSchema s,
            Hashtable sourceURIToNewLocationMap, boolean overrideAbsoluteAddress) {
        String sourceURI = s.getSourceURI();
        // check whether the sourece uri is an absolute one and are
        // we allowed to override it.
        // if the absolute uri overriding is not allowed the use the
        // original sourceURI as new one
        if (sourceURI.startsWith("http") && !overrideAbsoluteAddress) {
            nameTable.put(s, sourceURI);
            sourceURIToNewLocationMap.put(sourceURI, sourceURI);
        } else {
            String newURI = sourceURI.substring(sourceURI.lastIndexOf('/') + 1);
            if (newURI.endsWith(".xsd")) {
                // remove the .xsd extention
                newURI = newURI.substring(0, newURI.lastIndexOf("."));
            } else {
                newURI = "xsd" + count++;
            }

            newURI = customSchemaNameSuffix != null ? newURI
                    + customSchemaNameSuffix : newURI;
            // make it unique
            while (nameTable.containsValue(newURI)) {
                newURI = newURI + count++;
            }

            nameTable.put(s, newURI);
            sourceURIToNewLocationMap.put(sourceURI, newURI);
        }

    }

    /**
     * Run 2 - adjust the names
     */
    private Map adjustSchemaNames(List schemas, Hashtable nameTable,
            Hashtable sourceURIToNewLocationMap) {
        Hashtable importedSchemas = new Hashtable();
        // process the schemas in the main schema list
        for (int i = 0; i < schemas.size(); i++) {
            adjustSchemaName((XmlSchema) schemas.get(i), nameTable,
                    importedSchemas, sourceURIToNewLocationMap);
        }
        // process all the rest in the name table
        Enumeration nameTableKeys = nameTable.keys();
        while (nameTableKeys.hasMoreElements()) {
            adjustSchemaName((XmlSchema) nameTableKeys.nextElement(),
                    nameTable, importedSchemas, sourceURIToNewLocationMap);

        }
        return importedSchemas;
    }

    /**
     * Adjust a single schema
     * 
     * @param parentSchema
     * @param nameTable
     */
    private void adjustSchemaName(XmlSchema parentSchema, Hashtable nameTable,
                                  Hashtable importedScheams, Hashtable sourceURIToNewLocationMap) {
        for (XmlSchemaExternal xmlSchemaExternal : parentSchema.getExternals()) {
            XmlSchema s = xmlSchemaExternal.getSchema();
            adjustSchemaLocation(s, xmlSchemaExternal, nameTable,
                                 importedScheams, sourceURIToNewLocationMap);
        }
    }

    /**
     * Adjusts a given schema location
     * 
     * @param s
     * @param xmlSchemaExternal
     * @param nameTable
     */
    private void adjustSchemaLocation(XmlSchema s,
                                      XmlSchemaExternal xmlSchemaExternal, Hashtable nameTable,
                                      Hashtable importedScheams, Hashtable sourceURIToNewLocationMap) {
        if (s != null) {
            String schemaLocation = xmlSchemaExternal.getSchemaLocation();

            String newscheamlocation = customSchemaNamePrefix == null ?
                    // use the default mode
                    (this.getServiceEPR() + "?xsd=" + getScheamLocationWithDot(
                            sourceURIToNewLocationMap, s))
                    :
                    // custom prefix is present - add the custom prefix
                    (customSchemaNamePrefix + getScheamLocationWithDot(
                            sourceURIToNewLocationMap, s));
            xmlSchemaExternal.setSchemaLocation(newscheamlocation);
            importedScheams.put(schemaLocation, newscheamlocation);
        }
    }

    private Object getScheamLocationWithDot(
            Hashtable sourceURIToNewLocationMap, XmlSchema s) {
        String o = (String) sourceURIToNewLocationMap.get(s.getSourceURI());
        if (o != null && o.indexOf(".") < 0) {
            return o + ".xsd";
        }
        return o;
    }

    /**
     * Swap the key,value pairs
     * 
     * @param originalTable
     */
    private Map swapMappingTable(Map originalTable) {
        HashMap swappedTable = new HashMap(originalTable.size());
        Iterator keys = originalTable.keySet().iterator();
        Object key;
        while (keys.hasNext()) {
            key = keys.next();
            swappedTable.put(originalTable.get(key), key);
        }

        return swappedTable;
    }

    public boolean isClientSide() {
        return clientSide;
    }

    public void setClientSide(boolean clientSide) {
        this.clientSide = clientSide;
    }

    public boolean isElementFormDefault() {
        return elementFormDefault;
    }

    public void setElementFormDefault(boolean elementFormDefault) {
        this.elementFormDefault = elementFormDefault;
    }

    /**
     * User can set a parameter in services.xml saying he want to show the
     * original wsdl that he put into META-INF once someone ask for ?wsdl so if
     * you want to use your own wsdl then add following parameter into
     * services.xml <parameter name="useOriginalwsdl">true</parameter>
     */
    public boolean isUseUserWSDL() {
        Parameter parameter = getParameter("useOriginalwsdl");
        if (parameter != null) {
            String value = (String) parameter.getValue();
            if ("true".equals(value)) {
                return true;
            }
        }
        return false;
    }

    /**
     * By default the port address in user WSDLs is modified, set the following
     * parameter to override this behaviour <parameter
     * name="modifyUserWSDLPortAddress">false</parameter>
     */
    public boolean isModifyUserWSDLPortAddress() {
        Parameter parameter = getParameter("modifyUserWSDLPortAddress");
        if (parameter != null) {
            String value = (String) parameter.getValue();
            if ("false".equals(value)) {
                return false;
            }
        }
        return true;
    }

    public ServiceLifeCycle getServiceLifeCycle() {
        return serviceLifeCycle;
    }

    public void setServiceLifeCycle(ServiceLifeCycle serviceLifeCycle) {
        this.serviceLifeCycle = serviceLifeCycle;
    }

    public Map getP2nMap() {
        return p2nMap;
    }

    public void setP2nMap(Map p2nMap) {
        this.p2nMap = p2nMap;
    }

    public ObjectSupplier getObjectSupplier() {
        return objectSupplier;
    }

    public void setObjectSupplier(ObjectSupplier objectSupplier) {
        this.objectSupplier = objectSupplier;
    }

    public TypeTable getTypeTable() {
        return typeTable;
    }

    public void setTypeTable(TypeTable typeTable) {
        this.typeTable = typeTable;
    }

    /**
     * Find a data locator from the available data locators (both configured and
     * default ones) to retrieve Metadata or data specified in the request.
     * 
     * @param request
     *            an {@link DataRetrievalRequest} object
     * @param msgContext
     *            message context
     * @return array of {@link Data} object for the request.
     * @throws AxisFault
     */

    public Data[] getData(DataRetrievalRequest request,
            MessageContext msgContext) throws AxisFault {

        Data[] data;
        String dialect = request.getDialect();
        AxisDataLocator dataLocator = null;
        int nextDataLocatorIndex = 0;
        int totalLocators = availableDataLocatorTypes.length;
        for (int i = 0; i < totalLocators; i++) {
            dataLocator = getDataLocator(availableDataLocatorTypes[i], dialect);
            if (dataLocator != null) {
                nextDataLocatorIndex = i + 1;
                break;
            }
        }

        if (dataLocator == null) {
            return null;
        }

        data = dataLocator.getData(request, msgContext);
        // Null means Data Locator not understood request. Automatically find
        // Data Locator in the hierarchy to process the request.
        if (data == null) {
            if (nextDataLocatorIndex < totalLocators) {
                data = bubbleupDataLocators(nextDataLocatorIndex, request,
                        msgContext);
            }

        }
        return data;
    }

    /*
     * To search the next Data Locator from the available Data Locators that
     * understood the data retrieval request.
     */
    private Data[] bubbleupDataLocators(int nextIndex,
            DataRetrievalRequest request, MessageContext msgContext)
            throws AxisFault {
        Data[] data = null;
        if (nextIndex < availableDataLocatorTypes.length) {
            AxisDataLocator dataLocator = getDataLocator(
                    availableDataLocatorTypes[nextIndex], request.getDialect());
            nextIndex++;
            if (dataLocator != null) {
                data = dataLocator.getData(request, msgContext);
                if (data == null) {
                    data = bubbleupDataLocators(nextIndex, request, msgContext);
                } else {
                    return data;
                }

            } else {
                data = bubbleupDataLocators(nextIndex, request, msgContext);
            }

        }
        return data;
    }

    /**
     * Save data Locator configured at service level for this Axis Service
     * 
     * @param dialect-
     *            an absolute URI represents the Dialect i.e. WSDL, Policy,
     *            Schema or "ServiceLevel" for non-dialect service level data
     *            locator.
     * @param dataLocatorClassName -
     *            class name of the Data Locator configured to support data
     *            retrieval for the specified dialect.
     */
    public void addDataLocatorClassNames(String dialect,
            String dataLocatorClassName) {
        dataLocatorClassNames.put(dialect, dataLocatorClassName);
    }

    /*
     * Get data locator instance based on the LocatorType and dialect.
     */
    public AxisDataLocator getDataLocator(LocatorType locatorType,
            String dialect) throws AxisFault {
        AxisDataLocator locator;
        if (locatorType == LocatorType.SERVICE_DIALECT) {
            locator = getServiceDataLocator(dialect);
        } else if (locatorType == LocatorType.SERVICE_LEVEL) {
            locator = getServiceDataLocator(DRConstants.SERVICE_LEVEL);
        } else if (locatorType == LocatorType.GLOBAL_DIALECT) {
            locator = getGlobalDataLocator(dialect);
        } else if (locatorType == LocatorType.GLOBAL_LEVEL) {
            locator = getGlobalDataLocator(DRConstants.GLOBAL_LEVEL);
        } else if (locatorType == LocatorType.DEFAULT_AXIS) {
            locator = getDefaultDataLocator();
        } else {
            locator = getDefaultDataLocator();
        }

        return locator;
    }

    // Return default Axis2 Data Locator
    private AxisDataLocator getDefaultDataLocator()
            throws DataRetrievalException {

        if (defaultDataLocator == null) {
            defaultDataLocator = new AxisDataLocatorImpl(this);
        }

        defaultDataLocator.loadServiceData();

        return defaultDataLocator;
    }

    /*
     * Checks if service level data locator configured for specified dialect.
     * Returns an instance of the data locator if exists, and null otherwise.
     */
    private AxisDataLocator getServiceDataLocator(String dialect)
            throws AxisFault {
        AxisDataLocator locator;
        locator = (AxisDataLocator) dataLocators.get(dialect);
        if (locator == null) {
            String className = (String) dataLocatorClassNames.get(dialect);
            if (className != null) {
                locator = loadDataLocator(className);
                dataLocators.put(dialect, locator);
            }

        }

        return locator;

    }

    /*
     * Checks if global level data locator configured for specified dialect.
     * @param dialect- an absolute URI represents the Dialect i.e. WSDL, Policy,
     * Schema or "GlobalLevel" for non-dialect Global level data locator.
     * Returns an instance of the data locator if exists, and null otherwise.
     */

    public AxisDataLocator getGlobalDataLocator(String dialect)
            throws AxisFault {
        AxisConfiguration axisConfig = getAxisConfiguration();
        AxisDataLocator locator = null;
        if (axisConfig != null) {
            locator = axisConfig.getDataLocator(dialect);
            if (locator == null) {
                String className = axisConfig.getDataLocatorClassName(dialect);
                if (className != null) {
                    locator = loadDataLocator(className);
                    axisConfig.addDataLocator(dialect, locator);
                }
            }
        }

        return locator;

    }

    protected AxisDataLocator loadDataLocator(String className)
            throws AxisFault {

        AxisDataLocator locator;

        try {
            Class dataLocator;
            dataLocator = Class.forName(className, true, serviceClassLoader);
            locator = (AxisDataLocator) dataLocator.newInstance();
        } catch (ClassNotFoundException e) {
            throw AxisFault.makeFault(e);
        } catch (IllegalAccessException e) {
            throw AxisFault.makeFault(e);
        } catch (InstantiationException e) {
            throw AxisFault.makeFault(e);

        }

        return locator;
    }

    /**
     * Set the map of WSDL message element QNames to AxisOperations for this
     * service. This map is used during SOAP Body-based routing for
     * document/literal bare services to match the first child element of the
     * SOAP Body element to an operation. (Routing for RPC and document/literal
     * wrapped services occurs via the operationsAliasesMap.) <p/> From section
     * 4.7.6 of the WS-I BP 1.1: the "operation signature" is "the fully
     * qualified name of the child element of SOAP body of the SOAP input
     * message described by an operation in a WSDL binding," and thus this map
     * must be from a QName to an operation.
     * 
     * @param messageElementQNameToOperationMap
     *            The map from WSDL message element QNames to AxisOperations.
     */
    public void setMessageElementQNameToOperationMap(
            Map messageElementQNameToOperationMap) {
        this.messageElementQNameToOperationMap = messageElementQNameToOperationMap;
    }

    /**
     * Look up an AxisOperation for this service based off of an element QName
     * from a WSDL message element.
     * 
     * @param messageElementQName
     *            The QName to search for.
     * @return The AxisOperation registered to the QName or null if no match was
     *         found.
     * @see #setMessageElementQNameToOperationMap(Map)
     */
    public AxisOperation getOperationByMessageElementQName(
            QName messageElementQName) {
        return (AxisOperation) messageElementQNameToOperationMap
                .get(messageElementQName);
    }

    /**
     * Add an entry to the map between element QNames in WSDL messages and
     * AxisOperations for this service.
     * 
     * @param messageElementQName
     *            The QName of the element on the input message that maps to the
     *            given operation.
     * @param operation
     *            The AxisOperation to be mapped to.
     * @see #setMessageElementQNameToOperationMap(Map)
     */
    public void addMessageElementQNameToOperationMapping(
            QName messageElementQName, AxisOperation operation) {
        // when setting an operation we have to set it only if the
        // messegeElementQName does not
        // exists in the map.
        // does exists means there are two or more operations which has the same
        // input element (in doc/literal
        // this is possible. In this case better to set it as null without
        // giving
        // a random operation.
        if (messageElementQNameToOperationMap.containsKey(messageElementQName)
                && messageElementQNameToOperationMap.get(messageElementQName) != operation) {
            messageElementQNameToOperationMap.put(messageElementQName, null);
        } else {
            messageElementQNameToOperationMap.put(messageElementQName,
                    operation);
        }

    }

    /**
     * @deprecated use {@link AxisEndpoint#getEndpointURL()}
     */
    public String getEndpointURL() {
        return endpointURL;
    }

    /**
     * @deprecated use {@link AxisEndpoint#setEndpointURL(String)}
     */
    public void setEndpointURL(String endpointURL) {
        this.endpointURL = endpointURL;
    }

    // TODO : Explain what goes in this map!
    public Map<String, AxisEndpoint> getEndpoints() {
        return endpointMap;
    }

    public boolean isCustomWsdl() {
        return customWsdl;
    }

    public void setCustomWsdl(boolean customWsdl) {
        this.customWsdl = customWsdl;
    }

    public List getOperationsNameList() {
        return operationsNameList;
    }

    public void setOperationsNameList(List operationsNameList) {
        this.operationsNameList = operationsNameList;
    }

    public AxisServiceGroup getAxisServiceGroup() {
        return (AxisServiceGroup) parent;
    }

    public void setParent(AxisServiceGroup parent) {
        this.parent = parent;
    }

    public String toString() {
        return getName();
    }

    public ExcludeInfo getExcludeInfo() {
        return excludeInfo;
    }

    public void setExcludeInfo(ExcludeInfo excludeInfo) {
        this.excludeInfo = excludeInfo;
    }

    public void registerPolicy(String key, Policy policy) {
        policyMap.put(key, policy);
    }

    public Policy lookupPolicy(String key) {
        return (Policy) policyMap.get(key);
    }
    
    /**
     * Add a ServiceContextListener
     * @param scl
     */
    public void addMessageContextListener(MessageContextListener scl) {
        messageContextListeners.add(scl);
    }
    
    /**
     * Remove a ServiceContextListener
     * @param scl
     */
    public void removeMessageContextListener(MessageContextListener scl) {
        messageContextListeners.remove(scl);
    }
    
    /**
     * @param cls Class of ServiceContextListener
     * @return true if ServiceContextLister is in the list
     */
    public boolean hasMessageContextListener(Class cls) {
        for (int i=0; i<messageContextListeners.size(); i++) {
            if (messageContextListeners.get(i).getClass() == cls) {
                return true;
            }
        }
        return false;
    }
    
    /**
     * Signal an Attach ServiceContext Event
     * @param sc ServiceContext
     * @param mc MessageContext
     */
    public void attachServiceContextEvent(ServiceContext sc, MessageContext mc) {
        for (int i=0; i<messageContextListeners.size(); i++) {
            messageContextListeners.get(i).attachServiceContextEvent(sc, mc);
        }
    }
    
    /**
     * Signal an Attach Envelope Event
     * @param mc MessageContext
     */
    public void attachEnvelopeEvent(MessageContext mc) {
        for (int i=0; i<messageContextListeners.size(); i++) {
            messageContextListeners.get(i).attachEnvelopeEvent(mc);
        }
    }

    /**
     * returns a axisService given a input Stream of WSDL2.0 document.
     * 
     * @param description
     *            WSDL description
     * @param wsdlServiceName
     * @param endPoint
     * @param options
     * @return
     * @throws AxisFault
     */
    public static AxisService createClientSideAxisService(Description description,
            QName wsdlServiceName, String endPoint, Options options) throws AxisFault {
        WSDL20ToAxisServiceBuilder serviceBuilder = new WSDL20ToAxisServiceBuilder(description,
                wsdlServiceName, endPoint);
        serviceBuilder.setServerSide(false);
        AxisService axisService = serviceBuilder.populateService();
        AxisEndpoint axisEndpoint = (AxisEndpoint) axisService.getEndpoint(axisService
                .getEndpointName());
        if (axisEndpoint != null) {
            options.setTo(new EndpointReference(axisEndpoint.getEndpointURL()));
            options.setSoapVersionURI((String) axisEndpoint.getBinding().getProperty(
                    WSDL2Constants.ATTR_WSOAP_VERSION));
        }
        return axisService;
    }    
    private void printDescriptionObject(Description definition,
            OutputStream out, String requestIP) {
        //TODO - complete this method
        org.apache.woden.WSDLFactory fac;
        try {
            fac = org.apache.woden.WSDLFactory.newInstance();
            org.apache.woden.WSDLWriter writer = fac.newWSDLWriter();
            writer.writeWSDL(definition.toElement(), out);
        } catch (org.apache.woden.WSDLException e) {
            e.printStackTrace();
        }
        
        
    }
    
    private WSDLSupplier getUserDefinedWSDLSupplier(String wsdlVersion){
        WSDLSupplier wsdlSupplier = null;
        if("wsdl".equals(wsdlVersion)){
            Parameter para = getParameter(Constants.WSDL_11_SUPPLIER_CLASS_PARAM);
            if (para != null) {
                try {
                    wsdlSupplier = (WSDLSupplier) Class.forName((String) para.getValue()).newInstance();
                    if( wsdlSupplier instanceof WSDL11SupplierTemplate){
                        ((WSDL11SupplierTemplate)wsdlSupplier).init(this);                       
                    }
                } catch (Exception e) {
                    System.err.println("Following exception occurred when generating WSDL using "
                            + para);
                    e.printStackTrace();
                }
            }
        } else if("wsdl2".equals(wsdlVersion)){
            Parameter para = getParameter(Constants.WSDL_20_SUPPLIER_CLASS_PARAM);
            if(para != null){            
                try {
                    wsdlSupplier = (WSDLSupplier) Class.forName((String) para.getValue()).newInstance() ;
                    if( wsdlSupplier instanceof WSDL20SupplierTemplate){
                        ((WSDL20SupplierTemplate)wsdlSupplier).init(this);                       
                    }
                } catch (Exception e) {    
                    System.err.println("Following exception occurred when generating WSDL using "+ para );
                    e.printStackTrace();
                }                     
            }
            
        }
        return wsdlSupplier;        
    }
}
