/*
 * 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 "axiom_soap12_builder_helper.h"
#include <axutil_array_list.h>
#include "_axiom_soap_body.h"
#include "_axiom_soap_fault.h"
#include "_axiom_soap_envelope.h"
#include "_axiom_soap_fault_code.h"
#include "_axiom_soap_fault_sub_code.h"
#include "_axiom_soap_fault_node.h"
#include "_axiom_soap_fault_detail.h"
#include "_axiom_soap_fault_reason.h"
#include "_axiom_soap_fault_role.h"
#include "_axiom_soap_fault_value.h"
#include "_axiom_soap_fault_text.h"

struct axiom_soap12_builder_helper
{
    axiom_soap_builder_t *soap_builder;

    axis2_bool_t code_present;

    axis2_bool_t reason_present;

    axis2_bool_t node_present;

    axis2_bool_t role_present;

    axis2_bool_t detail_present;

    axis2_bool_t subcode_value_present;

    axis2_bool_t value_present;

    axis2_bool_t sub_code_present;

    axis2_bool_t sub_sub_code_present;

    axis2_bool_t code_processing;

    axis2_bool_t sub_code_processing;

    axis2_bool_t reason_processing;

    axutil_array_list_t *detail_element_names;
};

AXIS2_EXTERN axiom_soap12_builder_helper_t *AXIS2_CALL
axiom_soap12_builder_helper_create(
    const axutil_env_t * env,
    axiom_soap_builder_t * soap_builder)
{
    axiom_soap12_builder_helper_t *builder_helper = NULL;
    AXIS2_ENV_CHECK(env, NULL);
    AXIS2_PARAM_CHECK(env->error, soap_builder, NULL);

    builder_helper = (axiom_soap12_builder_helper_t *)AXIS2_MALLOC(env->allocator,
        sizeof(axiom_soap12_builder_helper_t));
    if(!builder_helper)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create SOAP 1.1 builder helper");
        return NULL;
    }

    builder_helper->code_present = AXIS2_FALSE;
    builder_helper->detail_present = AXIS2_FALSE;
    builder_helper->reason_present = AXIS2_FALSE;
    builder_helper->role_present = AXIS2_FALSE;
    builder_helper->sub_code_present = AXIS2_FALSE;
    builder_helper->reason_processing = AXIS2_FALSE;
    builder_helper->code_processing = AXIS2_FALSE;
    builder_helper->sub_code_processing = AXIS2_FALSE;
    builder_helper->detail_element_names = NULL;
    builder_helper->node_present = AXIS2_FALSE;
    builder_helper->soap_builder = soap_builder;
    builder_helper->sub_sub_code_present = AXIS2_FALSE;
    builder_helper->value_present = AXIS2_FALSE;
    builder_helper->subcode_value_present = AXIS2_FALSE;

    return builder_helper;
}

AXIS2_EXTERN void AXIS2_CALL
axiom_soap12_builder_helper_free(
    axiom_soap12_builder_helper_t * builder_helper,
    const axutil_env_t * env)
{
    AXIS2_ENV_CHECK(env, void);

    if(builder_helper->detail_element_names)
    {
        axutil_array_list_free(builder_helper->detail_element_names, env);
        builder_helper->detail_element_names = NULL;
    }

    AXIS2_FREE(env->allocator, builder_helper);
    builder_helper = NULL;
    return;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_soap12_builder_helper_handle_event(
    axiom_soap12_builder_helper_t * builder_helper,
    const axutil_env_t * env,
    axiom_node_t * om_ele_node,
    int element_level)
{
    axis2_char_t *ele_localname = NULL;
    axiom_element_t *om_ele = NULL;

    axiom_soap_body_t *soap_body = NULL;
    axiom_soap_fault_t *soap_fault = NULL;
    axiom_soap_envelope_t *soap_envelope = NULL;

    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, om_ele_node, AXIS2_FAILURE);

    om_ele = (axiom_element_t *)axiom_node_get_data_element(om_ele_node, env);
    if(!om_ele)
    {
        return AXIS2_FAILURE;
    }

    ele_localname = axiom_element_get_localname(om_ele, env);
    if(!ele_localname)
    {
        return AXIS2_FAILURE;
    }

    soap_envelope = axiom_soap_builder_get_soap_envelope(builder_helper->soap_builder, env);
    if(!soap_envelope)
    {
        return AXIS2_FAILURE;
    }

    soap_body = axiom_soap_envelope_get_body(soap_envelope, env);
    if(!soap_body)
    {
        return AXIS2_FAILURE;
    }

    soap_fault = axiom_soap_body_get_fault(soap_body, env);
    if(!soap_fault)
    {
        return AXIS2_FAILURE;
    }

    if(element_level == 4)
    {
        if(axutil_strcmp(AXIOM_SOAP12_SOAP_FAULT_CODE_LOCAL_NAME, ele_localname) == 0)
        {
            if(builder_helper->code_present)
            {
                AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MULTIPLE_CODE_ELEMENTS_ENCOUNTERED,
                    AXIS2_FAILURE);
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                    "Multiple  fault code elements encountered in SOAP fault");
                return AXIS2_FAILURE;
            }
            else
            {
                axiom_soap_fault_code_t *soap_fault_code = NULL;
                soap_fault_code = axiom_soap_fault_code_create(env);
                if(!soap_fault_code)
                {
                    return AXIS2_FAILURE;
                }
                axiom_soap_fault_code_set_base_node(soap_fault_code, env, om_ele_node);

                axiom_soap_fault_code_set_builder(soap_fault_code, env,
                    builder_helper->soap_builder);

                axiom_soap_fault_set_code(soap_fault, env, soap_fault_code);

                builder_helper->code_present = AXIS2_TRUE;
                builder_helper->code_processing = AXIS2_TRUE;
            }
        }
        else if(axutil_strcmp(AXIOM_SOAP12_SOAP_FAULT_REASON_LOCAL_NAME, ele_localname) == 0)
        {
            if(!(builder_helper->code_processing) && !(builder_helper->sub_code_processing))
            {
                if(builder_helper->code_present)
                {
                    if(builder_helper->reason_present)
                    {
                        AXIS2_ERROR_SET(env->error,
                            AXIS2_ERROR_MULTIPLE_REASON_ELEMENTS_ENCOUNTERED, AXIS2_FAILURE);
                        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                            "Multiple fault reason elements encountered in SOAP fault");

                        return AXIS2_FAILURE;
                    }
                    else
                    {
                        axiom_soap_fault_reason_t *fault_reason = NULL;
                        fault_reason = axiom_soap_fault_reason_create(env);
                        if(!fault_reason)
                        {
                            return AXIS2_FAILURE;
                        }

                        axiom_soap_fault_reason_set_base_node(fault_reason, env, om_ele_node);

                        axiom_soap_fault_set_reason(soap_fault, env, fault_reason);

                        axiom_soap_fault_reason_set_builder(fault_reason, env,
                            builder_helper-> soap_builder);

                        builder_helper->reason_present = AXIS2_TRUE;
                        builder_helper->reason_processing = AXIS2_TRUE;
                    }
                }
                else
                {
                    AXIS2_ERROR_SET(env->error, AXIS2_ERROR_WRONG_ELEMENT_ORDER_ENCOUNTERED,
                        AXIS2_FAILURE);
                    return AXIS2_FAILURE;
                }
            }
            else
            {
                if(builder_helper->code_processing)
                {
                    AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOAP_FAULT_CODE_DOES_NOT_HAVE_A_VALUE,
                        AXIS2_FAILURE);
                    return AXIS2_FAILURE;
                }
                else
                {
                    AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOAP_FAULT_CODE_DOES_NOT_HAVE_A_VALUE,
                        AXIS2_FAILURE);
                    return AXIS2_FAILURE;
                }
            }
        }
        else if(axutil_strcmp(ele_localname, AXIOM_SOAP12_SOAP_FAULT_NODE_LOCAL_NAME) == 0)
        {
            if(!(builder_helper->reason_processing))
            {
                if(builder_helper->reason_present && !(builder_helper->role_present)
                    && !(builder_helper->detail_present))
                {
                    if(builder_helper->node_present)
                    {
                        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MULTIPLE_NODE_ELEMENTS_ENCOUNTERED,
                            AXIS2_FAILURE);
                        return AXIS2_FAILURE;
                    }
                    else
                    {
                        axiom_soap_fault_node_t *soap_fault_node = NULL;
                        soap_fault_node = axiom_soap_fault_node_create(env);
                        if(!soap_fault_node)
                        {
                            return AXIS2_FAILURE;
                        }

                        axiom_soap_fault_node_set_base_node(soap_fault_node, env, om_ele_node);

                        axiom_soap_fault_set_node(soap_fault, env, soap_fault_node);

                        builder_helper->node_present = AXIS2_TRUE;
                    }
                }
                else
                {
                    AXIS2_ERROR_SET(env->error, AXIS2_ERROR_WRONG_ELEMENT_ORDER_ENCOUNTERED,
                        AXIS2_FALSE);

                    return AXIS2_FAILURE;
                }
            }
            else
            {
                AXIS2_ERROR_SET(env->error,
                    AXIS2_ERROR_SOAP_FAULT_REASON_ELEMENT_SHOULD_HAVE_A_TEXT, AXIS2_FALSE);
                return AXIS2_FAILURE;
            }

        }
        else if(axutil_strcmp(ele_localname, AXIOM_SOAP12_SOAP_FAULT_ROLE_LOCAL_NAME) == 0)
        {
            if(!(builder_helper->reason_processing))
            {
                if(builder_helper->reason_present && !(builder_helper->detail_present))
                {
                    if(builder_helper->role_present)
                    {
                        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MULTIPLE_ROLE_ELEMENTS_ENCOUNTERED,
                            AXIS2_FAILURE);

                        return AXIS2_FAILURE;
                    }
                    else
                    {
                        axiom_soap_fault_role_t *soap_fault_role = NULL;
                        soap_fault_role = axiom_soap_fault_role_create(env);
                        if(!soap_fault_role)
                            return AXIS2_FAILURE;

                        axiom_soap_fault_role_set_base_node(soap_fault_role, env, om_ele_node);

                        axiom_soap_fault_set_role(soap_fault, env, soap_fault_role);
                        builder_helper->role_present = AXIS2_TRUE;
                    }
                }
                else
                {
                    AXIS2_ERROR_SET(env->error, AXIS2_ERROR_WRONG_ELEMENT_ORDER_ENCOUNTERED,
                        AXIS2_FAILURE);
                    return AXIS2_FAILURE;
                }
            }
            else
            {

                AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOAP_FAULT_ROLE_ELEMENT_SHOULD_HAVE_A_TEXT,
                    AXIS2_FAILURE);
                return AXIS2_FAILURE;
            }
        }
        else if(axutil_strcmp(ele_localname, AXIOM_SOAP12_SOAP_FAULT_DETAIL_LOCAL_NAME) == 0)
        {
            if(!(builder_helper->reason_processing))
            {
                if(builder_helper->reason_present)
                {
                    if(builder_helper->detail_present)
                    {
                        AXIS2_ERROR_SET(env->error,
                            AXIS2_ERROR_MULTIPLE_DETAIL_ELEMENTS_ENCOUNTERED, AXIS2_FAILURE);
                        return AXIS2_FAILURE;
                    }
                    else
                    {

                        axiom_soap_fault_detail_t *soap_fault_detail = NULL;
                        soap_fault_detail = axiom_soap_fault_detail_create(env);
                        if(!soap_fault_detail)
                            return AXIS2_FAILURE;

                        axiom_soap_fault_detail_set_base_node(soap_fault_detail, env, om_ele_node);

                        axiom_soap_fault_set_detail(soap_fault, env, soap_fault_detail);
                        builder_helper->detail_present = AXIS2_TRUE;
                    }
                }
                else
                {
                    AXIS2_ERROR_SET(env->error, AXIS2_ERROR_WRONG_ELEMENT_ORDER_ENCOUNTERED,
                        AXIS2_FAILURE);

                    return AXIS2_FAILURE;

                }
            }
            else
            {
                AXIS2_ERROR_SET(env->error,
                    AXIS2_ERROR_SOAP_FAULT_REASON_ELEMENT_SHOULD_HAVE_A_TEXT, AXIS2_FAILURE);
                return AXIS2_FAILURE;
            }

        }
        else
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_UNSUPPORTED_ELEMENT_IN_SOAP_FAULT_ELEMENT,
                AXIS2_FAILURE);
            return AXIS2_FAILURE;
        }
    }
    else if(element_level == 5)
    {
        axiom_node_t *parent_node = NULL;
        axiom_element_t *parent_ele = NULL;
        axis2_char_t *parent_localname = NULL;
        parent_node = axiom_node_get_parent(om_ele_node, env);
        if(!parent_node)
        {
            return AXIS2_FAILURE;
        }
        parent_ele = (axiom_element_t *)axiom_node_get_data_element(parent_node, env);
        if(!parent_ele)
        {
            return AXIS2_FAILURE;
        }
        parent_localname = axiom_element_get_localname(parent_ele, env);
        if(!parent_localname)
        {
            return AXIS2_FAILURE;
        }

        if(axutil_strcmp(parent_localname, AXIOM_SOAP12_SOAP_FAULT_CODE_LOCAL_NAME) == 0)
        {
            if(axutil_strcmp(ele_localname, AXIOM_SOAP12_SOAP_FAULT_VALUE_LOCAL_NAME) == 0)
            {
                if(!(builder_helper->value_present))
                {
                    axiom_soap_fault_value_t *soap_fault_value = NULL;
                    axiom_soap_fault_code_t *parent_fcode = NULL;

                    soap_fault_value = axiom_soap_fault_value_create(env);
                    if(!soap_fault_value)
                    {
                        return AXIS2_FAILURE;
                    }
                    axiom_soap_fault_value_set_base_node(soap_fault_value, env, om_ele_node);

                    parent_fcode = axiom_soap_fault_get_code(soap_fault, env);
                    if(!parent_fcode)
                    {
                        return AXIS2_FAILURE;
                    }
                    axiom_soap_fault_code_set_value(parent_fcode, env, soap_fault_value);

                    builder_helper->value_present = AXIS2_TRUE;
                    builder_helper->code_processing = AXIS2_FALSE;

                }
                else
                {
                    AXIS2_ERROR_SET(env->error,
                        AXIS2_ERROR_MULTIPLE_VALUE_ENCOUNTERED_IN_CODE_ELEMENT, AXIS2_FAILURE);
                    return AXIS2_FAILURE;
                }
            }
            else if(axutil_strcmp(ele_localname, AXIOM_SOAP12_SOAP_FAULT_SUB_CODE_LOCAL_NAME) == 0)
            {
                if(!(builder_helper->sub_code_present))
                {
                    if(builder_helper->value_present)
                    {

                        axiom_soap_fault_sub_code_t *fault_subcode = NULL;
                        axiom_soap_fault_code_t *fault_code = NULL;

                        fault_subcode = axiom_soap_fault_sub_code_create(env);
                        if(!fault_subcode)
                        {
                            return AXIS2_FAILURE;
                        }
                        axiom_soap_fault_sub_code_set_base_node(fault_subcode, env, om_ele_node);

                        fault_code = axiom_soap_fault_get_code(soap_fault, env);
                        if(!fault_code)
                        {
                            return AXIS2_FAILURE;
                        }
                        axiom_soap_fault_code_set_sub_code(fault_code, env, fault_subcode);

                        axiom_soap_fault_sub_code_set_builder(fault_subcode, env,
                            builder_helper-> soap_builder);

                        builder_helper->sub_code_present = AXIS2_TRUE;
                        builder_helper->sub_code_processing = AXIS2_TRUE;
                    }
                    else
                    {
                        AXIS2_ERROR_SET(env->error,
                            AXIS2_ERROR_SOAP_FAULT_VALUE_SHOULD_BE_PRESENT_BEFORE_SUB_CODE,
                            AXIS2_FAILURE);
                        return AXIS2_FAILURE;
                    }
                }
                else
                {
                    AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MULTIPLE_SUB_CODE_VALUES_ENCOUNTERED,
                        AXIS2_FAILURE);
                    return AXIS2_FAILURE;
                }
            }
            else
            {
                AXIS2_ERROR_SET(env->error,
                    AXIS2_ERROR_THIS_LOCALNAME_NOT_SUPPORTED_INSIDE_THE_CODE_ELEMENT, AXIS2_FAILURE);
                return AXIS2_FAILURE;
            }
        }
        else if(axutil_strcmp(parent_localname, AXIOM_SOAP12_SOAP_FAULT_REASON_LOCAL_NAME) == 0)
        {
            if(axutil_strcmp(ele_localname, AXIOM_SOAP12_SOAP_FAULT_TEXT_LOCAL_NAME) == 0)
            {
                axiom_soap_fault_text_t *soap_fault_text = NULL;
                axiom_soap_fault_reason_t *fault_reason = NULL;

                soap_fault_text = axiom_soap_fault_text_create(env);
                if(!soap_fault_text)
                {
                    return AXIS2_FAILURE;
                }
                axiom_soap_fault_text_set_base_node(soap_fault_text, env, om_ele_node);

                fault_reason = axiom_soap_fault_get_reason(soap_fault, env);
                if(!fault_reason)
                {
                    return AXIS2_FAILURE;
                }

                axiom_soap_fault_reason_add_soap_fault_text(fault_reason, env, soap_fault_text);
                builder_helper->reason_processing = AXIS2_FALSE;

                axiom_soap_builder_set_bool_processing_mandatory_fault_elements(
                    builder_helper->soap_builder, env, AXIS2_FALSE);

            }
            else
            {
                AXIS2_ERROR_SET(env->error,
                    AXIS2_ERROR_THIS_LOCALNAME_IS_NOT_SUPPORTED_INSIDE_THE_REASON_ELEMENT,
                    AXIS2_FAILURE);
                return AXIS2_FAILURE;
            }

        }
        else if(axutil_strcmp(parent_localname, AXIOM_SOAP12_SOAP_FAULT_DETAIL_LOCAL_NAME) == 0)
        {
            axiom_soap_builder_set_processing_detail_elements(builder_helper-> soap_builder, env,
                AXIS2_TRUE);

            if(!(builder_helper->detail_element_names))
            {
                builder_helper->detail_element_names = axutil_array_list_create(env, 20);
            }

            axutil_array_list_add(builder_helper->detail_element_names, env, ele_localname);

        }
        else
        {

            return AXIS2_FAILURE;
        }

    }
    else if(element_level > 5)
    {
        axiom_node_t *parent_node = NULL;
        axiom_element_t *parent_ele = NULL;
        axis2_char_t *parent_localname = NULL;

        parent_node = axiom_node_get_parent(om_ele_node, env);
        if(!parent_node)
        {
            return AXIS2_FAILURE;
        }
        parent_ele = (axiom_element_t *)axiom_node_get_data_element(parent_node, env);
        if(!parent_ele)
        {
            return AXIS2_FAILURE;
        }

        parent_localname = axiom_element_get_localname(parent_ele, env);
        if(!parent_localname)
        {
            return AXIS2_FAILURE;
        }
        if(axutil_strcmp(parent_localname, AXIOM_SOAP12_SOAP_FAULT_SUB_CODE_LOCAL_NAME) == 0)
        {
            if(axutil_strcmp(ele_localname, AXIOM_SOAP12_SOAP_FAULT_VALUE_LOCAL_NAME) == 0)
            {
                if(builder_helper->subcode_value_present)
                {
                    AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MULTIPLE_SUB_CODE_VALUES_ENCOUNTERED,
                        AXIS2_FAILURE);
                    return AXIS2_FAILURE;
                }
                else
                {

                    axiom_soap_fault_sub_code_t *sub_code = NULL;
                    axiom_soap_fault_code_t *code = NULL;
                    axiom_soap_fault_value_t *value = NULL;
                    code = axiom_soap_fault_get_code(soap_fault, env);

                    if(!code)
                    {
                        AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
                            "fault code null when it should not be null");
                        return AXIS2_FAILURE;
                    }

                    sub_code = axiom_soap_fault_code_get_sub_code(code, env);
                    if(!sub_code)
                    {
                        AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
                            "fault subcode null when it should not be null");
                        return AXIS2_FAILURE;
                    }
                    value = axiom_soap_fault_value_create(env);
                    if(!value)
                    {
                        return AXIS2_FAILURE;
                    }

                    axiom_soap_fault_value_set_base_node(value, env, om_ele_node);

                    axiom_soap_fault_sub_code_set_value(sub_code, env, value);

                    builder_helper->subcode_value_present = AXIS2_TRUE;
                    builder_helper->sub_sub_code_present = AXIS2_FALSE;
                    builder_helper->sub_code_processing = AXIS2_FALSE;
                }
            }
            else if(axutil_strcmp(ele_localname, AXIOM_SOAP12_SOAP_FAULT_SUB_CODE_LOCAL_NAME) == 0)
            {
                if(builder_helper->subcode_value_present)
                {
                    if(!(builder_helper->sub_sub_code_present))
                    {
                        axiom_soap_fault_code_t *fault_code = NULL;
                        axiom_soap_fault_sub_code_t *parent_subcode = NULL;
                        axiom_soap_fault_sub_code_t *subcode = NULL;

                        subcode = axiom_soap_fault_sub_code_create(env);
                        if(!subcode)
                        {
                            return AXIS2_FAILURE;
                        }

                        axiom_soap_fault_sub_code_set_base_node(subcode, env, om_ele_node);

                        fault_code = axiom_soap_fault_get_code(soap_fault, env);
                        if(!fault_code)
                        {
                            AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
                                "fault code null when it should not be null");
                            return AXIS2_FAILURE;
                        }
                        parent_subcode = axiom_soap_fault_code_get_sub_code(fault_code, env);
                        if(!parent_subcode)
                        {
                            AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
                                "fault subcode null when it should not be null");
                            return AXIS2_FAILURE;
                        }

                        axiom_soap_fault_sub_code_set_sub_code(parent_subcode, env, subcode);

                        builder_helper->subcode_value_present = AXIS2_FALSE;
                        builder_helper->sub_sub_code_present = AXIS2_TRUE;
                        builder_helper->sub_code_processing = AXIS2_TRUE;
                    }
                    else
                    {
                        AXIS2_ERROR_SET(env->error,
                            AXIS2_ERROR_MULTIPLE_SUB_CODE_VALUES_ENCOUNTERED, AXIS2_FAILURE);

                        return AXIS2_FAILURE;
                    }
                }
                else
                {
                    AXIS2_ERROR_SET(env->error,
                        AXIS2_ERROR_SOAP_FAULT_VALUE_SHOULD_BE_PRESENT_BEFORE_SUB_CODE,
                        AXIS2_FAILURE);

                    return AXIS2_FAILURE;

                }
            }
            else
            {
                AXIS2_ERROR_SET(env->error,
                    AXIS2_ERROR_THIS_LOCALNAME_IS_NOT_SUPPORTED_INSIDE_THE_SUB_CODE_ELEMENT,
                    AXIS2_FAILURE);

                return AXIS2_FAILURE;
            }
        }
        else if(axiom_soap_builder_is_processing_detail_elements(builder_helper->soap_builder, env))
        {

            int detail_element_level = 0;
            axis2_bool_t local_name_exists = AXIS2_FALSE;
            int i = 0;
            if(!(builder_helper->detail_element_names))
            {
                return AXIS2_FAILURE;
            }

            for(i = 0; i < axutil_array_list_size(builder_helper->detail_element_names, env); i++)
            {
                if(axutil_strcmp(parent_localname, axutil_array_list_get(
                    builder_helper->detail_element_names, env, i)) == 0)
                {
                    local_name_exists = AXIS2_TRUE;
                    detail_element_level = i + 1;
                }
            }
            if(local_name_exists)
            {
                axutil_array_list_add(builder_helper->detail_element_names, env, ele_localname);
            }
            else
            {
                return AXIS2_FAILURE;
            }
        }
    }
    return AXIS2_SUCCESS;
}
