/*
 * 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.tuscany.sca.binding.jms;

import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;

import org.apache.tuscany.sca.assembly.ConfiguredOperation;
import org.apache.tuscany.sca.assembly.OperationSelector;
import org.apache.tuscany.sca.assembly.OperationsConfigurator;
import org.apache.tuscany.sca.assembly.WireFormat;
import org.apache.tuscany.sca.assembly.xml.ConfiguredOperationProcessor;
import org.apache.tuscany.sca.assembly.xml.Constants;
import org.apache.tuscany.sca.assembly.xml.PolicySubjectProcessor;
import org.apache.tuscany.sca.binding.jms.operationselector.OperationSelectorJMSDefault;
import org.apache.tuscany.sca.binding.jms.wireformat.WireFormatJMSDefault;
import org.apache.tuscany.sca.binding.jms.wireformat.WireFormatJMSObject;
import org.apache.tuscany.sca.binding.jms.wireformat.WireFormatJMSText;
import org.apache.tuscany.sca.binding.jms.wireformat.WireFormatJMSTextXML;
import org.apache.tuscany.sca.contribution.processor.BaseStAXArtifactProcessor;
import org.apache.tuscany.sca.contribution.processor.ContributionReadException;
import org.apache.tuscany.sca.contribution.processor.ContributionResolveException;
import org.apache.tuscany.sca.contribution.processor.ContributionWriteException;
import org.apache.tuscany.sca.contribution.processor.ProcessorContext;
import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
import org.apache.tuscany.sca.core.FactoryExtensionPoint;
import org.apache.tuscany.sca.monitor.Monitor;
import org.apache.tuscany.sca.monitor.Problem;
import org.apache.tuscany.sca.monitor.Problem.Severity;
import org.apache.tuscany.sca.policy.PolicyFactory;

/**
 * A processor to read the XML that describes the JMS binding...
 * 
 * <binding.jms correlationScheme="string"?
 *              initialContextFactory="xs:anyURI"?
 *              jndiURL="xs:anyURI"?
 *              requestConnection="QName"?
 *              responseConnection="QName"?
 *              operationProperties="QName"?
 *              ...>
 * 
 *     <headers type="string"?
 *              deliveryMode="string"?
 *              timeToLive="int"?
 *              priority="string"?>
 *         <property name="NMTOKEN" type="NMTOKEN">*
 *     </headers>?
 * 
 *     <destination jndiName="xs:anyURI" type="string"? create="string"?>
 *         <property name="NMTOKEN" type="NMTOKEN">*
 *     </destination>?
 * 
 *     <connectionFactory jndiName="xs:anyURI" create="string"?>
 *         <property name="NMTOKEN" type="NMTOKEN">*
 *     </connectionFactory>?
 * 
 *     <activationSpec name="xs:anyURI" create="string"?>
 *         <property name="NMTOKEN" type="NMTOKEN">*
 *     </activationSpec>?
 * 
 *     <response>
 *         <destination jndiName="xs:anyURI" type="string"? create="string"?>
 *             <property name="NMTOKEN" type="NMTOKEN">*
 *         </destination>?
 * 
 *         <connectionFactory jndiName="xs:anyURI" create="string"?>
 *             <property name="NMTOKEN" type="NMTOKEN">*
 *         </connectionFactory>?
 * 
 *         <activationSpec name="xs:anyURI" create="string"?>
 *             <property name="NMTOKEN" type="NMTOKEN">*
 *         </activationSpec>?
 *         
 *         <wireFormat.someWireFormat/>?
 *     </response>?
 * 
 *     <complexType name="SubscriptionHeaders"> 
 *         <attribute name="JMSSelector" type="string"/> 
 *     </complexType>
 *
 *     <resourceAdapter name="NMTOKEN">?
 *         <property name="NMTOKEN" type="NMTOKEN">*
 *     </resourceAdapter>?
 * 
 *     <operationProperties name="string" nativeOperation="string"?>
 *         <property name="NMTOKEN" type="NMTOKEN">*
 *         <headers type="string"?
 *                  deliveryMode="string"?
 *                  timeToLive="int"?
 *                  priority="string"?>
 *             <property name="NMTOKEN" type="NMTOKEN">*
 *         </headers>?
 *     </operationProperties>*
 *     
 *     <wireFormat.someWireFormat/>?
 * </binding.jms>
 *
 * Parsing error messages are recorded locally and reported as validation exceptions. Parsing
 * warnings do not cause validation exceptions.
 *
 * @version $Rev$ $Date$
 */

public class JMSBindingProcessor extends BaseStAXArtifactProcessor implements StAXArtifactProcessor<JMSBinding> {
    private PolicyFactory policyFactory;
    private PolicySubjectProcessor policyProcessor;
    private ConfiguredOperationProcessor configuredOperationProcessor;
    protected StAXArtifactProcessor<Object> extensionProcessor;

    public JMSBindingProcessor(FactoryExtensionPoint modelFactories, StAXArtifactProcessor<Object> extensionProcessor) {
        this.policyFactory = modelFactories.getFactory(PolicyFactory.class);
        this.policyProcessor = new PolicySubjectProcessor(policyFactory);

        this.configuredOperationProcessor = 
            new ConfiguredOperationProcessor(modelFactories);
        this.extensionProcessor = extensionProcessor;
    }
    
    /**
     * Report a error.
     * 
     * @param problems
     * @param message
     * @param model
    */
    private void warning(Monitor monitor, String message, Object model, Object... messageParameters) {
        if (monitor != null) {
            Problem problem = monitor.createProblem(this.getClass().getName(), "binding-jms-validation-messages", Severity.WARNING, model, message, (Object[])messageParameters);
    	    monitor.problem(problem);
        }        
    }
     
    /**
      * Report an error.
      * One side effect is that error messages are saved for future validation calls.
      * 
      * @param problems
      * @param message
      * @param model
    */
    private void error(Monitor monitor, String message, Object model, Object... messageParameters) {
        if (monitor != null) {
            Problem problem = monitor.createProblem(this.getClass().getName(), "binding-jms-validation-messages", Severity.ERROR, model, message, (Object[])messageParameters);
     	    monitor.problem(problem);
        }        
    }

    public QName getArtifactType() {
        return JMSBindingConstants.BINDING_JMS_QNAME;
    }

    public Class<JMSBinding> getModelType() {
        return JMSBinding.class;
    }

    public JMSBinding read(XMLStreamReader reader, ProcessorContext context) throws ContributionReadException, XMLStreamException {
        Monitor monitor = context.getMonitor();
        JMSBinding jmsBinding = new JMSBinding();
        // Reset validation message to keep track of validation issues.

        // Read policies
        policyProcessor.readPolicies(jmsBinding, reader);

        // Read binding name
        String name = reader.getAttributeValue(null, "name");
        if (name != null) {
            jmsBinding.setName(name);
        }

        // Read binding URI
        String uri = reader.getAttributeValue(null, "uri");
        if (uri != null && uri.length() > 0) {
            parseURI(uri, jmsBinding, monitor);
        }

        // Read correlation scheme
        String correlationScheme = reader.getAttributeValue(null, "correlationScheme");
        if (correlationScheme != null && correlationScheme.length() > 0) {
            if (JMSBindingConstants.VALID_CORRELATION_SCHEMES.contains(correlationScheme.toLowerCase())) {
                jmsBinding.setCorrelationScheme(correlationScheme);
            } else {
            	error(monitor, "InvalidCorrelationScheme", reader, correlationScheme);
            }
        }

        // Read initial context factory
        String initialContextFactory = getURIString(reader, "initialContextFactory");
        if (initialContextFactory != null && initialContextFactory.length() > 0) {
            jmsBinding.setInitialContextFactoryName(initialContextFactory);
        }

        // Read JNDI URL
        String jndiURL = getURIString(reader, "jndiURL");
        if (jndiURL != null && jndiURL.length() > 0) {
            jmsBinding.setJndiURL(jndiURL);
        }

        // Read message processor class name
        // TODO - maintain this for the time being but move over to 
        //        configuring wire formats instead of message processors
        String messageProcessorName = reader.getAttributeValue(null, "messageProcessor");
        if (messageProcessorName != null && messageProcessorName.length() > 0) {
            if ("XMLTextMessage".equalsIgnoreCase(messageProcessorName)) {
                // may be overwritten be real wire format later
                jmsBinding.setRequestWireFormat(new WireFormatJMSTextXML());
                jmsBinding.setResponseWireFormat(jmsBinding.getRequestWireFormat());
            } else if ("TextMessage".equalsIgnoreCase(messageProcessorName)) {
                // may be overwritten be real wire format later
                jmsBinding.setRequestWireFormat(new WireFormatJMSText());
                jmsBinding.setResponseWireFormat(jmsBinding.getRequestWireFormat());
            } else if ("ObjectMessage".equalsIgnoreCase(messageProcessorName)) {
                // may be overwritten be real wire format later
                jmsBinding.setRequestWireFormat(new WireFormatJMSObject());
                jmsBinding.setResponseWireFormat(jmsBinding.getRequestWireFormat());
            } else {
                jmsBinding.setRequestMessageProcessorName(messageProcessorName);
                jmsBinding.setResponseMessageProcessorName(messageProcessorName);
                // exploit the text wire format code to drive the user selected 
                // message processor
                jmsBinding.setRequestWireFormat(new WireFormatJMSText());
                jmsBinding.setResponseWireFormat(jmsBinding.getRequestWireFormat());
            }
        }

        String requestConnectionName = reader.getAttributeValue(null, "requestConnection");
        if (requestConnectionName != null && requestConnectionName.length() > 0) {
            jmsBinding.setRequestConnectionName(getQNameValue(reader, requestConnectionName));
        }
        String responseConnectionName = reader.getAttributeValue(null, "responseConnection");
        if (responseConnectionName != null && responseConnectionName.length() > 0) {
            jmsBinding.setResponseConnectionName(getQNameValue(reader, responseConnectionName));
        }

        String operationPropertiesName = reader.getAttributeValue(null, "operationProperties");
        if (operationPropertiesName != null && operationPropertiesName.length() > 0) {
            jmsBinding.setOperationPropertiesName(getQNameValue(reader, operationPropertiesName));
        }

        // Read sub-elements of binding.jms
        boolean endFound = false;
        while (!endFound) {
            int fg = reader.next();
            switch (fg) {
                case START_ELEMENT:
                    String elementName = reader.getName().getLocalPart();
                    if ("destination".equals(elementName)) {
                        parseDestination(reader, jmsBinding, monitor);
                    } else if ("connectionFactory".equals(elementName)) {
                        parseConnectionFactory(reader, jmsBinding, monitor);
                    } else if ("activationSpec".equals(elementName)) {
                        parseActivationSpec(reader, jmsBinding, monitor);
                    } else if ("response".equals(elementName)) {
                        parseResponse(reader, jmsBinding, context);
                    } else if ("resourceAdapter".equals(elementName)) {
                        parseResourceAdapter(reader, jmsBinding, monitor);
                    } else if ("headers".equals(elementName)) {
                        parseHeaders(reader, jmsBinding, monitor);
                    } else if ("operationProperties".equals(elementName)) {
                        parseOperationProperties(reader, jmsBinding, monitor);
                    } else if ("messageSelection".equals(elementName)) {
                        parseSubscriptionHeaders(reader, jmsBinding);
                    } else if (Constants.OPERATION_QNAME.equals(reader.getName())) {
                        ConfiguredOperation confOp = configuredOperationProcessor.read(reader, context);
                        if (confOp != null) {
                            ((OperationsConfigurator)jmsBinding).getConfiguredOperations().add(confOp);
                        }
                    } else {
                        Object extension = extensionProcessor.read(reader, context);
                        if (extension != null) {
                            if (extension instanceof WireFormat) {
                                if (jmsBinding.getRequestWireFormat() == null) {
                                    jmsBinding.setRequestWireFormat((WireFormat) extension);
                                } else {
                                    error(monitor, "WireFormatAlreadyDefined", reader, extension.toString());
                                }
                            } else if (extension instanceof OperationSelector) {
                                if (jmsBinding.getOperationSelector() == null) {
                                    jmsBinding.setOperationSelector((OperationSelector) extension);
                                } else {
                                    error(monitor, "OpSelectorAlreadyDefined", reader, extension.toString());
                                }

                            } else {
                                error(monitor, "UnexpectedElement", reader, extension.toString());
                            }
                        }
                    }
                    //reader.next();
                    break;
                case END_ELEMENT:
                    QName x = reader.getName();
                    if (Constants.OPERATION.equals(x.getLocalPart())) break;
                    // This assumption is not captured in schema, which isn't good, but will probably be fine for now.
                    // A better solution might be to require each processor to advance to its own END_ELEMENT.
                    if (x.getLocalPart().startsWith("wireFormat.") || x.getLocalPart().startsWith("operationSelector.")) {                         
                        break;
                    }
                    if (x.equals(JMSBindingConstants.BINDING_JMS_QNAME)) {
                        endFound = true;
                    } else {
                    	error(monitor, "UnexpectedElement: expected " + JMSBindingConstants.BINDING_JMS_QNAME + ", found " + x.toString(), 
                    	      reader, x.toString());
                    }
            }
        }
        
        // if no operation selector is specified then assume the default
        if (jmsBinding.getOperationSelector() == null){
            jmsBinding.setOperationSelector(new OperationSelectorJMSDefault());
        }
        
        // if no request wire format specified then assume the default
        if (jmsBinding.getRequestWireFormat() == null){
            jmsBinding.setRequestWireFormat(new WireFormatJMSDefault());
        }
        
        // if no response wire format specific then assume the same as the request
        if (jmsBinding.getResponseWireFormat() == null){
            jmsBinding.setResponseWireFormat(jmsBinding.getRequestWireFormat());
         }

        validate( jmsBinding, monitor );

        return jmsBinding;
    }

    protected void parseURI(String uri, JMSBinding jmsBinding, Monitor monitor) {
        if (!uri.startsWith("jms:")) {
        	error(monitor, "MustStartWithSchema", jmsBinding, uri);
        	return;
        }
        int i = uri.indexOf('?');            
        if (i >= 0) {
        	StringTokenizer st = new StringTokenizer(uri.substring(i+1),"&");
        	while (st.hasMoreTokens()) {
        	    String s = st.nextToken();
        	    if (s.startsWith("connectionFactoryName=")) {
        	        jmsBinding.setConnectionFactoryName(s.substring(22));
        	    } else {
        	        error(monitor, "UnknownTokenInURI", jmsBinding, s, uri);
                 	return;
        	     }
        	}
        	jmsBinding.setDestinationName(uri.substring(4, i));
        } else {
           jmsBinding.setDestinationName(uri.substring(4));
        }
    }

    public void resolve(JMSBinding model, ModelResolver resolver, ProcessorContext context) throws ContributionResolveException {
        if (model.getRequestConnectionName() != null) {
            model.setRequestConnectionBinding(getConnectionBinding(model, "requestConnection", model.getRequestConnectionName(), resolver, context));
        }
        if (model.getResponseConnectionName() != null) {
            model.setResponseConnectionBinding(getConnectionBinding(model, "responseConnection", model.getResponseConnectionName(), resolver, context));
        }
        if (model.getOperationPropertiesName() != null) {
            model.setOperationPropertiesBinding(getConnectionBinding(model, "operationProperties", model.getOperationPropertiesName(), resolver, context));
        }
    }

    private JMSBinding getConnectionBinding(JMSBinding model, String attrName, QName bindingName, ModelResolver resolver, ProcessorContext context) {
        JMSBinding binding = new JMSBinding();
        binding.setTargetNamespace(bindingName.getNamespaceURI());
        binding.setName(bindingName.getLocalPart());
        binding.setUnresolved(true);
        binding = resolver.resolveModel(JMSBinding.class, binding, context);
        if (binding.isUnresolved())
            error(context.getMonitor(), "BindingNotFound", model, attrName, bindingName);
        return binding;
    }

    private void parseDestination(XMLStreamReader reader, JMSBinding jmsBinding, Monitor monitor) throws XMLStreamException {
        String name = getURIString(reader, "jndiName");
        if (name != null && name.length() > 0) {
            jmsBinding.setDestinationName(name);
        }

        String type = reader.getAttributeValue(null, "type");                
        if (type != null && type.length() > 0) {
            if (JMSBindingConstants.DESTINATION_TYPE_QUEUE.equalsIgnoreCase(type)) {
                jmsBinding.setDestinationType(JMSBindingConstants.DESTINATION_TYPE_QUEUE);
            } else if (JMSBindingConstants.DESTINATION_TYPE_TOPIC.equalsIgnoreCase(type)) {
                jmsBinding.setDestinationType(JMSBindingConstants.DESTINATION_TYPE_TOPIC);
            } else {
            	error(monitor, "InvalidDestinationType", reader, type);
            }            
        }

        String create = reader.getAttributeValue(null, "create");
        if (create != null && create.length() > 0) {
            jmsBinding.setDestinationCreate(create);
        }

        jmsBinding.getDestinationProperties().putAll(parseBindingProperties(reader, monitor));
    }

    private void parseConnectionFactory(XMLStreamReader reader, JMSBinding jmsBinding, Monitor monitor) throws XMLStreamException {
        String name = getURIString(reader, "jndiName");
        if (name != null && name.length() > 0) {
            jmsBinding.setConnectionFactoryName(name);
        } else {
            error(monitor, "MissingConnectionFactoryName", reader);
        }
        jmsBinding.getConnectionFactoryProperties().putAll(parseBindingProperties(reader, monitor));
    }

    private void parseActivationSpec(XMLStreamReader reader, JMSBinding jmsBinding, Monitor monitor) throws XMLStreamException {
        String name = reader.getAttributeValue(null, "name");        
        if (name != null && name.length() > 0) {
            jmsBinding.setActivationSpecName(name);            
        } else {
            warning(monitor, "MissingActivationSpecName", reader);
        }
        jmsBinding.getActivationSpecProperties().putAll(parseBindingProperties(reader, monitor));
    }

    private void parseResponseDestination(XMLStreamReader reader, JMSBinding jmsBinding, Monitor monitor) throws XMLStreamException {
        String name = getURIString(reader, "jndiName");
        if (name != null && name.length() > 0) {
            jmsBinding.setResponseDestinationName(name);
        }

        String type = reader.getAttributeValue(null, "type");        
        if (type != null && type.length() > 0) {
            warning(monitor, "DoesntProcessResponseDestinationType", jmsBinding);
            if (JMSBindingConstants.DESTINATION_TYPE_QUEUE.equalsIgnoreCase(type)) {
                jmsBinding.setResponseDestinationType(JMSBindingConstants.DESTINATION_TYPE_QUEUE);
            } else if (JMSBindingConstants.DESTINATION_TYPE_TOPIC.equalsIgnoreCase(type)) {
                jmsBinding.setResponseDestinationType(JMSBindingConstants.DESTINATION_TYPE_TOPIC);
            } else {
                error(monitor, "InvalidResponseDestinationType", reader, type);
            }
        }

        String create = reader.getAttributeValue(null, "create");
        if (create != null && create.length() > 0) {
            jmsBinding.setResponseDestinationCreate(create);
        }

        jmsBinding.getResponseDestinationProperties().putAll(parseBindingProperties(reader, monitor));
    }

    private void parseResponseConnectionFactory(XMLStreamReader reader, JMSBinding jmsBinding, Monitor monitor) throws XMLStreamException {
        String name = getURIString(reader, "jndiName");
        if (name != null && name.length() > 0) {
            jmsBinding.setResponseConnectionFactoryName(name);            
        } else {
            warning(monitor, "MissingResponseConnectionFactory", reader);
        }
        jmsBinding.getResponseConnectionFactoryProperties().putAll(parseBindingProperties(reader, monitor));
    }

    private void parseResponseActivationSpec(XMLStreamReader reader, JMSBinding jmsBinding, Monitor monitor) throws XMLStreamException {
        String name = reader.getAttributeValue(null, "name");
        if (name != null && name.length() > 0) {
            jmsBinding.setResponseActivationSpecName(name);            
        } else {
            warning(monitor, "MissingResponseActivationSpec", reader);
        }
        jmsBinding.getResponseActivationSpecProperties().putAll(parseBindingProperties(reader, monitor));
    }

    private void parseResponse(XMLStreamReader reader, JMSBinding jmsBinding, ProcessorContext context) throws ContributionReadException, XMLStreamException {
        // Read sub-elements of response
        Monitor monitor = context.getMonitor();
        while (true) {
            switch (reader.next()) {
                case START_ELEMENT:
                    String elementName = reader.getName().getLocalPart();
                    if ("destination".equals(elementName)) {
                        parseResponseDestination(reader, jmsBinding, context.getMonitor());
                    } else if ("connectionFactory".equals(elementName)) {
                        parseResponseConnectionFactory(reader, jmsBinding, monitor);
                    } else if ("activationSpec".equals(elementName)) {
                        parseResponseActivationSpec(reader, jmsBinding, monitor);
                    } else {
                        Object extension = extensionProcessor.read(reader, context);
                        if (extension != null) {
                            if (extension instanceof WireFormat) {
                                if (jmsBinding.getResponseWireFormat() == null) {
                                    jmsBinding.setResponseWireFormat((WireFormat)extension);
                                } else {
                                    error(context.getMonitor(), "ResponseWireformatAlreadyDefined", reader, extension.toString());
                                }
                            } else {
                                error(context.getMonitor(), "UnexpectedElement", reader, extension.toString());
                            }
                        }
                        reader.next();
                    }
                    //reader.next();
                    break;
                case END_ELEMENT:
                    QName x = reader.getName();
                    if (x.getLocalPart().equals("response")) {
                        return;
                    } else {
                    	error(context.getMonitor(), "UnexpectedResponseElement", reader, x.toString());
                    }
            }
        }
    }

    private void parseResourceAdapter(XMLStreamReader reader, JMSBinding jmsBinding, Monitor monitor) throws XMLStreamException {
        String name = reader.getAttributeValue(null, "name");        
        if (name != null && name.length() > 0) {
            jmsBinding.setResourceAdapterName(name);            
        } else {
            error(monitor, "MissingResourceAdapterName", reader);
        }
        jmsBinding.getResourceAdapterProperties().putAll(parseBindingProperties(reader, monitor));
    }

    /**
     * <headers JMSType="string"?
     *          JMSCorrelationID="string"?
     *          JMSDeliveryMode="PERSISTENT or NON_PERSISTENT"?
     *          timeToLive="long"?      
     *          JMSPriority="0 .. 9"?>
     *     <property name="NMTOKEN" type="NMTOKEN"?>*    
     * </headers>?
     */
    private void parseHeaders(XMLStreamReader reader, JMSBinding jmsBinding, Monitor monitor) throws XMLStreamException {
        String jmsType = reader.getAttributeValue(null, "type");
        if (jmsType != null && jmsType.length() > 0) {
            jmsBinding.setJMSType(jmsType);
        }

        String jmsDeliveryMode = reader.getAttributeValue(null, "deliveryMode");
        if (jmsDeliveryMode != null && jmsDeliveryMode.length() > 0) {
            if ("persistent".equalsIgnoreCase(jmsDeliveryMode)) {
                jmsBinding.setJMSDeliveryMode(true);
            } else if ("nonpersistent".equalsIgnoreCase(jmsDeliveryMode)) {
                jmsBinding.setJMSDeliveryMode(false);
            } else {
                error(monitor, "InvalidJMSDeliveryMode", jmsBinding, jmsDeliveryMode);
            }
        }

        String jmsTimeToLive = reader.getAttributeValue(null, "timeToLive");
        if (jmsTimeToLive != null && jmsTimeToLive.length() > 0) {
            jmsBinding.setJMSTimeToLive(Long.parseLong(jmsTimeToLive));
        }

        String jmsPriority = reader.getAttributeValue(null, "priority");
        if (jmsPriority != null && jmsPriority.length() > 0) {
            try {
                int p = Integer.parseInt(jmsPriority);
                if (p >= 0 && p <= 9) {
                    jmsBinding.setJMSPriority(p);
                } else {
                    warning(monitor, "InvalidJMSPriority", jmsBinding, jmsPriority);
                }
            } catch (NumberFormatException ex) {
                error(monitor, "InvalidJMSPriority", jmsBinding, jmsPriority);
            }
        }

        while (true) {
            switch (reader.next()) {
                case START_ELEMENT:
                    if (reader.getName().getLocalPart().equals("property")) {
                        parseProperty(reader, jmsBinding);
                    }
                    break;
                case END_ELEMENT:
                    QName x = reader.getName();
                    if (x.getLocalPart().equals("headers")) {
                        return;
                    } else {
                        error(monitor, "UnexpectedResponseElement", reader, x.toString());
                    }
            }
        }
    }
    
    private void parseProperty(XMLStreamReader reader, JMSBinding jmsBinding) throws XMLStreamException {
        jmsBinding.setHeaders( true );
        String name = reader.getAttributeValue(null, "name");
        String type = reader.getAttributeValue(null, "type");        
        if (name != null && name.length() > 0) {
            Object value = reader.getElementText();
            if ("boolean".equalsIgnoreCase(type)) {
                value = Boolean.parseBoolean((String)value);
            } else if ("byte".equalsIgnoreCase(type)) {
                value = Byte.parseByte(((String)value));
            } else if ("short".equalsIgnoreCase(type)) {
                value = Short.parseShort((String)value);
            } else if ("int".equalsIgnoreCase(type)) {
                value = Integer.parseInt((String)value);
            } else if ("long".equalsIgnoreCase(type)) {
                value = Long.parseLong((String)value);
            } else if ("float".equalsIgnoreCase(type)) {
                value = Float.parseFloat((String)value);
            } else if ("double".equalsIgnoreCase(type)) {
                value = Double.parseDouble((String)value);
            } else if ("String".equalsIgnoreCase(type)) {
                // its already a string
            }
            jmsBinding.setProperty(name, value);
        }
    }

    /**
     * <operationProperties name="string" nativeOperation="string"?>
     *   <property name="NMTOKEN" type="NMTOKEN"?>*
     *   <headers JMSType="string"?
     *            JMSCorrelationID="string"?
     *            JMSDeliveryMode="PERSISTENT or NON_PERSISTENT"?
     *            timeToLive="long"?
     *            JMSPriority="0 .. 9"?>
     *       <property name="NMTOKEN" type="NMTOKEN"?>*
     *   </headers>?
     * </operationProperties>*
     */
    private void parseOperationProperties(XMLStreamReader reader, JMSBinding jmsBinding, Monitor monitor) throws XMLStreamException {
        
        if (jmsBinding.getOperationPropertiesName() != null) {
            error(monitor, "DuplicateOperationProperties", jmsBinding);
        }
        
        String opName = reader.getAttributeValue(null, "name");
        if (opName == null || opName.length() < 1) {
            warning(monitor, "MissingJMSOperationPropertyName", jmsBinding);
            return;
        }
        // Since nativeOpName, headers, and property elements are optional, must add opName.
        jmsBinding.addOperationName(opName);
        String nativeOpName = reader.getAttributeValue(null, "nativeOperation"); // optional
        if (nativeOpName != null && nativeOpName.length() > 0) {
            jmsBinding.setNativeOperationName(opName, nativeOpName);
        }

        Map<String, BindingProperty> props = new HashMap<String, BindingProperty>();
        while (true) {
            switch (reader.next()) {
                case START_ELEMENT:
                    if (reader.getName().getLocalPart().equals("headers")) { // optional
                        parseOperationHeaders(reader, jmsBinding, opName, monitor);
                    } else if (reader.getName().getLocalPart().equals("property")) { // optional
                    	processProperty(reader, props, monitor);
                    }
                break;
                case END_ELEMENT:
                    if (reader.isEndElement()) {
                        QName x = reader.getName();
                        if (x.getLocalPart().equals("headers")) {
                            break;
                        }
                        if (x.getLocalPart().equals("property")) {
                            break;
                        }
                        if (x.getLocalPart().equals("operationProperties")) {
                        	jmsBinding.getOperationPropertiesProperties(opName).putAll(props);
                            return;
                        } else {
                            error(monitor, "UnexpectedResponseElement", reader, x.toString());
                        }
                    }
            }
        }
    }

    private void parseOperationHeaders(XMLStreamReader reader, JMSBinding jmsBinding, String opName, Monitor monitor) throws XMLStreamException {
        String jmsType = reader.getAttributeValue(null, "type");
        if (jmsType != null && jmsType.length() > 0) {
            jmsBinding.setOperationJMSType(opName, jmsType);
        }

        String jmsDeliveryMode = reader.getAttributeValue(null, "deliveryMode");
        if (jmsDeliveryMode != null && jmsDeliveryMode.length() > 0) {
            if ("persistent".equalsIgnoreCase(jmsDeliveryMode)) {
                jmsBinding.setOperationJMSDeliveryMode(opName, true);
            } else if ("nonpersistent".equalsIgnoreCase(jmsDeliveryMode)) {
                jmsBinding.setOperationJMSDeliveryMode(opName, false);
            } else {
                error(monitor, "InvalidOPJMSDeliveryMode", jmsBinding, jmsDeliveryMode);
            }
        }

        String jmsTimeToLive = reader.getAttributeValue(null, "timeToLive");
        if (jmsTimeToLive != null && jmsTimeToLive.length() > 0) {
            jmsBinding.setOperationJMSTimeToLive(opName, Long.parseLong(jmsTimeToLive));
        }

        String jmsPriority = reader.getAttributeValue(null, "priority");
        if (jmsPriority != null && jmsPriority.length() > 0) {
            try {
                int p = Integer.parseInt(jmsPriority);
                if (p >= 0 && p <= 9) {
                    jmsBinding.setOperationJMSPriority(opName, p);
                } else {
                    warning(monitor, "InvalidOPJMSPriority", jmsBinding, jmsPriority);
                }
            } catch (NumberFormatException ex) {
                error(monitor, "InvalidOPJMSPriority", jmsBinding, jmsPriority);
            }
        }

        while (true) {
            switch (reader.next()) {
                case START_ELEMENT:
                    if (reader.getName().getLocalPart().equals("property")) {
                        parseOperationPropertyProperties(reader, jmsBinding, opName);
                    }
                    break;
                case END_ELEMENT:
                    QName x = reader.getName();
                    if (x.getLocalPart().equals("headers")) {
                        return;
                    } else {
                        error(monitor, "UnexpectedResponseElement", reader, x.toString());
                    }
            }
        }
    }

    private void parseOperationPropertyProperties(XMLStreamReader reader, JMSBinding jmsBinding, String opName) throws XMLStreamException {
        String propName = reader.getAttributeValue(null, "name");
        String type = reader.getAttributeValue(null, "type");
        if (propName != null && propName.length() > 0) {
            Object value = reader.getElementText();
            if ("boolean".equalsIgnoreCase(type)) {
                value = Boolean.parseBoolean((String)value);
            } else if ("byte".equalsIgnoreCase(type)) {
                value = Byte.parseByte(((String)value));
            } else if ("short".equalsIgnoreCase(type)) {
                value = Short.parseShort((String)value);
            } else if ("int".equalsIgnoreCase(type)) {
                value = Integer.parseInt((String)value);
            } else if ("long".equalsIgnoreCase(type)) {
                value = Long.parseLong((String)value);
            } else if ("float".equalsIgnoreCase(type)) {
                value = Float.parseFloat((String)value);
            } else if ("double".equalsIgnoreCase(type)) {
                value = Double.parseDouble((String)value);
            } else if ("String".equalsIgnoreCase(type)) {
                // its already a string
            }
            jmsBinding.setOperationProperty(opName, propName, value);
        }
    }

    private void parseSubscriptionHeaders(XMLStreamReader reader, JMSBinding jmsBinding) throws XMLStreamException {
        String jmsSelector = reader.getAttributeValue(null, "selector");
        if (jmsSelector != null && jmsSelector.length() > 0) {
            jmsBinding.setJMSSelector(jmsSelector);
        }
        
        // Skip to end element
        while (reader.hasNext()) {
            if (reader.next() == END_ELEMENT && "messageSelection".equals(reader.getName().getLocalPart())) {
                break;
            }
        } // end while
    }

    private Map<String, BindingProperty> parseBindingProperties(XMLStreamReader reader, Monitor monitor) throws XMLStreamException {
    	Map<String, BindingProperty> props = new HashMap<String, BindingProperty>();
    	String parentName = reader.getName().getLocalPart();        
        // Parse for all the properties within this element, until the end of
        // the element is reached.
    	boolean completed = false;
        while (!completed) {
            switch (reader.next()) {
                case START_ELEMENT:
                    String elementName = reader.getName().getLocalPart();
                    if ("property".equals(elementName)) {
                    	processProperty(reader, props, monitor);
                    }
                    break;
                case END_ELEMENT:
                	String endName = reader.getName().getLocalPart();
                	if (parentName.equals(endName)) {
                		completed = true;
                        break;
                	}
            }
        }        
        return props;
    }

    private void processProperty(XMLStreamReader reader, Map<String, BindingProperty> props, Monitor monitor) throws XMLStreamException {
        String name = reader.getAttributeValue(null, "name");
        if (name == null || name.length() < 1) {
            error(monitor, "InvalidPropertyElement", reader);
        }
        String type = reader.getAttributeValue(null, "type");
        String value = reader.getElementText();
        props.put(name, new BindingProperty(name, type, value));
    }

    /**
     * Preserve an existing public method. The method validate() is a legacy method 
     * that was called from reading am XML stream via the read(XMLStreamReader) method above.
     * However read(XMLStreamReader) now calls validate(JMSBinding jmsBinding) and
     * passes in the jmsBinding model.
     * The older validate() now calls validate(JMSBinding jmsBinding) with a null model. 
     */
    public void validate() {
        validate( null, null );
    }
    
    /**
     * Validates JMS parsing and JMSBinding model.
     * Validation rules are taken from the binding schema and the OSOA and OASIS specs:
     *    http://www.oasis-open.org/committees/documents.php?wg_abbrev=sca-bindings
     *    (sca-binding-jms-1.1-spec-cd01-rev4.pdf)
     *    http://www.osoa.org/display/Main/Service+Component+Architecture+Specifications
     *    (SCA JMS Binding V1.00 )
     * @param jmsBinding an optional JMS binding model to check for validity.  
     * @since 1.4
     */
    protected void validate( JMSBinding jmsBinding, Monitor monitor ) {        
        // If no JMSBinding model is provided, that is all the validation we can do.
        if ( jmsBinding == null ) {
            return;
        }

        // Connection factory should not contradict destination type.
        String connectionFactoryName = jmsBinding.getConnectionFactoryName();
        if (( connectionFactoryName != null ) && ( connectionFactoryName.length() > 0 )) {
            if (JMSBindingConstants.DESTINATION_TYPE_QUEUE == jmsBinding.getDestinationType()) {
                if ( connectionFactoryName.contains( "topic" )) {
                    error(monitor, "DestinationQueueContradiction", jmsBinding, connectionFactoryName );
                }
            }
            if (JMSBindingConstants.DESTINATION_TYPE_TOPIC == jmsBinding.getDestinationType()) {
                if ( connectionFactoryName.contains( "queue" )) {
                    error(monitor, "DestinationTopicContradiction", jmsBinding, connectionFactoryName );
                }
            }
        }
        
        // Connection factory and activation Specification are mutually exclusive.
        if (( connectionFactoryName != null ) && ( connectionFactoryName.length() > 0 )) {
            String activationSpecName = jmsBinding.getActivationSpecName();
            if ((activationSpecName != null) && (activationSpecName.length() > 0 )) {
                error(monitor, "ConnectionFactoryActivationSpecContradiction", jmsBinding, connectionFactoryName, activationSpecName );                
            }
        }

        // Given a response connection name attribute, there must not be a response element.
        // 156  /binding.jms/@responseConnection - identifies a binding.jms element that is present in a
        // 157 definition document, whose response child element is used to define the values for this binding. In
        // 158 this case this binding.jms element MUST NOT contain a response element.
        QName responseConnectionName = jmsBinding.getResponseConnectionName();
        if (( responseConnectionName != null ) && ( responseConnectionName.getLocalPart().length() > 0 )) {
            String responseDestinationName = jmsBinding.getResponseDestinationName();
            if (( responseDestinationName != null ) && (responseDestinationName.length() > 0)) {
                error(monitor, "ResponseAttrElement", jmsBinding, responseConnectionName, responseDestinationName );                               
            }
        }

        // Other jmsBinding model validation may be added here.

    }

    /**
     * Given a valid JMSBinding, write it as XML using the given XML writer.
     * 
     * This high-level method handles binding.jms element and its attributes. 
     * Sub elements have their own writer methods and are called from here.
     * <binding.jms 
     *    correlationScheme="string"?
     *    initialContextFactory="xs:anyURI"? 
     *    jndiURL="xs:anyURI"?
     *    requestConnection="QName"? 
     *    responseConnection="QName"?
     *    operationProperties="QName"? 
     *    ...>
     * @param writer an XMLStreamWriter that writes XML attributes and elements
     * @param jmsBinding JMSBinding model
     */
    public void write(JMSBinding jmsBinding, XMLStreamWriter writer, ProcessorContext context) throws ContributionWriteException,
        XMLStreamException {
        // Write a <binding.jms>
        writeStart(writer, Constants.SCA11_NS, JMSBindingConstants.BINDING_JMS,
                   new XAttr("requestConnection", jmsBinding.getRequestConnectionName()),
                   new XAttr("responseConnection", jmsBinding.getResponseConnectionName()),
                   new XAttr("operationProperties", jmsBinding.getOperationPropertiesName()));

        if (jmsBinding.getName() != null) {
            writer.writeAttribute("name", jmsBinding.getName());
        }

        if (jmsBinding.getURI() != null) {
            writer.writeAttribute("uri", jmsBinding.getURI());
        }

        //String dest = jmsBinding.getDestinationName();
        //if (dest != null) {
        //    if ( dest != null ) {
        //       writer.writeAttribute("uri", "jms:" + jmsBinding.getDestinationName());
        //    }
        //}

        String correlationScheme = jmsBinding.getCorrelationScheme();
        if ( correlationScheme != null ) {
            if ( !correlationScheme.equals(JMSBindingConstants.CORRELATE_MSG_ID) ) {
               writer.writeAttribute("correlationScheme", jmsBinding.getCorrelationScheme());
            }
        }
        
        if ( jmsBinding.getInitialContextFactoryName() != null ) {
            writer.writeAttribute("initialContextFactory", jmsBinding.getInitialContextFactoryName());            
        }
        
        if ( jmsBinding.getJndiURL() != null ) {
            writer.writeAttribute("jndiURL", jmsBinding.getJndiURL());            
        }
        
        if ( jmsBinding.containsHeaders() ) {
           writeHeaders( jmsBinding, writer);
        }

        writeOperationProperties( jmsBinding, writer );

        writeSubscriptionHeaders( jmsBinding, writer );
        
        writeDestinationProperties( jmsBinding, writer );
        
        writeConnectionFactoryProperties( jmsBinding, writer );
        
        writeActivationSpecProperties( jmsBinding, writer );

        // Write response info, if names are not defaults.
        String responseDestName = jmsBinding.getResponseDestinationName();
        String responseCFName = jmsBinding.getResponseConnectionFactoryName();
        String responseASName = jmsBinding.getResponseActivationSpecName();
        if (  responseDestName != null  || 
              responseCFName != null  ||
              responseASName != null ) {
            
           writer.writeStartElement(Constants.SCA11_NS, "response");
           writeResponseDestinationProperties( jmsBinding, writer );       
           writeResponseConnectionFactoryProperties( jmsBinding, writer );        
           writeResponseActivationSpecProperties( jmsBinding, writer );
           
           if ((jmsBinding.getResponseWireFormat() != null) &&
               !(jmsBinding.getResponseWireFormat() instanceof WireFormatJMSDefault)){
               writeWireFormat(jmsBinding.getResponseWireFormat(), writer, context);
           }
           
           writer.writeEndElement();
           // Strange bug. Without white space, headers end tag improperly read. 
           writer.writeCharacters( " " ); 
        }
        
        writeResourceAdapterProperties( jmsBinding, writer );
        
        writeConfiguredOperations( jmsBinding, writer, context );
        
        if ((jmsBinding.getRequestWireFormat() != null) &&
            !(jmsBinding.getRequestWireFormat() instanceof WireFormatJMSDefault)){
            writeWireFormat(jmsBinding.getRequestWireFormat(), writer, context);
        }
        
        if ((jmsBinding.getOperationSelector() != null) &&
            !(jmsBinding.getOperationSelector() instanceof OperationSelectorJMSDefault)){
            writeOperationSelector(jmsBinding.getOperationSelector(), writer, context);
        }
        
        writeEnd(writer);
    }

    /**
     * Writes headers element and its attributes.
     * <headers JMSType="string"?
     *          JMSCorrelationID="string"?
     *          JMSDeliveryMode="PERSISTENT or NON_PERSISTENT"?
     *          timeToLive="long"?      
     *          JMSPriority="0 .. 9"?>
     *     <property name="NMTOKEN" type="NMTOKEN"?>*    
     * </headers>?
     */
    private void writeHeaders( JMSBinding jmsBinding, XMLStreamWriter writer) throws XMLStreamException {

        writer.writeStartElement(Constants.SCA11_NS, JMSBindingConstants.HEADERS);

        String jmsType = jmsBinding.getJMSType();
        if (jmsType != null && jmsType.length() > 0) {
            writer.writeAttribute("type", jmsType);
        }

        Boolean jmsDeliveryMode = jmsBinding.isdeliveryModePersistent();
        if (jmsDeliveryMode != null) {
            if ( jmsDeliveryMode.booleanValue() )
               writer.writeAttribute("deliveryMode", "persistent");
            else
               writer.writeAttribute("deliveryMode", "nonpersistent");
        }

        Long jmsTimeToLive = jmsBinding.getJMSTimeToLive();
        if (jmsTimeToLive != null) {
            writer.writeAttribute("timeToLive", jmsTimeToLive.toString());
        }

        Integer jmsPriority = jmsBinding.getJMSPriority();
        if (jmsPriority != null) {
            writer.writeAttribute("priority", jmsPriority.toString());
        }

        Map<String, Object> properties = jmsBinding.getProperties();
        writeProperties( properties, writer );
        //writer.writeCharacters( "   " );
        
        writer.writeEndElement();
        // Strange bug. Without white space, headers end tag improperly read. 
        writer.writeCharacters( " " ); 
    }
    
    /**
     * Writes a complete set of properties to the given XML stream writer.
     * If the value is of type string, the property will be output:
     *    <property name="key">StringValue</property>
     * If the value is of type box (e.g.Integer, Long) or BindingProperty, the output will be    
     *    <property name="key" type="int">42</property>
     */
    @SuppressWarnings("unchecked")
    private void writeProperties(Map<String, Object> properties, XMLStreamWriter writer) throws XMLStreamException {
        if (( properties == null ) || ( properties.size() == 0 )) {
            return;
        }
        
        // For both the keys and values of a map
        for (Iterator it=properties.entrySet().iterator(); it.hasNext(); ) {
            Map.Entry entry = (Map.Entry)it.next();
            Object key = entry.getKey();
            Object value = entry.getValue();

            writer.writeStartElement(Constants.SCA11_NS, "property" );
            writer.writeAttribute("name", key.toString());

            if ( value instanceof String) {
                writer.writeCharacters( value.toString() );
            } else if ( value instanceof BindingProperty ) {
                BindingProperty property = (BindingProperty) value;
                String type = property.getType();
                if ( type != null ) {
                   writer.writeAttribute("type", type);
                }
                writer.writeCharacters( property.getValue().toString() );               
            } else if ( value instanceof Boolean ) {
                writer.writeAttribute("type", "boolean");
                writer.writeCharacters( value.toString() );
            } else if ( value instanceof Byte ) {
                writer.writeAttribute("type", "byte");
                writer.writeCharacters( value.toString() );
            } else if ( value instanceof Short ) {
                writer.writeAttribute("type", "short");
                writer.writeCharacters( value.toString() );
            } else if ( value instanceof Integer ) {
                writer.writeAttribute("type", "int");
                writer.writeCharacters( value.toString() );
            } else if ( value instanceof Long ) {
                writer.writeAttribute("type", "long");
                writer.writeCharacters( value.toString() );
            } else if ( value instanceof Float ) {
                writer.writeAttribute("type", "float");
                writer.writeCharacters( value.toString() );
            } else if ( value instanceof Double ) {
                writer.writeAttribute("type", "double");
                writer.writeCharacters( value.toString() );
            } else {
                writer.writeCharacters( value.toString() );                
            }
            writer.writeEndElement();
        }
    }

    /**
     * Writes operation properties if there are any.
     * 
     *     <operationProperties name="string" nativeOperation="string"?>
     *         <property name="NMTOKEN" type="NMTOKEN">*
     *         <headers JMSType="string"?
     *                  JMSCorrelationID="string"?
     *                  JMSDeliveryMode="string"?
     *                  timeToLive="int"?
     *                  JMSPriority="string"?>
     *             <property name="NMTOKEN" type="NMTOKEN">*
     *         </headers>?
     *     </operationProperties>*
     * </binding.jms>
     */
    private void writeOperationProperties( JMSBinding jmsBinding, XMLStreamWriter writer) throws XMLStreamException {
        if (jmsBinding.getOperationPropertiesBinding() != null) {
            return;   
        }
        Set<String> operationNames = jmsBinding.getOperationNames();
        if (operationNames == null || (operationNames.size() < 1)) {
            return;
        }

        for(Iterator<String> it=operationNames.iterator(); it.hasNext(); ) {
            String opName = it.next();
        
            writer.writeStartElement(Constants.SCA11_NS, "operationProperties");
            writer.writeAttribute("name", opName);

            String nativeOperation = jmsBinding.getNativeOperationName(opName);
            if (nativeOperation != null && nativeOperation.length() > 0) {
                if ( !nativeOperation.equals( opName )) {
                   writer.writeAttribute("nativeOperation", nativeOperation);
                }
            }

            Map<String, BindingProperty> operationPropertiesProperties =
                jmsBinding.getOperationPropertiesProperties(opName);
            writeBindingProperties( operationPropertiesProperties, writer );            

            String jmsType = jmsBinding.getOperationJMSType(opName);
            String jmsCorrelationId = jmsBinding.getOperationJMSCorrelationId(opName);
            Boolean jmsDeliveryMode = jmsBinding.getOperationJMSDeliveryMode(opName);
            Long jmsTimeToLive = jmsBinding.getOperationJMSTimeToLive(opName);
            Integer jmsPriority = jmsBinding.getOperationJMSPriority(opName);
            Map<String, Object> operationProperties = jmsBinding.getOperationProperties(opName);
            
            if (operationProperties != null){
                if ((jmsType != null && jmsType.length() > 0) || 
                    (jmsCorrelationId != null && jmsCorrelationId.length() > 0) || 
                    jmsDeliveryMode != null || jmsTimeToLive != null || 
                    jmsPriority != null) {
                    
                    writer.writeStartElement(Constants.SCA11_NS, JMSBindingConstants.HEADERS);              
                    
                    if (jmsType != null && jmsType.length() > 0) {
                        writer.writeAttribute("type", jmsType);
                    }
    
                    if (jmsDeliveryMode != null) {
                        if (jmsDeliveryMode.booleanValue())
                            writer.writeAttribute("deliveryMode", "persistent");
                        else
                            writer.writeAttribute("deliveryMode", "nonpersistent");
                    }
    
                    if (jmsTimeToLive != null) {
                        writer.writeAttribute("timeToLive", jmsTimeToLive.toString());
                    }
    
                    if (jmsPriority != null) {
                        writer.writeAttribute("priority", jmsPriority.toString());
                    }
                    
                    writeProperties( operationProperties, writer );
                    
                    writer.writeEndElement();
                    // Strange bug. Without white space, headers end tag improperly read. 
                    // writer.writeCharacters( " " ); 
                }
            }

            writer.writeEndElement();
            // Strange bug. Without white space, headers end tag improperly read.
            writer.writeCharacters(" ");
        }
    }
    
    /**
     * Writes a complete set of properties to the given XML stream writer.
     * If the value is of type string, the property will be output:
     *    <property name="key">StringValue</property>
     * If the value is of type box (e.g.Integer, Long) or BindingProperty, the output will be    
     *    <property name="key" type="int">42</property>
     */
    @SuppressWarnings("unchecked")
    private void writeBindingProperties(Map<String, BindingProperty> properties, XMLStreamWriter writer) throws XMLStreamException {
        if (( properties == null ) || ( properties.size() == 0 )) {
            return;
        }
        
        // For both the keys and values of a map
        for (Iterator it=properties.entrySet().iterator(); it.hasNext(); ) {
            Map.Entry entry = (Map.Entry)it.next();
            Object key = entry.getKey();
            Object value = entry.getValue();

            writer.writeStartElement(Constants.SCA11_NS, "property" );
            if (key != null){
                writer.writeAttribute("name", key.toString());
            }

            if ( value instanceof String) {
                writer.writeCharacters( value.toString() );
            } else if ( value instanceof BindingProperty ) {
                BindingProperty property = (BindingProperty) value;
                String type = property.getType();
                if ( type != null ) {
                   writer.writeAttribute("type", type);
                }
                writer.writeCharacters( property.getValue().toString() );
            } else {
                writer.writeCharacters( value.toString() );                
            }
            writer.writeEndElement();
        }
    }

    /**
     * Writes subscription headers if there are any.
     *     <complexType name="messageSelection"> 
     *         <attribute name="selector" type="string"/> 
     *     </complexType>
     *
     */
    private void writeSubscriptionHeaders( JMSBinding jmsBinding, XMLStreamWriter writer) throws XMLStreamException {
        String jmsSubscriptionHeaders = jmsBinding.getJMSSelector();
        if (jmsSubscriptionHeaders != null && jmsSubscriptionHeaders.length() > 0) {
            writer.writeStartElement(Constants.SCA11_NS, "messageSelection");
            writer.writeAttribute("selector", jmsSubscriptionHeaders);
            writer.writeEndElement();
            // Strange bug. Without white space, headers end tag improperly read. 
            // writer.writeCharacters( " " ); 
        }       
    }
    
    /**
     * Writes destination properties if there are any.
     *     <destination jndiName="xs:anyURI" type="string"? create="string"?>
     *         <property name="NMTOKEN" type="NMTOKEN">*
     *     </destination>?
     */
    private void writeDestinationProperties( JMSBinding jmsBinding, XMLStreamWriter writer) throws XMLStreamException {       
        String destinationName = jmsBinding.getDestinationName();
        if (destinationName == null || (destinationName.length() < 1)) {
            return;
        }
        if (destinationName == null) {
            return;
        }

        writer.writeStartElement(Constants.SCA11_NS, "destination");

        if ( destinationName != null && destinationName.length() > 0) {
            writer.writeAttribute("jndiName", destinationName);            
        }

        // Type not handled yet
        // String destinationType = jmsBinding.getDestinationType();
        // if ( destinationType != null && destinationType.length() > 0) {
        //     writer.writeAttribute("type", destinationType);            
        // }

        String destinationCreate = jmsBinding.getDestinationCreate();
        if ( destinationCreate != null && destinationCreate.length() > 0 &&
             !destinationCreate.equals(JMSBindingConstants.CREATE_IF_NOT_EXIST)) {
            writer.writeAttribute("create", destinationCreate);            
        }

        Map<String, BindingProperty> destinationProperties =
            jmsBinding.getDestinationProperties();
        writeBindingProperties( destinationProperties, writer );            

        writer.writeEndElement();
        // Strange bug. Without white space, headers end tag improperly read.
        writer.writeCharacters(" ");
    }
    
    /**
     * Writes connection factory properties if there are any.
     *     <connectionFactory jndiName="xs:anyURI" create="string"?>
     *         <property name="NMTOKEN" type="NMTOKEN">*
     *     </connectionFactory>?
     */
    private void writeConnectionFactoryProperties( JMSBinding jmsBinding, XMLStreamWriter writer) throws XMLStreamException {       
        String cfName = jmsBinding.getConnectionFactoryName();
        if (cfName == null || (cfName.length() < 1)) {
            return;
        }

        writer.writeStartElement(Constants.SCA11_NS, "connectionFactory");

        if ( cfName != null && cfName.length() > 0) {
            writer.writeAttribute("jndiName", cfName);            
        }

        String destinationCreate = jmsBinding.getConnectionFactoryCreate();
        if ( destinationCreate != null && destinationCreate.length() > 0 &&
             !destinationCreate.equals(JMSBindingConstants.CREATE_IF_NOT_EXIST)) {
            writer.writeAttribute("create", destinationCreate);            
        }

        Map<String, BindingProperty> cfProperties =
            jmsBinding.getConnectionFactoryProperties();
        writeBindingProperties( cfProperties, writer );            

        writer.writeEndElement();
        // Strange bug. Without white space, headers end tag improperly read.
        writer.writeCharacters(" ");
    }
    
    /**
     * Writes activation Spec properties if there are any.
     *     <activationSpec name="xs:anyURI" create="string"?>
     *         <property name="NMTOKEN" type="NMTOKEN">*
     *     </activationSpec>?
     * 
     */
    private void writeActivationSpecProperties( JMSBinding jmsBinding, XMLStreamWriter writer) throws XMLStreamException {       
        String asName = jmsBinding.getActivationSpecName();
        if (asName == null || (asName.length() < 1)) {
            return;
        }

        writer.writeStartElement(Constants.SCA11_NS, "activationSpec");

        if ( asName != null && asName.length() > 0) {
            writer.writeAttribute("name", asName);            
        }

        String destinationCreate = jmsBinding.getActivationSpecCreate();
        if ( destinationCreate != null && destinationCreate.length() > 0) {
            writer.writeAttribute("create", destinationCreate);            
        }

        Map<String, BindingProperty> cfProperties =
            jmsBinding.getActivationSpecProperties();
        writeBindingProperties( cfProperties, writer );            

        writer.writeEndElement();
        // Strange bug. Without white space, headers end tag improperly read.
        writer.writeCharacters(" ");
    }
    
    /**
     * Writes response destination properties if there are any.
     *     <destination jndiName="xs:anyURI" type="string"? create="string"?>
     *         <property name="NMTOKEN" type="NMTOKEN">*
     *     </destination>?
     */
    private void writeResponseDestinationProperties( JMSBinding jmsBinding, XMLStreamWriter writer) throws XMLStreamException {       
        String destinationName = jmsBinding.getResponseDestinationName();
        if (destinationName == null || (destinationName.length() < 1)) {
            return;
        }
        if (destinationName == null) {
            return;
        }

        writer.writeStartElement(Constants.SCA11_NS, "destination");

        if ( destinationName != null && destinationName.length() > 0) {
            writer.writeAttribute("jndiName", destinationName);            
        }

        // Type not handled yet
        // String destinationType = jmsBinding.getDestinationType();
        // if ( destinationType != null && destinationType.length() > 0) {
        //     writer.writeAttribute("type", destinationType);            
        // }

        String destinationCreate = jmsBinding.getResponseDestinationCreate();
        if ( destinationCreate != null && destinationCreate.length() > 0) {
            writer.writeAttribute("create", destinationCreate);            
        }

        Map<String, BindingProperty> destinationProperties =
            jmsBinding.getResponseDestinationProperties();
        writeBindingProperties( destinationProperties, writer );            

        writer.writeEndElement();
        // Strange bug. Without white space, headers end tag improperly read.
        writer.writeCharacters(" ");
    }
    
    /**
     * Writes response connection factory properties if there are any.
     *     <connectionFactory jndiName="xs:anyURI" create="string"?>
     *         <property name="NMTOKEN" type="NMTOKEN">*
     *     </connectionFactory>?
     * 
     */
    private void writeResponseConnectionFactoryProperties( JMSBinding jmsBinding, XMLStreamWriter writer) throws XMLStreamException {       
        String cfName = jmsBinding.getResponseConnectionFactoryName();
        if (cfName == null || (cfName.length() < 1)) {
            return;
        }

        writer.writeStartElement(Constants.SCA11_NS, "connectionFactory");

        if ( cfName != null && cfName.length() > 0) {
            writer.writeAttribute("jndiName", cfName);            
        }

        String destinationCreate = jmsBinding.getResponseConnectionFactoryCreate();
        if ( destinationCreate != null && destinationCreate.length() > 0) {
            writer.writeAttribute("create", destinationCreate);            
        }

        Map<String, BindingProperty> cfProperties =
            jmsBinding.getResponseConnectionFactoryProperties();
        writeBindingProperties( cfProperties, writer );            

        writer.writeEndElement();
        // Strange bug. Without white space, headers end tag improperly read.
        writer.writeCharacters(" ");
    }
    
    /**
     * Writes response activation Spec properties if there are any.
     *     <activationSpec name="xs:anyURI" create="string"?>
     *         <property name="NMTOKEN" type="NMTOKEN">*
     *     </activationSpec>?
     * 
     */
    private void writeResponseActivationSpecProperties( JMSBinding jmsBinding, XMLStreamWriter writer) throws XMLStreamException {       
        String asName = jmsBinding.getResponseActivationSpecName();
        if (asName == null || (asName.length() < 1)) {
            return;
        }

        writer.writeStartElement(Constants.SCA11_NS, "activationSpec");

        if ( asName != null && asName.length() > 0) {
            writer.writeAttribute("name", asName);            
        }

        String destinationCreate = jmsBinding.getResponseActivationSpecCreate();
        if ( destinationCreate != null && destinationCreate.length() > 0) {
            writer.writeAttribute("create", destinationCreate);            
        }

        Map<String, BindingProperty> cfProperties =
            jmsBinding.getResponseActivationSpecProperties();
        writeBindingProperties( cfProperties, writer );            

        writer.writeEndElement();
        // Strange bug. Without white space, headers end tag improperly read.
        writer.writeCharacters(" ");
    }  

    /**
     * Writes resource adapter properties if there are any.
     *    <resourceAdapter name="NMTOKEN">?
     *         <property name="NMTOKEN" type="NMTOKEN">*
     *    </resourceAdapter>? 
     */
    private void writeResourceAdapterProperties( JMSBinding jmsBinding, XMLStreamWriter writer) throws XMLStreamException {       
        String asName = jmsBinding.getResourceAdapterName();
        if (asName == null || (asName.length() < 1)) {
            return;
        }

        writer.writeStartElement(Constants.SCA11_NS, "resourceAdapter");

        if ( asName != null && asName.length() > 0) {
            writer.writeAttribute("name", asName);            
        }

        Map<String, BindingProperty> cfProperties =
            jmsBinding.getResourceAdapterProperties();
        writeBindingProperties( cfProperties, writer );            

        writer.writeEndElement();
        // Strange bug. Without white space, headers end tag improperly read.
        writer.writeCharacters(" ");
    }
    
    /**
     * Writes configured operations if there are any.
     *  <binding.jms uri=\"jms:testQueue\" >"
     *      <operationProperties name=\"op1\">"
     *      </operationProperties >" 
     *       <operation name=\"op1\" requires=\"IntentOne IntentTwo\"/>"
     *   </binding.jms>"
     */
    private void writeConfiguredOperations( JMSBinding jmsBinding, XMLStreamWriter writer, ProcessorContext context) throws XMLStreamException, ContributionWriteException {       
        List<ConfiguredOperation> configOps = jmsBinding.getConfiguredOperations();
        if (configOps == null || (configOps.size() < 1)) {
            return;
        }

        for( Iterator<ConfiguredOperation> it = configOps.iterator(); it.hasNext();) {
           configuredOperationProcessor.write(it.next(), writer, context);
        }

        // Strange bug. Without white space, headers end tag improperly read.
        writer.writeCharacters(" ");
    }
    
    /**
     * Wire out a request or response wire format element. Uses extension processors
     * to do this as wire format is an extension point
     * 
     * @param wireFormat
     * @param writer
     */
    private void writeWireFormat(WireFormat wireFormat, XMLStreamWriter writer, ProcessorContext context ) throws XMLStreamException, ContributionWriteException {
        extensionProcessor.write(wireFormat, writer, context);
    }
    
    /**
     * Wire out an operation selector element. Uses extension processors
     * to do this as operation selector is an extension point
     * 
     * @param operationSeletor
     * @param writer
     */
    private void writeOperationSelector(OperationSelector operationSeletor, XMLStreamWriter writer, ProcessorContext context ) throws XMLStreamException, ContributionWriteException{
        extensionProcessor.write(operationSeletor, writer, context);        
    }
    
}
