/*
 * 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_core_utils.h>
#include <axutil_string.h>
#include <axis2_conf.h>
#include <axis2_relates_to.h>
#include <axis2_addr.h>
#include <axis2_http_transport.h>
#include <axutil_uuid_gen.h>
#include <axutil_property.h>
#include <axis2_conf_ctx.h>


/* internal structure to keep the rest map in a multi level hash */
typedef struct
{
    /* the structure will keep as many as following fields */

    /* if the mapped value is directly the operation */
    axis2_op_t *op_desc;

    /* if the mapped value is a constant, this keeps a hash map of
     possible constants => corrosponding map_internal structure */
    axutil_hash_t *consts_map;

    /* if the mapped value is a param, this keeps a hash map of
     possible param_values => corrosponding_map_internal structre */
    axutil_hash_t *params_map;

} axutil_core_utils_map_internal_t;

/* some functions to use internally in handling rest map */
/* infer op from the live url */
axis2_op_t *
axis2_core_utils_infer_op_from_parent_rest_map(
    const axutil_env_t *env,
    axutil_hash_t *rest_map,
    axis2_char_t *live_url,
    axutil_array_list_t *param_keys,
    axutil_array_list_t *param_values);

/* build the restmap recursively - internal function*/
axis2_status_t AXIS2_CALL
axis2_core_utils_internal_build_rest_map_recursively(
    const axutil_env_t * env,
    axis2_char_t * url,
    axutil_core_utils_map_internal_t *mapping_struct,
    axis2_op_t *op_desc);

/* infer op from the live url recursively */
axis2_op_t *AXIS2_CALL
axis2_core_utils_internal_infer_op_from_rest_map_recursively(
    const axutil_env_t *env,
    const axutil_core_utils_map_internal_t *parent_mapping_struct,
    axis2_char_t *live_url,
    axutil_array_list_t *param_keys,
    axutil_array_list_t *param_values);

/* match a pattern with a url component */
axis2_status_t
axis2_core_utils_match_url_component_with_pattern(
    const axutil_env_t *env,
    axis2_char_t *pattern,
    axis2_char_t *url_component,
    axutil_array_list_t *param_keys,
    axutil_array_list_t *param_values);

AXIS2_EXTERN axis2_msg_ctx_t *AXIS2_CALL
axis2_core_utils_create_out_msg_ctx(
    const axutil_env_t * env,
    axis2_msg_ctx_t * in_msg_ctx)
{
    axis2_ctx_t *ctx = NULL;
    axis2_msg_ctx_t *new_msg_ctx = NULL;
    axis2_conf_ctx_t *conf_ctx = NULL;
    axis2_transport_in_desc_t *transport_in = NULL;
    axis2_transport_out_desc_t *transport_out = NULL;
    axis2_msg_info_headers_t *old_msg_info_headers = NULL;
    axis2_msg_info_headers_t *msg_info_headers = NULL;
    axis2_endpoint_ref_t *reply_to = NULL;
    axis2_endpoint_ref_t *fault_to = NULL;
    axis2_endpoint_ref_t *to = NULL;
    const axis2_char_t *msg_id = NULL;
    axis2_relates_to_t *relates_to = NULL;
    const axis2_char_t *action = NULL;
    axis2_op_ctx_t *op_ctx = NULL;
    axis2_svc_ctx_t *svc_ctx = NULL;
    axis2_bool_t doing_rest = AXIS2_FALSE;
    axis2_bool_t doing_mtom = AXIS2_FALSE;
#ifdef AXIS2_JSON_ENABLED
    axis2_bool_t doing_json = AXIS2_FALSE;
#endif
    axis2_bool_t server_side = AXIS2_FALSE;
    axis2_svc_grp_ctx_t *svc_grp_ctx = NULL;
    axis2_char_t *msg_uuid = NULL;
    axutil_stream_t *out_stream = NULL;
    axutil_param_t *expose_headers_param = NULL;
    axis2_bool_t expose_headers = AXIS2_FALSE;

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

    conf_ctx = axis2_msg_ctx_get_conf_ctx(in_msg_ctx, env);
    transport_in = axis2_msg_ctx_get_transport_in_desc(in_msg_ctx, env);
    transport_out = axis2_msg_ctx_get_transport_out_desc(in_msg_ctx, env);

    new_msg_ctx = axis2_msg_ctx_create(env, conf_ctx, transport_in, transport_out);
    if(!new_msg_ctx)
    {
        return NULL;
    }

    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)
    {
        axis2_msg_ctx_set_transport_headers(new_msg_ctx, env,
            axis2_msg_ctx_extract_transport_headers(in_msg_ctx, env));
    }
    axis2_msg_ctx_set_http_accept_record_list(new_msg_ctx, env,
        axis2_msg_ctx_extract_http_accept_record_list(in_msg_ctx, env));
    axis2_msg_ctx_set_http_accept_charset_record_list(new_msg_ctx, env,
        axis2_msg_ctx_extract_http_accept_charset_record_list(in_msg_ctx, env));
    axis2_msg_ctx_set_http_accept_language_record_list(new_msg_ctx, env,
        axis2_msg_ctx_extract_http_accept_language_record_list(in_msg_ctx, env));

    old_msg_info_headers = axis2_msg_ctx_get_msg_info_headers(in_msg_ctx, env);
    if(!old_msg_info_headers)
    {
        return NULL;
    }
    msg_info_headers = axis2_msg_ctx_get_msg_info_headers(new_msg_ctx, env);
    if(!msg_info_headers)
    {
        /* if there is no msg info header in ew msg ctx, then create one */
        msg_info_headers = axis2_msg_info_headers_create(env, NULL, NULL);
        if(!msg_info_headers)
            return NULL;
        axis2_msg_ctx_set_msg_info_headers(new_msg_ctx, env, msg_info_headers);
    }

    msg_uuid = axutil_uuid_gen(env);
    axis2_msg_info_headers_set_message_id(msg_info_headers, env, msg_uuid);
    if(msg_uuid)
    {
        AXIS2_FREE(env->allocator, msg_uuid);
        msg_uuid = NULL;
    }
    reply_to = axis2_msg_info_headers_get_reply_to(old_msg_info_headers, env);
    axis2_msg_info_headers_set_to(msg_info_headers, env, reply_to);

    fault_to = axis2_msg_info_headers_get_fault_to(old_msg_info_headers, env);
    axis2_msg_info_headers_set_fault_to(msg_info_headers, env, fault_to);

    to = axis2_msg_info_headers_get_to(old_msg_info_headers, env);
    axis2_msg_info_headers_set_from(msg_info_headers, env, to);

    msg_id = axis2_msg_info_headers_get_message_id(old_msg_info_headers, env);

    /* we can create with default Relates to namespace. 
     Actual namespace based on addressing version will be created in addressing out handler */
    relates_to = axis2_relates_to_create(env, msg_id,
        AXIS2_WSA_RELATES_TO_RELATIONSHIP_TYPE_DEFAULT_VALUE);
    axis2_msg_info_headers_set_relates_to(msg_info_headers, env, relates_to);

    action = axis2_msg_info_headers_get_action(old_msg_info_headers, env);
    axis2_msg_info_headers_set_action(msg_info_headers, env, action);

    op_ctx = axis2_msg_ctx_get_op_ctx(in_msg_ctx, env);
    axis2_msg_ctx_set_op_ctx(new_msg_ctx, env, op_ctx);

    svc_ctx = axis2_msg_ctx_get_svc_ctx(in_msg_ctx, env);
    axis2_msg_ctx_set_svc_ctx(new_msg_ctx, env, svc_ctx);

    ctx = axis2_msg_ctx_get_base(in_msg_ctx, env);
    if(ctx)
    {
        axis2_ctx_t *new_ctx = axis2_msg_ctx_get_base(new_msg_ctx, env);
        if(new_ctx)
        {
            axis2_ctx_set_property_map(new_ctx, env, axis2_ctx_get_property_map(ctx, env));
        }
    }

    out_stream = axis2_msg_ctx_get_transport_out_stream(in_msg_ctx, env);
    axis2_msg_ctx_set_transport_out_stream(new_msg_ctx, env, out_stream);
    axis2_msg_ctx_set_out_transport_info(new_msg_ctx, env, axis2_msg_ctx_get_out_transport_info(
        in_msg_ctx, env));

    /* Setting the character set encoding */
    doing_rest = axis2_msg_ctx_get_doing_rest(in_msg_ctx, env);
    axis2_msg_ctx_set_doing_rest(new_msg_ctx, env, doing_rest);

    doing_mtom = axis2_msg_ctx_get_doing_mtom(in_msg_ctx, env);
    axis2_msg_ctx_set_doing_mtom(new_msg_ctx, env, doing_mtom);

#ifdef AXIS2_JSON_ENABLED
    doing_json = axis2_msg_ctx_get_doing_json(in_msg_ctx, env);
    axis2_msg_ctx_set_doing_json(new_msg_ctx, env, doing_json);
#endif

    server_side = axis2_msg_ctx_get_server_side(in_msg_ctx, env);
    axis2_msg_ctx_set_server_side(new_msg_ctx, env, server_side);

    svc_grp_ctx = axis2_msg_ctx_get_svc_grp_ctx(in_msg_ctx, env);
    axis2_msg_ctx_set_svc_grp_ctx(new_msg_ctx, env, svc_grp_ctx);

    axis2_msg_ctx_set_is_soap_11(new_msg_ctx, env, axis2_msg_ctx_get_is_soap_11(in_msg_ctx, env));
    axis2_msg_ctx_set_keep_alive(new_msg_ctx, env, axis2_msg_ctx_is_keep_alive(in_msg_ctx, env));

    axis2_msg_ctx_set_charset_encoding(new_msg_ctx, env, axis2_msg_ctx_get_charset_encoding(
        in_msg_ctx, env));

    return new_msg_ctx;
}

AXIS2_EXTERN void AXIS2_CALL
axis2_core_utils_reset_out_msg_ctx(
    const axutil_env_t * env,
    axis2_msg_ctx_t * out_msg_ctx)
{
    axis2_msg_info_headers_t *msg_info_headers = NULL;
    if(!out_msg_ctx)
        return;

    msg_info_headers = axis2_msg_ctx_get_msg_info_headers(out_msg_ctx, env);
    if(msg_info_headers)
    {
        axis2_msg_info_headers_set_to(msg_info_headers, env, NULL);
        axis2_msg_info_headers_set_fault_to(msg_info_headers, env, NULL);
        axis2_msg_info_headers_set_from(msg_info_headers, env, NULL);
        axis2_msg_info_headers_set_reply_to(msg_info_headers, env, NULL);
    }

    axis2_msg_ctx_set_op_ctx(out_msg_ctx, env, NULL);
    axis2_msg_ctx_set_svc_ctx(out_msg_ctx, env, NULL);
    axis2_msg_ctx_reset_transport_out_stream(out_msg_ctx, env);
    axis2_msg_ctx_reset_out_transport_info(out_msg_ctx, env);
    axis2_msg_ctx_set_svc_grp_ctx(out_msg_ctx, env, NULL);

    return;
}

AXIS2_EXTERN axutil_qname_t *AXIS2_CALL
axis2_core_utils_get_module_qname(
    const axutil_env_t * env,
    const axis2_char_t * name,
    const axis2_char_t * version)
{
    axutil_qname_t *ret_qname = NULL;
    AXIS2_PARAM_CHECK(env->error, name, NULL);

    if(version && 0 != axutil_strlen(version))
    {
        axis2_char_t *mod_name1 = NULL;
        axis2_char_t *mod_name = NULL;
        mod_name1 = axutil_stracat(env, name, "-");
        if(!mod_name1)
        {
            return NULL;
        }
        mod_name = axutil_stracat(env, mod_name1, version);
        if(!mod_name)
        {
            AXIS2_FREE(env->allocator, mod_name1);
            mod_name1 = NULL;
            return NULL;
        }
        ret_qname = axutil_qname_create(env, mod_name, NULL, NULL);
        AXIS2_FREE(env->allocator, mod_name);
        AXIS2_FREE(env->allocator, mod_name1);
        return ret_qname;
    }
    ret_qname = axutil_qname_create(env, name, NULL, NULL);
    return ret_qname;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_core_utils_calculate_default_module_version(
    const axutil_env_t * env,
    axutil_hash_t * modules_map,
    axis2_conf_t * axis_conf)
{
    axutil_hash_t *default_modules = NULL;
    axutil_hash_index_t *hi = NULL;
    void *val = NULL;

    AXIS2_PARAM_CHECK(env->error, modules_map, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, axis_conf, AXIS2_FAILURE);

    default_modules = axutil_hash_make(env);
    if(!default_modules)
    {
        return AXIS2_FAILURE;
    }
    for(hi = axutil_hash_first(modules_map, env); hi; hi = axutil_hash_next(env, hi))
    {
        axis2_module_desc_t *mod_desc = NULL;

        axutil_hash_this(hi, NULL, NULL, &val);
        mod_desc = (axis2_module_desc_t *)val;
        if(mod_desc)
        {
            const axutil_qname_t *module_qname = NULL;
            module_qname = axis2_module_desc_get_qname(mod_desc, env);
            if(module_qname)
            {
                axis2_char_t *mod_name_with_ver = NULL;
                mod_name_with_ver = axutil_qname_get_localpart(module_qname, env);
                if(mod_name_with_ver)
                {
                    axis2_char_t *module_name_str = NULL;
                    axis2_char_t *module_ver_str = NULL;
                    axis2_char_t *current_def_ver = NULL;

                    module_name_str = axis2_core_utils_get_module_name(env, mod_name_with_ver);
                    if(!module_name_str)
                    {
                        return AXIS2_FAILURE;
                    }
                    module_ver_str = axis2_core_utils_get_module_version(env, mod_name_with_ver);
                    current_def_ver = axutil_hash_get(default_modules, module_name_str,
                        AXIS2_HASH_KEY_STRING);
                    if(current_def_ver)
                    {
                        if(module_ver_str && AXIS2_TRUE == axis2_core_utils_is_latest_mod_ver(env,
                            module_ver_str, current_def_ver))
                        {
                            axutil_hash_set(default_modules, module_name_str,
                                AXIS2_HASH_KEY_STRING, module_ver_str);
                        }
                        else
                        {
                            if(module_name_str)
                            {
                                AXIS2_FREE(env->allocator, module_name_str);
                            }
                            if(module_ver_str)
                            {
                                AXIS2_FREE(env->allocator, module_ver_str);
                            }
                        }
                    }
                    else
                    {
                        axutil_hash_set(default_modules, module_name_str, AXIS2_HASH_KEY_STRING,
                            module_ver_str);
                    }

                    if(module_name_str)
                    {
                        AXIS2_FREE(env->allocator, module_name_str);
                    }
                }
            }
        }
        val = NULL;
    }

    hi = NULL;
    val = NULL;
    for(hi = axutil_hash_first(default_modules, env); hi; hi = axutil_hash_next(env, hi))
    {
        void *key_string = NULL;
        axutil_hash_this(hi, (const void **)&key_string, NULL, &val);
        if(key_string && NULL != val)
        {
            axis2_conf_add_default_module_version(axis_conf, env, (axis2_char_t *)key_string,
                (axis2_char_t *)val);
            AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Added default module"
                " version : %s for module : %s", (axis2_char_t *)val, (axis2_char_t *)key_string);
        }
    }

    if(default_modules)
    {
        axutil_hash_free(default_modules, env);
        default_modules = NULL;
    }

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axis2_core_utils_get_module_name(
    const axutil_env_t * env,
    axis2_char_t * module_name)
{
    axis2_char_t version_seperator = '-';
    axis2_char_t *name = NULL;
    axis2_char_t *version_sep_loc = NULL;

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

    name = axutil_strdup(env, module_name);
    if(!name)
    {
        return NULL;
    }
    version_sep_loc = axutil_rindex(name, version_seperator);
    if(version_sep_loc)
    {
        *version_sep_loc = '\0';
    }
    return name;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axis2_core_utils_get_module_version(
    const axutil_env_t * env,
    axis2_char_t * module_name)
{
    axis2_char_t version_seperator = '-';
    axis2_char_t *version_sep_loc = NULL;

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

    version_sep_loc = axutil_rindex(module_name, version_seperator);
    if(version_sep_loc)
    {
        return axutil_strdup(env, version_sep_loc + sizeof(axis2_char_t));
    }
    return NULL;
}

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axis2_core_utils_is_latest_mod_ver(
    const axutil_env_t * env,
    axis2_char_t * module_ver,
    axis2_char_t * current_def_ver)
{
    double cur_ver = 0.0;
    double mod_ver = 0.0;
    AXIS2_PARAM_CHECK(env->error, module_ver, AXIS2_FALSE);
    AXIS2_PARAM_CHECK(env->error, current_def_ver, AXIS2_FALSE);
    cur_ver = atof(current_def_ver);
    mod_ver = atof(module_ver);
    if(mod_ver > cur_ver)
    {
        return AXIS2_TRUE;
    }
    return AXIS2_FAILURE;
}

/* build the rest map - external function */
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_core_utils_prepare_rest_mapping(
    const axutil_env_t * env,
    axis2_char_t * url,
    axutil_hash_t *rest_map,
    axis2_op_t *op_desc)
{

    axis2_char_t *first_delimitter = NULL;
    axis2_char_t *next_level_url = NULL;
    axis2_char_t *mapping_key = NULL;
    axutil_core_utils_map_internal_t *mapping_struct = NULL;
    axis2_status_t status = AXIS2_SUCCESS;
    axis2_char_t *bracket_start = NULL;

    first_delimitter = axutil_strchr(url, '/');

    if(first_delimitter)
    {
        /* if there is another recursive level,
         this will get the url of that level */
        next_level_url = first_delimitter + 1;
        *first_delimitter = '\0';
    }

    if((bracket_start = axutil_strchr(url, '{')))
    {
        /* we support multiple param per url component,
         but we validate only one param */
        if(axutil_strchr(bracket_start, '}'))
        {
            /* this is validated */
        }

        else
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_URL_FORMAT, AXIS2_FAILURE);
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                "Invalid URL Format, no closing bracket in declaring parameters");
            return AXIS2_FAILURE;
        }
    }

    /* only constants are allowed in this level, so here url become the mapping_key */
    mapping_key = url;

    if(*mapping_key == '\0') /* empty mapping key */
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_URL_FORMAT, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Invalid URL Format: empty mapping key");
        return AXIS2_FAILURE;
    }

    /* retrieve or create the mapping structure for the key*/
    mapping_struct = axutil_hash_get(rest_map, mapping_key, AXIS2_HASH_KEY_STRING);
    if(!mapping_struct)
    {
        mapping_struct = (axutil_core_utils_map_internal_t*)AXIS2_MALLOC(env->allocator,
            sizeof(axutil_core_utils_map_internal_t));
        if(!mapping_struct)
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                "No memory. Cannot create internal rest mapping structure");
            return AXIS2_FAILURE;

        }
        memset(mapping_struct, 0, sizeof(axutil_core_utils_map_internal_t));

        mapping_key = axutil_strdup(env, mapping_key);
        axutil_hash_set(rest_map, mapping_key, AXIS2_HASH_KEY_STRING, mapping_struct);
    }

    if(!next_level_url)
    {
        /* if no next level url, put the op_desc in right this level */
        if(mapping_struct->op_desc)
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_DUPLICATE_URL_REST_MAPPING, AXIS2_FAILURE);
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Duplicate URL Mapping found");
            return AXIS2_FAILURE;
        }
        mapping_struct->op_desc = op_desc;
    }
    else
    {
        /* we have to build the map_internal structure recursively */
        status = axis2_core_utils_internal_build_rest_map_recursively(env, next_level_url,
            mapping_struct, op_desc);
    }

    return status;

}

/* build the restmap recursively - internal function*/
axis2_status_t AXIS2_CALL
axis2_core_utils_internal_build_rest_map_recursively(
    const axutil_env_t * env,
    axis2_char_t * url,
    axutil_core_utils_map_internal_t *parent_mapping_struct,
    axis2_op_t *op_desc)
{

    /* Here url is expected to be in the form
     {student}/marks/{subject} or
     marks/{subject}
     */

    axis2_char_t *first_delimitter = NULL;
    axis2_char_t *next_level_url = NULL;
    axis2_char_t *mapping_key = NULL;
    axutil_core_utils_map_internal_t *mapping_struct = NULL;
    axutil_hash_t *cur_level_rest_map = NULL;
    axis2_status_t status = AXIS2_SUCCESS;
    axis2_char_t *bracket_start = NULL;

    axis2_bool_t is_key_a_param = AXIS2_FALSE;

    first_delimitter = axutil_strchr(url, '/');

    if(first_delimitter)
    {
        /* if there is another recurisive level,
         this will get the url of that level */
        next_level_url = first_delimitter + 1;
        *first_delimitter = '\0';
    }

    if((bracket_start = axutil_strchr(url, '{')))
    {
        /* we support multiple param per url component,
         but we validate only one param */
        if(axutil_strchr(bracket_start, '}'))
        {
            is_key_a_param = AXIS2_TRUE;
        }

        else
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_URL_FORMAT, AXIS2_FAILURE);
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                "Invalid URL Format, no closing bracket in declaring parameters");
            return AXIS2_FAILURE;
        }
    }

    /* here the url become the mapping_key */
    mapping_key = url;

    if(*mapping_key == '\0') /* empty mappng key */
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_URL_FORMAT, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Invalid URL Format: empty mapping key");
        return AXIS2_FAILURE;
    }

    if(is_key_a_param)
    {
        /* set the rest map as the params_map */
        if(parent_mapping_struct->params_map == NULL)
        {
            parent_mapping_struct->params_map = axutil_hash_make(env);
            if(!parent_mapping_struct->params_map)
            {
                AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                    "No memory. Cannot create internal rest mapping structure");
                return AXIS2_FAILURE;
            }
        }
        cur_level_rest_map = parent_mapping_struct->params_map;
    }
    else
    {
        /* set the rest map as the consts_map */
        if(parent_mapping_struct->consts_map == NULL)
        {
            parent_mapping_struct->consts_map = axutil_hash_make(env);
            if(!parent_mapping_struct->consts_map)
            {
                AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                    "No memory. Cannot create internal rest mapping structure");
                return AXIS2_FAILURE;
            }
        }
        cur_level_rest_map = parent_mapping_struct->consts_map;
    }

    /* retrieve or create the maping structure for the key*/
    mapping_struct = axutil_hash_get(cur_level_rest_map, mapping_key, AXIS2_HASH_KEY_STRING);
    if(!mapping_struct)
    {
        mapping_struct = (axutil_core_utils_map_internal_t*)AXIS2_MALLOC(env->allocator,
            sizeof(axutil_core_utils_map_internal_t));
        if(!mapping_struct)
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                "No memory. Cannot create internal rest mapping structure");
            return AXIS2_FAILURE;

        }
        memset(mapping_struct, 0, sizeof(axutil_core_utils_map_internal_t));

        mapping_key = axutil_strdup(env, mapping_key);
        axutil_hash_set(cur_level_rest_map, mapping_key, AXIS2_HASH_KEY_STRING, mapping_struct);
    }

    if(!next_level_url)
    {
        /* if no next level url, put the op_desc in right this level */
        if(mapping_struct->op_desc)
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_DUPLICATE_URL_REST_MAPPING, AXIS2_FAILURE);
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Duplicate URL Mapping found");
            return AXIS2_FAILURE;
        }
        mapping_struct->op_desc = op_desc;
    }
    else
    {
        /* we have to build the map_internal structure recursively */
        status = axis2_core_utils_internal_build_rest_map_recursively(env, next_level_url,
            mapping_struct, op_desc);
    }

    return status;
}

/* free the rest map recursively */
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_core_utils_free_rest_map(
    const axutil_env_t *env,
    axutil_hash_t *rest_map)
{

    axutil_hash_index_t *hi = NULL;
    const void *key = NULL;
    void *val = NULL;
    axis2_status_t status = AXIS2_SUCCESS;

    for(hi = axutil_hash_first(rest_map, env); hi; hi = axutil_hash_next(env, hi))
    {
        axutil_hash_this(hi, &key, NULL, &val);

        if(val)
        {
            axutil_core_utils_map_internal_t *mapping_struct = NULL;
            mapping_struct = (axutil_core_utils_map_internal_t*)val;

            /* freeing the consts_map and params_map */
            if(mapping_struct->consts_map)
            {
                axis2_core_utils_free_rest_map(env, mapping_struct->consts_map);
            }

            if(mapping_struct->params_map)
            {
                axis2_core_utils_free_rest_map(env, mapping_struct->params_map);
            }
            AXIS2_FREE(env->allocator, mapping_struct);
        }

        if(key)
        {
            AXIS2_FREE(env->allocator, (axis2_char_t *)key);
            key = NULL;
        }
    }
    axutil_hash_free(rest_map, env);
    return status;
}

AXIS2_EXTERN axis2_op_t *AXIS2_CALL
axis2_core_utils_get_rest_op_with_method_and_location(
    axis2_svc_t *svc,
    const axutil_env_t *env,
    const axis2_char_t *method,
    const axis2_char_t *location,
    axutil_array_list_t *param_keys,
    axutil_array_list_t *param_values)
{
    axis2_char_t *addition_params_str = NULL;
    axis2_char_t *adjusted_local_url = NULL;

    axis2_char_t *live_mapping_url = NULL;
    axis2_char_t *local_url = NULL;

    axis2_op_t *op = NULL;

    int key_len = 0;

    AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Checking for operation using "
        "REST HTTP Location fragment : %s", location);

    /* we are creating a dup of the location */
    local_url = (axis2_char_t*)axutil_strdup(env, location);
    if(!local_url)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "No memory. Cannot create the live rest mapping url");
        return NULL;
    }

    /* checking the existence of the addition parameters
     after the question mark '?' */
    addition_params_str = strchr(local_url, '?');
    if(addition_params_str)
    {
        *addition_params_str = '\0';
        addition_params_str++;
    }

    /* if the first character is '/' ignore that */
    if(*local_url == '/')
    {
        adjusted_local_url = local_url + 1;
    }
    else
    {
        adjusted_local_url = local_url;
    }

    /* now create the mapping url */
    key_len = axutil_strlen(method) + axutil_strlen(adjusted_local_url) + 2;

    live_mapping_url
        = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * key_len));

    if(!live_mapping_url)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "No memory. Cannot create the live rest mapping url");
        AXIS2_FREE(env->allocator, local_url);
        return NULL;
    }

    sprintf(live_mapping_url, "%s:%s", method, adjusted_local_url);

    op = axis2_core_utils_infer_op_from_parent_rest_map(env, axis2_svc_get_rest_map(svc, env),
        live_mapping_url, param_keys, param_values);

    if(op)
    {
        axis2_char_t *params_str;

        AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
            "Operation found using target endpoint uri fragment");

        /* here we are going to extract out the additional parameters 
         * put after '?' mark */
        params_str = addition_params_str;
        while(params_str && *params_str != '\0')
        {
            axis2_char_t *next_params_str = NULL;
            axis2_char_t *key_value_seperator = NULL;

            axis2_char_t *key = NULL;
            axis2_char_t *value = NULL;

            /* we take one parameter pair to the params_str */
            next_params_str = strchr(params_str, '&');
            if(next_params_str)
            {
                *next_params_str = '\0';
            }

            key_value_seperator = strchr(params_str, '=');
            if(key_value_seperator)
            {
                /* devide the key value pair */
                *key_value_seperator = '\0';
                key = params_str;
                value = key_value_seperator + 1;
            }
            else
            {
                /* there is no '=' symbol, that mean only the key exist */
                key = params_str;
            }
            if(key)
            {
                key = axutil_strdup(env, key);
                axutil_array_list_add(param_keys, env, key);
            }
            if(value)
            {
                value = axutil_strdup(env, value);
                axutil_array_list_add(param_values, env, value);
            }

            if(next_params_str)
            {
                /* if there was an '&' character then */
                params_str = next_params_str + 1;
            }
            else
            {
                params_str = NULL; /* just to end the loop */
            }
        }
    }

    if(live_mapping_url)
    {
        AXIS2_FREE(env->allocator, live_mapping_url);
    }
    if(local_url)
    {
        AXIS2_FREE(env->allocator, local_url);
    }
    return op;
}

/* infer op from the live url */
axis2_op_t *
axis2_core_utils_infer_op_from_parent_rest_map(
    const axutil_env_t *env,
    axutil_hash_t *rest_map,
    axis2_char_t *live_url,
    axutil_array_list_t *param_keys,
    axutil_array_list_t *param_values)
{
    axis2_char_t *first_delimitter = NULL;
    axis2_char_t *next_level_url = NULL;
    axis2_char_t *url_component = NULL;

    axis2_op_t *op_desc = NULL;
    axutil_core_utils_map_internal_t *mapping_struct = NULL;

    first_delimitter = axutil_strchr(live_url, '/');

    if(first_delimitter)
    {
        /* if there is another recursive level,
         this will get the url of that level */
        next_level_url = first_delimitter + 1;
        *first_delimitter = '\0';
    }

    /* so live url is the url_component */
    url_component = live_url;

    /* check it in the hash map */
    mapping_struct = (axutil_core_utils_map_internal_t*)axutil_hash_get(rest_map, url_component,
        AXIS2_HASH_KEY_STRING);

    if(mapping_struct)
    {
        if(!next_level_url)
        {
            /* if no level exists, find it here */
            op_desc = mapping_struct->op_desc;
        }
        else
        {

            op_desc = axis2_core_utils_internal_infer_op_from_rest_map_recursively(env,
                mapping_struct, next_level_url, param_keys, param_values);
        }
    }
    if(!op_desc)
    {
        /* if the url is not mapped to the given constant url 
         * we have to match it with the url pattern */

        axutil_hash_index_t *hi = NULL;
        const void *key = NULL;
        void *val = NULL;
        axis2_status_t matched_status = AXIS2_FAILURE;

        for(hi = axutil_hash_first(rest_map, env); hi; hi = axutil_hash_next(env, hi))
        {
            axutil_hash_this(hi, &key, NULL, &val);

            if(key == url_component)
            {
                continue; /* skip the already checked key */
            }
            if(key && val)
            {
                axis2_char_t *hash_key = (axis2_char_t*)key;
                axis2_char_t *dup_url_component = NULL;
                axis2_char_t *dup_pattern = NULL;

                /* temporary param keys and values for each entry */
                axutil_array_list_t *tmp_param_keys = NULL;
                axutil_array_list_t *tmp_param_values = NULL;

                tmp_param_keys = axutil_array_list_create(env, 10);
                if(!tmp_param_keys)
                {
                    AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                        "No memory. Cannot create internal rest mapping structure");

                    return NULL;
                }
                tmp_param_values = axutil_array_list_create(env, 10);
                if(!tmp_param_values)
                {
                    AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                        "No memory. Cannot create internal rest mapping structure");
                    axutil_array_list_free(tmp_param_keys, env);
                    return NULL;
                }

                dup_url_component = axutil_strdup(env, url_component);
                if(!dup_url_component)
                {
                    AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                        "No memory. Cannot create internal rest mapping structure");
                    axutil_array_list_free(tmp_param_keys, env);
                    axutil_array_list_free(tmp_param_values, env);
                    return NULL;
                }
                dup_pattern = axutil_strdup(env, hash_key);
                if(!dup_pattern)
                {
                    AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                        "No memory. Cannot create internal rest mapping structure");
                    axutil_array_list_free(tmp_param_keys, env);
                    axutil_array_list_free(tmp_param_values, env);
                    AXIS2_FREE(env->allocator, dup_url_component);
                    return NULL;
                }

                matched_status = axis2_core_utils_match_url_component_with_pattern(env,
                    dup_pattern, dup_url_component, tmp_param_keys, tmp_param_values);

                AXIS2_FREE(env->allocator, dup_url_component);
                AXIS2_FREE(env->allocator, dup_pattern);

                if(matched_status == AXIS2_SUCCESS && val)
                {
                    mapping_struct = (axutil_core_utils_map_internal_t*)val;

                    if(!next_level_url)
                    {
                        op_desc = mapping_struct->op_desc;
                    }
                    else
                    {

                        op_desc = axis2_core_utils_internal_infer_op_from_rest_map_recursively(env,
                            mapping_struct, next_level_url, tmp_param_keys, tmp_param_values);
                    }
                    if(op_desc)
                    {
                        /* we are done, the url is matched with a pattern */
                        /* but before leaving should merge the param arrays */

                        int i = 0;
                        void *param_key = NULL;
                        void *param_value = NULL;

                        for(i = 0; i < axutil_array_list_size(tmp_param_keys, env); i++)
                        {
                            /* size(tmp_param_keys) == size(tmp_param_values) */
                            param_key = axutil_array_list_get(tmp_param_keys, env, i);
                            param_value = axutil_array_list_get(tmp_param_values, env, i);

                            /* add it to original array */
                            axutil_array_list_add(param_keys, env, param_key);
                            axutil_array_list_add(param_values, env, param_value);

                        }
                        /* since of is found, no more searches needed */
                        break;
                    }
                }
                /* freeing the temporary arrays */
                axutil_array_list_free(tmp_param_keys, env);
                axutil_array_list_free(tmp_param_values, env);
            }
        }
    }

    if(!op_desc)
    {
        /* no more to look up */
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_URL_FORMAT, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "REST maping structure is NULL for the accessed URL");
        return NULL;
    }

    return op_desc;
}

/* infer op from the live url recursively */
axis2_op_t *AXIS2_CALL
axis2_core_utils_internal_infer_op_from_rest_map_recursively(
    const axutil_env_t *env,
    const axutil_core_utils_map_internal_t *parent_mapping_struct,
    axis2_char_t *live_url,
    axutil_array_list_t *param_keys,
    axutil_array_list_t *param_values)
{

    axis2_char_t *first_delimitter = NULL;
    axis2_char_t *next_level_url = NULL;
    axis2_char_t *url_component = NULL;

    axis2_op_t *op_desc = NULL;
    axutil_core_utils_map_internal_t *child_mapping_struct = NULL;

    axutil_hash_index_t *hi = NULL;
    const void *key = NULL;
    void *val = NULL;

    first_delimitter = axutil_strchr(live_url, '/');

    if(first_delimitter)
    {
        /* if there is another recurisive level,
         this will get the url of that level */
        next_level_url = first_delimitter + 1;
        *first_delimitter = '\0';
    }

    /* so live url is the url_component */
    url_component = live_url;

    /* first check the url component in the constants array list */
    if(parent_mapping_struct->consts_map)
    {
        child_mapping_struct = axutil_hash_get(parent_mapping_struct->consts_map, url_component,
            AXIS2_HASH_KEY_STRING);
    }

    /* if the url component exists in the consts_map, go through it inside */

    if(child_mapping_struct)
    {
        if(!next_level_url)
        {
            /* there is no another level, so the op should be here */

            op_desc = child_mapping_struct->op_desc;

            if(!op_desc)
            {
                AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
                    "The operation descriptor not found constant given in the url");
            }
            /* rather than returning NULL we continue to search params_map */

        }
        else
        {

            op_desc = axis2_core_utils_internal_infer_op_from_rest_map_recursively(env,
                child_mapping_struct, next_level_url, param_keys, param_values);
        }
    }

    if(op_desc)
    {
        /* if the op for the accessed url found, no further searching is needed */
        return op_desc;
    }

    /* if it is not found in the consts_map we have to assume it is in a params_map */

    if(!parent_mapping_struct->params_map)
    {
        /* wrong operation, abort to continue to let calling function to check other operations */
        if(first_delimitter)
        {
            /* restore the delimmiters */
            *first_delimitter = '/';
        }
        return NULL;
    }

    for(hi = axutil_hash_first(parent_mapping_struct->params_map, env); hi; hi = axutil_hash_next(
        env, hi))
    {
        axutil_hash_this(hi, &key, NULL, &val);

        if(key && val)
        {
            int i = 0;
            axis2_char_t *hash_key = (axis2_char_t*)key;
            axis2_status_t matched_status = AXIS2_SUCCESS;
            axis2_char_t *dup_url_component = NULL;
            axis2_char_t *dup_pattern = NULL;

            /* temporary param keys and values for each entry */
            axutil_array_list_t *tmp_param_keys;
            axutil_array_list_t *tmp_param_values;

            tmp_param_keys = axutil_array_list_create(env, 10);
            if(!tmp_param_keys)
            {
                AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                    "No memory. Cannot create internal rest mapping structure");

                return NULL;
            }
            tmp_param_values = axutil_array_list_create(env, 10);
            if(!tmp_param_values)
            {
                AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                    "No memory. Cannot create internal rest mapping structure");
                axutil_array_list_free(tmp_param_keys, env);
                return NULL;
            }

            dup_url_component = axutil_strdup(env, url_component);
            if(!dup_url_component)
            {
                AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                    "No memory. Cannot create internal rest mapping structure");
                axutil_array_list_free(tmp_param_keys, env);
                axutil_array_list_free(tmp_param_values, env);
                return NULL;
            }
            dup_pattern = axutil_strdup(env, hash_key);
            if(!dup_pattern)
            {
                AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                    "No memory. Cannot create internal rest mapping structure");
                axutil_array_list_free(tmp_param_keys, env);
                axutil_array_list_free(tmp_param_values, env);
                AXIS2_FREE(env->allocator, dup_url_component);
                return NULL;
            }

            matched_status = axis2_core_utils_match_url_component_with_pattern(env, dup_pattern,
                dup_url_component, tmp_param_keys, tmp_param_values);

            AXIS2_FREE(env->allocator, dup_url_component);
            AXIS2_FREE(env->allocator, dup_pattern);

            if(matched_status == AXIS2_SUCCESS)
            {
                child_mapping_struct = (axutil_core_utils_map_internal_t*)val;

                if(!next_level_url)
                {
                    /* there is no another level, so the op should be here */
                    op_desc = child_mapping_struct->op_desc;

                }
                else
                {

                    /* if there is next level, we should check that level too */
                    op_desc = axis2_core_utils_internal_infer_op_from_rest_map_recursively(env,
                        child_mapping_struct, next_level_url, tmp_param_keys, tmp_param_values);
                }

                if(op_desc)
                {
                    /* the operation is found */
                    /* but before leaving should merge the param arrays */

                    int i = 0;
                    void *param_key = NULL;
                    void *param_value = NULL;
                    for(i = 0; i < axutil_array_list_size(tmp_param_keys, env); i++)
                    {
                        /* size(tmp_param_keys) == size(tmp_param_values) */
                        param_key = axutil_array_list_get(tmp_param_keys, env, i);
                        param_value = axutil_array_list_get(tmp_param_values, env, i);

                        /* add it to original array */
                        axutil_array_list_add(param_keys, env, param_key);
                        axutil_array_list_add(param_values, env, param_value);

                    }

                    /* freeing the temporary arrays */
                    axutil_array_list_free(tmp_param_keys, env);
                    axutil_array_list_free(tmp_param_values, env);
                    /* since of is found, no more searches needed */
                    break;
                }
            }

            /* if we come here => op is not yet found */
            /* just freeing the temp key and value arrays */
            for(i = 0; i < axutil_array_list_size(tmp_param_keys, env); i++)
            {
                void *value = axutil_array_list_get(tmp_param_keys, env, i);
                if(value)
                {
                    AXIS2_FREE(env->allocator, value);
                }
            }
            for(i = 0; i < axutil_array_list_size(tmp_param_values, env); i++)
            {
                void *value = axutil_array_list_get(tmp_param_values, env, i);
                if(value)
                {
                    AXIS2_FREE(env->allocator, value);
                }
            }
            axutil_array_list_free(tmp_param_keys, env);
            axutil_array_list_free(tmp_param_values, env);
        }
    }

    if(!op_desc)
    {
        /* this is not an error, since the calling function
         may find another opertion match with the url */
        AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
            "The operation descriptor not found for the accessed URL");

        if(first_delimitter)
        {
            /* restore the delimmiters */
            *first_delimitter = '/';
        }
    }
    return op_desc;
}

/* match a pattern with a url component */
axis2_status_t
axis2_core_utils_match_url_component_with_pattern(
    const axutil_env_t *env,
    axis2_char_t *pattern,
    axis2_char_t *url_component,
    axutil_array_list_t *param_keys,
    axutil_array_list_t *param_values)
{
    axutil_array_list_t *const_components = NULL;
    axis2_char_t *c = NULL;
    axis2_char_t *url_c = NULL;
    axis2_char_t *pattern_c = NULL;
    axis2_char_t *const_part = NULL;
    axis2_char_t *param_part = NULL;
    axis2_char_t *param_value = NULL;
    axis2_status_t status = AXIS2_SUCCESS;
    /* here the state can have following values
     0 - inside a constant
     1 - inside a param
     */
    int loop_state = 0;
    int i = 0;
    int pattern_ending_with_param = 0;

    /* the constant that undergoing matching */
    int matching_constant_index = 0;
    axis2_char_t *matching_constant = NULL;

    /* dividing the pattern to consts */
    const_components = axutil_array_list_create(env, 10);
    if(!const_components)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "No memory. Cannot create internal rest mapping structure");
    }
    /* check whether the pattern ending with a param */
    if(*(pattern + axutil_strlen(pattern) - 1) == '}')
    {
        pattern_ending_with_param = 1;
    }

    const_part = pattern;
    /* a parse to fil the const array and key array */
    for(c = pattern; c && *c != '\0'; c++)
    {
        if(loop_state == 0)
        {
            /* inside a constant */
            if(*c == '{')
            {
                if(const_part == c)
                {
                    /* no const part */
                }
                else
                {
                    /* add the constant */
                    *c = '\0';
                    const_part = axutil_strdup(env, const_part);
                    if(!const_part)
                    {
                        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
                        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                            "No memory. Cannot create internal rest mapping structure");

                        status = AXIS2_FAILURE;
                        break;

                    }
                    axutil_array_list_add(const_components, env, const_part);

                }
                param_part = c + 1; /* start the param */
                loop_state = 1; /* moving to the param from next iteration */
            }
            else if(*c == '}')
            {
                /* invalid state */
                AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_URL_FORMAT, AXIS2_FAILURE);
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in parsing the url for %s",
                    url_component);

                status = AXIS2_FAILURE;
                break;
            }
        }
        else
        {
            /* inside a param */
            if(*c == '}')
            {
                if(*(c + 1) == '{') /* you can not have two params without a constant in between */
                {
                    /* invalid state */
                    AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_URL_FORMAT, AXIS2_FAILURE);
                    AXIS2_LOG_ERROR(
                        env->log,
                        AXIS2_LOG_SI,
                        "Error in parsing the url for %s, Please put constant between 2 parameters",
                        url_component);

                    status = AXIS2_FAILURE;
                    break;
                }
                if(param_part == c)
                {
                    /* no param part */
                }
                else
                {
                    /* add the param */
                    *c = '\0';
                    param_part = axutil_strdup(env, param_part);

                    if(param_part == NULL)
                    {
                        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
                        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                            "No memory. Cannot create internal rest mapping structure");
                        status = AXIS2_FAILURE;
                        break;
                    }
                    axutil_array_list_add(param_keys, env, param_part);

                    const_part = c + 1; /* start the const */
                }
                loop_state = 0; /* moving to the const from next iteration */
            }
            else if(*c == '{')
            {
                /* invalid state */
                AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_URL_FORMAT, AXIS2_FAILURE);
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in parsing the url for %s",
                    url_component);

                status = AXIS2_FAILURE;
                break;

            }
        }
    }
    /* loop should stop in state 0 */
    if(loop_state != 0)
    {
        status = AXIS2_FAILURE;
    }

    if(const_part != c)
    {
        /* add the tailing const */
        const_part = axutil_strdup(env, const_part);
        if(!const_part)
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                "No memory. Cannot create internal rest mapping structure");
            status = AXIS2_FAILURE;
        }
        axutil_array_list_add(const_components, env, const_part);
    }

    if(axutil_array_list_size(const_components, env) == 0 && status == AXIS2_SUCCESS)
    {
        /* no constants mean, the url componenent itself is the value */
        url_component = axutil_strdup(env, url_component);
        if(url_component)
        {
            axutil_array_list_add(param_values, env, url_component);

            /* free the empty const array */

            axutil_array_list_free(const_components, env);
            return AXIS2_SUCCESS;
        }
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "No memory. Cannot create internal rest mapping structure");
        status = AXIS2_FAILURE;

    }

    if(status == AXIS2_FAILURE)
    {
        /* invalid state */
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_URL_FORMAT, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in parsing the url for %s", url_component);

        /* free the const array */
        for(i = 0; i < axutil_array_list_size(const_components, env); i++)
        {
            void *value;
            value = axutil_array_list_get(const_components, env, i);

            AXIS2_FREE(env->allocator, value);
        }

        axutil_array_list_free(const_components, env);

        return status;
    }

    /* we are tracking the loop_state here too - this is useful only to track start*/
    /* we are using the param_value part to track the matching param value */
    if(*pattern != '{')
    {
        /* starting_with_constant  */
        loop_state = 0;
        param_value = NULL;
    }
    else
    {
        /* starting_with_param  */
        loop_state = 1;
        param_value = url_component;

    }

    matching_constant_index = 0;
    matching_constant = axutil_array_list_get(const_components, env, 0);

    /* now parse the url component */
    for(url_c = url_component; *url_c != '\0' && status == AXIS2_SUCCESS && matching_constant
        != NULL; url_c++)
    {
        axis2_char_t *tmp_url_c = url_c;
        pattern_c = matching_constant;

        while(*tmp_url_c == *pattern_c && *tmp_url_c != '\0' && *pattern_c != '\0')
        {
            tmp_url_c++;
            pattern_c++;
        }

        if(*pattern_c == '\0')
        {
            /* we finised matching the constant pattern successfuly*/
            if(loop_state == 0)
            {
                /* loop_state => we expected there is a constant */
            }
            else
            {
                /* we expected a param, but the constant is found => 
                 url_c should mark the end of the param */
                if(param_value == NULL)
                {
                    /* unexpected invalid state */
                    AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_URL_FORMAT, AXIS2_FAILURE);
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in parsing the url for %s",
                        url_component);
                    status = AXIS2_FAILURE;
                }
                *url_c = '\0';
                param_value = axutil_strdup(env, param_value);

                if(param_value == NULL)
                {
                    AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                        "No memory. Cannot create internal rest mapping structure");
                    status = AXIS2_FAILURE;
                    break;
                }
                axutil_array_list_add(param_values, env, param_value);

            }
            /* next the param part is starting */
            param_value = tmp_url_c;

            loop_state = 1; /* the end of the constant expects, start of a variable */

            /* so we found one constant, go for the other */
            matching_constant_index++;
            matching_constant = axutil_array_list_get(const_components, env,
                matching_constant_index);

            tmp_url_c--;
            /* increment the url_c to tmp_url_c */
            url_c = tmp_url_c;
        }
        else
        {
            /* pattern not matched */
            if(loop_state == 0)
            {
                /* we are expected this to be a constant, but it has not happend
                 * mean: the pattern match failed 
                 */
                status = AXIS2_FAILURE;
                break;
            }
        }

    }

    if(matching_constant_index != axutil_array_list_size(const_components, env))
    {
        status = AXIS2_FAILURE;
    }

    if(pattern_ending_with_param)
    {
        if(param_value)
        {
            param_value = axutil_strdup(env, param_value);

            if(param_value == NULL)
            {
                AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                    "No memory. Cannot create internal rest mapping structure");
                status = AXIS2_FAILURE;
            }
            else
            {
                axutil_array_list_add(param_values, env, param_value);
            }
        }
    }
    else if(*url_c != '\0')
    {
        /* here the pattern ending is a constant (not a param), and matches all are already made
         * but some url part left => this is a not mach */
        status = AXIS2_FAILURE;
    }

    /* finally freeing the const array */
    for(i = 0; i < axutil_array_list_size(const_components, env); i++)
    {
        void *value;
        value = axutil_array_list_get(const_components, env, i);

        AXIS2_FREE(env->allocator, value);
    }
    axutil_array_list_free(const_components, env);

    return status;
}
