/**
  * Executes the OperationClient
  *
  * @param opClient - Fully configured OperationClient
  * @param block - Indicates if blocking or non-blocking execute
  * @param msgContext - Axis2 MessageContext
  * @throws AxisFault - All exceptions are returned as AxisFaults
  */
 private void execute(
     OperationClient opClient, boolean block, org.apache.axis2.context.MessageContext msgContext)
     throws AxisFault {
   try {
     // Pre-Execute logging and setup
     preExecute(opClient, block, msgContext);
     // check if Exception should be thrown on SOAPFault
     if (log.isDebugEnabled()) {
       log.debug("Read throwExceptionIfSOAPFault property");
     }
     boolean exceptionToBeThrownOnSOAPFault =
         ClientUtils.getExceptionToBeThrownOnSOAPFault(msgContext);
     if (log.isDebugEnabled()) {
       log.debug(
           "throwExceptionIfSOAPFault property set on OperationClient.options "
               + exceptionToBeThrownOnSOAPFault);
     }
     opClient.getOptions().setExceptionToBeThrownOnSOAPFault(exceptionToBeThrownOnSOAPFault);
     // Invoke the OperationClient
     opClient.execute(block);
   } catch (Throwable e) {
     // Catch all Throwable (including runtime exceptions and Errors) and
     // throw as AxisFault.
     // Since e could be a Throwable (or Error) instead of an Exception, we'll have to wrap it:
     throw AxisFault.makeFault(ExceptionFactory.makeWebServiceException(e));
   } finally {
     // Post-Execute logging and setup
     postExecute(opClient, block, msgContext);
   }
 }
  /*
   *  (non-Javadoc)
   * @see org.apache.axis2.jaxws.core.controller.InvocationController#invokeAsync(org.apache.axis2.jaxws.core.InvocationContext)
   */
  public Response doInvokeAsync(MessageContext request) {
    // We need the qname of the operation being invoked to know which
    // AxisOperation the OperationClient should be based on.
    // Note that the OperationDesc is only set through use of the Proxy. Dispatch
    // clients do not use operations, so the operationDesc will be null.  In this
    // case an anonymous AxisService with anoymouns AxisOperations for the supported
    // MEPs will be created; and it is that anonymous operation name which needs to
    // be specified
    QName operationName = getOperationNameToUse(request, ServiceClient.ANON_OUT_IN_OP);

    // TODO: Will the ServiceClient stick around on the InvocationContext
    // or will we need some other mechanism of creating this?
    // Try to create an OperationClient from the passed in ServiceClient
    InvocationContext ic = request.getInvocationContext();
    ServiceClient svcClient = ic.getServiceClient();
    OperationClient opClient = createOperationClient(svcClient, operationName);

    initOperationClient(opClient, request);

    // Setup the client so that it knows whether the underlying call to
    // Axis2 knows whether or not to start a listening port for an
    // asynchronous response.
    Boolean useAsyncMep = (Boolean) request.getProperty(Constants.USE_ASYNC_MEP);
    if ((useAsyncMep != null && useAsyncMep.booleanValue())
        || opClient.getOptions().isUseSeparateListener()) {
      configureAsyncListener(opClient);
    } else {
      if (log.isDebugEnabled()) {
        log.debug(
            "Asynchronous message exchange not enabled.  The invocation will be synchronous.");
      }
    }

    AsyncResponse resp = ic.getAsyncResponseListener();
    PollingFuture pf = new PollingFuture(ic);
    opClient.setCallback(pf);

    org.apache.axis2.context.MessageContext axisRequestMsgCtx = request.getAxisMessageContext();
    try {
      execute(opClient, false, axisRequestMsgCtx);
    } catch (AxisFault af) {
      if (log.isDebugEnabled()) {
        log.debug(
            axisRequestMsgCtx.getLogIDString()
                + " AxisFault received from client: "
                + af.getMessage());
      }
      /*
       * Save the exception on the callback.  The client will learn about the error when they try to
       * retrieve the async results via the Response.get().  "Errors that occur during the invocation
       * are reported via an exception when the client attempts to retrieve the results of the operation."
       * -- JAXWS 4.3.3
       */
      pf.onError(af);
    }

    return resp;
  }
  /** Auto generated method signature */
  public void setEmp(com.pa.SetEmp setEmp3) throws java.rmi.RemoteException {

    org.apache.axis2.context.MessageContext _messageContext = null;

    org.apache.axis2.client.OperationClient _operationClient =
        _serviceClient.createClient(_operations[0].getName());
    _operationClient.getOptions().setAction("urn:setEmp");
    _operationClient.getOptions().setExceptionToBeThrownOnSOAPFault(true);

    addPropertyToOperationClient(
        _operationClient,
        org.apache.axis2.description.WSDL2Constants.ATTR_WHTTP_QUERY_PARAMETER_SEPARATOR,
        "&");

    org.apache.axiom.soap.SOAPEnvelope env = null;
    _messageContext = new org.apache.axis2.context.MessageContext();

    // Style is Doc.

    env =
        toEnvelope(
            getFactory(_operationClient.getOptions().getSoapVersionURI()),
            setEmp3,
            optimizeContent(new javax.xml.namespace.QName("http://pa.com", "setEmp")),
            new javax.xml.namespace.QName("http://pa.com", "setEmp"));

    // adding SOAP soap_headers
    _serviceClient.addHeadersToEnvelope(env);
    // create message context with that soap envelope

    _messageContext.setEnvelope(env);

    // add the message contxt to the operation client
    _operationClient.addMessageContext(_messageContext);

    _operationClient.execute(true);

    if (_messageContext.getTransportOut() != null) {
      _messageContext.getTransportOut().getSender().cleanup(_messageContext);
    }

    return;
  }
  /**
   * Called by execute(OperationClient) to perform pre-execute tasks.
   *
   * @param opClient
   * @param block - Indicates if blocking or non-blocking execute
   * @param msgContext - Axis2 MessageContext
   */
  private void preExecute(
      OperationClient opClient, boolean block, org.apache.axis2.context.MessageContext msgContext)
      throws AxisFault {
    // This assumes that we are on the ultimate execution thread

    // This has to be here so the ThreadContextMigrator can pick it up.
    msgContext.getOptions().setUseSeparateListener(opClient.getOptions().isUseSeparateListener());

    ThreadContextMigratorUtil.performMigrationToContext(
        Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID, msgContext);

    // Enable the ThreadContextMigrator to override UseSeparateListener
    opClient.getOptions().setUseSeparateListener(msgContext.getOptions().isUseSeparateListener());

    if (log.isDebugEnabled()) {
      log.debug("Start OperationClient.execute(" + block + ")");
      log.debug("UseSeparateListener: " + opClient.getOptions().isUseSeparateListener());
    }
  }
  private void initOperationClient(OperationClient opClient, MessageContext requestMsgCtx) {
    org.apache.axis2.context.MessageContext axisRequest = requestMsgCtx.getAxisMessageContext();
    setupProperties(requestMsgCtx); // , axisRequest.getOptions());

    if (opClient != null) {
      Options options = opClient.getOptions();

      // Get the target endpoint address and setup the TO endpoint
      // reference.  This tells us where the request is going.
      EndpointReference toEPR = axisRequest.getTo();

      if (toEPR == null) {
        String targetUrl =
            (String) requestMsgCtx.getProperty(BindingProvider.ENDPOINT_ADDRESS_PROPERTY);
        toEPR = new EndpointReference(targetUrl);
      }

      options.setTo(toEPR);

      // Get the SOAP Action (if needed)
      String soapAction = ClientUtils.findSOAPAction(requestMsgCtx);
      options.setAction(soapAction);
      // get the timeout from the request message context options as it may have been
      // set by the user; if it was not set by the user we will just be setting the
      // timeout on the operation client to the default so it will not have a negative
      // effect; this logic is reliant on the fact the JAX-WS MessageContext is delegating
      // to the Axis2 Options object and not storing its own property bag
      long timeout = axisRequest.getOptions().getTimeOutInMilliSeconds();
      options.setTimeOutInMilliSeconds(timeout);

      // Use the OperationClient to send the request and put the contents
      // of the response in the response MessageContext.
      try {
        // Set the Axis2 request MessageContext
        opClient.addMessageContext(axisRequest);
      } catch (Exception e) {
        // TODO: Do something
      }
    }
  }
  /**
   * Auto generated method signature for Asynchronous Invocations
   *
   * @see com.pa.SecondFileService#startgetEmp
   * @param getEmp4
   */
  public void startgetEmp(
      com.pa.GetEmp getEmp4, final com.pa.SecondFileServiceCallbackHandler callback)
      throws java.rmi.RemoteException {

    org.apache.axis2.client.OperationClient _operationClient =
        _serviceClient.createClient(_operations[1].getName());
    _operationClient.getOptions().setAction("urn:getEmp");
    _operationClient.getOptions().setExceptionToBeThrownOnSOAPFault(true);

    addPropertyToOperationClient(
        _operationClient,
        org.apache.axis2.description.WSDL2Constants.ATTR_WHTTP_QUERY_PARAMETER_SEPARATOR,
        "&");

    // create SOAP envelope with that payload
    org.apache.axiom.soap.SOAPEnvelope env = null;
    final org.apache.axis2.context.MessageContext _messageContext =
        new org.apache.axis2.context.MessageContext();

    // Style is Doc.

    env =
        toEnvelope(
            getFactory(_operationClient.getOptions().getSoapVersionURI()),
            getEmp4,
            optimizeContent(new javax.xml.namespace.QName("http://pa.com", "getEmp")),
            new javax.xml.namespace.QName("http://pa.com", "getEmp"));

    // adding SOAP soap_headers
    _serviceClient.addHeadersToEnvelope(env);
    // create message context with that soap envelope
    _messageContext.setEnvelope(env);

    // add the message context to the operation client
    _operationClient.addMessageContext(_messageContext);

    _operationClient.setCallback(
        new org.apache.axis2.client.async.AxisCallback() {
          public void onMessage(org.apache.axis2.context.MessageContext resultContext) {
            try {
              org.apache.axiom.soap.SOAPEnvelope resultEnv = resultContext.getEnvelope();

              java.lang.Object object =
                  fromOM(
                      resultEnv.getBody().getFirstElement(),
                      com.pa.GetEmpResponse.class,
                      getEnvelopeNamespaces(resultEnv));
              callback.receiveResultgetEmp((com.pa.GetEmpResponse) object);

            } catch (org.apache.axis2.AxisFault e) {
              callback.receiveErrorgetEmp(e);
            }
          }

          public void onError(java.lang.Exception error) {
            if (error instanceof org.apache.axis2.AxisFault) {
              org.apache.axis2.AxisFault f = (org.apache.axis2.AxisFault) error;
              org.apache.axiom.om.OMElement faultElt = f.getDetail();
              if (faultElt != null) {
                if (faultExceptionNameMap.containsKey(
                    new org.apache.axis2.client.FaultMapKey(faultElt.getQName(), "getEmp"))) {
                  // make the fault by reflection
                  try {
                    java.lang.String exceptionClassName =
                        (java.lang.String)
                            faultExceptionClassNameMap.get(
                                new org.apache.axis2.client.FaultMapKey(
                                    faultElt.getQName(), "getEmp"));
                    java.lang.Class exceptionClass = java.lang.Class.forName(exceptionClassName);
                    java.lang.reflect.Constructor constructor =
                        exceptionClass.getConstructor(String.class);
                    java.lang.Exception ex =
                        (java.lang.Exception) constructor.newInstance(f.getMessage());
                    // message class
                    java.lang.String messageClassName =
                        (java.lang.String)
                            faultMessageMap.get(
                                new org.apache.axis2.client.FaultMapKey(
                                    faultElt.getQName(), "getEmp"));
                    java.lang.Class messageClass = java.lang.Class.forName(messageClassName);
                    java.lang.Object messageObject = fromOM(faultElt, messageClass, null);
                    java.lang.reflect.Method m =
                        exceptionClass.getMethod(
                            "setFaultMessage", new java.lang.Class[] {messageClass});
                    m.invoke(ex, new java.lang.Object[] {messageObject});

                    callback.receiveErrorgetEmp(new java.rmi.RemoteException(ex.getMessage(), ex));
                  } catch (java.lang.ClassCastException e) {
                    // we cannot intantiate the class - throw the original Axis fault
                    callback.receiveErrorgetEmp(f);
                  } catch (java.lang.ClassNotFoundException e) {
                    // we cannot intantiate the class - throw the original Axis fault
                    callback.receiveErrorgetEmp(f);
                  } catch (java.lang.NoSuchMethodException e) {
                    // we cannot intantiate the class - throw the original Axis fault
                    callback.receiveErrorgetEmp(f);
                  } catch (java.lang.reflect.InvocationTargetException e) {
                    // we cannot intantiate the class - throw the original Axis fault
                    callback.receiveErrorgetEmp(f);
                  } catch (java.lang.IllegalAccessException e) {
                    // we cannot intantiate the class - throw the original Axis fault
                    callback.receiveErrorgetEmp(f);
                  } catch (java.lang.InstantiationException e) {
                    // we cannot intantiate the class - throw the original Axis fault
                    callback.receiveErrorgetEmp(f);
                  } catch (org.apache.axis2.AxisFault e) {
                    // we cannot intantiate the class - throw the original Axis fault
                    callback.receiveErrorgetEmp(f);
                  }
                } else {
                  callback.receiveErrorgetEmp(f);
                }
              } else {
                callback.receiveErrorgetEmp(f);
              }
            } else {
              callback.receiveErrorgetEmp(error);
            }
          }

          public void onFault(org.apache.axis2.context.MessageContext faultContext) {
            org.apache.axis2.AxisFault fault =
                org.apache.axis2.util.Utils.getInboundFaultFromMessageContext(faultContext);
            onError(fault);
          }

          public void onComplete() {
            try {
              _messageContext.getTransportOut().getSender().cleanup(_messageContext);
            } catch (org.apache.axis2.AxisFault axisFault) {
              callback.receiveErrorgetEmp(axisFault);
            }
          }
        });

    org.apache.axis2.util.CallbackReceiver _callbackReceiver = null;
    if (_operations[1].getMessageReceiver() == null
        && _operationClient.getOptions().isUseSeparateListener()) {
      _callbackReceiver = new org.apache.axis2.util.CallbackReceiver();
      _operations[1].setMessageReceiver(_callbackReceiver);
    }

    // execute the operation client
    _operationClient.execute(false);
  }
  /**
   * Auto generated method signature
   *
   * @see com.pa.SecondFileService#getEmp
   * @param getEmp4
   */
  public com.pa.GetEmpResponse getEmp(com.pa.GetEmp getEmp4) throws java.rmi.RemoteException {

    org.apache.axis2.context.MessageContext _messageContext = null;
    try {
      org.apache.axis2.client.OperationClient _operationClient =
          _serviceClient.createClient(_operations[1].getName());
      _operationClient.getOptions().setAction("urn:getEmp");
      _operationClient.getOptions().setExceptionToBeThrownOnSOAPFault(true);

      addPropertyToOperationClient(
          _operationClient,
          org.apache.axis2.description.WSDL2Constants.ATTR_WHTTP_QUERY_PARAMETER_SEPARATOR,
          "&");

      // create a message context
      _messageContext = new org.apache.axis2.context.MessageContext();

      // create SOAP envelope with that payload
      org.apache.axiom.soap.SOAPEnvelope env = null;

      env =
          toEnvelope(
              getFactory(_operationClient.getOptions().getSoapVersionURI()),
              getEmp4,
              optimizeContent(new javax.xml.namespace.QName("http://pa.com", "getEmp")),
              new javax.xml.namespace.QName("http://pa.com", "getEmp"));

      // adding SOAP soap_headers
      _serviceClient.addHeadersToEnvelope(env);
      // set the message context with that soap envelope
      _messageContext.setEnvelope(env);

      // add the message contxt to the operation client
      _operationClient.addMessageContext(_messageContext);

      // execute the operation client
      _operationClient.execute(true);

      org.apache.axis2.context.MessageContext _returnMessageContext =
          _operationClient.getMessageContext(
              org.apache.axis2.wsdl.WSDLConstants.MESSAGE_LABEL_IN_VALUE);
      org.apache.axiom.soap.SOAPEnvelope _returnEnv = _returnMessageContext.getEnvelope();

      java.lang.Object object =
          fromOM(
              _returnEnv.getBody().getFirstElement(),
              com.pa.GetEmpResponse.class,
              getEnvelopeNamespaces(_returnEnv));

      return (com.pa.GetEmpResponse) object;

    } catch (org.apache.axis2.AxisFault f) {

      org.apache.axiom.om.OMElement faultElt = f.getDetail();
      if (faultElt != null) {
        if (faultExceptionNameMap.containsKey(
            new org.apache.axis2.client.FaultMapKey(faultElt.getQName(), "getEmp"))) {
          // make the fault by reflection
          try {
            java.lang.String exceptionClassName =
                (java.lang.String)
                    faultExceptionClassNameMap.get(
                        new org.apache.axis2.client.FaultMapKey(faultElt.getQName(), "getEmp"));
            java.lang.Class exceptionClass = java.lang.Class.forName(exceptionClassName);
            java.lang.reflect.Constructor constructor = exceptionClass.getConstructor(String.class);
            java.lang.Exception ex = (java.lang.Exception) constructor.newInstance(f.getMessage());
            // message class
            java.lang.String messageClassName =
                (java.lang.String)
                    faultMessageMap.get(
                        new org.apache.axis2.client.FaultMapKey(faultElt.getQName(), "getEmp"));
            java.lang.Class messageClass = java.lang.Class.forName(messageClassName);
            java.lang.Object messageObject = fromOM(faultElt, messageClass, null);
            java.lang.reflect.Method m =
                exceptionClass.getMethod("setFaultMessage", new java.lang.Class[] {messageClass});
            m.invoke(ex, new java.lang.Object[] {messageObject});

            throw new java.rmi.RemoteException(ex.getMessage(), ex);
          } catch (java.lang.ClassCastException e) {
            // we cannot intantiate the class - throw the original Axis fault
            throw f;
          } catch (java.lang.ClassNotFoundException e) {
            // we cannot intantiate the class - throw the original Axis fault
            throw f;
          } catch (java.lang.NoSuchMethodException e) {
            // we cannot intantiate the class - throw the original Axis fault
            throw f;
          } catch (java.lang.reflect.InvocationTargetException e) {
            // we cannot intantiate the class - throw the original Axis fault
            throw f;
          } catch (java.lang.IllegalAccessException e) {
            // we cannot intantiate the class - throw the original Axis fault
            throw f;
          } catch (java.lang.InstantiationException e) {
            // we cannot intantiate the class - throw the original Axis fault
            throw f;
          }
        } else {
          throw f;
        }
      } else {
        throw f;
      }
    } finally {
      if (_messageContext.getTransportOut() != null) {
        _messageContext.getTransportOut().getSender().cleanup(_messageContext);
      }
    }
  }
  public CadConsultaCadastro2Stub.ConsultaCadastro2Result consultaCadastro2(
      final CadConsultaCadastro2Stub.NfeDadosMsg nfeDadosMsg,
      final CadConsultaCadastro2Stub.NfeCabecMsgE nfeCabecMsg)
      throws java.rmi.RemoteException {

    org.apache.axis2.context.MessageContext _messageContext = null;
    try {
      final org.apache.axis2.client.OperationClient _operationClient =
          this._serviceClient.createClient(this._operations[0].getName());
      _operationClient
          .getOptions()
          .setAction(
              "http://www.portalfiscal.inf.br/nfe/wsdl/CadConsultaCadastro2/consultaCadastro2");
      _operationClient.getOptions().setExceptionToBeThrownOnSOAPFault(true);

      this.addPropertyToOperationClient(
          _operationClient,
          org.apache.axis2.description.WSDL2Constants.ATTR_WHTTP_QUERY_PARAMETER_SEPARATOR,
          "&");

      // create a message context
      _messageContext = new org.apache.axis2.context.MessageContext();

      // create SOAP envelope with that payload
      org.apache.axiom.soap.SOAPEnvelope env = null;

      env =
          this.toEnvelope(
              Stub.getFactory(_operationClient.getOptions().getSoapVersionURI()),
              nfeDadosMsg,
              this.optimizeContent(
                  new javax.xml.namespace.QName(
                      "http://www.portalfiscal.inf.br/nfe/wsdl/CadConsultaCadastro2",
                      "consultaCadastro2")),
              new javax.xml.namespace.QName(
                  "http://www.portalfiscal.inf.br/nfe/wsdl/CadConsultaCadastro2",
                  "consultaCadastro2"));

      env.build();

      // add the children only if the parameter is not null
      if (nfeCabecMsg != null) {

        final org.apache.axiom.om.OMElement omElementnfeCabecMsg =
            this.toOM(
                nfeCabecMsg,
                this.optimizeContent(
                    new javax.xml.namespace.QName(
                        "http://www.portalfiscal.inf.br/nfe/wsdl/CadConsultaCadastro2",
                        "consultaCadastro2")));
        this.addHeader(omElementnfeCabecMsg, env);
      }

      // adding SOAP soap_headers
      this._serviceClient.addHeadersToEnvelope(env);
      // set the message context with that soap envelope
      _messageContext.setEnvelope(env);

      // add the message contxt to the operation client
      _operationClient.addMessageContext(_messageContext);

      // execute the operation client
      _operationClient.execute(true);

      final org.apache.axis2.context.MessageContext _returnMessageContext =
          _operationClient.getMessageContext(
              org.apache.axis2.wsdl.WSDLConstants.MESSAGE_LABEL_IN_VALUE);
      final org.apache.axiom.soap.SOAPEnvelope _returnEnv = _returnMessageContext.getEnvelope();

      final java.lang.Object object =
          this.fromOM(
              _returnEnv.getBody().getFirstElement(),
              CadConsultaCadastro2Stub.ConsultaCadastro2Result.class,
              this.getEnvelopeNamespaces(_returnEnv));

      return (CadConsultaCadastro2Stub.ConsultaCadastro2Result) object;

    } catch (final org.apache.axis2.AxisFault f) {

      final org.apache.axiom.om.OMElement faultElt = f.getDetail();
      if (faultElt != null) {
        if (this.faultExceptionNameMap.containsKey(
            new org.apache.axis2.client.FaultMapKey(faultElt.getQName(), "consultaCadastro2"))) {
          // make the fault by reflection
          try {
            final java.lang.String exceptionClassName =
                (java.lang.String)
                    this.faultExceptionClassNameMap.get(
                        new org.apache.axis2.client.FaultMapKey(
                            faultElt.getQName(), "consultaCadastro2"));
            final Class<?> exceptionClass = java.lang.Class.forName(exceptionClassName);
            final Constructor<?> constructor = exceptionClass.getConstructor(String.class);
            final java.lang.Exception ex =
                (java.lang.Exception) constructor.newInstance(f.getMessage());
            // message class
            final java.lang.String messageClassName =
                (java.lang.String)
                    this.faultMessageMap.get(
                        new org.apache.axis2.client.FaultMapKey(
                            faultElt.getQName(), "consultaCadastro2"));
            final Class<?> messageClass = java.lang.Class.forName(messageClassName);
            final java.lang.Object messageObject = this.fromOM(faultElt, messageClass, null);
            final java.lang.reflect.Method m =
                exceptionClass.getMethod("setFaultMessage", messageClass);
            m.invoke(ex, messageObject);

            throw new java.rmi.RemoteException(ex.getMessage(), ex);
          } catch (final ClassCastException
              | InstantiationException
              | IllegalAccessException
              | java.lang.reflect.InvocationTargetException
              | NoSuchMethodException
              | ClassNotFoundException e) {
            // we cannot intantiate the class - throw the original Axis fault
            throw f;
          }
        } else {
          throw f;
        }
      } else {
        throw f;
      }
    } finally {
      if (_messageContext.getTransportOut() != null) {
        _messageContext.getTransportOut().getSender().cleanup(_messageContext);
      }
    }
  }
  /*
   * (non-Javadoc)
   * @see org.apache.axis2.jaxws.core.controller.InvocationController#invoke(org.apache.axis2.jaxws.core.InvocationContext)
   */
  public MessageContext doInvoke(MessageContext request) {

    // We need the qname of the operation being invoked to know which
    // AxisOperation the OperationClient should be based on.
    // Note that the OperationDesc is only set through use of the Proxy. Dispatch
    // clients do not use operations, so the operationDesc will be null.  In this
    // case an anonymous AxisService with anoymouns AxisOperations for the supported
    // MEPs will be created; and it is that anonymous operation name which needs to
    // be specified
    QName operationName = getOperationNameToUse(request, ServiceClient.ANON_OUT_IN_OP);

    // TODO: Will the ServiceClient stick around on the InvocationContext
    // or will we need some other mechanism of creating this?
    // Try to create an OperationClient from the passed in ServiceClient
    InvocationContext ic = request.getInvocationContext();
    ServiceClient svcClient = ic.getServiceClient();
    OperationClient opClient = createOperationClient(svcClient, operationName);

    initOperationClient(opClient, request);

    // Setup the client so that it knows whether the underlying call to
    // Axis2 knows whether or not to start a listening port for an
    // asynchronous response.
    Boolean useAsyncMep = (Boolean) request.getProperty(Constants.USE_ASYNC_MEP);
    if ((useAsyncMep != null && useAsyncMep.booleanValue())
        || opClient.getOptions().isUseSeparateListener()) {
      configureAsyncListener(opClient);
    } else {
      if (log.isDebugEnabled()) {
        log.debug(
            "Asynchronous message exchange not enabled.  The invocation will be synchronous.");
      }
    }

    org.apache.axis2.context.MessageContext axisRequestMsgCtx = request.getAxisMessageContext();
    org.apache.axis2.context.MessageContext axisResponseMsgCtx = null;

    MessageContext response = null;

    AxisFault faultexception =
        null; // don't let the keyword "fault" confuse you.  This is an exception class.
    try {
      execute(opClient, true, axisRequestMsgCtx);
    } catch (AxisFault af) {
      // If an AxisFault was thrown, we need to cleanup the original OperationContext.
      // Failure to do so results in a memory leak.
      opClient.getOperationContext().cleanup();
      // save the fault in case it didn't come from the endpoint, and thus
      // there would be no message on the MessageContext
      faultexception = af;
      if (log.isDebugEnabled()) {
        log.debug(
            axisRequestMsgCtx.getLogIDString()
                + " AxisFault received from client: "
                + af.getMessage());
      }
    }

    try {
      // Collect the response MessageContext and envelope
      axisResponseMsgCtx = opClient.getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
      response = new MessageContext(axisResponseMsgCtx);
      response.setMEPContext(request.getMEPContext());

      // If the Message object is still null, then it's possible that a
      // local AxisFault was thrown and we need to save it for later throwing
      // We do not want to create a message and go through the whole handler or
      // XMLFault processing because it's unnecessary.
      //
      // Same is true if we get a valid non-fault server response but some jaxws
      // client processing (a handler, perhaps) throws an exception.
      //
      // If the response message itself is a fault message, let it pass through.
      if ((faultexception != null)
          && ((response.getMessage() == null) || (!response.getMessage().isFault()))) {
        MessageFactory factory = (MessageFactory) FactoryRegistry.getFactory(MessageFactory.class);
        Message message = factory.create(request.getMessage().getProtocol());
        response.setLocalException(faultexception);
        response.setMessage(message);
      }

      // This assumes that we are on the ultimate execution thread
      ThreadContextMigratorUtil.performMigrationToThread(
          Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID, axisResponseMsgCtx);
    } catch (Exception e) {
      throw ExceptionFactory.makeWebServiceException(e);
    }

    return response;
  }
 private void configureAsyncListener(OperationClient client) {
   client.getOptions().setUseSeparateListener(true);
 }
  /*
   *  (non-Javadoc)
   * @see org.apache.axis2.jaxws.core.controller.InvocationController#invokeAsync(org.apache.axis2.jaxws.core.InvocationContext, javax.xml.ws.AsyncHandler)
   */
  public Future<?> doInvokeAsync(MessageContext request, AsyncHandler callback) {
    // We need the qname of the operation being invoked to know which
    // AxisOperation the OperationClient should be based on.
    // Note that the OperationDesc is only set through use of the Proxy. Dispatch
    // clients do not use operations, so the operationDesc will be null.  In this
    // case an anonymous AxisService with anoymouns AxisOperations for the supported
    // MEPs will be created; and it is that anonymous operation name which needs to
    // be specified
    QName operationName = getOperationNameToUse(request, ServiceClient.ANON_OUT_IN_OP);

    // TODO: Will the ServiceClient stick around on the InvocationContext
    // or will we need some other mechanism of creating this?
    // Try to create an OperationClient from the passed in ServiceClient
    InvocationContext ic = request.getInvocationContext();
    ServiceClient svcClient = ic.getServiceClient();
    OperationClient opClient = createOperationClient(svcClient, operationName);

    initOperationClient(opClient, request);

    // Setup the client so that it knows whether the underlying call to
    // Axis2 knows whether or not to start a listening port for an
    // asynchronous response.
    Boolean useAsyncMep = (Boolean) request.getProperty(Constants.USE_ASYNC_MEP);
    if ((useAsyncMep != null && useAsyncMep.booleanValue())
        || opClient.getOptions().isUseSeparateListener()) {
      configureAsyncListener(opClient);
    } else {
      if (log.isDebugEnabled()) {
        log.debug(
            "Asynchronous message exchange not enabled.  The invocation will be synchronous.");
      }
    }

    CallbackFuture cbf = null;
    if (callback != null) {
      cbf = new CallbackFuture(ic, callback);
    } else {
      throw ExceptionFactory.makeWebServiceException(Messages.getMessage("ICErr4"));
    }

    opClient.setCallback(cbf);

    org.apache.axis2.context.MessageContext axisRequestMsgCtx = request.getAxisMessageContext();
    try {
      execute(opClient, false, axisRequestMsgCtx);
    } catch (AxisFault af) {
      if (log.isDebugEnabled()) {
        log.debug(
            axisRequestMsgCtx.getLogIDString()
                + " AxisFault received from client: "
                + af.getMessage());
      }
      /*
       * Save the exception on the callback.  The client will learn about the error when they try to
       * retrieve the async results via the Response.get().  "Errors that occur during the invocation
       * are reported via an exception when the client attempts to retrieve the results of the operation."
       * -- JAXWS 4.3.3
       */

      /*
       * TODO:  This is the appropriate thing to do here since the thrown exception may occur before
       * we switch threads to the async thread.  But... what happens if we've already switched over
       * to the async thread?  So far, it appears that the exception gets set on the FutureTask
       * Concurrent object, and we never hit this scope.  This means that later, when the client
       * calls future.get(), no exception will be thrown despite what the spec says.  The client can,
       * however, retrieve errors via it's AsyncHandler.
       */
      cbf.onError(af);
    }

    return cbf.getFutureTask();
  }