/*
 * 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.
 */

#include <axis2_op_client.h>
#include <axis2_const.h>
#include <axutil_hash.h>
#include <axutil_uuid_gen.h>
#include <axis2_listener_manager.h>
#include <axis2_engine.h>
#include "axis2_callback_recv.h"
#include <axiom_xml_reader.h>
#include <axis2_core_utils.h>
#include <axiom_soap_envelope.h>
#include <axiom_soap_const.h>
#include <axiom_soap_body.h>
#include <axutil_types.h>
#include <platforms/axutil_platform_auto_sense.h>

struct axis2_op_client
{
    axis2_svc_ctx_t *svc_ctx;

    axis2_options_t *options;

    axis2_op_ctx_t *op_ctx;

    axis2_callback_t *callback;

    axis2_bool_t completed;

    /* to hold the locally created async result */
    axis2_async_result_t *async_result;

    axis2_callback_recv_t *callback_recv;

    /** message exchange pattern */
    axis2_char_t *mep;

    axis2_char_t *soap_version_uri;
    axutil_string_t *soap_action;
    axis2_char_t *wsa_action;
    axis2_bool_t reuse;

};

typedef struct axis2_op_client_worker_func_args
{
    const axutil_env_t *env;
    axis2_op_client_t *op_client;
    axis2_callback_t *callback;
    axis2_op_t *op;
    axis2_msg_ctx_t *msg_ctx;
} axis2_op_client_worker_func_args_t;

void *AXIS2_THREAD_FUNC axis2_op_client_worker_func(
    axutil_thread_t * thd,
    void *data);

static axis2_char_t *AXIS2_CALL axis2_op_client_get_transport_from_url(
    const axis2_char_t * url,
    const axutil_env_t * env);

AXIS2_EXTERN axis2_op_client_t *AXIS2_CALL
axis2_op_client_create(
    const axutil_env_t * env,
    axis2_op_t * op,
    axis2_svc_ctx_t * svc_ctx,
    axis2_options_t * options)
{
    axis2_op_client_t *op_client = NULL;
    const axis2_char_t *mep_uri = NULL;

    AXIS2_ENV_CHECK(env, NULL);
    AXIS2_PARAM_CHECK(env->error, op, NULL);
    AXIS2_PARAM_CHECK(env->error, svc_ctx, NULL);
    AXIS2_PARAM_CHECK(env->error, options, NULL);

    op_client = AXIS2_MALLOC(env->allocator, sizeof(axis2_op_client_t));
    if(!op_client)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create op client.");
        return NULL;
    }

    /** initialize data */
    op_client->callback = NULL;
    op_client->completed = AXIS2_FALSE;
    op_client->reuse = AXIS2_FALSE;
    op_client->async_result = NULL;
    op_client->callback_recv = NULL;

    op_client->options = options;
    op_client->svc_ctx = svc_ctx;

    op_client->mep = NULL;
    op_client->soap_version_uri = NULL;
    op_client->soap_action = NULL;
    op_client->wsa_action = NULL;

    op_client->op_ctx = axis2_op_ctx_create(env, op, op_client->svc_ctx);
    if(!(op_client->op_ctx))
    {
        axis2_op_client_free(op_client, env);
        return NULL;
    }

    mep_uri = axis2_op_get_msg_exchange_pattern(op, env);

    if(!mep_uri)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MEP_CANNOT_DETERMINE_MEP, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot find message exchange pattern uri.");
        axis2_op_client_free(op_client, env);
        return NULL;
    }

    op_client->mep = axutil_strdup(env, mep_uri);

    op_client->soap_version_uri = axutil_strdup(env, AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI);
    if(!(op_client->soap_version_uri))
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create soap version uri.");
        axis2_op_client_free(op_client, env);
        return NULL;
    }

    /** initialize parser for thread safety */
    axiom_xml_reader_init();
    return op_client;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_op_client_set_options(
    axis2_op_client_t * op_client,
    const axutil_env_t * env,
    const axis2_options_t * options)
{
    if(op_client->options)
    {
        axis2_options_free(op_client->options, env);
    }
    op_client->options = (axis2_options_t *)options;

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN const axis2_options_t *AXIS2_CALL
axis2_op_client_get_options(
    const axis2_op_client_t * op_client,
    const axutil_env_t * env)
{
    return op_client->options;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_op_client_add_msg_ctx(
    axis2_op_client_t * op_client,
    const axutil_env_t * env,
    axis2_msg_ctx_t * mc)
{
    axis2_msg_ctx_t *out_msg_ctx = NULL, *in_msg_ctx = NULL;
    axis2_msg_ctx_t **msg_ctx_map = NULL;

    /* Don't use AXIS2_PARAM_CHECK to verify op_client, as it clobbers 
     env->error->status_code on no error destroying the information
     therein that an error has already occurred. */
    if(!op_client)
    {
        if(axutil_error_get_status_code(env->error) == AXIS2_SUCCESS)
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE);
        }
        return AXIS2_FAILURE;
    }
    /* mc message context pointer may be NULL, e.g., when no response message 
     is received */

    if(op_client->op_ctx)
    {
        msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_client->op_ctx, env);
    }
    else
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "op_ctx is NULL, unable to continue");
        return AXIS2_FAILURE;
    }

    if(msg_ctx_map)
    {
        out_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT];
        in_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN];
    }
    else
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "msg_ctx_map is NULL, unable to continue");
        return AXIS2_FAILURE;
    }

    if(op_client->reuse)
    {
        /* This is the second invocation using the same service client,
         so reset */
        if(out_msg_ctx)
        {
            axis2_msg_ctx_free(out_msg_ctx, env);
            out_msg_ctx = NULL;
            msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT] = NULL;
        }

        if(in_msg_ctx)
        {
            axis2_msg_ctx_free(in_msg_ctx, env);
            in_msg_ctx = NULL;
            msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN] = NULL;
        }

        axis2_op_ctx_set_complete(op_client->op_ctx, env, AXIS2_FALSE);
        op_client->reuse = AXIS2_FALSE;
    }

    if(out_msg_ctx && in_msg_ctx)
    {
        /* may be this is the second invocation using the same service clinet,
         so reset */
        axis2_msg_ctx_free(out_msg_ctx, env);
        out_msg_ctx = NULL;
        msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT] = NULL;
        axis2_msg_ctx_free(in_msg_ctx, env);
        in_msg_ctx = NULL;
        msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN] = NULL;
        axis2_op_ctx_set_complete(op_client->op_ctx, env, AXIS2_FALSE);
    }

    if(!out_msg_ctx)
    {
        msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT] = mc;
    }
    else
    {
        msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN] = mc;
        axis2_op_ctx_set_complete(op_client->op_ctx, env, AXIS2_TRUE);
    }

    if(out_msg_ctx && !mc)
    {
        axutil_property_t *dump_property;
        axis2_char_t *dump_value = NULL;
        if(!axis2_msg_ctx_get_doing_rest(out_msg_ctx, env))
        {
            dump_property = axis2_msg_ctx_get_property(out_msg_ctx, env, AXIS2_DUMP_INPUT_MSG_TRUE);
            if(dump_property)
            {
                dump_value = (axis2_char_t *)axutil_property_get_value(dump_property, env);
            }
        }

        if(axutil_strcmp(dump_value, AXIS2_VALUE_TRUE))
        {
            axis2_msg_ctx_free(out_msg_ctx, env);
            out_msg_ctx = NULL;
            msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT] = NULL;
        }
    }
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_op_client_add_out_msg_ctx(
    axis2_op_client_t * op_client,
    const axutil_env_t * env,
    axis2_msg_ctx_t * mc)
{
    axis2_msg_ctx_t **msg_ctx_map = NULL;

    msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_client->op_ctx, env);

    if(msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT])
    {
        axis2_msg_ctx_free(msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT], env);
    }
    msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT] = mc;

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_op_client_add_in_msg_ctx(
    axis2_op_client_t * op_client,
    const axutil_env_t * env,
    axis2_msg_ctx_t * mc)
{
    axis2_msg_ctx_t **msg_ctx_map = NULL;

    msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_client->op_ctx, env);

    if(msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN])
    {
        axis2_msg_ctx_free(msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN], env);
    }
    msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN] = mc;

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN const axis2_msg_ctx_t *AXIS2_CALL
axis2_op_client_get_msg_ctx(
    const axis2_op_client_t * op_client,
    const axutil_env_t * env,
    const axis2_wsdl_msg_labels_t message_label)
{
    return axis2_op_ctx_get_msg_ctx(op_client->op_ctx, env, message_label);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_op_client_set_callback(
    axis2_op_client_t * op_client,
    const axutil_env_t * env,
    axis2_callback_t * callback)
{
    if(op_client->callback)
    {
        axis2_callback_free(op_client->callback, env);
    }

    op_client->callback = callback;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_callback_t *AXIS2_CALL
axis2_op_client_get_callback(
    axis2_op_client_t * op_client,
    const axutil_env_t * env)
{
    return op_client->callback;
}

/* This function is called from service client irrespective of the message exchange pattern 
 * and whether one/two way channel used.
 */
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_op_client_execute(
    axis2_op_client_t * op_client,
    const axutil_env_t * env,
    const axis2_bool_t block)
{
    axis2_conf_ctx_t *conf_ctx = NULL;
    axis2_msg_ctx_t *msg_ctx = NULL;

    axis2_transport_out_desc_t *transport_out = NULL;
    axis2_transport_in_desc_t *transport_in = NULL;

    axis2_status_t status = AXIS2_FAILURE;
    axis2_op_t *op = NULL;
    axis2_char_t *msg_id = NULL;

    if(op_client->completed)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Op client execute failed. Already completed.");
        return AXIS2_FAILURE;
    }

    conf_ctx = axis2_svc_ctx_get_conf_ctx(op_client->svc_ctx, env);

    msg_ctx = (axis2_msg_ctx_t *)axis2_op_client_get_msg_ctx(op_client, env,
        AXIS2_WSDL_MESSAGE_LABEL_OUT);

    if(!msg_ctx)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "Op client execute failed. Message context is not valid.");
        return AXIS2_FAILURE;
    }

    axis2_msg_ctx_set_options(msg_ctx, env, op_client->options);

    /**
     if the transport to use for sending is not specified, try to find it
     from the URL or the client option.
     */
    transport_out = axis2_options_get_transport_out(op_client->options, env);
    if(!transport_out)
    {
        axis2_endpoint_ref_t *to_epr = NULL;
        axutil_property_t *property = NULL;
        property = axis2_options_get_property(op_client->options, env, AXIS2_TARGET_EPR);
        if(property)
        {
            to_epr = axutil_property_get_value(property, env);
        }

        if(!to_epr)
        {
            to_epr = axis2_options_get_to(op_client->options, env);
        }

        if(!to_epr)
        {
            to_epr = axis2_msg_ctx_get_to(msg_ctx, env);
        }

        transport_out = axis2_op_client_infer_transport(op_client, env, to_epr);
    }

    if(!transport_out)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "Op client execute failed. Cannot find transport out.");
        return AXIS2_FAILURE;
    }

    if(!(axis2_msg_ctx_get_transport_out_desc(msg_ctx, env)))
    {
        axis2_msg_ctx_set_transport_out_desc(msg_ctx, env, transport_out);
    }

    transport_in = axis2_options_get_transport_in(op_client->options, env);
    if(!transport_in)
    {
        axis2_conf_ctx_t *conf_ctx = axis2_svc_ctx_get_conf_ctx(op_client->svc_ctx, env);

        if(conf_ctx)
        {
            axis2_conf_t *conf = axis2_conf_ctx_get_conf(conf_ctx, env);
            if(conf)
            {
                transport_in = axis2_conf_get_transport_in(conf, env,
                    axis2_transport_out_desc_get_enum(transport_out, env));
            }
        }
    }
    if(!transport_in)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "Op client execute failed. Cannot find transport in.");
        return AXIS2_FAILURE;
    }

    if(!(axis2_msg_ctx_get_transport_in_desc(msg_ctx, env)))
    {
        axis2_msg_ctx_set_transport_in_desc(msg_ctx, env, transport_in);
    }

    op = axis2_op_ctx_get_op(op_client->op_ctx, env);

    if(!op)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Op client execute failed. Cannot find operation.");
        return AXIS2_FAILURE;
    }
    status = axis2_op_client_prepare_invocation(op_client, env, op, msg_ctx);
    if(status != AXIS2_SUCCESS)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "Op client execute failed. Preparing for invocation failed.");
        return AXIS2_FAILURE;
    }
    msg_id = (axis2_char_t *)axutil_uuid_gen(env);
    axis2_msg_ctx_set_message_id(msg_ctx, env, msg_id);
    if(msg_id)
    {
        AXIS2_FREE(env->allocator, msg_id);
        msg_id = NULL;
    }

    /* If dual channel. */
    if(axis2_options_get_use_separate_listener(op_client->options, env))
    {
        axis2_engine_t *engine = NULL;

        if(op_client->callback)
        {
            AXIS2_CALLBACK_RECV_ADD_CALLBACK(op_client->callback_recv, env,
                axis2_msg_ctx_get_msg_id(msg_ctx, env), op_client->callback);
        }

        axis2_msg_ctx_set_op_ctx(msg_ctx, env, axis2_op_find_op_ctx(op, env, msg_ctx,
            op_client-> svc_ctx));
        axis2_msg_ctx_set_svc_ctx(msg_ctx, env, op_client->svc_ctx);

        /* send the message */
        engine = axis2_engine_create(env, conf_ctx);
        if(!engine)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                "Op client execute failed due to engine creation failure.");
            return AXIS2_FAILURE;
        }
        axis2_engine_send(engine, env, msg_ctx);
        axis2_engine_free(engine, env);
    }
    else /* Same channel will be used irrespective of message exchange pattern. */
    {
        if(block)
        {
            axis2_msg_ctx_t *response_mc = NULL;

            axis2_msg_ctx_set_svc_ctx(msg_ctx, env, op_client->svc_ctx);
            axis2_msg_ctx_set_conf_ctx(msg_ctx, env, axis2_svc_ctx_get_conf_ctx(
                op_client-> svc_ctx, env));
            axis2_msg_ctx_set_op_ctx(msg_ctx, env, op_client->op_ctx);

            /*Send the SOAP Message and receive a response */
            response_mc = axis2_op_client_two_way_send(env, msg_ctx);
            if(!response_mc)
            {
                const axis2_char_t *mep = axis2_op_get_msg_exchange_pattern(op, env);
                if(!(axutil_strcmp(mep, AXIS2_MEP_URI_OUT_ONLY)) || !(axutil_strcmp(mep,
                    AXIS2_MEP_URI_ROBUST_OUT_ONLY)))
                {
                    if(env->error)
                    {
                        return env->error->status_code;
                    }
                    else
                    {
                        return AXIS2_FAILURE;
                    }
                }
                else
                {
                    return AXIS2_FAILURE;
                }
            }
            axis2_op_client_add_msg_ctx(op_client, env, response_mc);
        }
        else
        {
            axis2_op_client_worker_func_args_t *arg_list = NULL;
            arg_list = AXIS2_MALLOC(env->allocator, sizeof(axis2_op_client_worker_func_args_t));
            if(!arg_list)
            {
                AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                    "No memory. Cannot create op client worker function argument list.");
                return AXIS2_FAILURE;
            }
            arg_list->env = env;
            arg_list->op_client = op_client;
            arg_list->callback = op_client->callback;
            arg_list->op = op;
            arg_list->msg_ctx = msg_ctx;
#ifdef AXIS2_SVR_MULTI_THREADED
            if (env->thread_pool)
            {
				axutil_thread_t *worker_thread = NULL;
                worker_thread = axutil_thread_pool_get_thread(env->thread_pool,
                    axis2_op_client_worker_func,
                    (void *)
                    arg_list);
                if (!worker_thread)
                {
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                        "Thread creation failed call invoke non blocking");
                }
                else
                {
                    axutil_thread_pool_thread_detach(env->thread_pool,
                        worker_thread);
                }
            }
            else
            {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                    "Thread pool not set in environment"
                    "Cannot invoke call non blocking");
            }
#else
            axis2_op_client_worker_func(NULL, (void *)arg_list);
#endif

        }
    }
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_op_client_reset(
    axis2_op_client_t * op_client,
    const axutil_env_t * env)
{
    if(!op_client->completed)
        return AXIS2_FAILURE;

    op_client->completed = AXIS2_FALSE;

    op_client->op_ctx = NULL;

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_op_client_complete(
    axis2_op_client_t * op_client,
    const axutil_env_t * env,
    axis2_msg_ctx_t * mc)
{
    axis2_conf_ctx_t *conf_ctx = NULL;
    axis2_listener_manager_t *listener_manager = NULL;
    AXIS2_TRANSPORT_ENUMS transport = AXIS2_TRANSPORT_ENUM_HTTP;

    conf_ctx = axis2_msg_ctx_get_conf_ctx(mc, env);

    if(!conf_ctx)
        return AXIS2_FAILURE;

    if(!listener_manager)
        return AXIS2_FAILURE;

    return axis2_listener_manager_stop(listener_manager, env, transport);
}

AXIS2_EXTERN axis2_op_ctx_t *AXIS2_CALL
axis2_op_client_get_operation_context(
    const axis2_op_client_t * op_client,
    const axutil_env_t * env)
{
    return op_client->op_ctx;
}

AXIS2_EXTERN void AXIS2_CALL
axis2_op_client_free(
    axis2_op_client_t * op_client,
    const axutil_env_t * env)
{
    if(!op_client)
        return;

    /*if(op_client->callback)
    {
        axis2_callback_free(op_client->callback, env);
    }*/

    if(op_client->op_ctx)
    {
        axis2_op_ctx_free(op_client->op_ctx, env);
        op_client->op_ctx = NULL;
    }

    if(op_client->soap_version_uri)
    {
        AXIS2_FREE(env->allocator, op_client->soap_version_uri);
    }

    if(op_client->mep)
    {
        AXIS2_FREE(env->allocator, op_client->mep);
    }

    if(axis2_options_get_xml_parser_reset(op_client->options, env))
    {
        axiom_xml_reader_cleanup();
    }

    AXIS2_FREE(env->allocator, op_client);
}

/* This function is the thread worker function for the single channel non blocking case. Here
 * being non-blocking implies that message is two way. */
void *AXIS2_THREAD_FUNC
axis2_op_client_worker_func(
    axutil_thread_t * thd,
    void *data)
{
    axis2_op_client_worker_func_args_t *args_list = NULL;
    axis2_op_ctx_t *op_ctx = NULL;
    axis2_msg_ctx_t *response = NULL;
    axutil_env_t *th_env = NULL;
    axutil_thread_pool_t *th_pool = NULL;

    args_list = (axis2_op_client_worker_func_args_t *)data;
    if(!args_list)
    {
        return NULL;
    }

    th_env = axutil_init_thread_env(args_list->env);

    op_ctx = axis2_op_ctx_create(th_env, args_list->op, args_list->op_client->svc_ctx);
    if(!op_ctx)
    {
        return NULL;
    }
    axis2_msg_ctx_set_op_ctx(args_list->msg_ctx, th_env, op_ctx);
    axis2_msg_ctx_set_svc_ctx(args_list->msg_ctx, th_env, args_list->op_client->svc_ctx);

    /* send the request and wait for response */
    response = axis2_op_client_two_way_send(th_env, args_list->msg_ctx);

    /* We do not need to handle the NULL response here because this thread function is called only
     * in the single channel non blocking case which, imply this is two way message by design.
     */

    /* Here after the code is a subset of what callback receiver do in dual channel case.*/
    axis2_op_client_add_msg_ctx(args_list->op_client, th_env, response);
    args_list->op_client->async_result = axis2_async_result_create(th_env, response);

    if(args_list->callback)
    {
        axis2_callback_invoke_on_complete(args_list->callback, th_env,
            args_list->op_client->async_result);

        axis2_callback_set_complete(args_list->callback, th_env, AXIS2_TRUE);
    }

    /* Clean up memory */
    axis2_async_result_free(args_list->op_client->async_result, th_env);

    axis2_op_ctx_free(op_ctx, th_env);

    th_pool = th_env->thread_pool;

    AXIS2_FREE(th_env->allocator, args_list);

    if(th_env)
    {
        axutil_free_thread_env(th_env);
        th_env = NULL;
    }
    axutil_thread_pool_exit_thread(th_pool, thd);
    return NULL;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_op_client_set_callback_recv(
    axis2_op_client_t * op_client,
    const axutil_env_t * env,
    axis2_callback_recv_t * callback_recv)
{
    op_client->callback_recv = callback_recv;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axutil_string_t *AXIS2_CALL
axis2_op_client_get_soap_action(
    const axis2_op_client_t * op_client,
    const axutil_env_t * env)
{
    return op_client->soap_action;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_op_client_prepare_invocation(
    axis2_op_client_t * op_client,
    const axutil_env_t * env,
    axis2_op_t * op,
    axis2_msg_ctx_t * msg_ctx)
{
    axis2_svc_t *svc = NULL;

    AXIS2_PARAM_CHECK(env->error, op, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);

    /* make sure operation's MEP is the same as given MEP */
    if(op_client->mep)
    {
        if(axutil_strcmp(op_client->mep, axis2_op_get_msg_exchange_pattern(op, env)))
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MEP_MISMATCH_IN_MEP_CLIENT, AXIS2_FAILURE);
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                "Message exchange pattern of op client and operation are different.");
            return AXIS2_FAILURE;
        }
    }
    else
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MEP_CANNOT_BE_NULL_IN_MEP_CLIENT, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "Message exchange pattern of op client is not valid.");
        return AXIS2_FAILURE;
    }
    /* If operation has a parent service get it */
    svc = axis2_op_get_parent(op, env);
    if(svc)
    {
        axis2_svc_ctx_set_svc(op_client->svc_ctx, env, svc);
    }
    else
    {
        svc = axis2_svc_ctx_get_svc(op_client->svc_ctx, env);
        if(svc)
        {
            axis2_op_t *temp_op = NULL;
            const axutil_qname_t *op_qname = axis2_op_get_qname(op, env);
            temp_op = axis2_svc_get_op_with_qname(svc, env, op_qname);
            if(!temp_op)
            {
                axis2_svc_add_op(svc, env, op);
            }
        }
    }

    if(op_client->wsa_action)
    {
        axis2_msg_ctx_set_wsa_action(msg_ctx, env, op_client->wsa_action);
    }

    if(op_client->soap_action)
    {
        axis2_msg_ctx_set_soap_action(msg_ctx, env, op_client->soap_action);
    }

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_msg_ctx_t *AXIS2_CALL
axis2_op_client_prepare_soap_envelope(
    axis2_op_client_t * op_client,
    const axutil_env_t * env,
    axiom_node_t * to_send)
{
    axis2_msg_ctx_t *msg_ctx = NULL;
    axiom_soap_envelope_t *envelope = NULL;
    int soap_version = AXIOM_SOAP12;

    if(op_client->svc_ctx)
    {
        msg_ctx = axis2_msg_ctx_create(env, axis2_svc_ctx_get_conf_ctx(op_client-> svc_ctx, env),
            NULL, NULL);
    }

    if(!msg_ctx)
    {
        return NULL;
    }

    if(op_client->soap_version_uri)
    {
        if(!(axutil_strcmp(op_client->soap_version_uri, AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI)))
            soap_version = AXIOM_SOAP11;
        else
            soap_version = AXIOM_SOAP12;
    }

    envelope = axiom_soap_envelope_create_default_soap_envelope(env, soap_version);
    if(!envelope)
    {
        return NULL;
    }

    if(to_send)
    {
        axiom_soap_body_t *soap_body = NULL;
        soap_body = axiom_soap_envelope_get_body(envelope, env);
        if(soap_body)
        {
            axiom_node_t *node = NULL;
            node = axiom_soap_body_get_base_node(soap_body, env);
            if(node)
            {
                axiom_node_add_child(node, env, to_send);
            }
        }
    }

    axis2_msg_ctx_set_soap_envelope(msg_ctx, env, envelope);

    return msg_ctx;
}

AXIS2_EXTERN axis2_transport_out_desc_t *AXIS2_CALL
axis2_op_client_infer_transport(
    axis2_op_client_t * op_client,
    const axutil_env_t * env,
    axis2_endpoint_ref_t * epr)
{
    axis2_char_t *transport = NULL;
    axis2_transport_out_desc_t *transport_out_desc = NULL;
    axis2_conf_ctx_t *conf_ctx = NULL;
    axis2_conf_t *conf = NULL;
    AXIS2_TRANSPORT_ENUMS transport_enum = AXIS2_TRANSPORT_ENUM_MAX;

    AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Start:axis2_op_client_infer_transport");

    /* We first try the client option */
    transport_enum = axis2_options_get_sender_transport_protocol(op_client->options, env);
    if(transport_enum == AXIS2_TRANSPORT_ENUM_MAX)
    {
        /* If we couldn't find the transport we default to HTTP */
        transport_enum = AXIS2_TRANSPORT_ENUM_HTTP;
        /* We try to infer transport from the url */
        if(epr)
        {
            const axis2_char_t *to_url = axis2_endpoint_ref_get_address(epr, env);

            transport = axis2_op_client_get_transport_from_url(to_url, env);
        }

        if(transport)
        {
            if(!axutil_strcmp(transport, AXIS2_TRANSPORT_HTTP))
            {
                transport_enum = AXIS2_TRANSPORT_ENUM_HTTP;
            }
            else if(!axutil_strcmp(transport, AXIS2_TRANSPORT_HTTPS))
            {
                transport_enum = AXIS2_TRANSPORT_ENUM_HTTPS;
            }
            else if(!axutil_strcmp(transport, AXIS2_TRANSPORT_XMPP))
            {
                transport_enum = AXIS2_TRANSPORT_ENUM_XMPP;
            }
            else if(!axutil_strcmp(transport, AXIS2_TRANSPORT_TCP))
            {
                transport_enum = AXIS2_TRANSPORT_ENUM_TCP;
            }
            else if(!axutil_strcmp(transport, AXIS2_TRANSPORT_AMQP))
            {
                transport_enum = AXIS2_TRANSPORT_ENUM_AMQP;
            }
            else if(!axutil_strcmp(transport, AXIS2_TRANSPORT_UDP))
            {
                transport_enum = AXIS2_TRANSPORT_ENUM_UDP;
            }

            AXIS2_FREE(env->allocator, transport);
            transport = NULL;
        }
    }
    conf_ctx = axis2_svc_ctx_get_conf_ctx(op_client->svc_ctx, env);
    if(conf_ctx)
    {
        conf = axis2_conf_ctx_get_conf(conf_ctx, env);
        if(conf)
        {
            transport_out_desc = axis2_conf_get_transport_out(conf, env, transport_enum);
        }
    }
    if(!transport_out_desc)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot infer transport");
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_CANNOT_INFER_TRANSPORT, AXIS2_FAILURE);
    }
    AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "End:axis2_op_client_infer_transport");
    return transport_out_desc;
}

AXIS2_EXTERN axiom_soap_envelope_t *AXIS2_CALL
axis2_op_client_create_default_soap_envelope(
    axis2_op_client_t * op_client,
    const axutil_env_t * env)
{
    axiom_soap_envelope_t *envelope = NULL;

    if(!(axutil_strcmp(AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI, op_client->soap_version_uri)))
    {
        envelope = axiom_soap_envelope_create_with_soap_version_prefix(env, AXIOM_SOAP12, NULL);
    }

    if(!(axutil_strcmp(AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI, op_client->soap_version_uri)))
    {
        envelope = axiom_soap_envelope_create_with_soap_version_prefix(env, AXIOM_SOAP11, NULL);
    }
    return envelope;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_op_client_engage_module(
    axis2_op_client_t * op_client,
    const axutil_env_t * env,
    const axutil_qname_t * qname)
{
    axis2_conf_ctx_t *conf_ctx = NULL;
    axis2_conf_t *conf = NULL;

    if(op_client->svc_ctx)
    {
        conf_ctx = axis2_svc_ctx_get_conf_ctx(op_client->svc_ctx, env);
        if(conf_ctx)
        {
            conf = axis2_conf_ctx_get_conf(conf_ctx, env);
            if(conf)
            {
                /*if it is already engaged do not engage it again */
                if(!(axis2_conf_is_engaged(conf, env, qname)))
                {
                    return axis2_conf_engage_module(conf, env, qname);
                }
            }
        }
    }

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_op_client_set_soap_version_uri(
    axis2_op_client_t * op_client,
    const axutil_env_t * env,
    const axis2_char_t * soap_version_uri)
{
    if(op_client->soap_version_uri)
    {
        AXIS2_FREE(env->allocator, op_client->soap_version_uri);
        op_client->soap_version_uri = NULL;
    }

    if(soap_version_uri)
    {
        op_client->soap_version_uri = axutil_strdup(env, soap_version_uri);
        if(!(op_client->soap_version_uri))
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create soap version uri.");
            return AXIS2_FAILURE;
        }
    }

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_op_client_set_soap_action(
    axis2_op_client_t * op_client,
    const axutil_env_t * env,
    axutil_string_t * soap_action)
{
    if(op_client->soap_action)
    {
        axutil_string_free(op_client->soap_action, env);
        op_client->soap_action = NULL;
    }

    if(soap_action)
    {
        op_client->soap_action = axutil_string_clone(soap_action, env);
        if(!(op_client->soap_action))
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create soap action.");
            return AXIS2_FAILURE;
        }
    }

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_op_client_set_wsa_action(
    axis2_op_client_t * op_client,
    const axutil_env_t * env,
    const axis2_char_t * wsa_action)
{
    if(op_client->wsa_action)
    {
        AXIS2_FREE(env->allocator, op_client->wsa_action);
        op_client->wsa_action = NULL;
    }

    if(wsa_action)
    {
        op_client->wsa_action = axutil_strdup(env, wsa_action);
        if(!(op_client->wsa_action))
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create wsa action.");
            return AXIS2_FAILURE;
        }
    }

    return AXIS2_SUCCESS;
}

static axis2_char_t *AXIS2_CALL
axis2_op_client_get_transport_from_url(
    const axis2_char_t * url,
    const axutil_env_t * env)
{
    axis2_char_t *transport = NULL;
    const axis2_char_t *start = NULL;
    const axis2_char_t *end = NULL;
    AXIS2_PARAM_CHECK(env->error, url, NULL);
    start = url;
    end = url;
    while((*end) && (*end) != ':')
        end++;

    if((*end) == ':')
    {
        const axis2_char_t *c = NULL;
        transport = AXIS2_MALLOC(env->allocator, (end - start + 1) * sizeof(char));
        if(!transport)
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                "No memory. Cannot create transport protocol identifier.");
            return NULL;
        }

        for(c = start; c < end; c++)
            transport[c - start] = *c;
        transport[c - start] = '\0';
    }
    else
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "URL is malformed or does not contain a transport protocol");
    }
    return transport;
}

AXIS2_EXTERN axis2_svc_ctx_t *AXIS2_CALL
axis2_op_client_get_svc_ctx(
    const axis2_op_client_t * op_client,
    const axutil_env_t * env)
{
    return op_client->svc_ctx;
}

/* This function is called only for single channel invocations */
AXIS2_EXTERN axis2_msg_ctx_t *AXIS2_CALL
axis2_op_client_two_way_send(
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx)
{
    axis2_engine_t *engine = NULL;
    axis2_status_t status = AXIS2_SUCCESS;
    axis2_msg_ctx_t *response = NULL;
    axis2_conf_ctx_t *conf_ctx = NULL;
    axis2_op_t *op = NULL;
    axiom_soap_envelope_t *response_envelope = NULL;
    axutil_property_t *property = NULL;
    long index = -1;
    axis2_bool_t wait_indefinitely = AXIS2_FALSE;
    axis2_char_t *mep = NULL;
    axis2_char_t *msg_id = NULL;

    conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
    engine = axis2_engine_create(env, conf_ctx);
    if(!engine)
        return NULL;
    property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_TIMEOUT_IN_SECONDS);
    if(property)
    {
        axis2_char_t *value = axutil_property_get_value(property, env);
        if(value)
            index = AXIS2_ATOI(value);
        if(index == -1)
        {
            wait_indefinitely = AXIS2_TRUE;
            index = 1;
        }
    }

    status = axis2_engine_send(engine, env, msg_ctx);

    axis2_engine_free(engine, env);
    engine = NULL;

    if(status != AXIS2_SUCCESS)
    {
        if(AXIS2_ERROR_GET_STATUS_CODE(env->error) == AXIS2_SUCCESS)
        {
            AXIS2_ERROR_SET_STATUS_CODE(env->error, AXIS2_FAILURE);
        }
        return NULL;
    }

    op = axis2_msg_ctx_get_op(msg_ctx, env);
    if(op)
    {
        mep = (axis2_char_t *)axis2_op_get_msg_exchange_pattern(op, env);
    }

    if(!mep)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MEP_CANNOT_DETERMINE_MEP, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot determine message exchange pattern.");
        return NULL;
    }

    /* handle one way non robust case */
    if(!(axutil_strcmp(mep, AXIS2_MEP_URI_OUT_ONLY)))
    {
        return NULL;
    }

    /* create the response */
    response = axis2_msg_ctx_create(env, conf_ctx,
        axis2_msg_ctx_get_transport_in_desc(msg_ctx, env), axis2_msg_ctx_get_transport_out_desc(
            msg_ctx, env));
    if(!response)
        return NULL;

    axis2_msg_ctx_set_server_side(response, env, AXIS2_FALSE);
    axis2_msg_ctx_set_conf_ctx(response, env, axis2_msg_ctx_get_conf_ctx(msg_ctx, env));
    axis2_msg_ctx_set_svc_grp_ctx(response, env, axis2_msg_ctx_get_svc_grp_ctx(msg_ctx, env));

    msg_id = (axis2_char_t *)axutil_uuid_gen(env);
    axis2_msg_ctx_set_message_id(response, env, msg_id);
    if(msg_id)
    {
        AXIS2_FREE(env->allocator, msg_id);
        msg_id = NULL;
    }
	
    /* If request is REST we assume the response is REST, so set the variable */
    axis2_msg_ctx_set_doing_rest(response, env, axis2_msg_ctx_get_doing_rest(msg_ctx, env));
    axis2_msg_ctx_set_status_code(response, env, axis2_msg_ctx_get_status_code(msg_ctx, env));

    if(op)
    {
        axis2_op_register_op_ctx(op, env, response, axis2_msg_ctx_get_op_ctx(msg_ctx, env));
    }

    /* set response envelope */
    if(engine)
    {
        axis2_engine_free(engine, env);
        engine = NULL;
    }
    response_envelope = axis2_msg_ctx_get_response_soap_envelope(msg_ctx, env);
    if(response_envelope)
    {
		axiom_soap_body_t * soap_body = NULL;
		axis2_bool_t has_fault = AXIS2_FALSE;
        axis2_msg_ctx_set_soap_envelope(response, env, response_envelope);
		soap_body = axiom_soap_envelope_get_body(response_envelope, env);
		has_fault = axiom_soap_body_has_fault(soap_body, env);
        
        engine = axis2_engine_create(env, conf_ctx);
        if(engine)
        {
            property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HANDLER_ALREADY_VISITED);
            if(property)
            {
                axis2_char_t *value = axutil_property_get_value(property, env);
                if(!axutil_strcmp(AXIS2_VALUE_TRUE, value))
                {
                    if(engine)
                    {
                        axis2_engine_free(engine, env);
                    }
                    return response;
                }
            }
			if(has_fault)
			{
				 status = axis2_engine_receive_fault(engine, env, msg_ctx);
			}
			else
			{
				status = axis2_engine_receive(engine, env, response);
			}
			if(status != AXIS2_SUCCESS )  
				return NULL;
		}
    }
    else
    {
        while(!response_envelope && index > 0)
        {
            /*wait till the response arrives */
            AXIS2_SLEEP(1);
            if(!wait_indefinitely)
                index--;
            response_envelope = axis2_msg_ctx_get_response_soap_envelope(msg_ctx, env);
        }
        /* if it is a two way message, then the status should be in error,
         else it is a one way message */
        if(response_envelope)
        {
            axis2_msg_ctx_set_soap_envelope(response, env, response_envelope);
            /* There could be a scenariao where the message has already passed
             * through the incoming phases. eg. Reliable Messaging 1.0 two
             * way single channel
             */
            property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HANDLER_ALREADY_VISITED);
            if(property)
            {
                axis2_char_t *value = axutil_property_get_value(property, env);
                if(!axutil_strcmp(AXIS2_VALUE_TRUE, value))
                {
                    return response;
                }
            }
            engine = axis2_engine_create(env, conf_ctx);
            if(engine)
            {
                status = axis2_engine_receive(engine, env, response);
                if(status != AXIS2_SUCCESS)
                    return NULL;
            }
        }
        else
        {
            if(AXIS2_ERROR_GET_STATUS_CODE(env->error) != AXIS2_SUCCESS)
            {
                AXIS2_ERROR_SET(env->error, AXIS2_ERROR_BLOCKING_INVOCATION_EXPECTS_RESPONSE,
                    AXIS2_FAILURE);
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                    "Response is not valid. Blocking invocation expects response.");
                if(engine)
                {
                    axis2_engine_free(engine, env);
                    engine = NULL;
                }
                axis2_msg_ctx_free(response, env);
                return NULL;
            }
        }
    }

    /*following is no longer valid. Just keeping for others view*/

    /* property is NULL, and we set null for AXIS2_TRANSPORT_IN in msg_ctx to
     avoid double free of this property */
    /*axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_TRANSPORT_IN, property);*/

    if(engine)
    {
        axis2_engine_free(engine, env);
        engine = NULL;
    }
    if(!(axutil_strcmp(mep, AXIS2_MEP_URI_ROBUST_OUT_ONLY)) && response)
    {
        if(axis2_msg_ctx_get_doing_rest(response, env) && axis2_msg_ctx_get_status_code(response,
            env) >= 400)
        {
            /* All HTTP 4xx and 5xx status codes are treated as errors */
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_HTTP_CLIENT_TRANSPORT_ERROR, AXIS2_FAILURE);
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "HTTP client transport error.");
            return NULL;
        }
        switch(axis2_msg_ctx_get_status_code(response, env))
        {
            /* In a SOAP request HTTP status code 500 is used for errors */
            case 500:
                AXIS2_ERROR_SET(env->error, AXIS2_ERROR_HTTP_CLIENT_TRANSPORT_ERROR, AXIS2_FAILURE);
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "HTTP client transport error.");
                break;
            case 0:
                AXIS2_ERROR_SET(env->error, AXIS2_ERROR_BLOCKING_INVOCATION_EXPECTS_RESPONSE,
                    AXIS2_FAILURE);
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                    "Response is not valid. Blocking invocation expects response.");
                break;
            case -1:
                AXIS2_ERROR_SET(env->error, AXIS2_ERROR_BLOCKING_INVOCATION_EXPECTS_RESPONSE,
                    AXIS2_FAILURE);
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                    "Response is not valid. Blocking invocation expects response.");
                break;
        }

        if(response)
        {
            axis2_msg_ctx_free(response, env);
        }

        return NULL;
    }
    return response;
}

AXIS2_EXTERN axis2_msg_ctx_t *AXIS2_CALL
axis2_op_client_receive(
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx)
{
    axis2_engine_t *engine = NULL;
    axis2_status_t status = AXIS2_SUCCESS;
    axis2_msg_ctx_t *response = NULL;
    axis2_conf_ctx_t *conf_ctx = NULL;
    axis2_op_t *op = NULL;
    axiom_soap_envelope_t *response_envelope = NULL;
    axutil_property_t *property = NULL;

    /* create the response */
    response = axis2_msg_ctx_create(env, conf_ctx,
        axis2_msg_ctx_get_transport_in_desc(msg_ctx, env), axis2_msg_ctx_get_transport_out_desc(
            msg_ctx, env));
    if(!response)
        return NULL;

    property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_TRANSPORT_IN);
    if(property)
    {
        axis2_msg_ctx_set_property(response, env, AXIS2_TRANSPORT_IN, property);
        property = NULL;
    }

    op = axis2_msg_ctx_get_op(msg_ctx, env);
    if(op)
    {
        axis2_op_register_op_ctx(op, env, response, axis2_msg_ctx_get_op_ctx(msg_ctx, env));
    }
    axis2_msg_ctx_set_server_side(response, env, AXIS2_FALSE);
    axis2_msg_ctx_set_conf_ctx(response, env, axis2_msg_ctx_get_conf_ctx(msg_ctx, env));
    axis2_msg_ctx_set_svc_grp_ctx(response, env, axis2_msg_ctx_get_svc_grp_ctx(msg_ctx, env));

    /* If request is REST we assume the response is REST, so set the variable */
    axis2_msg_ctx_set_doing_rest(response, env, axis2_msg_ctx_get_doing_rest(msg_ctx, env));

    response_envelope = axis2_msg_ctx_get_response_soap_envelope(msg_ctx, env);
    if(response_envelope)
    {
        axis2_msg_ctx_set_soap_envelope(response, env, response_envelope);
        if(engine)
        {
            axis2_engine_free(engine, env);
            engine = NULL;
        }

        engine = axis2_engine_create(env, conf_ctx);
        if(engine)
        {
            status = axis2_engine_receive(engine, env, response);
            if(status != AXIS2_SUCCESS)
            {
                return NULL;
            }
        }

    }
    else
    {
        /* if it is a two way message, then the status should be in error,
         else it is a one way message */
        if(AXIS2_ERROR_GET_STATUS_CODE(env->error) != AXIS2_SUCCESS)
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_BLOCKING_INVOCATION_EXPECTS_RESPONSE,
                AXIS2_FAILURE);
            return NULL;
        }
    }

    /* property is NULL, and we set null for AXIS2_TRANSPORT_IN in msg_ctx to
     avoid double free of this property */
    axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_TRANSPORT_IN, property);

    if(engine)
    {
        axis2_engine_free(engine, env);
        engine = NULL;
    }
    return response;
}

AXIS2_EXTERN void AXIS2_CALL
axis2_op_client_set_reuse(
    axis2_op_client_t * op_client,
    const axutil_env_t * env,
    axis2_bool_t reuse)
{
    op_client->reuse = reuse;
}

