/*
 * 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.core.runtime.impl;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;

import javax.xml.namespace.QName;

import org.apache.tuscany.sca.assembly.AssemblyFactory;
import org.apache.tuscany.sca.assembly.Base;
import org.apache.tuscany.sca.assembly.Binding;
import org.apache.tuscany.sca.assembly.Callback;
import org.apache.tuscany.sca.assembly.ComponentReference;
import org.apache.tuscany.sca.assembly.ComponentService;
import org.apache.tuscany.sca.assembly.Endpoint;
import org.apache.tuscany.sca.assembly.EndpointReference;
import org.apache.tuscany.sca.assembly.Multiplicity;
import org.apache.tuscany.sca.assembly.SCABinding;
import org.apache.tuscany.sca.assembly.builder.BindingBuilder;
import org.apache.tuscany.sca.assembly.builder.BuilderContext;
import org.apache.tuscany.sca.assembly.builder.BuilderExtensionPoint;
import org.apache.tuscany.sca.assembly.builder.CompositeBuilder;
import org.apache.tuscany.sca.assembly.builder.PolicyBuilder;
import org.apache.tuscany.sca.core.ExtensionPointRegistry;
import org.apache.tuscany.sca.core.FactoryExtensionPoint;
import org.apache.tuscany.sca.core.UtilityExtensionPoint;
import org.apache.tuscany.sca.core.assembly.impl.RuntimeEndpointImpl;
import org.apache.tuscany.sca.core.assembly.impl.RuntimeEndpointReferenceImpl;
import org.apache.tuscany.sca.definitions.Definitions;
import org.apache.tuscany.sca.interfacedef.InterfaceContract;
import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
import org.apache.tuscany.sca.interfacedef.impl.TuscanyInterfaceContractImpl;
import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract;
import org.apache.tuscany.sca.interfacedef.util.Audit;
import org.apache.tuscany.sca.monitor.Monitor;
import org.apache.tuscany.sca.monitor.MonitorFactory;
import org.apache.tuscany.sca.policy.BindingType;
import org.apache.tuscany.sca.policy.ExtensionType;
import org.apache.tuscany.sca.policy.Intent;
import org.apache.tuscany.sca.policy.IntentMap;
import org.apache.tuscany.sca.policy.PolicySet;
import org.apache.tuscany.sca.policy.Qualifier;
import org.apache.tuscany.sca.provider.EndpointReferenceAsyncProvider;
import org.apache.tuscany.sca.provider.ReferenceBindingProvider;
import org.apache.tuscany.sca.runtime.CompositeActivator;
import org.apache.tuscany.sca.runtime.DomainRegistry;
import org.apache.tuscany.sca.runtime.EndpointReferenceBinder;
import org.apache.tuscany.sca.runtime.RuntimeEndpoint;
import org.apache.tuscany.sca.runtime.RuntimeEndpointReference;
import org.apache.tuscany.sca.runtime.UnknownEndpointHandler;
import org.oasisopen.sca.ServiceRuntimeException;

/**
 * A builder that takes endpoint references and resolves them. It either finds local
 * service endpoints if they are available or asks the domain. The main function here
 * is to perform binding and policy matching.
 * 
 * This is a separate from the builders so that the mechanism for reference/service matching 
 * can be used at runtime as well as build time and can also be replaced independently
 *
 * @version $Rev$ $Date$
 */
public class EndpointReferenceBinderImpl implements EndpointReferenceBinder {
    private static final Logger logger = Logger.getLogger(EndpointReferenceBinderImpl.class.getName());

    protected ExtensionPointRegistry extensionPoints;
    protected AssemblyFactory assemblyFactory;
    protected InterfaceContractMapper interfaceContractMapper;
    protected BuilderExtensionPoint builders;
    protected CompositeActivator compositeActivator;
    protected Monitor monitor;
    protected UnknownEndpointHandler unknownEndpointHandler;
    protected CompositeBuilder policyAppliesToBuilder;


    public EndpointReferenceBinderImpl(ExtensionPointRegistry extensionPoints) {
        this.extensionPoints = extensionPoints;

        FactoryExtensionPoint factories = extensionPoints.getExtensionPoint(FactoryExtensionPoint.class);
        this.assemblyFactory = factories.getFactory(AssemblyFactory.class);

        UtilityExtensionPoint utils = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class);
        this.interfaceContractMapper = utils.getUtility(InterfaceContractMapper.class);
        
        MonitorFactory monitorFactory = utils.getUtility(MonitorFactory.class);
        monitor = monitorFactory.createMonitor();

        this.unknownEndpointHandler = utils.getUtility(UnknownEndpointHandler.class);
        
        this.builders = extensionPoints.getExtensionPoint(BuilderExtensionPoint.class);
        
        this.compositeActivator = extensionPoints.getExtensionPoint(CompositeActivator.class);
    }
    
    /**
     * Bind a single endpoint reference at build time. Here we only expect the
     * registry to have a record of local endpoints
     *
     * @param domainRegistry
     * @param endpointReference
     */
    public void bindBuildTime(DomainRegistry domainRegistry, 
                              EndpointReference endpointReference, 
                              BuilderContext builderContext) {
       bind(domainRegistry, endpointReference, builderContext, false);
    }
    
    /**
     * Bind a single endpoint reference at run time. Here we expect the
     * registry to be populated with endpoints from across the domain
     *
     * @param domainRegistry
     * @param endpointReference
     */
    public void bindRunTime(DomainRegistry domainRegistry,
                            EndpointReference endpointReference) {
        bind(domainRegistry, endpointReference, null, true);
    }
    
    /**
     * Bind a reference to a service endpoint
     * 
     * @param domainRegistry
     * @param endpointReference
     * @param runtime set true if called from the runtime 
     */
    public void bind(DomainRegistry domainRegistry,  
                     EndpointReference endpointReference,
                     BuilderContext builderContext,
                     boolean runtime){
        
        logger.fine("Binding " + endpointReference.toString());
        
        Audit matchAudit = new Audit();
             
        // This logic does post build autowire matching but isn't actually used at the moment
        // as problems with dependencies mean we still do this during build
        if (endpointReference.getStatus() == EndpointReference.Status.AUTOWIRE_PLACEHOLDER){ 
           
            // do autowire matching
            // will only be called at build time at the moment
            Multiplicity multiplicity = endpointReference.getReference().getMultiplicity();
            for (Endpoint endpoint : domainRegistry.getEndpoints()){
//              if (endpoint is in the same composite as endpoint reference){
                    if ((multiplicity == Multiplicity.ZERO_ONE || 
                         multiplicity == Multiplicity.ONE_ONE) && 
                        (endpointReference.getReference().getEndpointReferences().size() > 1)) {
                        break;
                    }

                    // Prevent autowire connecting to self
                    if (endpointReference.getComponent() == 
                        endpoint.getComponent()) {
                        continue;
                    }
                    
                    if (haveMatchingPolicy(endpointReference, endpoint, matchAudit, builderContext) &&
                        haveMatchingInterfaceContracts(endpointReference, endpoint, matchAudit)){
                        // matching service so find if this reference already has 
                        // an endpoint reference for this endpoint
                        Endpoint autowireEndpoint = null;
                        
                        for (EndpointReference epr : endpointReference.getReference().getEndpointReferences()){
                            if (epr.getTargetEndpoint() == endpoint){
                                autowireEndpoint = endpoint;
                                break;
                            }
                        }
                        
                        if (autowireEndpoint == null){
                            // create new EPR for autowire
                            EndpointReference autowireEndpointRefrence = null;
                            try {
                                autowireEndpointRefrence = (EndpointReference)endpointReference.clone();
                            } catch (Exception ex){
                                // won't happen as clone is supported
                            }
                            
                            autowireEndpointRefrence.setTargetEndpoint(endpoint);
                            autowireEndpointRefrence.setBinding(endpoint.getBinding());
                            autowireEndpointRefrence.setStatus(EndpointReference.Status.WIRED_TARGET_FOUND_AND_MATCHED);
                            endpointReference.getReference().getEndpointReferences().add(autowireEndpointRefrence);  
                        }
                    }
//              }
            }
            
            if (multiplicity == Multiplicity.ONE_N || multiplicity == Multiplicity.ONE_ONE) {
                if (endpointReference.getReference().getEndpointReferences().size() == 1) {
                    Monitor.error(monitor,
                                  this,
                                  "endpoint-validation-messages",
                                  "NoComponentReferenceTarget",
                                  endpointReference.getReference().getName());
                    //throw new ServiceRuntimeException("Unable to bind " +
                    //                                  monitor.getLastProblem().toString());
                }
            }
            
            setSingleAutoWireTarget(endpointReference.getReference());
            
        } else if ( endpointReference.getStatus() == EndpointReference.Status.WIRED_TARGET_FOUND_AND_MATCHED||
                    endpointReference.getStatus() == EndpointReference.Status.RESOLVED_BINDING ) {
            // The endpoint reference is already resolved to either
            // a service endpoint local to this composite or it has
            // a remote binding. Just make sure the binding is built
            build(endpointReference);
            
            // still need to check that the callback endpoint is set correctly
            if (hasCallback(endpointReference) && 
                (endpointReference.getCallbackEndpoint() == null 
                    || endpointReference.getCallbackEndpoint().isUnresolved())) {
                selectCallbackEndpoint(endpointReference,
                                       endpointReference.getReference().getCallbackService(),
                                       matchAudit, 
                                       builderContext, 
                                       runtime);
            } 
        } else if (endpointReference.getStatus() == EndpointReference.Status.WIRED_TARGET_FOUND_READY_FOR_MATCHING ){
            // The endpoint reference is already resolved to either
            // a service endpoint but no binding was specified in the 
            // target URL and/or the policies have yet to be matched.
            // Used when $self references are resolved
            
            selectForwardEndpoint(endpointReference,
                                  endpointReference.getTargetEndpoint().getService().getEndpoints(),
                                  matchAudit,
                                  builderContext,
                                  runtime);

            if (hasCallback(endpointReference)){
                selectCallbackEndpoint(endpointReference,
                                       endpointReference.getReference().getCallbackService(),
                                       matchAudit,
                                       builderContext, 
                                       runtime);
            }             
        } else if (endpointReference.getStatus() == EndpointReference.Status.WIRED_TARGET_IN_BINDING_URI ||
                   endpointReference.getStatus() == EndpointReference.Status.WIRED_TARGET_NOT_FOUND ||
                   endpointReference.getStatus() == EndpointReference.Status.NOT_CONFIGURED){
            // The reference is not yet matched to a service
          
            // find the service in the endpoint registry
            List<Endpoint> endpoints = domainRegistry.findEndpoint(endpointReference);
            
            if (endpoints.size() > 0){
                selectForwardEndpoint(endpointReference,
                        endpoints,
                        matchAudit,
                        builderContext, 
                        runtime);

                // If the reference was matched try to match the callback
                if (endpointReference.getStatus().equals(EndpointReference.Status.WIRED_TARGET_FOUND_AND_MATCHED) &&
                    hasCallback(endpointReference)){
                    selectCallbackEndpoint(endpointReference,
                                           endpointReference.getReference().getCallbackService(),
                                           matchAudit,
                                           builderContext, 
                                           runtime);
                } 
            } else if (runtime) {
                // tweak to test if this could be a resolved binding. This is the back end of the test
                // in the builder that pulls the URI out of the binding if there are no targets
                // on the reference. have to wait until here to see if the binding uri matches any
                // available services. If not we assume here that it's a resolved binding
                if (endpointReference.getStatus() == EndpointReference.Status.WIRED_TARGET_IN_BINDING_URI){
                    endpointReference.getTargetEndpoint().setBinding(endpointReference.getBinding());
                    endpointReference.setStatus(EndpointReference.Status.RESOLVED_BINDING);
                } else {
                    processUnknownEndpoint(endpointReference, matchAudit);
                    
                    if (!endpointReference.getStatus().equals(EndpointReference.Status.WIRED_TARGET_FOUND_AND_MATCHED)){
                        Monitor.error(monitor, 
                                      this, 
                                      "endpoint-validation-messages", 
                                      "NoEndpointsFound", 
                                      endpointReference.toString()); 
                        throw new ServiceRuntimeException(monitor.getMessageString(EndpointReferenceBinderImpl.class.getName(),
                                                                                   "endpoint-validation-messages", 
                                                                                   "UnableToBind") + 
                                                          " " +
                                                          monitor.getLastProblem().toString());
                    }
                }
            } else {
                // it's build time so just give the UnknownEndpoint code a chance
                // without regard for the result
                processUnknownEndpoint(endpointReference, matchAudit);
            }
        } 
        
        logger.fine(matchAudit.toString());

        if (endpointReference.getStatus() != EndpointReference.Status.WIRED_TARGET_FOUND_AND_MATCHED &&
            endpointReference.getStatus() != EndpointReference.Status.RESOLVED_BINDING){
            
            if (runtime){
                Monitor.error(monitor, 
                              this, 
                              "endpoint-validation-messages", 
                              "EndpointReferenceCantBeMatched", 
                              endpointReference.toString(),
                              matchAudit);
                throw new ServiceRuntimeException(monitor.getMessageString(EndpointReferenceBinderImpl.class.getName(),
                                                                           "endpoint-validation-messages", 
                                                                           "UnableToBind") + 
                                                  " " +
                                                  monitor.getLastProblem().toString());
            } else {
                Monitor.warning(monitor, 
                                this, 
                                "endpoint-validation-messages", 
                                "ComponentReferenceTargetNotFound", 
                                endpointReference.toString());
                return;
            }
               

        }
        
        // [rfeng] Setup the target endpoint if the reference uses an explicit binding
        if (endpointReference.getTargetEndpoint().getBinding() == null) {
            endpointReference.getTargetEndpoint().setBinding(endpointReference.getBinding());
        }
        
        // Now the endpoint reference is resolved check that the binding interfaces contract
        // and the reference contract are compatible
        try {
            ((RuntimeEndpointReference)endpointReference).validateReferenceInterfaceCompatibility();
        } catch (ServiceRuntimeException ex) {
            // don't re-throw this exception at build time just record the
            // error. If it's thrown here is messes up the order in which
            // build time errors are reported and that in turn messes
            // up the output of the compliance tests. 
            if (runtime){
                throw ex;
            } else {
                Monitor.error(monitor, 
                        this, 
                        "endpoint-validation-messages", 
                        "EndpointReferenceCantBeMatched", 
                        endpointReference.toString(),
                        ex.getMessage());
            }
        }
        
        // TUSCANY-3783
        // if the reference is an async reference and the binding doesn't support
        // async natively fluff up the response service/endpoint
        ReferenceBindingProvider referenceBindingProvider = ((RuntimeEndpointReference)endpointReference).getBindingProvider();
        if ( referenceBindingProvider instanceof EndpointReferenceAsyncProvider &&
             !((EndpointReferenceAsyncProvider)referenceBindingProvider).supportsNativeAsync() &&
             endpointReference.isAsyncInvocation() && 
             endpointReference.getCallbackEndpoint() == null) {
            ((RuntimeEndpointReference)endpointReference).createAsyncCallbackEndpoint();
        }
    
        // System.out.println("MATCH AUDIT:" + matchAudit.toString());
    }       
        
    private void processUnknownEndpoint(EndpointReference endpointReference, Audit matchAudit){
        Binding b = null;
        if (unknownEndpointHandler != null) {
            b = unknownEndpointHandler.handleUnknownEndpoint(endpointReference);
        }
        if (b != null) {
            Endpoint matchedEndpoint = new RuntimeEndpointImpl(extensionPoints);
            matchedEndpoint.setBinding(b);
            matchedEndpoint.setRemote(true);
            endpointReference.setTargetEndpoint(matchedEndpoint);
            endpointReference.setBinding(b);
            endpointReference.setUnresolved(false);
            endpointReference.setStatus(EndpointReference.Status.WIRED_TARGET_FOUND_AND_MATCHED);
            matchAudit.append("Match because the UnknownEndpointHandler provided a binding: " + b.getType() + " uri: " + b.getURI());
            matchAudit.appendSeperator();
        }
    }
   
    /**
     * Returns true if the reference has a callback
     */
    private boolean hasCallback(EndpointReference endpointReference){
        if (endpointReference.getReference().getInterfaceContract() == null ||
            endpointReference.getReference().getInterfaceContract().getCallbackInterface() == null ||
            endpointReference.getReference().getName().startsWith("$self$.")){
            return false;
        } else {
            return true;
        }
    }

    /**
     * Selects a forward endpoint from a list of possible candidates
     * 
     * @param endpointReference
     * @param endpoints
     */
    private void selectForwardEndpoint(EndpointReference endpointReference, List<Endpoint> endpoints, Audit matchAudit, BuilderContext builderContext, boolean runtime) {    
             
        Endpoint matchedEndpoint = null;
        
        if (endpointReference.getReference().getName().startsWith("$self$.")){
            // just select the first one and don't do any policy matching
            if (endpointReference.getTargetEndpoint() != null && !endpointReference.getTargetEndpoint().isUnresolved()) {
                matchedEndpoint = endpointReference.getTargetEndpoint();
            } else {
                matchedEndpoint = endpoints.get(0);
            }
        } else {
            // find the endpoints that match this endpoint reference
            List<Endpoint> matchedEndpoints = new ArrayList<Endpoint>();
            
            for (Endpoint endpoint : endpoints){
                if (haveMatchingPolicy(endpointReference, endpoint, matchAudit, builderContext) &&
                    haveMatchingInterfaceContracts(endpointReference, endpoint, matchAudit)){
                    matchedEndpoints.add(endpoint);
                }
            }
            
            // TUSCANY-4005 - raise an error if a reference target that only specifies the
            //                component name matches more than one component service
            if (endpointReference.getTargetEndpoint().getService() == null &&
                endpointReference.getTargetEndpoint().getBinding() == null &&
                matchedEndpoints.size() > 1   ) {
                
                String serviceName = null;
                for (Endpoint endpoint : matchedEndpoints){
                    // ignore service names called "default" as these indicate dynamic services
                    // created for the likes of implementation.python
                    if (serviceName == null &&
                        !endpoint.getService().getName().equals("default")){
                        serviceName = endpoint.getService().getName();
                    }
                    
                    if (serviceName != null &&
                        !endpoint.getService().getName().equals("default") &&
                        !endpoint.getService().getName().equals(serviceName)){
                        if (runtime){
                            Monitor.error(monitor, 
                                          this, 
                                          "endpoint-validation-messages", 
                                          "TooManyTargetServices", 
                                          endpointReference.toString(),
                                          endpointReference.getTargetEndpoint().toString(),
                                          matchAudit);
                            throw new ServiceRuntimeException("Unable to bind " + 
                                                              monitor.getLastProblem().toString());
                        } else {
                            Monitor.warning(monitor, 
                                            this, 
                                            "endpoint-validation-messages", 
                                            "TooManyTargetServices", 
                                            endpointReference.toString(),
                                            endpointReference.getTargetEndpoint().toString());
                            return;
                        }
                    }
                }
            }
            
            // TUSCANY-3941 check for the case where the user has provided a 
            //              binding.sca at the reference and make sure we pick
            //              a binding.sca at the service regardless of how many
            //              other bindings are provided
            if (endpointReference.getBinding() != null &&
                endpointReference.getBinding() instanceof SCABinding ){
                for (Endpoint endpoint : matchedEndpoints){
                    if (endpoint.getBinding() instanceof SCABinding){
                        matchedEndpoint = endpoint;
                        break;
                    }
                }
            } 

            if (matchedEndpoint == null) {
                // just take the first matched endpoint from the list
                if (matchedEndpoints.size() > 0){
                    matchedEndpoint = matchedEndpoints.get(0);
                }
            }
        }
        
        if (matchedEndpoint == null){
            return;
        } else {
            endpointReference.setTargetEndpoint(matchedEndpoint);
            Binding binding = matchedEndpoint.getBinding();
            try {
                endpointReference.setBinding((Binding)binding.clone());
            } catch (CloneNotSupportedException e) {
                // shouldn't happen
                throw new RuntimeException(e);
            }
            // TUSCANY-3873 - add policy from the service
            //                we don't care about intents at this stage
            endpointReference.getPolicySets().addAll(matchedEndpoint.getPolicySets());
            
            // TODO - we need to re-run the appliesTo processing here but there is some question about what 
            //        appliesTo means. It's also difficult to get to the PolicyAppliesToBuilder from here and
            //        need a new EntensionInterface to support access. So for now I'm just cheating and looking to 
            //        see if the XPath expression contains the binding type as a string while we discuss appliesTo
            List<PolicySet> psToRemove = new ArrayList<PolicySet>();
            
            for (PolicySet ps : endpointReference.getPolicySets() ) {
                if (!ps.getAppliesTo().contains(endpointReference.getBinding().getType().getLocalPart())){
                    psToRemove.add(ps);
                }
            }
            
            endpointReference.getPolicySets().removeAll(psToRemove);
            
            build(endpointReference);
            endpointReference.setStatus(EndpointReference.Status.WIRED_TARGET_FOUND_AND_MATCHED);
            endpointReference.setUnresolved(false);
        }
        
    }

    private void build(EndpointReference endpointReference) {
        BindingBuilder builder = builders.getBindingBuilder(endpointReference.getBinding().getType());
        if (builder != null) {
            builder.build(endpointReference.getComponent(),
                          endpointReference.getReference(),
                          endpointReference.getBinding(),
                          new BuilderContext(extensionPoints),
                          false);
        }
    }

    /**
     * This code is very similar to the code in EnpointReferenceBuilder.fixUpCallbackLinks()
     * but here we are selecting endpoint/endpoint references at runtime. 
     * 
     * To recap the general model is as follows:
     * 
     *  Forward EPR  -----------> Forward EP (target EP)
     *     |                          |
     *     \/                         \/
     *  Callback EP <------------ Callback EPR 
     * 
     * The question then becomes how to construct this model given that
     * target resolution can happen at runtime and EPR and EP can be 
     * distributed across the domain. 
     * 
     * The forward link is resolved by searching in the registry for an EP 
     * that matches the EPR. 
     * 
     * At build time we've made the assumption that, if the user configures
     * a callback binding at all, they will choose the same binding as the
     * forward call (TODO - this may be a bold assumption). So here we just
     * assume that the callback endpoint that is set on the reference
     * at build time matches. This may not be true if the callback bindings
     * are configured differently on the reference and service. 
     * 
     * @param endpointReference
     * @param endpoints
     */
    private void selectCallbackEndpoint(EndpointReference endpointReference, ComponentService callbackService, Audit matchAudit, BuilderContext builderContext, boolean runtime) {
        
        // A simplifying assumption here is that the user will only specify a callback binding
        // of the same type as the forward binding in order to specify further configuration
        // We can then assume that if there is no callback endpoint that matches already then we have 
        // picked up binding config from the service and we can create a callback endpoint to match
        
        // So having said this we look in three places for the callback binding. 
        // 1/ in callback endpoints at the reference
        //      - will find it here if the user has manually configured a callback binding at the reference
        // 2/ in the service callback structure 
        //      - will find it here if the user has manually configured a callback binding at the service
        // 3/ in the service callback reference structure
        //      - will find it here if the system has constructed the callback binding based on the forward binding
        //
        // 2 and 3 are conflated in the distributed case as be write any derived callback bindings out into the
        // callback structure as the endpoint is serialized across the domain
        
        RuntimeEndpoint callbackEndpoint = null;
        
        // 1/ look in callback endpoints at the reference
        //      - exploiting the assumption that the user will specific callback bindings of 
        //        the same type as the forward binding
        match1:
        for(Endpoint loopCallbackEndpoint : callbackService.getEndpoints()){
            if(loopCallbackEndpoint.getBinding().getType().equals(endpointReference.getBinding().getType())){
                callbackEndpoint = (RuntimeEndpoint)loopCallbackEndpoint;
                break match1;
            }
        }   
        
        // if no callback endpoint was found then create a new callback endpoint
        if (callbackEndpoint == null ){
            callbackEndpoint = (RuntimeEndpoint)assemblyFactory.createEndpoint();
            callbackEndpoint.setComponent(endpointReference.getComponent());
            callbackEndpoint.setService(callbackService);
            
            Binding forwardBinding = endpointReference.getBinding();
            Binding callbackBinding = null;
            
            // 2/  look in the service callback structure 
            Callback serviceCallback = endpointReference.getTargetEndpoint().getService().getCallback();
            
            if (serviceCallback != null){
                for(Binding loopCallbackBinding : serviceCallback.getBindings()){
                    if(loopCallbackBinding.getType().equals(endpointReference.getBinding().getType())){
                        callbackBinding = loopCallbackBinding;
                        break;
                    }
                }
            }

            // 3/ look in the service endpoint callback reference structure
            ComponentReference callbackReference = endpointReference.getTargetEndpoint().getService().getCallbackReference();
            
            if (callbackReference != null){
                for (EndpointReference loopEndpointReference : callbackReference.getEndpointReferences()){
                    if (loopEndpointReference.getBinding().getType().equals(endpointReference.getBinding().getType())){
                        callbackBinding = loopEndpointReference.getBinding();
                        break;
                    }
                }
            }
            
            // if all else fails clone the forward binding
            // TODO - do we ever get here?
            if (callbackBinding == null){
                try {
                    callbackBinding = (Binding)forwardBinding.clone();
                } catch (CloneNotSupportedException ex){
                }  
            }

            // get the callback binding URI by looking at the SCA binding 
            // that will have been added at build time
            callbackBinding.setURI(null);
            for (Endpoint endpoint : callbackService.getEndpoints()){
                if (endpoint.getBinding().getType().equals(SCABinding.TYPE)){
                    callbackBinding.setURI(endpoint.getBinding().getURI());
                }
            }
            
            callbackEndpoint.setBinding(callbackBinding);
            callbackService.getBindings().add(callbackBinding);
            
            callbackEndpoint.setUnresolved(false);
            callbackService.getEndpoints().add(callbackEndpoint);
            
            // build it
            build(callbackEndpoint);
            
            // Only activate the callback endpoint if the bind is being done at runtime
            // and hence everything else is running. If it's build time then the
            // endpoint will be activated at the same time as all the other endpoints
            if (runtime) {
                // activate it
                compositeActivator.activate(((RuntimeEndpointReferenceImpl)endpointReference).getCompositeContext(), 
                                            callbackEndpoint);
                
                // start it
                compositeActivator.start(((RuntimeEndpointReferenceImpl)endpointReference).getCompositeContext(), 
                                         callbackEndpoint);  
            }
        } 
        
        // finally set the callback endpoint into the forward reference
        endpointReference.setCallbackEndpoint(callbackEndpoint);       
    }
    
    private void build(Endpoint endpoint) {
        
        BindingBuilder builder = builders.getBindingBuilder(endpoint.getBinding().getType());
        if (builder != null) {
            builder.build(endpoint.getComponent(),
                          endpoint.getService(),
                          endpoint.getBinding(),
                          new BuilderContext(extensionPoints), 
                          true);
        }
    }    

    /**
     * Determine if endpoint reference and endpoint policies match. We know by this stage
     * that 
     *   - a given policy set will only contain expressions from a single language
     *   - a given endpoint or endpoint reference's policy sets will only contain
     *     expressions from a single language
     *     
     * Matching algorithm (read from the top down):
     *   - FAIL if there are intents that are mutually exclusive between reference and service
     *   - PASS if there are no intents or policies present at reference and service
     *   - FAIL if there are unresolved intents (intents with no policy set) at the reference (service should have been checked previously)
     *          the wrinkle here is that we need to adopt policy from the service if the reference doesn't define a binding
     *   - PASS if there are no policies at reference and service (now we know all intents are resolved)
     *   - FAIL if there are some policies on one side but not on the other
     *   - PASS if the QName of the policy sets on each side match
     *   - FAIL if the policy languages on both sides are different
     *   - Perform policy specific match
     *   
     */
    private boolean haveMatchingPolicy(EndpointReference endpointReference, Endpoint endpoint, Audit matchAudit, BuilderContext builderContext){
        matchAudit.append("Match policy of " + endpointReference.toString() + " to " + endpoint.toString() + " ");
        
        if (!endpoint.getSpecVersion().equals(Base.SCA11_NS)){
            // the thing we need to check here is asyncInvocation as only OASIS supports that
            if (endpointReference.isAsyncInvocation()){
                // this definitely won't mactch anything but OASIS so fail
                matchAudit.append("No match because the endpoint reference is configured for asyncInvocation " +
                                  "and the target endpoint is not an OASIS endpoint, specVersion = " + 
                                  endpoint.getSpecVersion());
                matchAudit.appendSeperator();
                return false;
            } else {
                // Assume it matches as we don't know how to do policy 
                // matching with anything but OASIS endpoints
                matchAudit.append("Match because the target endpoint is not an OASIS endpoint, specVersion = " + 
                                  endpoint.getSpecVersion());
                matchAudit.appendSeperator();
                return true;
            }
        }
            
        List<PolicySet> referencePolicySets = new ArrayList<PolicySet>();
        Binding binding = null;
        
        if (endpointReference.getBinding() == null){
            binding = endpoint.getBinding();
        } else {
            binding = endpointReference.getBinding();
        }
        
        // if there are any intents that are mutually exclusive between 
        // service and reference then they don't match
        for (Intent eprIntent : endpointReference.getRequiredIntents()){
            for (Intent epIntent : endpoint.getRequiredIntents()){ 
                if (eprIntent.getExcludedIntents().contains(epIntent) ||
                    epIntent.getExcludedIntents().contains(eprIntent) ||
                    checkQualifiedMutualExclusion(eprIntent.getExcludedIntents(), epIntent) ||
                    checkQualifiedMutualExclusion(epIntent.getExcludedIntents(), eprIntent)){
                    matchAudit.append("No match because the following intents are mutually exclusive " + 
                                      eprIntent.toString() +
                                      " " +
                                      epIntent.toString() +
                                      " ");
                    matchAudit.appendSeperator();
                    return false;
                }
            }
        }
        
        // Find the set of policy sets from this reference. This includes 
        // the policy sets that are specific to the service binding and 
        // any policy sets that are not binding specific    
        for (PolicySet policySet : endpointReference.getPolicySets()){
            PolicyBuilder policyBuilder = null;
            
            if (policySet.getPolicies().size() > 0){
                QName policyType = policySet.getPolicies().get(0).getName();
                policyBuilder = builders.getPolicyBuilder(policyType);
            }
            
            if ((policyBuilder == null) ||
                (policyBuilder != null && policyBuilder.getSupportedBindings() == null) ||
                (policyBuilder != null && policyBuilder.getSupportedBindings().contains(binding.getType()))){
                referencePolicySets.add(policySet);
            }
        }
        
        // if there are no policy sets on the reference take the policy sets from the
        // service binding we are matching against
        if (referencePolicySets.isEmpty()) {
            for (PolicySet policySet : endpoint.getPolicySets()){
                PolicyBuilder policyBuilder = null;
                
                if (policySet.getPolicies().size() > 0){
                    QName policyType = policySet.getPolicies().get(0).getName();
                    policyBuilder = builders.getPolicyBuilder(policyType);
                }
                
                if ((policyBuilder == null) ||
                    (policyBuilder != null && policyBuilder.getSupportedBindings() == null) ||
                    (policyBuilder != null && policyBuilder.getSupportedBindings().contains(binding.getType()))){
                    referencePolicySets.add(policySet);
                }
            }   
        }
        
        // the "appliesTo" algorithm to remove any policy sets that 
        // don't apply to the service binding will already have been 
        // run during the build phase
        
        // Determine if there are any reference policies
        boolean noEndpointReferencePolicies = true;
        
        for (PolicySet policySet : referencePolicySets){
            if (policySet.getPolicies().size() > 0){
                noEndpointReferencePolicies = false;
                break;
            }
        }
        
        // Determine of there are any service policies
        boolean noEndpointPolicies = true;
        
        for (PolicySet policySet : endpoint.getPolicySets()){
            if (policySet.getPolicies().size() > 0){
                noEndpointPolicies = false;
                break;
            }
        }        
        
        // if no policy sets or intents are present then they match
        if ((endpointReference.getRequiredIntents().size() == 0) &&
            (endpoint.getRequiredIntents().size() == 0) &&
            (noEndpointReferencePolicies) &&
            (noEndpointPolicies)) {
            matchAudit.append("Match because there are no intents or policies ");
            matchAudit.appendSeperator();
            return true;
        }        
        
        // check that the intents on the reference side are resolved 
        // can't do this until this point as the service binding
        // may come into play. Intents may be satisfied by the default
        // or optional intents that the binding type provides. Failing
        // this they must be satisfied by reference policy sets
        // Failing this the intent is unresolved and the reference and 
        // service don't match
        
        // TODO - seems that we should do this loop on a binding by binding basis
        //        rather than each time we do matching
        BindingType bindingType = null;
        
        Definitions systemDefinitions = null;
        if (builderContext != null){
            systemDefinitions = builderContext.getDefinitions();
        } else {
            if (((RuntimeEndpoint)endpoint).getCompositeContext() == null) {
                return true;
            }
            systemDefinitions = ((RuntimeEndpoint)endpoint).getCompositeContext().getSystemDefinitions();
        }
        
        bindingType = systemDefinitions.getBindingType(binding.getType());
        
        // Before we start examining intents, remove any whose constrained
        // types don't include the binding type
        removeConstrainedIntents(endpointReference, bindingType);
        
        List<Intent> eprIntents = new ArrayList<Intent>();
        List<Intent> eprMayProvideInterationIntents = new ArrayList<Intent>();
        eprIntents.addAll(endpointReference.getRequiredIntents());
        
        // first check the binding type
        for (Intent intent : endpointReference.getRequiredIntents()){ 
            if (bindingType != null && 
                bindingType.getAlwaysProvidedIntents().contains(intent)){
                eprIntents.remove(intent);
            } else if (bindingType != null &&
                       bindingType.getMayProvidedIntents().contains(intent)){
                eprIntents.remove(intent);
                if (intent.getType().equals(Intent.Type.interaction)){
                    eprMayProvideInterationIntents.add(intent);
                }
            } else {
               // TODO - this code also appears in the ComponentPolicyBuilder
               //        so should rationalize
               loop: for (PolicySet policySet : referencePolicySets){
                    if (policySet.getProvidedIntents().contains(intent)){
                        eprIntents.remove(intent);
                        break;
                    }
                    
                    for (Intent psProvidedIntent : policySet.getProvidedIntents()){
                        if (isQualifiedBy(psProvidedIntent, intent)){
                            eprIntents.remove(intent);
                            break loop;
                        }
                    }

                    for (IntentMap map : policySet.getIntentMaps()) {
                        for (Qualifier q : map.getQualifiers()) {
                            if (intent.equals(q.getIntent())) {
                                eprIntents.remove(intent);
                                break loop;
                            }
                        }
                    }                    
                }          
            }                
        }
        
        // if there are unresolved intents the service and reference don't match
        if (eprIntents.size() > 0){
            matchAudit.append("No match because there are unresolved intents " + eprIntents.toString() + " ");
            matchAudit.appendSeperator();
            return false;
        }  
        
        // TUSCANY-3959 - something that's not explicitly stated in the spec. mayProvides intents don't
        //                lead to policy sets as the binding natively implements the intent. So 
        //                we need to check that these intents match explicitly between reference and service
        //                sides
        if (eprMayProvideInterationIntents.size() > 0){
            for (Intent eprIntent : eprMayProvideInterationIntents){
                boolean match = false;
                for (Intent epIntent : endpoint.getRequiredIntents()){
                    if (epIntent.equals(eprIntent)){
                        match = true;
                        break;
                    }
                }
                
                if (!match){
                    matchAudit.append("No match because the reference has a mayProvide intent that the service doesn't have " + eprIntent.getName());
                    matchAudit.appendSeperator();
                    return false;
                }
            }
        }
        
        // if there are no policies on epr or ep side then 
        // they match
        if (noEndpointPolicies && noEndpointReferencePolicies){
            matchAudit.append("Match because the intents are resolved and there are no policy sets ");
            matchAudit.appendSeperator();
            return true;
        }
        
        // if there are some policies on one side and not the other then 
        // the don't match
        if (noEndpointPolicies && !noEndpointReferencePolicies) {
            matchAudit.append("No match because there are policy sets at the endpoint reference but not at the endpoint ");
            matchAudit.appendSeperator();
            return false;
        }
        
        if (!noEndpointPolicies && noEndpointReferencePolicies){
            matchAudit.append("No match because there are policy sets at the endpoint but not at the endpoint reference ");
            matchAudit.appendSeperator();
            return false;
        }
        
        // If policy set QNames from epr and er match exactly then the reference and 
        // service policies are compatible
        Set<PolicySet> referencePolicySet = new HashSet<PolicySet>(referencePolicySets);
        Set<PolicySet> servicePolicySet = new HashSet<PolicySet>(endpoint.getPolicySets());
        if(referencePolicySet.equals(servicePolicySet)){
            matchAudit.append("Match because the policy sets on both sides are eactly the same ");
            matchAudit.appendSeperator();
            return true;
        }
        
        // if policy set language at ep and epr are not the same then there is no
        // match. We get the policy language by looking at the first expression
        // of the first policy set. By this stage we know that all the policy sets
        // in an endpoint or endpoint reference will use a single language and we know 
        // that there is at least one policy set with at least one policy
        QName eprLanguage = null;
        
        for (PolicySet policySet : referencePolicySets){
            if (policySet.getPolicies().size() > 0){
                eprLanguage = policySet.getPolicies().get(0).getName();
                break;
            }
        }
        
        QName epLanguage = null;
          
        for (PolicySet policySet : endpoint.getPolicySets()){
            if (policySet.getPolicies().size() > 0){
                epLanguage = policySet.getPolicies().get(0).getName();
                break;
            }
        }
        
        if(!eprLanguage.getNamespaceURI().equals(epLanguage.getNamespaceURI())){
            matchAudit.append("No match because the policy sets on either side have policies in differnt languages " + 
                              eprLanguage + 
                              " and " +
                              epLanguage +
                              " ");
            matchAudit.appendSeperator();
            return false;
        }
        
        // now do a policy specific language match 
        PolicyBuilder builder = builders.getPolicyBuilder(eprLanguage);
        boolean match = false;
        
        // switch the derived list of policy sets into the reference
        // it will be left there if there is a match
        List<PolicySet> originalPolicySets = endpointReference.getPolicySets();
        endpointReference.getPolicySets().clear();
        endpointReference.getPolicySets().addAll(referencePolicySets);
        
        if (builder != null) {
            if (builderContext == null){
                builderContext = new BuilderContext(monitor);
            }
            
            match = builder.build(endpointReference, endpoint, builderContext);
        } 
                
        if (!match){
            matchAudit.append("No match because the language specific matching failed ");
            matchAudit.appendSeperator();
            endpointReference.getPolicySets().clear();
            endpointReference.getPolicySets().addAll(originalPolicySets);
        } else {
            matchAudit.append("Match because the language specific matching succeeded ");
            matchAudit.appendSeperator();
        }
        
        return match;
    }
    
    // Copied from ComponentPolicyBuilder, should probably be refactored
    protected void removeConstrainedIntents(EndpointReference subject, BindingType bindingType) {
        List<Intent> intents = subject.getRequiredIntents();
        
        // Remove the intents whose @contrains do not include the current element       
        if(bindingType != null){
            List<Intent> copy = new ArrayList<Intent>(intents);
            for (Intent i : copy) {
            	List<ExtensionType> constrainedTypes = i.getConstrainedTypes();
            	if (( constrainedTypes.size() == 0 ) && ( i.getQualifiableIntent() != null ) )  
            		constrainedTypes = i.getQualifiableIntent().getConstrainedTypes();
            	
                if (constrainedTypes.size() > 0){               
                    boolean constraintFound = false;
                    for (ExtensionType constrainedType : constrainedTypes){
                        if (constrainedType.getType().equals(bindingType.getType()) ||
                            constrainedType.getType().equals(bindingType.getBaseType())){
                            constraintFound = true;
                            break;
                        }
                    }
                    if(!constraintFound){
                        intents.remove(i);
                    }
                }
            }
        }
    }
  

	protected boolean isQualifiedBy(Intent qualifiableIntent, Intent qualifiedIntent){
        if (qualifiedIntent.getQualifiableIntent() == qualifiableIntent){
            return true;
        } else {
            return false;
        }
    }
    
    protected boolean checkQualifiedMutualExclusion(List<Intent> excludedIntentList, Intent intent){
        for (Intent excludedIntent : excludedIntentList){
            if (intent.getQualifiableIntent() != null &&
                excludedIntent != null &&
                intent.getQualifiableIntent().equals(excludedIntent)){
                return true;
            }
        }
        return false;
    }      
    
    /**
     * Determine if endpoint reference and endpoint interface contracts match 
     */
    private boolean haveMatchingInterfaceContracts(EndpointReference endpointReference, Endpoint endpoint, Audit matchAudit){
        matchAudit.append("Match interface of " + endpointReference.toString() + " to " + endpoint.toString() + " ");
        
        InterfaceContract endpointReferenceContract = endpointReference.getReference().getInterfaceContract();
        InterfaceContract endpointContract = endpoint.getComponentServiceInterfaceContract();
        
        if (endpointReferenceContract == null || endpointContract == null){
            matchAudit.append("Match because there is no interface contract on the reference ");
            matchAudit.appendSeperator();
            return true;
        } 
        
        if (!endpoint.getSpecVersion().equals(Base.SCA11_NS)){
            // Assume it matches as we don't know how to do interface 
            // matching with anything but OASIS endpoint
            matchAudit.append("Match because the target endpoint is not an OASIS endpoint, specVersion = " + 
                              endpoint.getSpecVersion());
            matchAudit.appendSeperator();
            return true;
        }        
        
/*  For testing this code turns off remote interface matching completely   
        if (endpoint.isRemote()){
            matchAudit.append("Match because endpoint is remote");
            matchAudit.appendSeperator();
            return true;
        }
*/       
        
        // If the remote interface was not retrieved successfully from the registry for whatever reason
        // then assume the interfaces match and leave the checking until runtime. We looking for an interface
        // with no operations defined to tell us this. 
        if ((endpointContract.getInterface().getOperations().size() == 0 &&
             endpointContract.getNormalizedWSDLContract() == null) ||
            (endpointContract.getNormalizedWSDLContract() != null &&
             endpointContract.getNormalizedWSDLContract().getInterface().getOperations().size() == 0)){
            matchAudit.append("Match because the endpoint is remote and we don't have a copy of it's interface contract ");
            matchAudit.appendSeperator();
            return true;
        }
        
        // TUSCANY-4033
        // Detect the case where the interfaces are both Java but the Endpoint is remote in which case
        // we have to match the local Java interface with the remote Tuscany interface. But we can do this
        // without running WSDLGen
        if (endpointReferenceContract.getClass() == endpointContract.getClass() &&
            endpointReferenceContract instanceof JavaInterfaceContract &&
            endpointContract.getNormalizedWSDLContract() != null &&
            endpointContract.getNormalizedWSDLContract() instanceof TuscanyInterfaceContractImpl){
            // use the TuscanyInterfaceContractImpl to compare against the Java contract
            endpointContract = endpointContract.getNormalizedWSDLContract();
        } else if (endpointReferenceContract.getClass() != endpointContract.getClass() ||
            endpointReferenceContract.getNormalizedWSDLContract() != null ||
            endpointContract.getNormalizedWSDLContract() != null) {
            // If the contracts are not of the same type use normailized interfaces
            endpointReferenceContract = ((RuntimeEndpointReference)endpointReference).getGeneratedWSDLContract(endpointReferenceContract);
            endpointContract = ((RuntimeEndpoint)endpoint).getGeneratedWSDLContract(endpointContract);
        }        
             
        boolean match = false;
        match = interfaceContractMapper.isCompatibleSubset(endpointReferenceContract, 
                                                           endpointContract, 
                                                           matchAudit);
        
        if (!match){
            matchAudit.append("Match failed because the interface contract mapper failed ");
        } else {
            matchAudit.append("Match because the interface contract mapper succeeded ");
        }
        
        matchAudit.appendSeperator();
        
        return match;
    }
    
    /**
     * Checks to see if the registry has been updated since the reference was last matched
     * 
     * @return true is the registry has changed
     */
    public boolean isOutOfDate(DomainRegistry domainRegistry, EndpointReference endpointReference) {
        Endpoint te = endpointReference.getTargetEndpoint();
        if (te != null && !te.isUnresolved()
            && te.getURI() != null
            && endpointReference.getStatus() != EndpointReference.Status.RESOLVED_BINDING) {
            return domainRegistry.isOutOfDate(endpointReference);
        }
        return false;
    }

    /**
     * ASM_5021: where a <reference/> of a <component/> has @autowire=true 
     * and where the <reference/> has a <binding/> child element which 
     * declares a single target service,  the reference is wired only to 
     * the single service identified by the <wire/> element
     */    
    private void setSingleAutoWireTarget(ComponentReference reference) {
        if (reference.getEndpointReferences().size() > 1 && reference.getBindings() != null
            && reference.getBindings().size() == 1) {
            String uri = reference.getBindings().get(0).getURI();
            if (uri != null) {
                if (uri.indexOf('/') > -1) {
                    // TODO: must be a way to avoid this fiddling
                    int i = uri.indexOf('/');
                    String c = uri.substring(0, i);
                    String s = uri.substring(i + 1);
                    uri = c + "#service(" + s + ")";
                }
                for (EndpointReference er : reference.getEndpointReferences()) {
                    if (er.getTargetEndpoint() != null && uri.equals(er.getTargetEndpoint().getURI())) {
                        reference.getEndpointReferences().clear();
                        reference.getEndpointReferences().add(er);
                        return;
                    }
                }
            }
        }
    }
    
     
}
