/*
 * 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_svc_client.h>
#include <axis2_phases_info.h>
#include <axis2_const.h>
#include <axutil_hash.h>
#include <axutil_uri.h>
#include "axis2_callback_recv.h"
#include <axiom_soap_const.h>
#include <axiom_soap_body.h>
#include <axiom_soap_header.h>
#include <axiom_util.h>
#include <axis2_listener_manager.h>
#include <axis2_module_desc.h>
#include <axutil_array_list.h>
#include <axis2_options.h>
#include <axis2_conf_init.h>
#include <platforms/axutil_platform_auto_sense.h>
#include <stdio.h>
#include <axutil_generic_obj.h>
#include <axis2_http_transport.h>
#include <axis2_http_header.h>
#include <neethi_util.h>
#include <axis2_policy_include.h>

struct axis2_svc_client
{
    axis2_svc_t *svc;

    axis2_conf_t *conf;

    axis2_conf_ctx_t *conf_ctx;

    axis2_svc_ctx_t *svc_ctx;

    axis2_options_t *options;

    axis2_options_t *override_options;

    /* SOAP Headers */
    axutil_array_list_t *headers;

    /* for receiving the async messages */
    axis2_callback_recv_t *callback_recv;

    axis2_listener_manager_t *listener_manager;

    axis2_op_client_t *op_client;

    axiom_soap_envelope_t *last_response_soap_envelope;

    axis2_bool_t last_response_has_fault;

    axis2_bool_t reuse;

    axis2_bool_t auth_failed;

    axis2_bool_t required_auth_is_http;

    axis2_char_t *auth_type;

    axutil_array_list_t *http_headers;

    int http_status_code;

    axis2_bool_t keep_externally_passed_ctx_and_svc;

};

static void
axis2_svc_client_set_http_info(
    axis2_svc_client_t * svc_client,
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx);

static axis2_svc_t *
axis2_svc_client_create_annonymous_svc(
    axis2_svc_client_t * svc_client,
    const axutil_env_t * env);

static axis2_bool_t
axis2_svc_client_init_transports_from_conf_ctx(
    const axutil_env_t * env,
    axis2_svc_client_t * svc_client,
    axis2_conf_ctx_t * conf_ctx,
    const axis2_char_t * client_home);

static axis2_bool_t
axis2_svc_client_init_data(
    const axutil_env_t * env,
    axis2_svc_client_t * svc_client);

static axis2_bool_t
axis2_svc_client_fill_soap_envelope(
    const axutil_env_t * env,
    axis2_svc_client_t * svc_client,
    axis2_msg_ctx_t * msg_ctx,
    const axiom_node_t * payload);

AXIS2_EXTERN axis2_svc_client_t *AXIS2_CALL
axis2_svc_client_create(
    const axutil_env_t * env,
    const axis2_char_t * client_home)
{
    axis2_svc_client_t *svc_client = NULL;

    AXIS2_ENV_CHECK(env, NULL);
    svc_client = axis2_svc_client_create_with_conf_ctx_and_svc(env, client_home, NULL, NULL);

    return svc_client;
}

AXIS2_EXTERN axis2_svc_client_t *AXIS2_CALL
axis2_svc_client_create_with_conf_ctx_and_svc(
    const axutil_env_t * env,
    const axis2_char_t * client_home,
    axis2_conf_ctx_t * conf_ctx,
    axis2_svc_t * svc)
{
    axis2_svc_client_t *svc_client = NULL;
    axis2_svc_grp_t *svc_grp = NULL;
    axis2_svc_grp_ctx_t *svc_grp_ctx = NULL;
    const axis2_char_t *svc_grp_name = NULL;

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

    svc_client->svc = NULL;
    svc_client->conf = NULL;
    svc_client->conf_ctx = NULL;
    svc_client->svc_ctx = NULL;
    svc_client->options = NULL;
    svc_client->override_options = NULL;
    svc_client->headers = NULL;
    svc_client->callback_recv = NULL;
    svc_client->listener_manager = NULL;
    svc_client->op_client = NULL;
    svc_client->last_response_soap_envelope = NULL;
    svc_client->last_response_has_fault = AXIS2_FALSE;
    svc_client->reuse = AXIS2_FALSE;
    svc_client->auth_failed = AXIS2_FALSE;
    svc_client->required_auth_is_http = AXIS2_FALSE;
    svc_client->auth_type = NULL;
    svc_client->http_headers = NULL;
    svc_client->keep_externally_passed_ctx_and_svc = AXIS2_FALSE;

    if(!axis2_svc_client_init_data(env, svc_client))
    {
        axis2_svc_client_free(svc_client, env);
        return NULL;
    }

    /*create the default conf_ctx if it is NULL */
    if(!axis2_svc_client_init_transports_from_conf_ctx(env, svc_client, conf_ctx, client_home))
    {
        axis2_svc_client_free(svc_client, env);
        return NULL;
    }

    svc_client->conf = axis2_conf_ctx_get_conf(svc_client->conf_ctx, env);

    if(svc)
    {
        svc_client->keep_externally_passed_ctx_and_svc = AXIS2_TRUE;
        svc_client->svc = svc;
    }
    else
    {
        svc_client->svc = axis2_svc_client_create_annonymous_svc(svc_client, env);
        if(!svc_client->svc)
        {
            axis2_svc_client_free(svc_client, env);
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot create annonymous service.");
            return NULL;
        }
    }

    /** add the service to the config context if it isn't in there already */
    if(!axis2_conf_get_svc(svc_client->conf, env, axis2_svc_get_name(svc_client->svc, env)))
    {
        axis2_conf_add_svc(svc_client->conf, env, svc_client->svc);
    }

    /** create a service context for myself: create a new service group
     context and then get the service context for myself as I'll need that
     later for stuff that I gotta do */
    svc_grp = axis2_svc_get_parent(svc_client->svc, env);
    if(!svc_grp)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot access service group of service client.");
        return NULL;
    }

    svc_grp_ctx = axis2_svc_grp_get_svc_grp_ctx(svc_grp, env, svc_client->conf_ctx);
    if(!svc_grp_ctx)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "Cannot access service group context of service client.");
        return NULL;
    }

    svc_grp_name = axis2_svc_grp_get_name(svc_grp, env);
    if(!svc_grp_name)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "Cannot access service group name of service client.");
        return NULL; /* service group name is mandatory */
    }

    axis2_conf_ctx_register_svc_grp_ctx(svc_client->conf_ctx, env, svc_grp_name, svc_grp_ctx);

    svc_client->svc_ctx = axis2_svc_grp_ctx_get_svc_ctx(svc_grp_ctx, env, axis2_svc_get_name(
        svc_client->svc, env));

    return svc_client;
}

AXIS2_EXTERN axis2_svc_t *AXIS2_CALL
axis2_svc_client_get_svc(
    const axis2_svc_client_t * svc_client,
    const axutil_env_t * env)
{
    AXIS2_PARAM_CHECK(env->error, svc_client, NULL);
    return svc_client->svc;
}

AXIS2_EXTERN axis2_conf_ctx_t *AXIS2_CALL
axis2_svc_client_get_conf_ctx(
    const axis2_svc_client_t * svc_client,
    const axutil_env_t * env)
{
    AXIS2_PARAM_CHECK(env->error, svc_client, NULL);
    return svc_client->conf_ctx;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_svc_client_set_options(
    axis2_svc_client_t * svc_client,
    const axutil_env_t * env,
    const axis2_options_t * options)
{
    AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE);
    if(svc_client->options)
    {
        axis2_options_free(svc_client->options, env);
    }
    svc_client->options = (axis2_options_t *)options;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN const axis2_options_t *AXIS2_CALL
axis2_svc_client_get_options(
    const axis2_svc_client_t * svc_client,
    const axutil_env_t * env)
{
    AXIS2_PARAM_CHECK(env->error, svc_client, NULL);
    return svc_client->options;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_svc_client_set_override_options(
    axis2_svc_client_t * svc_client,
    const axutil_env_t * env,
    const axis2_options_t * override_options)
{
    AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE);
    if(svc_client->override_options)
    {
        axis2_options_free(svc_client->override_options, env);
    }

    svc_client->override_options = (axis2_options_t *)override_options;

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN const axis2_options_t *AXIS2_CALL
axis2_svc_client_get_override_options(
    const axis2_svc_client_t * svc_client,
    const axutil_env_t * env)
{
    AXIS2_PARAM_CHECK(env->error, svc_client, NULL);
    return svc_client->override_options;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_svc_client_engage_module(
    axis2_svc_client_t * svc_client,
    const axutil_env_t * env,
    const axis2_char_t * module_name)
{
    axis2_module_desc_t *module = NULL;
    axutil_qname_t *mod_qname = NULL;

    AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, module_name, AXIS2_FAILURE);

    mod_qname = axutil_qname_create(env, module_name, NULL, NULL);

    if(!mod_qname)
    {
        return AXIS2_FAILURE;
    }

    module = axis2_conf_get_module(svc_client->conf, env, mod_qname);

    axutil_qname_free(mod_qname, env);
    mod_qname = NULL;

    if(module)
    {
        return axis2_svc_engage_module(svc_client->svc, env, module, svc_client->conf);
    }
    return AXIS2_FAILURE;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_svc_client_disengage_module(
    axis2_svc_client_t * svc_client,
    const axutil_env_t * env,
    const axis2_char_t * module_name)
{
    axis2_module_desc_t *module = NULL;
    axutil_qname_t *mod_qname = NULL;

    AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, module_name, AXIS2_FAILURE);

    mod_qname = axutil_qname_create(env, module_name, NULL, NULL);
    if(!mod_qname)
    {
        return AXIS2_FAILURE;
    }

    module = axis2_conf_get_module(svc_client->conf, env, mod_qname);
    axutil_qname_free(mod_qname, env);
    mod_qname = NULL;

    if(module)
    {
        return axis2_svc_disengage_module(svc_client->svc, env, module, svc_client->conf);
    }
    return AXIS2_FAILURE;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_svc_client_add_header(
    axis2_svc_client_t * svc_client,
    const axutil_env_t * env,
    axiom_node_t * header)
{

    AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE);
    if(!svc_client->headers)
    {
        svc_client->headers = axutil_array_list_create(env, 0);
        if(!svc_client->headers)
        {
            return AXIS2_FAILURE;
        }
    }
    axutil_array_list_add(svc_client->headers, env, header);

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_svc_client_remove_all_headers(
    axis2_svc_client_t * svc_client,
    const axutil_env_t * env)
{
    int i = 0;
    int size = 0;

    AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE);

    if(!svc_client->headers)
    {
        return AXIS2_SUCCESS;
    }

    size = axutil_array_list_size(svc_client->headers, env);

    for(i = size - 1; i > -1; i--)
    {
        axutil_array_list_remove(svc_client->headers, env, i);
    }
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_svc_client_send_robust_with_op_qname(
    axis2_svc_client_t * svc_client,
    const axutil_env_t * env,
    const axutil_qname_t * op_qname,
    const axiom_node_t * payload)
{
    axis2_msg_ctx_t *msg_ctx = NULL;
    axis2_status_t status = AXIS2_FAILURE;
    axis2_bool_t qname_free_flag = AXIS2_FALSE;

    AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE);

    if(!op_qname)
    {
        op_qname = axutil_qname_create(env, AXIS2_ANON_ROBUST_OUT_ONLY_OP, NULL, NULL);
        if(!op_qname)
        {
            return AXIS2_FAILURE;
        }
        qname_free_flag = AXIS2_TRUE;
    }
    else
    {
        axis2_op_t *op = NULL;
        axis2_char_t *mep = NULL;
        axis2_svc_t *svc = NULL;
        svc = axis2_svc_client_get_svc(svc_client, env);
        if(!svc)
        {
            return AXIS2_FAILURE;
        }
        op = axis2_svc_get_op_with_qname(svc, env, op_qname);
        if(!op)
        {
            return AXIS2_FAILURE;
        }
        mep = (axis2_char_t *)axis2_op_get_msg_exchange_pattern(op, env);
        if(!mep || axutil_strcmp(AXIS2_MEP_URI_OUT_ONLY, mep) != 0)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s%s",
                "To use this method opeation uri should be", AXIS2_MEP_URI_OUT_ONLY);
            return AXIS2_FAILURE;
        }
    }

    svc_client->auth_failed = AXIS2_FALSE;
    svc_client->required_auth_is_http = AXIS2_FALSE;
    if(svc_client->auth_type)
    {
        AXIS2_FREE(env->allocator, svc_client->auth_type);
    }
    svc_client->auth_type = NULL;

    msg_ctx = axis2_msg_ctx_create(env, axis2_svc_ctx_get_conf_ctx(svc_client->svc_ctx, env), NULL,
        NULL);
    if(!axis2_svc_client_fill_soap_envelope(env, svc_client, msg_ctx, payload))
    {
        return AXIS2_FAILURE;
    }

    if(!axis2_svc_client_create_op_client(svc_client, env, op_qname))
    {
        return AXIS2_FAILURE;
    }

    axis2_op_client_add_out_msg_ctx(svc_client->op_client, env, msg_ctx);
    status = axis2_op_client_execute(svc_client->op_client, env, AXIS2_TRUE);
    axis2_svc_client_set_http_info(svc_client, env, msg_ctx);
    svc_client->auth_failed = axis2_msg_ctx_get_auth_failed(msg_ctx, env);
    svc_client->required_auth_is_http = axis2_msg_ctx_get_required_auth_is_http(msg_ctx, env);
    if(axis2_msg_ctx_get_auth_type(msg_ctx, env))
    {
        svc_client->auth_type = axutil_strdup(env, axis2_msg_ctx_get_auth_type(msg_ctx, env));
    }

    if(qname_free_flag)
    {
        axutil_qname_free((axutil_qname_t *)op_qname, env);
    }

    return status;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_svc_client_send_robust(
    axis2_svc_client_t * svc_client,
    const axutil_env_t * env,
    const axiom_node_t * payload)
{
    return axis2_svc_client_send_robust_with_op_qname(svc_client, env, NULL, payload);
}

AXIS2_EXTERN void AXIS2_CALL
axis2_svc_client_fire_and_forget_with_op_qname(
    axis2_svc_client_t * svc_client,
    const axutil_env_t * env,
    const axutil_qname_t * op_qname,
    const axiom_node_t * payload)
{
    axis2_msg_ctx_t *msg_ctx = NULL;
    axis2_bool_t qname_free_flag = AXIS2_FALSE;

    AXIS2_PARAM_CHECK_VOID(env->error, svc_client);

    if(!op_qname)
    {
        op_qname = axutil_qname_create(env, AXIS2_ANON_OUT_ONLY_OP, NULL, NULL);
        if(!op_qname)
        {
            return;
        }
        qname_free_flag = AXIS2_TRUE;
    }

    svc_client->auth_failed = AXIS2_FALSE;
    svc_client->required_auth_is_http = AXIS2_FALSE;
    if(svc_client->auth_type)
    {
        AXIS2_FREE(env->allocator, svc_client->auth_type);
    }
    svc_client->auth_type = NULL;

    msg_ctx = axis2_msg_ctx_create(env, axis2_svc_ctx_get_conf_ctx(svc_client->svc_ctx, env), NULL,
        NULL);
    if(!axis2_svc_client_fill_soap_envelope(env, svc_client, msg_ctx, payload))
    {
        return;
    }

    if(!axis2_svc_client_create_op_client(svc_client, env, op_qname))
    {
        return;
    }

    axis2_op_client_add_out_msg_ctx(svc_client->op_client, env, msg_ctx);
    axis2_op_client_execute(svc_client->op_client, env, AXIS2_TRUE);
    axis2_svc_client_set_http_info(svc_client, env, msg_ctx);
    svc_client->auth_failed = axis2_msg_ctx_get_auth_failed(msg_ctx, env);
    svc_client->required_auth_is_http = axis2_msg_ctx_get_required_auth_is_http(msg_ctx, env);
    if(axis2_msg_ctx_get_auth_type(msg_ctx, env))
    {
        svc_client->auth_type = axutil_strdup(env, axis2_msg_ctx_get_auth_type(msg_ctx, env));
    }

    if(qname_free_flag)
    {
        axutil_qname_free((axutil_qname_t *)op_qname, env);
    }
}

AXIS2_EXTERN void AXIS2_CALL
axis2_svc_client_fire_and_forget(
    axis2_svc_client_t * svc_client,
    const axutil_env_t * env,
    const axiom_node_t * payload)
{
    axis2_svc_client_fire_and_forget_with_op_qname(svc_client, env, NULL, payload);
}

AXIS2_EXTERN axiom_node_t *AXIS2_CALL
axis2_svc_client_send_receive_with_op_qname(
    axis2_svc_client_t * svc_client,
    const axutil_env_t * env,
    const axutil_qname_t * op_qname,
    const axiom_node_t * payload)
{
    axiom_soap_envelope_t *soap_envelope = NULL;
    axiom_soap_body_t *soap_body = NULL;
    axiom_node_t *soap_node = NULL;
    axis2_op_t *op = NULL;
    axutil_param_t *param = NULL;
    axutil_uri_t *action_uri = NULL;
    axis2_char_t *action_str = NULL;
    axis2_bool_t qname_free_flag = AXIS2_FALSE;

    axis2_msg_ctx_t *res_msg_ctx = NULL;
    axis2_msg_ctx_t *msg_ctx = NULL;

    AXIS2_PARAM_CHECK(env->error, svc_client, NULL);

    svc_client->last_response_soap_envelope = NULL;
    svc_client->last_response_has_fault = AXIS2_FALSE;
    svc_client->auth_failed = AXIS2_FALSE;
    svc_client->required_auth_is_http = AXIS2_FALSE;
    if(svc_client->auth_type)
    {
        AXIS2_FREE(env->allocator, svc_client->auth_type);
    }
    svc_client->auth_type = NULL;

    op = axis2_svc_get_op_with_qname(svc_client->svc, env, op_qname);
    if(op)
    {
        param = axis2_op_get_param(op, env, AXIS2_SOAP_ACTION);
        if(param)
        {
            action_uri = (axutil_uri_t *)axutil_param_get_value(param, env);
            action_str = axutil_uri_to_string(action_uri, env, AXIS2_URI_UNP_OMITUSERINFO);
            axis2_options_set_action(svc_client->options, env, action_str);
        }
    }

    if(!op_qname)
    {
        op_qname = axutil_qname_create(env, AXIS2_ANON_OUT_IN_OP, NULL, NULL);
        if(!op_qname)
            return NULL;

        qname_free_flag = AXIS2_TRUE;
    }

    /* If dual channel blocking. We come to this block if the client indicate to use
     * a separate listener but don't provide a callback function to acted upon when
     * response is received in the listener thread. What we do here is we create a callback
     * and call axis2_svc_client_send_receive_non_blocking_with_op_qname with it. */
    if(axis2_options_get_use_separate_listener(svc_client->options, env))
    {
        axis2_callback_t *callback = NULL;
        axis2_msg_ctx_t *msg_ctx = NULL;
        long index = 0;

        /* This means doing a Request-Response invocation using two channels.
         If the transport is a two way transport (e.g. http), only one channel is used
         (e.g. in http cases 202 OK is sent to say no response available).
         Axis2 gets blocked and return when the response is available. */

        callback = axis2_callback_create(env);
        if(!callback)
        {
            return NULL;
        }

        /* Call two channel non blocking invoke to do the work and wait on the callback. We don't 
         * set a callback function for the callback. That functionality is handled here. 
         */
        axis2_svc_client_send_receive_non_blocking_with_op_qname(svc_client, env, op_qname,
            payload, callback);

        index = axis2_options_get_timeout_in_milli_seconds(svc_client->options, env) / 10;

        while(!axis2_callback_get_complete(callback, env))
        {
            if(index-- >= 0)
            {
                AXIS2_USLEEP(10000);
            }
            else
            {
                AXIS2_ERROR_SET(env->error, AXIS2_ERROR_RESPONSE_TIMED_OUT, AXIS2_FAILURE);
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Response time out.");
                return NULL;
            }
        }

        soap_envelope = axis2_callback_get_envelope(callback, env);
        msg_ctx = axis2_callback_get_msg_ctx(callback, env);
        axis2_op_client_add_in_msg_ctx(svc_client->op_client, env, msg_ctx);

        /* start of hack to get rid of memory leak */
        /*msg_ctx = axis2_msg_ctx_create(env, axis2_svc_ctx_get_conf_ctx(svc_client-> svc_ctx, env),
            NULL, NULL);
        if(!msg_ctx)
            return NULL;

        axis2_op_client_add_in_msg_ctx(svc_client->op_client, env, msg_ctx);

        axis2_msg_ctx_set_soap_envelope(msg_ctx, env, soap_envelope);*/
        /* end of hack to get rid of memory leak */

        /* process the result of the invocation */
        if(!soap_envelope)
        {
            if(axis2_callback_get_error(callback, env) != AXIS2_ERROR_NONE)
            {
                AXIS2_ERROR_SET(env->error, axis2_callback_get_error(callback, env), AXIS2_FAILURE);
                return NULL;
            }
        }
    }
    else
    {
        msg_ctx = axis2_msg_ctx_create(env, axis2_svc_ctx_get_conf_ctx(svc_client->svc_ctx, env),
            NULL, NULL);
        if(!msg_ctx)
            return NULL;

        if(!axis2_svc_client_fill_soap_envelope(env, svc_client, msg_ctx, payload))
        {
            return NULL;
        }

        if(!axis2_svc_client_create_op_client(svc_client, env, op_qname))
        {
            return NULL;
        }

        axis2_op_client_add_msg_ctx(svc_client->op_client, env, msg_ctx);
        axis2_op_client_execute(svc_client->op_client, env, AXIS2_TRUE);
        axis2_svc_client_set_http_info(svc_client, env, msg_ctx);
        svc_client->auth_failed = axis2_msg_ctx_get_auth_failed(msg_ctx, env);
        svc_client->required_auth_is_http = axis2_msg_ctx_get_required_auth_is_http(msg_ctx, env);
        if(axis2_msg_ctx_get_auth_type(msg_ctx, env))
        {
            svc_client->auth_type = axutil_strdup(env, axis2_msg_ctx_get_auth_type(msg_ctx, env));
        }
        res_msg_ctx = (axis2_msg_ctx_t *)axis2_op_client_get_msg_ctx(svc_client-> op_client, env,
            AXIS2_WSDL_MESSAGE_LABEL_IN);

        if(res_msg_ctx)
        {
            soap_envelope = axis2_msg_ctx_get_soap_envelope(res_msg_ctx, env);
        }
        else
        {
            axis2_op_client_add_msg_ctx(svc_client->op_client, env, res_msg_ctx);
            /* set in msg_ctx to be NULL to reset */
        }
    }

    if(qname_free_flag)
    {
        axutil_qname_free((axutil_qname_t *)op_qname, env);
    }

    if(!soap_envelope)
    {
        return NULL;
    }
    svc_client->last_response_soap_envelope = soap_envelope;

    soap_body = axiom_soap_envelope_get_body(soap_envelope, env);

    if(!soap_body)
    {
        axiom_node_t *node = axiom_soap_envelope_get_base_node(soap_envelope, env);
        if(node)
        {
            axiom_element_t *envelope_element = (axiom_element_t *)axiom_node_get_data_element(
                node, env);
            axiom_util_get_first_child_element_with_localname(envelope_element, env, node,
                AXIOM_SOAP_BODY_LOCAL_NAME, &soap_node);
            if(soap_node)
            {
                return axiom_node_get_first_element(soap_node, env);
            }
        }
        return NULL;
    }

    if(axis2_msg_ctx_get_doing_rest(res_msg_ctx, env))
    {
        /* All HTTP 4xx and 5xx status codes are treated as errors */
        if(axis2_msg_ctx_get_status_code(res_msg_ctx, env) >= 400)
        {
            svc_client->last_response_has_fault = AXIS2_TRUE;
        }
        else
        {
            svc_client->last_response_has_fault = AXIS2_FALSE;
        }
    }
    else
    {
        svc_client->last_response_has_fault = axiom_soap_body_has_fault(soap_body, env);
    }

    if(AXIOM_SOAP11 == axiom_soap_envelope_get_soap_version(soap_envelope, env))
    {
        axiom_soap_body_convert_fault_to_soap11(soap_body, env);
    }

    soap_node = axiom_soap_body_get_base_node(soap_body, env);
    if(!soap_node)
    {
        return NULL;
    }
    return axiom_node_get_first_element(soap_node, env);
}

AXIS2_EXTERN axiom_node_t *AXIS2_CALL
axis2_svc_client_send_receive(
    axis2_svc_client_t * svc_client,
    const axutil_env_t * env,
    const axiom_node_t * payload)
{
    return axis2_svc_client_send_receive_with_op_qname(svc_client, env, NULL, payload);
}

AXIS2_EXTERN void AXIS2_CALL
axis2_svc_client_send_receive_non_blocking_with_op_qname(
    axis2_svc_client_t * svc_client,
    const axutil_env_t * env,
    const axutil_qname_t * op_qname,
    const axiom_node_t * payload,
    axis2_callback_t * callback)
{
    axis2_msg_ctx_t *msg_ctx = NULL;
    AXIS2_TRANSPORT_ENUMS transport_in_protocol;
    axis2_bool_t qname_free_flag = AXIS2_FALSE;

    AXIS2_PARAM_CHECK_VOID(env->error, svc_client);

    if(!op_qname)
    {
        op_qname = axutil_qname_create(env, AXIS2_ANON_OUT_IN_OP, NULL, NULL);
        if(!op_qname)
            return;
        qname_free_flag = AXIS2_TRUE;
    }

    svc_client->auth_failed = AXIS2_FALSE;
    svc_client->required_auth_is_http = AXIS2_FALSE;
    if(svc_client->auth_type)
    {
        AXIS2_FREE(env->allocator, svc_client->auth_type);
    }
    svc_client->auth_type = NULL;

    msg_ctx = axis2_msg_ctx_create(env, axis2_svc_ctx_get_conf_ctx(svc_client-> svc_ctx, env),
        NULL, NULL);
    if(!msg_ctx)
        return;

    if(!axis2_svc_client_fill_soap_envelope(env, svc_client, msg_ctx, payload))
    {
        return;
    }

    if(!axis2_svc_client_create_op_client(svc_client, env, op_qname))
    {
        return;
    }

    axis2_op_client_set_callback(svc_client->op_client, env, callback);
    axis2_op_client_add_out_msg_ctx(svc_client->op_client, env, msg_ctx);

    /* If dual channel */
    if(axis2_options_get_use_separate_listener(svc_client->options, env))
    {
        axis2_op_t *op = NULL;

        transport_in_protocol = axis2_options_get_transport_in_protocol(svc_client->options, env);
        if(transport_in_protocol == AXIS2_TRANSPORT_ENUM_MAX)
        {
            axis2_options_set_transport_in_protocol(svc_client->options, env,
                AXIS2_TRANSPORT_ENUM_HTTP);
            transport_in_protocol = AXIS2_TRANSPORT_ENUM_HTTP;
        }
        axis2_listener_manager_make_sure_started(svc_client->listener_manager, env,
            transport_in_protocol, svc_client->conf_ctx);
        /* Following sleep is required to ensure the listener is ready to receive response.
         If it is missing, the response gets lost. - Samisa */
        AXIS2_USLEEP(1);

        op = axis2_svc_get_op_with_qname(svc_client->svc, env, op_qname);
        /* At the end of the incoming flow this message receiver will be hit */
        axis2_op_set_msg_recv(op, env,
            AXIS2_CALLBACK_RECV_GET_BASE(svc_client-> callback_recv, env));
        axis2_op_client_set_callback_recv(svc_client->op_client, env, svc_client->callback_recv);
    }

    axis2_op_client_execute(svc_client->op_client, env, AXIS2_FALSE);
    axis2_svc_client_set_http_info(svc_client, env, msg_ctx);
    svc_client->auth_failed = axis2_msg_ctx_get_auth_failed(msg_ctx, env);
    svc_client->required_auth_is_http = axis2_msg_ctx_get_required_auth_is_http(msg_ctx, env);
    if(axis2_msg_ctx_get_auth_type(msg_ctx, env))
    {
        svc_client->auth_type = axutil_strdup(env, axis2_msg_ctx_get_auth_type(msg_ctx, env));
    }

    if(qname_free_flag)
    {
        axutil_qname_free((axutil_qname_t *)op_qname, env);
        op_qname = NULL;
    }
}

AXIS2_EXTERN void AXIS2_CALL
axis2_svc_client_send_receive_non_blocking(
    axis2_svc_client_t * svc_client,
    const axutil_env_t * env,
    const axiom_node_t * payload,
    axis2_callback_t * callback)
{
    axis2_svc_client_send_receive_non_blocking_with_op_qname(svc_client, env, NULL, payload,
        callback);
}

AXIS2_EXTERN axis2_op_client_t *AXIS2_CALL
axis2_svc_client_create_op_client(
    axis2_svc_client_t * svc_client,
    const axutil_env_t * env,
    const axutil_qname_t * op_qname)
{
    axis2_op_t *op = NULL;

    AXIS2_PARAM_CHECK(env->error, svc_client, NULL);

    op = axis2_svc_get_op_with_qname(svc_client->svc, env, op_qname);

    if(!op)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot find operation to create op client.");
        return NULL;
    }

    if(!(svc_client->op_client) || svc_client->reuse)
    {
        if((svc_client->reuse) && (svc_client->op_client))
            axis2_op_client_free(svc_client->op_client, env);
        svc_client->op_client = axis2_op_client_create(env, op, svc_client->svc_ctx,
            svc_client->options);
    }

    /**
     If override options have been set, that means we need to make sure
     those options override the options of even the operation client. So,
     what we do is switch the parents around to make that work.
     */
    if(svc_client->override_options)
    {
        axis2_options_set_parent(svc_client->override_options, env, axis2_op_client_get_options(
            svc_client-> op_client, env));
        axis2_op_client_set_options(svc_client->op_client, env, svc_client->override_options);
    }
    svc_client->reuse = AXIS2_TRUE;
    axis2_op_client_set_reuse(svc_client->op_client, env, svc_client->reuse);
    return svc_client->op_client;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_svc_client_finalize_invoke(
    axis2_svc_client_t * svc_client,
    const axutil_env_t * env)
{
    AXIS2_TRANSPORT_ENUMS transport_in_protocol;

    AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE);

    transport_in_protocol = axis2_options_get_transport_in_protocol(svc_client->options, env);

    if(svc_client->listener_manager)
    {
        return axis2_listener_manager_stop(svc_client->listener_manager, env, transport_in_protocol);
    }

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN const axis2_endpoint_ref_t *AXIS2_CALL
axis2_svc_client_get_own_endpoint_ref(
    const axis2_svc_client_t * svc_client,
    const axutil_env_t * env,
    const axis2_char_t * transport)
{
    return NULL;
}

AXIS2_EXTERN const axis2_endpoint_ref_t *AXIS2_CALL
axis2_svc_client_get_target_endpoint_ref(
    const axis2_svc_client_t * svc_client,
    const axutil_env_t * env)
{
    return NULL;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_svc_client_set_target_endpoint_ref(
    axis2_svc_client_t * svc_client,
    const axutil_env_t * env,
    axis2_endpoint_ref_t * target_endpoint_ref)
{
    return AXIS2_FAILURE;
}

AXIS2_EXTERN axis2_svc_ctx_t *AXIS2_CALL
axis2_svc_client_get_svc_ctx(
    const axis2_svc_client_t * svc_client,
    const axutil_env_t * env)
{
    AXIS2_PARAM_CHECK(env->error, svc_client, NULL);
    return svc_client->svc_ctx;
}

static axis2_bool_t
axis2_svc_client_init_transports_from_conf_ctx(
    const axutil_env_t * env,
    axis2_svc_client_t * svc_client,
    axis2_conf_ctx_t * conf_ctx,
    const axis2_char_t * client_home)
{
    svc_client->conf_ctx = conf_ctx;
    if(!svc_client->conf_ctx)
    {
        svc_client->conf_ctx = axis2_build_client_conf_ctx(env, client_home);
        if(!svc_client->conf_ctx)
        {
            return AXIS2_FALSE;
        }
    }
    else
    {
        svc_client->keep_externally_passed_ctx_and_svc = AXIS2_TRUE;
    }

    if(!svc_client->listener_manager)
    {
        svc_client->listener_manager = axis2_listener_manager_create(env);
        if(!svc_client->listener_manager)
        {
            return AXIS2_FALSE;
        }
    }

    return AXIS2_TRUE;
}

static axis2_bool_t
axis2_svc_client_init_data(
    const axutil_env_t * env,
    axis2_svc_client_t * svc_client)
{
    svc_client->svc = NULL;
    svc_client->conf_ctx = NULL;
    svc_client->svc_ctx = NULL;

    svc_client->options = axis2_options_create(env);
    if(!svc_client->options)
    {
        return AXIS2_FALSE;
    }

    svc_client->override_options = NULL;
    svc_client->headers = NULL;

    if(svc_client->callback_recv)
    {
        AXIS2_CALLBACK_RECV_FREE(svc_client->callback_recv, env);
        svc_client->callback_recv = NULL;
    }

    svc_client->callback_recv = axis2_callback_recv_create(env);
    if(!svc_client->callback_recv)
    {
        return AXIS2_FALSE;
    }

    return AXIS2_TRUE;
}

static axis2_svc_t *
axis2_svc_client_create_annonymous_svc(
    axis2_svc_client_t * svc_client,
    const axutil_env_t * env)
{

    /**
     now add anonymous operations to the axis2 service for use with the
     shortcut client API. NOTE: We only add the ones we know we'll use
     later in the convenience API; if you use
     this constructor then you can't expect any magic!
     */
    axutil_qname_t *tmp_qname;
    axis2_svc_t *svc;
    axis2_op_t *op_out_in, *op_out_only, *op_robust_out_only;
    axis2_phases_info_t *info = NULL;

    tmp_qname = axutil_qname_create(env, AXIS2_ANON_SERVICE, NULL, NULL);
    if(!tmp_qname)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,"Error creating QName for service");
        return NULL;
    }

    svc = axis2_svc_create_with_qname(env, tmp_qname);
    axutil_qname_free(tmp_qname, env);
    if(!svc)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error creating the service");
        return NULL;
    }

    tmp_qname = axutil_qname_create(env, AXIS2_ANON_OUT_IN_OP, NULL, NULL);
    if(!tmp_qname)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error creating the QName for out-in operation");
        return NULL;
    }
    op_out_in = axis2_op_create_with_qname(env, tmp_qname);
    axutil_qname_free(tmp_qname, env);

    tmp_qname = axutil_qname_create(env, AXIS2_ANON_OUT_ONLY_OP, NULL, NULL);
    if(!tmp_qname)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error creating the QName for out-only operation");
        return NULL;
    }
    op_out_only = axis2_op_create_with_qname(env, tmp_qname);
    axutil_qname_free(tmp_qname, env);

    tmp_qname = axutil_qname_create(env, AXIS2_ANON_ROBUST_OUT_ONLY_OP, NULL, NULL);
    if(!tmp_qname)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "Error creating the QName for robust-out-only operation");
        return NULL;
    }
    op_robust_out_only = axis2_op_create_with_qname(env, tmp_qname);
    axutil_qname_free(tmp_qname, env);

    if(!op_out_in || !op_out_only || !op_robust_out_only)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        if(op_out_in)
        {
            axis2_op_free(op_out_in, env);
        }
        if(op_out_only)
        {
            axis2_op_free(op_out_only, env);
        }
        if(op_robust_out_only)
        {
            axis2_op_free(op_robust_out_only, env);
        }

        return NULL;
    }

    axis2_op_set_msg_exchange_pattern(op_out_in, env, AXIS2_MEP_URI_OUT_IN);
    axis2_op_set_msg_exchange_pattern(op_out_only, env, AXIS2_MEP_URI_OUT_ONLY);
    axis2_op_set_msg_exchange_pattern(op_robust_out_only, env, AXIS2_MEP_URI_ROBUST_OUT_ONLY);

    /* Setting operation phase */
    info = axis2_conf_get_phases_info(svc_client->conf, env);
    axis2_phases_info_set_op_phases(info, env, op_out_in);
    axis2_phases_info_set_op_phases(info, env, op_out_only);
    axis2_phases_info_set_op_phases(info, env, op_robust_out_only);
    axis2_svc_add_op(svc, env, op_out_in);
    axis2_svc_add_op(svc, env, op_out_only);
    axis2_svc_add_op(svc, env, op_robust_out_only);
    return svc;
}

AXIS2_EXTERN void AXIS2_CALL
axis2_svc_client_free(
    axis2_svc_client_t * svc_client,
    const axutil_env_t * env)
{
    if(!svc_client)
    {
        return;
    }

    if(svc_client->headers)
    {
        axis2_svc_client_remove_all_headers(svc_client, env);
        axutil_array_list_free(svc_client->headers, env);
        svc_client->headers = NULL;
    }

    if(svc_client->svc && !svc_client->keep_externally_passed_ctx_and_svc)
    {
        axis2_svc_free(svc_client->svc, env);
    }

    if(svc_client->callback_recv)
    {
        AXIS2_CALLBACK_RECV_FREE(svc_client->callback_recv, env);
    }

    if(svc_client->op_client)
    {
        axis2_op_client_free(svc_client->op_client, env);
        svc_client->op_client = NULL;
    }

    if(svc_client->options)
    {
        axis2_options_free(svc_client->options, env);
    }

    if(svc_client->listener_manager)
    {
        axis2_listener_manager_free(svc_client->listener_manager, env);
    }

    if(svc_client->conf_ctx && !svc_client->keep_externally_passed_ctx_and_svc)
    {
        axis2_conf_ctx_free(svc_client->conf_ctx, env);
    }

    if(svc_client->auth_type)
    {
        AXIS2_FREE(env->allocator, svc_client->auth_type);
    }

    if(svc_client->http_headers)
    {
        axis2_svc_client_set_http_info(svc_client, env, NULL);
    }

    AXIS2_FREE(env->allocator, svc_client);

    return;
}

static axis2_bool_t
axis2_svc_client_fill_soap_envelope(
    const axutil_env_t * env,
    axis2_svc_client_t * svc_client,
    axis2_msg_ctx_t * msg_ctx,
    const axiom_node_t * payload)
{
    const axis2_char_t *soap_version_uri;
    int soap_version;
    axiom_soap_envelope_t *envelope = NULL;
    AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE);

    soap_version_uri = axis2_options_get_soap_version_uri(svc_client->options, env);

    if(!soap_version_uri)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot find soap version uri.");
        return AXIS2_FALSE;
    }

    if(axutil_strcmp(soap_version_uri, AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI) == 0)
    {
        soap_version = AXIOM_SOAP11;
    }
    else
    {
        soap_version = AXIOM_SOAP12;
    }

    envelope = axiom_soap_envelope_create_default_soap_envelope(env, soap_version);
    if(!envelope)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot create default soap envelope.");
        return AXIS2_FALSE;
    }

    if(svc_client->headers)
    {
        axiom_soap_header_t *soap_header = NULL;
        soap_header = axiom_soap_envelope_get_header(envelope, env);

        if(soap_header)
        {
            axiom_node_t *header_node = NULL;
            header_node = axiom_soap_header_get_base_node(soap_header, env);

            if(header_node)
            {
                int size = 0;
                int i = 0;
                size = axutil_array_list_size(svc_client->headers, env);
                while(i < size)
                {
                    axiom_node_t *node = NULL;
                    node = axutil_array_list_remove(svc_client->headers, env, 0);
                    /* This removes and retrieves data. The order of the 
                     * removal is chosen such that the headers are appended
                     * in the order they were added.
                     */
                    size--;
                    if(node)
                    {
                        axiom_node_add_child(header_node, env, node);
                    }
                }
            }
        }
    }

    if(payload)
    {
        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)
            {
				//Get compatibility with anothers Web Services Frameworks, adjust payload with xmlns
				axiom_element_t *element = (axiom_element_t*)axiom_node_get_data_element(node, env);
				
				axiom_attribute_t *attXmlXsi = axiom_attribute_create(env, "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance", NULL);
				axiom_element_add_attribute(element, env, attXmlXsi, node);

				axiom_attribute_t *attXmlXsd = axiom_attribute_create(env, "xmlns:xsd", "http://www.w3.org/2001/XMLSchema", NULL);
				axiom_element_add_attribute(element, env, attXmlXsd, node);

                axiom_node_add_child(node, env, (axiom_node_t *)payload);
            }
        }
    }

    axis2_msg_ctx_set_soap_envelope(msg_ctx, env, envelope);

    return AXIS2_TRUE;
}

AXIS2_EXTERN axis2_op_client_t *AXIS2_CALL
axis2_svc_client_get_op_client(
    const axis2_svc_client_t * svc_client,
    const axutil_env_t * env)
{
    AXIS2_PARAM_CHECK(env->error, svc_client, NULL);
    return svc_client->op_client;
}

AXIS2_EXTERN axiom_soap_envelope_t *AXIS2_CALL
axis2_svc_client_get_last_response_soap_envelope(
    const axis2_svc_client_t * svc_client,
    const axutil_env_t * env)
{
    AXIS2_PARAM_CHECK(env->error, svc_client, NULL);
    return svc_client->last_response_soap_envelope;
}

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axis2_svc_client_get_last_response_has_fault(
    const axis2_svc_client_t * svc_client,
    const axutil_env_t * env)
{
    AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FALSE);
    return svc_client->last_response_has_fault;
}

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axis2_svc_client_get_http_auth_required(
    const axis2_svc_client_t * svc_client,
    const axutil_env_t * env)
{
    AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FALSE);
    if(svc_client->auth_failed && svc_client->required_auth_is_http)
    {
        return AXIS2_TRUE;
    }
    return AXIS2_FALSE;
}

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axis2_svc_client_get_proxy_auth_required(
    const axis2_svc_client_t * svc_client,
    const axutil_env_t * env)
{
    AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FALSE);
    if(svc_client->auth_failed && !svc_client->required_auth_is_http)
    {
        return AXIS2_TRUE;
    }
    return AXIS2_FALSE;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axis2_svc_client_get_auth_type(
    const axis2_svc_client_t * svc_client,
    const axutil_env_t * env)
{
    return svc_client->auth_type;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_svc_client_set_proxy_with_auth(
    axis2_svc_client_t * svc_client,
    const axutil_env_t * env,
    axis2_char_t * proxy_host,
    axis2_char_t * proxy_port,
    axis2_char_t * username,
    axis2_char_t * password)
{
    axis2_transport_out_desc_t *trans_desc = NULL;
    axis2_conf_t *conf = NULL;
    axutil_param_container_t *param_container;
    axutil_param_t *param;
    axis2_char_t *proxy = AXIS2_HTTP_PROXY_API;
    axutil_hash_t *attribute;
    axutil_generic_obj_t *host_obj = NULL;
    axutil_generic_obj_t *port_obj = NULL;
    axutil_generic_obj_t *username_obj = NULL;
    axutil_generic_obj_t *password_obj = NULL;
    axiom_attribute_t *host_attr = NULL;
    axiom_attribute_t *port_attr = NULL;
    axiom_attribute_t *username_attr = NULL;
    axiom_attribute_t *password_attr = NULL;

    AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, proxy_host, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, proxy_port, AXIS2_FAILURE);

    if(svc_client->conf)
    {
        conf = svc_client->conf;
        trans_desc = axis2_conf_get_transport_out(conf, env, AXIS2_TRANSPORT_ENUM_HTTP);
        if(!trans_desc)
        {
            return AXIS2_FAILURE;
        }
        param_container = axis2_transport_out_desc_param_container(trans_desc, env);
        param = axutil_param_create(env, proxy, (void *)NULL);

        if(!param)
        {
            return AXIS2_FAILURE;
        }

        attribute = axutil_hash_make(env);
        host_obj = axutil_generic_obj_create(env);
        port_obj = axutil_generic_obj_create(env);
        host_attr = axiom_attribute_create(env, AXIS2_HTTP_PROXY_HOST, proxy_host, NULL);
        port_attr = axiom_attribute_create(env, AXIS2_HTTP_PROXY_PORT, proxy_port, NULL);
        axutil_generic_obj_set_value(host_obj, env, host_attr);
        axutil_generic_obj_set_free_func(host_obj, env, axiom_attribute_free_void_arg);
        axutil_generic_obj_set_value(port_obj, env, port_attr);
        axutil_generic_obj_set_free_func(port_obj, env, axiom_attribute_free_void_arg);

        axutil_hash_set(attribute, AXIS2_HTTP_PROXY_HOST, AXIS2_HASH_KEY_STRING, host_obj);
        axutil_hash_set(attribute, AXIS2_HTTP_PROXY_PORT, AXIS2_HASH_KEY_STRING, port_obj);
        if(username && password)
        {
            username_obj = axutil_generic_obj_create(env);
            password_obj = axutil_generic_obj_create(env);
            username_attr = axiom_attribute_create(env, AXIS2_HTTP_PROXY_USERNAME, username, NULL);
            password_attr = axiom_attribute_create(env, AXIS2_HTTP_PROXY_PASSWORD, password, NULL);
            axutil_generic_obj_set_value(username_obj, env, username_attr);
            axutil_generic_obj_set_value(password_obj, env, password_attr);
            axutil_generic_obj_set_free_func(username_obj, env, axiom_attribute_free_void_arg);
            axutil_generic_obj_set_free_func(password_obj, env, axiom_attribute_free_void_arg);
            axutil_hash_set(attribute, AXIS2_HTTP_PROXY_USERNAME, AXIS2_HASH_KEY_STRING,
                username_obj);
            axutil_hash_set(attribute, AXIS2_HTTP_PROXY_PASSWORD, AXIS2_HASH_KEY_STRING,
                password_obj);
        }
        axutil_param_set_attributes(param, env, attribute);
        axutil_param_container_add_param(param_container, env, param);
    }
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_svc_client_set_proxy(
    axis2_svc_client_t * svc_client,
    const axutil_env_t * env,
    axis2_char_t * proxy_host,
    axis2_char_t * proxy_port)
{
    return axis2_svc_client_set_proxy_with_auth(svc_client, env, proxy_host, proxy_port, NULL, NULL);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_svc_client_set_policy_from_om(
    axis2_svc_client_t * svc_client,
    const axutil_env_t * env,
    axiom_node_t * root_node)
{
    neethi_policy_t *neethi_policy = NULL;

    AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE);
    neethi_policy = neethi_util_create_policy_from_om(env, root_node);

    if(neethi_policy)
    {
        return axis2_svc_client_set_policy(svc_client, env, neethi_policy);
    }
    else
    {
        return AXIS2_FAILURE;
    }
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_svc_client_set_policy(
    axis2_svc_client_t * svc_client,
    const axutil_env_t * env,
    neethi_policy_t * policy)
{

    axis2_svc_t *svc = NULL;
    axis2_desc_t *desc = NULL;
    axis2_policy_include_t *policy_include = NULL;

    AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, policy, AXIS2_FAILURE);

    svc = axis2_svc_client_get_svc(svc_client, env);

    if(!svc)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "Cannot find service of service client. Cannot set policy.");
        return AXIS2_FAILURE;
    }

    desc = axis2_svc_get_base(svc, env);
    if(!desc)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "Cannot find service description of service client. Cannot set policy.");
        return AXIS2_FAILURE;
    }

    policy_include = axis2_desc_get_policy_include(desc, env);
    if(!policy_include)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot find policy include. Cannot set policy.");
        return AXIS2_FAILURE;
    }

    axis2_policy_include_add_policy_element(policy_include, env, AXIS2_SERVICE_POLICY, policy);
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL
axis2_svc_client_get_http_headers(
    axis2_svc_client_t * svc_client,
    const axutil_env_t * env)
{
    return svc_client->http_headers;
}

AXIS2_EXTERN int AXIS2_CALL
axis2_svc_client_get_http_status_code(
    axis2_svc_client_t * svc_client,
    const axutil_env_t * env)
{
    return svc_client->http_status_code;
}

void
axis2_svc_client_set_http_info(
    axis2_svc_client_t * svc_client,
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx)
{
    axis2_transport_in_desc_t *transport_in = NULL;
    axutil_param_t *expose_headers_param = NULL;
    axis2_bool_t expose_headers = AXIS2_FALSE;

    if(msg_ctx)
    {
        transport_in = axis2_msg_ctx_get_transport_in_desc(msg_ctx, env);
        if(transport_in)
        {
            expose_headers_param = axutil_param_container_get_param(
                axis2_transport_in_desc_param_container(transport_in, env), env,
                AXIS2_EXPOSE_HEADERS);
        }
        if(expose_headers_param)
        {
            axis2_char_t *expose_headers_value = NULL;
            expose_headers_value = axutil_param_get_value(expose_headers_param, env);
            if(expose_headers_value && 0 == axutil_strcasecmp(expose_headers_value,
                AXIS2_VALUE_TRUE))
            {
                expose_headers = AXIS2_TRUE;
            }
        }
    }
    if(expose_headers)
    {
        if(svc_client->http_headers == axis2_msg_ctx_get_http_output_headers(msg_ctx, env))
        {
            svc_client->http_status_code = axis2_msg_ctx_get_status_code(msg_ctx, env);
            return;
        }
    }

    if(svc_client->http_headers)
    {
        axis2_http_header_t *header = NULL;
        while(axutil_array_list_size(svc_client->http_headers, env))
        {
            header = (axis2_http_header_t *)axutil_array_list_remove(svc_client->http_headers, env,
                0);
            if(header)
            {
                axis2_http_header_free(header, env);
            }
        }
        axutil_array_list_free(svc_client->http_headers, env);
        svc_client->http_headers = NULL;
    }
    svc_client->http_status_code = 0;

    if(msg_ctx)
    {
        if(expose_headers)
        {
            svc_client->http_headers = axis2_msg_ctx_extract_http_output_headers(msg_ctx, env);
        }
        svc_client->http_status_code = axis2_msg_ctx_get_status_code(msg_ctx, env);
    }
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_svc_client_close(
    axis2_svc_client_t * svc_client,
    const axutil_env_t * env)
{
    axis2_status_t status = AXIS2_FAILURE;
    axutil_property_t *property = NULL;
    axis2_endpoint_ref_t *replyto = NULL;

    property = axutil_property_create_with_args(env, 0, 0, 0, AXIS2_VALUE_TRUE);
    axis2_options_set_property(svc_client->options, env, AXIS2_SVC_CLIENT_CLOSED, property);
    replyto = axis2_options_get_reply_to(svc_client->options, env);
    if(replyto)
    {
        axiom_node_t *reply = NULL;

        reply = axis2_svc_client_send_receive(svc_client, env, NULL);
        if(reply)
        {
            status = AXIS2_SUCCESS;
        }
    }
    else
    {
        status = axis2_svc_client_send_robust(svc_client, env, NULL);
    }

    return status;
}

