/*
 * 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_element_internal.h"
#include "axiom_node_internal.h"
#include <axiom_attribute.h>
#include <axiom_namespace.h>
#include <axiom_xml_writer.h>
#include <axiom_stax_builder.h>
#include <string.h>
#include <stdio.h>

struct axiom_element
{

    /** Element's namespace */
    axiom_namespace_t *ns;

    /** Element's local name */
    axutil_string_t *localname;

    /** List of attributes */
    axutil_hash_t *attributes;

    /** List of other namespaces */
    axutil_hash_t *namespaces;

    /* denotes whether current element is an empty element. i.e. <element/>
     * Used only when writing the output */
    axis2_bool_t is_empty;

    /* Following members are kept as a result of some operations. Reason for keeping them is,
     * (1) we can free them without memory leak
     * (2) Improve the performance, so that we don't need to re-do the calculation again
     */
    axutil_qname_t *qname;                          /* result of axiom_element_get_qname */
    axiom_child_element_iterator_t *child_ele_iter; /* result of axiom_element_get_child_elements*/
    axiom_children_iterator_t *children_iter;       /* result of axiom_element_get_children */
    axiom_children_qname_iterator_t *children_qname_iter; /*axiom_element_get_children_with_qname */
    axis2_char_t *text_value;                       /* result of axiom_element_get_text */

};

/**
 * Creates an AXIOM element with given local name
 *
 * @param env Environment. MUST NOT be NULL.
 * @param parent parent of the element node to be created. can be NULL.
 * @param localname local name of the element. cannot be NULL.
 * @param ns namespace of the element.  can be NULL.
 *                       If the value of the namespace has not already been declared
 *                       then the namespace structure ns will be cloned and declared and will be
 *                       freed when the tree is freed.
 *                       Caller has to delete the original ns object passed to the method.
 * @param node This is an out parameter. cannot be NULL.
 *                       Returns the node corresponding to the comment created.
 *                       Node type will be set to AXIOM_ELEMENT
 *
 * @return a pointer to the newly created element struct
 */
AXIS2_EXTERN axiom_element_t *AXIS2_CALL
axiom_element_create(
    const axutil_env_t * env,
    axiom_node_t * parent,
    const axis2_char_t * localname,
    axiom_namespace_t * ns,
    axiom_node_t ** node)
{
    axiom_element_t *element;
    AXIS2_ASSERT(localname != NULL);
    AXIS2_ASSERT(node != NULL);
    AXIS2_ASSERT(env != NULL);

    (*node) = axiom_node_create(env);
    if (!(*node))
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to create axiom node needed by element");
        return NULL;
    }

    element = (axiom_element_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_element_t));
    if (!element)
    {
        axiom_node_free_tree(*node, env);
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Insufficient memory to create axiom element");
        return NULL;
    }
    memset(element, 0, sizeof(axiom_element_t));

    element->localname = axutil_string_create(env, localname);
    if (!element->localname)
    {
        AXIS2_FREE(env->allocator, element);/* Still we haven't set the data element. so, we have */
        axiom_node_free_tree(*node, env);   /* to free node and element separately */
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to create string to store local name");
        return NULL;
    }

    if (parent)
        axiom_node_add_child(parent, env, (*node));

    axiom_node_set_node_type((*node), env, AXIOM_ELEMENT);
    axiom_node_set_data_element((*node), env, element);

    if (ns)
    {
        if (axiom_element_set_namespace(element, env, ns, *node) != AXIS2_SUCCESS)
        {
            axiom_node_free_tree(*node, env); /* this will internally free axiom element */
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to set namespace of element");
            return NULL;
        }
    }

    return element;
}

/**
 * Creates an AXIOM element with given qname
 *
 * @param env Environment. MUST NOT be NULL.
 * @param parent parent of the element node to be created. can be NULL.
 * @param qname qname of the elment.cannot be NULL.
 * @param node This is an out parameter. cannot be NULL.
 *                       Returns the node corresponding to the comment created.
 *                       Node type will be set to AXIOM_ELEMENT
 *
 * @return a pointer to the newly created element struct
 */
AXIS2_EXTERN axiom_element_t *AXIS2_CALL
axiom_element_create_with_qname(
    const axutil_env_t * env,
    axiom_node_t * parent,
    const axutil_qname_t * qname,
    axiom_node_t ** node)
{
    axiom_element_t *element;
    axis2_char_t *localpart;
    axis2_char_t *temp_nsuri;
    axis2_char_t *temp_prefix;

    AXIS2_ASSERT(qname != NULL);
    AXIS2_ASSERT(node != NULL);
    AXIS2_ASSERT(env != NULL);

    localpart = axutil_qname_get_localpart(qname, env);
    AXIS2_ASSERT(localpart != NULL);

    element = axiom_element_create(env, parent, localpart, NULL, node);
    if (!element)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to create element with qname");
        return NULL;
    }

    AXIS2_ASSERT(*node != NULL);

    temp_nsuri = axutil_qname_get_uri(qname, env);
    temp_prefix = axutil_qname_get_prefix(qname, env);

    /** if no namespace uri is available in given qname no need to bother about it */
    if ((!temp_nsuri) || (axutil_strcmp(temp_nsuri, "") == 0))
        return element;

    /** if could not find a namespace so declare namespace */
    element->ns = axiom_element_find_namespace(element, env, (*node), temp_nsuri, temp_prefix);
    if (!element->ns)
    {
        axiom_namespace_t *ns = axiom_namespace_create(env, temp_nsuri, temp_prefix);
        if (!ns)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to create namespace needed by element");
            axiom_node_free_tree(*node, env);
            *node = NULL;
            return NULL;
        }

        if (axiom_element_declare_namespace(element, env, *node, ns) != AXIS2_SUCCESS)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to declare namespace needed by element");
            axiom_node_free_tree(*node, env);
            *node = NULL;
            axiom_namespace_free(ns, env);
            return NULL;
        }

        element->ns = ns;
    }
    else
    {
        /* namespace is declared somewhere, but since we are going to keep it, we should
         * increment the reference
         */
        axiom_namespace_increment_ref(element->ns, env);
    }
    return element;
}

/**
 * Frees given element
 *
 * @param element AXIOM element to be freed.
 * @param env Environment. MUST NOT be NULL.
 *
 * @return status of the operation. AXIS2_SUCCESS on success ,AXIS2_FAILURE on error.
 */
AXIS2_EXTERN void AXIS2_CALL
axiom_element_free(
    axiom_element_t * om_element,
    const axutil_env_t * env)
{
    AXIS2_ASSERT(om_element != NULL);
    AXIS2_ASSERT(env != NULL);
    AXIS2_ASSERT(om_element->localname != NULL);

    axutil_string_free(om_element->localname, env);
    if (om_element->ns)
        axiom_namespace_free(om_element->ns, env);

    if (om_element->attributes)
    {
        axutil_hash_index_t *hi;
        void *val;
        for(hi = axutil_hash_first(om_element->attributes, env); hi; hi = axutil_hash_next(env, hi))
        {
            axutil_hash_this(hi, NULL, NULL, &val);
            AXIS2_ASSERT(val != NULL);
            axiom_attribute_free((axiom_attribute_t *)val, env);
        }
        axutil_hash_free(om_element->attributes, env);
    }

    if (om_element->namespaces)
    {
        axutil_hash_index_t *hi;
        void *val;
        for(hi = axutil_hash_first(om_element->namespaces, env); hi; hi = axutil_hash_next(env, hi))
        {
            axutil_hash_this(hi, NULL, NULL, &val);
            AXIS2_ASSERT(val != NULL);
            axiom_namespace_free((axiom_namespace_t *)val, env);
        }
        axutil_hash_free(om_element->namespaces, env);
    }

    if (om_element->qname)
        axutil_qname_free(om_element->qname, env);

    if (om_element->children_iter)
        axiom_children_iterator_free(om_element->children_iter, env);

    if (om_element->child_ele_iter)
        axiom_child_element_iterator_free(om_element->child_ele_iter, env);

    if (om_element->children_qname_iter)
        axiom_children_qname_iterator_free(om_element->children_qname_iter, env);

    if (om_element->text_value)
    {
        AXIS2_FREE(env->allocator, om_element->text_value);
    }

    AXIS2_FREE(env->allocator, om_element);
}

/**
 * finds a namespace in current element's scope, by uri or prefix or both. Will not check in the
 * parents, so even it is defined in parent nodes, this method will return NULL if it is not defined
 * in element's scope
 *
 * @param om_element pointer to om_element
 * @param env environment MUST not be NULL
 * @param uri namespace uri, may be null
 * @param prefix prefix
 *
 * @return axiom_namespace_t if found, else return NULL
 */
AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL
axiom_element_find_declared_namespace(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    const axis2_char_t * uri,
    const axis2_char_t * prefix)
{
    AXIS2_ASSERT(om_element != NULL);
    AXIS2_ASSERT(env != NULL);

    if (om_element->namespaces)
    {
        if (uri && (!prefix || axutil_strcmp(prefix, "") == 0))
        {
            /** prefix is null , so iterate the namespaces hash to find the namespace */
            axutil_hash_index_t *hashindex;
            for(hashindex = axutil_hash_first(om_element->namespaces, env); hashindex;
                hashindex = axutil_hash_next(env, hashindex))
            {
                void *ns = NULL;
                axutil_hash_this(hashindex, NULL, NULL, &ns);
                if (ns)
                {
                    axiom_namespace_t *temp_ns = (axiom_namespace_t *)ns;
                    axis2_char_t *temp_nsuri = axiom_namespace_get_uri(temp_ns, env);
                    if (axutil_strcmp(temp_nsuri, uri) == 0)
                    {
                        /** namespace uri matches, so free hash index and return ns*/
                        AXIS2_FREE(env->allocator, hashindex);
                        return temp_ns;
                    }
                }
            }
        }
        else if (prefix)
        {
            /** prefix is not null get namespace directly if exist */
            axiom_namespace_t *ns = (axiom_namespace_t *)axutil_hash_get(om_element->namespaces, prefix, AXIS2_HASH_KEY_STRING);
            if (ns)
            {
                /* if uri provided, return found ns only if uri matches */
                if ((uri) && (axutil_strcmp(axiom_namespace_get_uri(ns, env), uri) != 0))
                    ns = NULL;

                return ns;
            }
        }
    }
    return NULL;
}

/**
 * Find a namespace in the scope of the document.
 * Start to find from the given node and go up the hierarchy.
 *
 * @param om_element pointer to om_element_struct contained in node ,
 * @param env Environment. MUST NOT be NULL.
 * @param node node containing an instance of an AXIOM element,cannot be NULL.
 * @param uri namespace uri..
 * @param prefix namespace prefix. can be NULL.
 *
 * @return pointer to the namespace, if found, else NULL. On error, returns
 *           NULL and sets error code in environment,s error
 */
AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL
axiom_element_find_namespace(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axiom_node_t * element_node,
    const axis2_char_t * uri,
    const axis2_char_t * prefix)
{
    axiom_node_t *parent;
    axiom_namespace_t *ns;

    AXIS2_ASSERT(om_element != NULL);
    AXIS2_ASSERT(env != NULL);
    AXIS2_ASSERT(element_node != NULL);

    /* check whether we can find the namespace in current element scope */
    ns = axiom_element_find_declared_namespace(om_element, env, uri, prefix);
    if (ns)
        return ns;

    /* could not find the namespace in current element scope look in the parent */
    parent = axiom_node_get_parent(element_node, env);
    if ((parent) && (axiom_node_get_node_type(parent, env) == AXIOM_ELEMENT))
    {
        axiom_element_t *om_element;
        om_element = (axiom_element_t *)axiom_node_get_data_element(parent, env);
        if (om_element)
        {
            /** parent exist, parent is om element so find in parent*/
            return axiom_element_find_namespace(om_element, env, parent, uri, prefix);
        }
    }
    return NULL;
}

/**
 * Finds a namespace using qname. Start to find from the given node and go up the hierarchy.
 *
 * @param om_element om_element contained in node
 * @param env Environment. MUST NOT be NULL.
 * @param node node containing an instance of an AXIOM element, cannot be NULL.
 * @param qname qname of the namespace to be found. cannot be NULL.
 *
 * @return pointer to the namespace, if found, else NULL. On error, returns
 *           NULL and sets the error code in environment's error struct.
 */
AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL
axiom_element_find_namespace_with_qname(
    axiom_element_t * element,
    const axutil_env_t * env,
    axiom_node_t * node,
    axutil_qname_t * qname)
{
    AXIS2_ASSERT(qname != NULL);
    AXIS2_ASSERT(axutil_qname_get_uri(qname, env) != NULL);

    return axiom_element_find_namespace(element, env, node,
                                        axutil_qname_get_uri(qname, env),
                                        axutil_qname_get_prefix(qname, env));
}

/**
 * Declare a namespace in current element (in the scope of this element ).
 * It checks to see if it is already declared at this level or in its ancestors
 *
 * @param om_element contained in the om node struct
 * @param env Environment. MUST NOT be NULL.
 * @param node node containing an instance of an AXIOM element.
 * @param ns pointer to the namespace struct to be declared. Should not be null
 *
 * @return status of the operation. AXIS2_SUCCESS on success else AXIS2_FAILURE.
 */
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_element_declare_namespace(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axiom_node_t * node,
    axiom_namespace_t * ns)
{
    axiom_namespace_t *declared_ns;
    axis2_char_t *prefix;
    axis2_char_t *uri;

    AXIS2_ASSERT(node != NULL);
    AXIS2_ASSERT(ns != NULL);
    AXIS2_ASSERT(om_element != NULL);
    AXIS2_ASSERT(env != NULL);

    uri = axiom_namespace_get_uri(ns, env);
    prefix = axiom_namespace_get_prefix(ns, env);

    /* If namespace already declared, return */
    declared_ns = axiom_element_find_namespace(om_element, env, node, uri, prefix);
    if (declared_ns)
        return AXIS2_SUCCESS;

    if (!om_element->namespaces)
    {
        om_element->namespaces = axutil_hash_make(env);
        if (!om_element->namespaces)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to create namespaces hash map");
            return AXIS2_FAILURE;
        }
    }

    if (prefix)
        axutil_hash_set(om_element->namespaces, prefix, AXIS2_HASH_KEY_STRING, ns);
    else
    {
        /* create a key with empty string */
        axis2_char_t *key;
        key = AXIS2_MALLOC(env->allocator, sizeof(char) * 1);
        if (!key)
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Insufficient memory to create key to store namespace");
        }
        key[0] = '\0';
        axutil_hash_set(om_element->namespaces, key, AXIS2_HASH_KEY_STRING, ns);
    }
    axiom_namespace_increment_ref(ns, env);
    return AXIS2_SUCCESS;
}

/**
 * retrieves the default namespace of this element
 *
 * @param om_element pointer to om element
 * @param env axutil_environment MUST Not be NULL
 * @param element_node corresponding om element node of this om element
 *
 * @returns pointer to default namespace if available , NULL otherwise
 */
axiom_namespace_t *AXIS2_CALL
axiom_element_get_default_namespace(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axiom_node_t * element_node)
{
    axiom_node_t *parent_node;
    AXIS2_ASSERT(om_element != NULL);
    AXIS2_ASSERT(env != NULL);
    AXIS2_ASSERT(element_node != NULL);

    if (om_element->namespaces)
    {
        axiom_namespace_t *default_ns;
        default_ns = axutil_hash_get(om_element->namespaces, "", AXIS2_HASH_KEY_STRING);
        if (default_ns)
            return default_ns;
    }

    parent_node = axiom_node_get_parent(element_node, env);
    if ((parent_node) && (axiom_node_get_node_type(parent_node, env) == AXIOM_ELEMENT))
    {
        axiom_element_t *parent_ele;
        parent_ele = (axiom_element_t *)axiom_node_get_data_element(parent_node, env);
        return axiom_element_get_default_namespace(parent_ele, env, parent_node);
    }
    return NULL;
}

/**
 * get the namespace  of om_element
 *
 * @param om_element om_element struct
 * @param env environment, MUST NOT be NULL.
 *
 * @returns pointer to axiom_namespace_t struct
 *          NULL if there is no namespace associated with the element,
 *          NULL on error with error code set to environment's error
 */
AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL
axiom_element_get_namespace(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axiom_node_t * ele_node)
{
    axiom_namespace_t *ns;
    AXIS2_ASSERT(om_element != NULL);
    AXIS2_ASSERT(env != NULL);
    AXIS2_ASSERT(ele_node != NULL);

    if (om_element->ns)
        ns = om_element->ns;
    else
        ns = axiom_element_get_default_namespace(om_element, env, ele_node);

    return ns;
}

/**
 * set the namespace of the element
 * @param om_element pointer to om_element
 * @param env environment MUST not be NULL
 * @param ns pointer to namespace. Must not be NULL
 *                       If the value of the namespace has not already been declared
 *                       then the namespace structure ns will be declared and will be
 *                       freed when the tree is freed.
 * @returns status code of the op, with error code
 *                  set to environment's error
 */
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_element_set_namespace(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axiom_namespace_t * ns,
    axiom_node_t * node)
{
    AXIS2_ASSERT(om_element != NULL);
    AXIS2_ASSERT(env != NULL);
    AXIS2_ASSERT(ns != NULL);
    AXIS2_ASSERT(node != NULL);

    if (axiom_element_declare_namespace(om_element, env, node, ns) != AXIS2_SUCCESS)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to declare namespace given");
        return AXIS2_FAILURE;
    }
    om_element->ns = ns;
    axiom_namespace_increment_ref(ns, env);
    return AXIS2_SUCCESS;
}

/**
 * get the namespace list of the element
 *
 * @param om_element pointer to om_element
 * @param env environment MUST not be NULL
 *
 * @returns axutil_hash pointer to namespaces hash
 * this hash table is read only
 */
AXIS2_EXTERN axutil_hash_t *AXIS2_CALL
axiom_element_get_namespaces(
    axiom_element_t * om_element,
    const axutil_env_t * env)
{
    return om_element->namespaces;
}

/**
 * Adds an attribute to current element. The current element takes responsibility of the
 * assigned attribute
 * @param om_element element to which the attribute is to be added.cannot be NULL.
 * @param env Environment. MUST NOT be NULL.
 * @param attribute attribute to be added.
 * @param node axiom_node_t node that om_element is contained in
 * @return status of the operation. AXIS2_SUCCESS on success else AXIS2_FAILURE.
 */
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_element_add_attribute(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axiom_attribute_t * attribute,
    axiom_node_t * element_node)
{
    axutil_qname_t *qname;
    axiom_namespace_t *om_namespace;

    AXIS2_ASSERT(attribute != NULL);
    AXIS2_ASSERT(element_node != NULL);
    AXIS2_ASSERT(env != NULL);
    AXIS2_ASSERT(om_element != NULL);

    om_namespace = axiom_attribute_get_namespace(attribute, env);
    if (om_namespace)
    {
        /* Declare the namespace in element */
        if (axiom_element_declare_namespace(om_element, env, element_node, om_namespace) != AXIS2_SUCCESS)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to declare attribute namespace");
            return AXIS2_FAILURE;
        }
    }

    if (!om_element->attributes)
    {
        om_element->attributes = axutil_hash_make(env);
        if (!om_element->attributes)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to create hash map to store attributes");
            return AXIS2_FAILURE;
        }
    }

    qname = axiom_attribute_get_qname(attribute, env);
    if (qname)
    {
        axis2_char_t *name = axutil_qname_to_string(qname, env);
        axutil_hash_set(om_element->attributes, name, AXIS2_HASH_KEY_STRING, attribute);
        axiom_attribute_increment_ref(attribute, env);
    }
    else
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to create qname to store attribute");
        return AXIS2_FAILURE;
    }

    return AXIS2_SUCCESS;
}

/**
 * Gets (finds) the attribute with the given qname
 *
 * @param element element whose attribute is to be found.
 * @param env Environment. MUST NOT be NULL.
 * @param qname qname of the attribute to be found. should not be NULL.
 *
 * @return a pointer to the attribute with given qname if found, else NULL.
 *           On error, returns NULL and sets the error code in environment's error struct.
 */
AXIS2_EXTERN axiom_attribute_t *AXIS2_CALL
axiom_element_get_attribute(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axutil_qname_t * qname)
{
    axis2_char_t *name;
    void *attr;

    AXIS2_ASSERT(env != NULL);
    AXIS2_ASSERT(qname != NULL);
    AXIS2_ASSERT(om_element != NULL);

    /* if there are no attributes, then return NULL */
    if (!om_element->attributes)
        return NULL;

    name = axutil_qname_to_string(qname, env);
    if (!name)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to get string representation of qname");
        return NULL;
    }

    attr = axutil_hash_get(om_element->attributes, name, AXIS2_HASH_KEY_STRING);
    return (axiom_attribute_t *)attr;
}

/**
 * get  the attribute list of the element
 *
 * @param om_element pointer to om_element
 * @param env environment MUST not be NULL
 *
 * @returns axutil_hash pointer to attributes hash
 * This hash table is read only
 */
AXIS2_EXTERN axutil_hash_t *AXIS2_CALL
axiom_element_get_all_attributes(
    axiom_element_t * om_element,
    const axutil_env_t * env)
{
    return om_element->attributes;
}

/**
 * Gets (finds) the attribute value with the given qname
 *
 * @param element element whose attribute is to be found.
 * @param env Environment. MUST NOT be NULL.
 * @param qname qname of the attribute to be found. should not be NULL.
 *
 * @return the attribute value with given qname if found, else NULL.
 *  On error, returns NULL and sets the error code in environment's error struct.
 */
AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axiom_element_get_attribute_value(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axutil_qname_t * qname)
{
    axiom_attribute_t *attr = axiom_element_get_attribute(om_element, env, qname);
    if (!attr)
        return NULL;

    return axiom_attribute_get_value(attr, env);
}

/**
 *  Extract attributes , returns a clones hash table of attributes,
 *
 * @param om_element pointer to om_element
 * @param env environment MUST not be NULL
 * @param om_node pointer to this element node
 */
AXIS2_EXTERN axutil_hash_t *AXIS2_CALL
axiom_element_extract_attributes(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axiom_node_t * ele_node)
{
    axutil_hash_index_t *hi;
    axutil_hash_t *ht_cloned;

    AXIS2_ASSERT(om_element != NULL);
    AXIS2_ASSERT(env != NULL);
    AXIS2_ASSERT(ele_node != NULL);

    if (!om_element->attributes)
        return NULL;

    ht_cloned = axutil_hash_make(env);
    if (!ht_cloned)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to create hashmap to extract attributes");
        return NULL;
    }

    for(hi = axutil_hash_first(om_element->attributes, env); hi; hi = axutil_hash_next(env, hi))
    {
        void *val;
        axiom_attribute_t *cloned_attr;
        axis2_char_t *key = NULL;

        axutil_hash_this(hi, NULL, NULL, &val);
        AXIS2_ASSERT(val != NULL);

        cloned_attr = axiom_attribute_clone((axiom_attribute_t*)val, env);
        if (cloned_attr)
        {
            axutil_qname_t *qn = axiom_attribute_get_qname(cloned_attr, env);
            if (qn)
                key = axutil_qname_to_string(qn, env);
        }

        if (key)
            axutil_hash_set(ht_cloned, key, AXIS2_HASH_KEY_STRING, cloned_attr);
        else
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to clone attribute");
            return NULL;
        }
    }
    return ht_cloned;
}

/**
 * Returns the attribute value as a string for the given element
 * @param om_element pointer to om_element
 * @param env environment MUST not be NULL
 * @param attr_name the attribute name
 * @return the attribute value as a string
 */
AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axiom_element_get_attribute_value_by_name(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axis2_char_t * attr_name)
{
    axutil_hash_index_t *hi;

    AXIS2_ASSERT(attr_name != NULL);
    AXIS2_ASSERT(om_element != NULL);
    AXIS2_ASSERT(env != NULL);

    if (!om_element->attributes)
        return NULL;

    for(hi = axutil_hash_first(om_element->attributes, env); hi; hi = axutil_hash_next(env, hi))
    {
        void *attr;
        axis2_char_t *this_attr_name;
        axiom_namespace_t *attr_ns;
        axis2_char_t *prefix;

        axutil_hash_this(hi, NULL, NULL, &attr);
        AXIS2_ASSERT(attr != NULL);

        this_attr_name = axiom_attribute_get_localname((axiom_attribute_t*)attr, env);
        attr_ns = axiom_attribute_get_namespace((axiom_attribute_t*)attr, env);
        if (attr_ns && (prefix = axiom_namespace_get_prefix(attr_ns, env)) &&
            (axutil_strcmp(prefix, "") != 0))
        {
            /* namespace is defined and prefix is not empty. So, prefix:localname should match
             * with given name
             */
            axis2_char_t *attr_qn_str = axutil_strcat(env, prefix, ":", this_attr_name, NULL);
            if (axutil_strcmp(attr_qn_str, attr_name) != 0)
            {
                /* not the attribute we are looking for */
                AXIS2_FREE(env->allocator, attr_qn_str);
                continue;
            }
            AXIS2_FREE(env->allocator, attr_qn_str);
        }
        else
        {
            /* no namespace or no prefix. so compare only local name */
            if (axutil_strcmp(this_attr_name, attr_name) != 0)
            {
                /* not the attribute we are looking for */
                continue;
            }
        }

        /* we found the attribute */
        AXIS2_FREE(env->allocator, hi);
        return axiom_attribute_get_value((axiom_attribute_t*)attr, env);
    }
    return NULL;
}

/**
 * Select all the text children and concatenate them to a single string. The string
 * returned by this method call will be free by axiom when this method is called again.
 * So it is recommended to have a copy of the return value if this method is going to
 * be called more that once and the return values of the earlier calls are important.
 * @param om_element pointer to om_element
 * @param env environment MUST not be NULL
 * @param element node , the container node of this om element
 * @return the concatenated text of all text children text values
 *         return null if no text children is available or on error
 */
AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axiom_element_get_text(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axiom_node_t * element_node)
{
    axiom_node_t *temp_node;
    axis2_char_t *dest = NULL;

    AXIS2_ASSERT(env != NULL);
    AXIS2_ASSERT(element_node != NULL);
    AXIS2_ASSERT(om_element != NULL);

    if (om_element->text_value)
    {
        AXIS2_FREE(env->allocator, om_element->text_value);
        om_element->text_value = NULL;
    }

    temp_node = axiom_node_get_first_child(element_node, env);
    while(temp_node)
    {
        if (axiom_node_get_node_type(temp_node, env) == AXIOM_TEXT)
        {
            const axis2_char_t *temp_text;
            axiom_text_t *text_ele;

            text_ele = (axiom_text_t *)axiom_node_get_data_element(temp_node, env);
            AXIS2_ASSERT(text_ele != NULL);
            temp_text = axiom_text_get_value(text_ele, env);
            if (dest && temp_text && axutil_strcmp(temp_text, "") != 0)
            {
                axis2_char_t *temp_dest = axutil_stracat(env, dest, temp_text);
                AXIS2_FREE(env->allocator, dest);
                dest = temp_dest;
            }
            else if (!dest && temp_text && axutil_strcmp(temp_text, "") != 0)
                dest = axutil_strdup(env, temp_text);
        }
        temp_node = axiom_node_get_next_sibling(temp_node, env);
    }

    om_element->text_value = dest;
    return om_element->text_value;
}

/**
 * Sets the text of the given element.
 * caution - This method will wipe out all the text elements (and hence any mixed content)
 * before setting the text
 *
 * @param om_element pointer to om_element
 * @param env environment MUST not be NULL
 * @param text text to set.
 * @param element_node node of element.
 *
 * @return AXIS2_SUCCESS if attribute was found and removed, else AXIS2_FAILURE
 */
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_element_set_text(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    const axis2_char_t * text,
    axiom_node_t * element_node)
{
    axiom_node_t *temp_node, *next_node;

    AXIS2_ASSERT(om_element != NULL);
    AXIS2_ASSERT(env != NULL);
    AXIS2_ASSERT(text != NULL);
    AXIS2_ASSERT(element_node != NULL);

    next_node = axiom_node_get_first_child(element_node, env);
    while(next_node)
    {
        temp_node = next_node;
        next_node = axiom_node_get_next_sibling(temp_node, env);
        if (axiom_node_get_node_type(temp_node, env) == AXIOM_TEXT)
            axiom_node_free_tree(temp_node, env);
    }

    if (!axiom_text_create(env, element_node, text, &temp_node))
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to set text to element");
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}

/**
 * returns the localname of this element
 * @param om_element pointer to om_element
 * @param env environment MUST not be NULL
 * @returns localname of element, returns NULL on error.
 */
AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axiom_element_get_localname(
    axiom_element_t * om_element,
    const axutil_env_t * env)
{
    AXIS2_ASSERT(om_element != NULL);
    AXIS2_ASSERT(om_element->localname != NULL);

    return (axis2_char_t *)axutil_string_get_buffer(om_element->localname, env);
}

/**
 * set the localname of this element
 * @param om_element pointer to om_element
 * @param env environment MUST not be NULL
 * @localname text value to be set as localname
 * @returns status code of operation, AXIS2_SUCCESS on success, AXIS2_FAILURE on error.
 */
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_element_set_localname(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    const axis2_char_t * localname)
{
    axutil_string_t *new_name;

    AXIS2_ASSERT(om_element != NULL);
    AXIS2_ASSERT(om_element->localname != NULL);
    AXIS2_ASSERT(localname != NULL);
    AXIS2_ASSERT(env != NULL);

    new_name = axutil_string_create(env, localname);
    if (!new_name)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to set local name of element");
        return AXIS2_FAILURE;
    }

    axutil_string_free(om_element->localname, env);
    om_element->localname = new_name;
    return AXIS2_SUCCESS;
}

/**
 * return qname of this element. The returned qname should not be freed by the caller.
 * It will be freed when om_element struct is freed
 * @param om_element pointer to om_element
 * @param env environment MUST not be NULL
 * @param ele_node pointer to this element node
 * @returns axutil_qname_t struct , NULL on failure
 */
AXIS2_EXTERN axutil_qname_t *AXIS2_CALL
axiom_element_get_qname(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axiom_node_t * ele_node)
{
    AXIS2_ASSERT(om_element != NULL);
    AXIS2_ASSERT(env != NULL);
    AXIS2_ASSERT(ele_node != NULL);

    if (!om_element->qname)
    {
        axiom_namespace_t *ns = axiom_element_get_namespace(om_element, env, ele_node);
        const axis2_char_t *localname = axutil_string_get_buffer(om_element->localname, env);
        axis2_char_t *prefix = NULL;
        axis2_char_t *uri = NULL;

        if (ns)
        {
            prefix = axiom_namespace_get_prefix(ns, env);
            uri = axiom_namespace_get_uri(ns, env);
        }

        om_element->qname = axutil_qname_create(env, localname, uri, prefix);
    }
    return om_element->qname;
}

/**
 * returns a list of children iterator. Returned iterator is freed when om_element struct
 * is freed
 * @param om_element pointer to om_element
 * @param env environment MUST not be NULL
 * @param element_node pointer to this element node
 */
AXIS2_EXTERN axiom_children_iterator_t *AXIS2_CALL
axiom_element_get_children(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axiom_node_t * element_node)
{
    AXIS2_ASSERT(element_node != NULL);
    AXIS2_ASSERT(om_element != NULL);
    AXIS2_ASSERT(env != NULL);

    if (!om_element->children_iter)
        om_element->children_iter = axiom_children_iterator_create(env, axiom_node_get_first_child(element_node, env));
    else
        axiom_children_iterator_reset(om_element->children_iter, env);

    return om_element->children_iter;
}

/**
 * returns a list of children iterator with qname. Returned iterator is freed when om element
 * struct is freed
 *
 * @param om_element pointer to om_element
 * @param env environment MUST not be NULL
 * @param element_node pointer to this element node
 *
 * @returns children qname iterator struct
 */
AXIS2_EXTERN axiom_children_qname_iterator_t *AXIS2_CALL
axiom_element_get_children_with_qname(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axutil_qname_t * element_qname,
    axiom_node_t * element_node)
{
    AXIS2_ASSERT(element_node != NULL);
    AXIS2_ASSERT(om_element != NULL);

    if (om_element->children_qname_iter)
        axiom_children_qname_iterator_free(om_element->children_qname_iter, env);

    om_element->children_qname_iter = axiom_children_qname_iterator_create(env,
        axiom_node_get_first_child(element_node, env), element_qname);
    return om_element->children_qname_iter;
}

/**
 * Returns the first om_element corresponding to element_qname
 *
 * @param om_element pointer to om_element
 * @param env environment MUST not be NULL
 * @param element_qname qname of the element
 * @param om_node pointer to this element node
 * @param element_node
 * @param child_node
 *
 * @returns children qname iterator struct
 */
AXIS2_EXTERN axiom_element_t *AXIS2_CALL
axiom_element_get_first_child_with_qname(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axutil_qname_t * qname,
    axiom_node_t * element_node,
    axiom_node_t ** child_node)
{
    axiom_children_qname_iterator_t *children_iterator;
    children_iterator = axiom_element_get_children_with_qname(om_element, env, qname, element_node);
    if (!children_iterator)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Could not get children qname iterator");
        return NULL;
    }

    if (axiom_children_qname_iterator_has_next(children_iterator, env))
    {
        axiom_node_t *om_node = axiom_children_qname_iterator_next(children_iterator, env);
        AXIS2_ASSERT(om_node != NULL);
        AXIS2_ASSERT(axiom_node_get_node_type(om_node, env) == AXIOM_ELEMENT);

        if (child_node)
            *child_node = om_node;

        return (axiom_element_t *)axiom_node_get_data_element(om_node, env);
    }

    return NULL;
}

/**
 * returns the first child om element of this om element node
 * @param om_element pointer to om_element
 * @param env environment MUST not be NULL
 * @param om_node pointer to this element node
 * @return om_element if one is available otherwise return NULL
 */
AXIS2_EXTERN axiom_element_t *AXIS2_CALL
axiom_element_get_first_element(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axiom_node_t * element_node,
    axiom_node_t ** first_ele_node)
{
    axiom_node_t *temp_node;

    AXIS2_ASSERT(env != NULL);
    AXIS2_ASSERT(element_node != NULL);

    temp_node = axiom_node_get_first_child(element_node, env);
    while(temp_node)
    {
        if (axiom_node_get_node_type(temp_node, env) == AXIOM_ELEMENT)
        {
            if (first_ele_node)
                *first_ele_node = temp_node;

            return (axiom_element_t *)axiom_node_get_data_element(temp_node, env);
        }
        else
            temp_node = axiom_node_get_next_sibling(temp_node, env);
    }
    return NULL;
}

/**
 * returns an iterator with child elements of type AXIOM_ELEMENT
 * iterator is freed when om_element node is freed
 * @param om_element pointer to om_element
 * @param env environment MUST not be NULL
 * @param element_node
 * @returns axiom_child_element_iterator_t , NULL on error
 */
AXIS2_EXTERN axiom_child_element_iterator_t *AXIS2_CALL
axiom_element_get_child_elements(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axiom_node_t * element_node)
{
    AXIS2_ASSERT(env != NULL);
    AXIS2_ASSERT(om_element != NULL);
    AXIS2_ASSERT(element_node != NULL);

    if (om_element->child_ele_iter)
        return om_element->child_ele_iter;
    else
    {
        axiom_node_t *first_node;
        axiom_element_t *ele;
        ele = axiom_element_get_first_element(om_element, env, element_node, &first_node);
        if (ele)
        {
            AXIS2_ASSERT(first_node != NULL);
            om_element->child_ele_iter = axiom_child_element_iterator_create(env, first_node);
            return om_element->child_ele_iter;
        }
    }
    return NULL;
}



/**
 * Collect all the namespaces with distinct prefixes in the parents of the given element.
 * Effectively this is the set of namespaces declared above this element and might be used by it
 * or its children. Output of this will be used later by axiom_element_redeclare_parent_namespaces
 *
 * @param om_element pointer to om_element
 * @param env environment MUST not be NULL
 * @param om_node pointer to this element node
 *
 * @returns pointer to hash of relevant namespaces
 */
axutil_hash_t * AXIS2_CALL
axiom_element_gather_parent_namespaces(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axiom_node_t * om_node)
{
    axutil_hash_t *inscope_namespaces;
    axiom_node_t *parent_node = om_node;

    AXIS2_ASSERT(om_element != NULL);
    AXIS2_ASSERT(env != NULL);
    AXIS2_ASSERT(om_node != NULL);

    inscope_namespaces = axutil_hash_make(env);
    if (!inscope_namespaces)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "Unable to create hashmap needed to gather parent namespace");
        return NULL;
    }

    while ((parent_node = axiom_node_get_parent(parent_node, env))
            && (axiom_node_get_node_type(parent_node, env) == AXIOM_ELEMENT))
    {
        axiom_element_t *parent_element;
        axutil_hash_t *parent_namespaces;
        axutil_hash_index_t *hi;

        parent_element = (axiom_element_t *)axiom_node_get_data_element(parent_node, env);
        parent_namespaces = axiom_element_get_namespaces(parent_element, env);

        /* If no namespaces are declared. So, continue without processing */
        if (!parent_namespaces)
            continue;

        for (hi = axutil_hash_first(parent_namespaces, env); hi; hi = axutil_hash_next(env, hi))
        {
            axis2_char_t *key;
            void *val;
            axutil_hash_this(hi, NULL, NULL, &val);
            AXIS2_ASSERT(val != NULL);

            key = axiom_namespace_get_prefix((axiom_namespace_t *)val, env);
            if (!key)
                key = "";

            /* Check if prefix already associated with some namespace in a parent node */
            if (!axutil_hash_get(inscope_namespaces, key, AXIS2_HASH_KEY_STRING))
            {
                /* Remember this namespace as needing to be declared, if used */
                axutil_hash_set(inscope_namespaces, key, AXIS2_HASH_KEY_STRING, val);
            }
        }
    }

    return inscope_namespaces;
}

/**
 * If the provided namespace used by the provided element is one of the namespaces from the
 * parent of the detached node, redeclares that namespace at the element level and removes it
 * from the hash of parent namespaces
 *
 * @param om_element pointer to om_element
 * @param env environment MUST not be NULL
 * @param om_node pointer to this element node
 * @param ns pointer to namespace to redeclare
 * @param inscope_namespaces pointer to hash of parent namespaces
 */
void AXIS2_CALL
axiom_element_use_parent_namespace(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axiom_node_t * om_node,
    axiom_namespace_t *ns,
    axutil_hash_t *inscope_namespaces)
{
    AXIS2_ASSERT(om_element != NULL);
    AXIS2_ASSERT(env != NULL);
    AXIS2_ASSERT(om_node != NULL);

    if (ns && inscope_namespaces)
    {
        axiom_namespace_t *parent_ns;
        axis2_char_t *key = axiom_namespace_get_prefix(ns, env);
        if (!key)
            key = "";

        parent_ns = axutil_hash_get(inscope_namespaces, key, AXIS2_HASH_KEY_STRING);
        /* Check if namespace is a namespace declared in a parent and not also declared at an
         * intermediate level */
        if (parent_ns)
        {
            /* declare the namespace. If it is already declared in intermediate level,
             * axiom_elment_declare_namespace will handle it
             */
            axiom_element_declare_namespace(om_element, env, om_node, parent_ns);
            /* Remove the namespace from the inscope parent namespaces now that it has
             been redeclared. */
            axutil_hash_set(inscope_namespaces, key, AXIS2_HASH_KEY_STRING, NULL);
        }
    }
}

/**
 * Examines the subtree beginning at the provided element for each element or attribute,
 * if it refers to a namespace declared in a parent of the subtree root element, if not already
 * declared, redeclares that namespace at the level of the subtree root and removes
 * it from the set of parent inscope_namespaces. inscope_namespaces contains all the parent
 * namespaces which should be redeclared at some point.
 *
 * @param om_element pointer to om_element
 * @param env environment MUST not be NULL
 * @param om_node pointer to this element node
 * @param inscope_namespaces pointer to hash of parent namespaces
 */
void AXIS2_CALL
axiom_element_redeclare_parent_namespaces(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axiom_node_t * om_node,
    axutil_hash_t *inscope_namespaces)
{
    axiom_node_t *child_node;
    axutil_hash_t * attributes;
    AXIS2_ASSERT(om_element != NULL);
    AXIS2_ASSERT(env != NULL);
    AXIS2_ASSERT(om_node != NULL);

    /* ensure the element's namespace is declared */
    axiom_element_use_parent_namespace(om_element, env, om_node, om_element->ns, inscope_namespaces);

    /* for each attribute, ensure the attribute's namespace is declared */
    attributes = om_element->attributes;
    if (attributes)
    {
        axutil_hash_index_t *hi;
        for(hi = axutil_hash_first(attributes, env); hi; hi = axutil_hash_next(env, hi))
        {
            void *val;
            axiom_namespace_t* ns;

            axutil_hash_this(hi, NULL, NULL, &val);
            AXIS2_ASSERT(val != NULL);

            ns = axiom_attribute_get_namespace((axiom_attribute_t*)val, env);
            axiom_element_use_parent_namespace(om_element, env, om_node,ns, inscope_namespaces);
        }
    }

    /* ensure the namespaces in all the children are declared */
    child_node = axiom_node_get_first_child(om_node, env);
    while(child_node && (axutil_hash_count(inscope_namespaces) > 0))
    {
        if (axiom_node_get_node_type(child_node, env) == AXIOM_ELEMENT)
        {
            axiom_element_redeclare_parent_namespaces(axiom_node_get_data_element(child_node, env),
                env, child_node, inscope_namespaces);
        }
        child_node = axiom_node_get_next_sibling(child_node, env);
    }
}

/**
 * Serializes the start part of the given element
 * @param element element to be serialized.
 * @param env Environment. MUST NOT be NULL.
 * @param om_output AXIOM output handler to be used in serializing
 * @return status of the operation. AXIS2_SUCCESS on success else AXIS2_FAILURE
 */
axis2_status_t AXIS2_CALL
axiom_element_serialize_start_part(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axiom_output_t * om_output,
    axiom_node_t * ele_node)
{
    axis2_status_t status = AXIS2_SUCCESS;

    AXIS2_ASSERT(env != NULL);
    AXIS2_ASSERT(om_element != NULL);
    AXIS2_ASSERT(om_output != NULL);
    AXIS2_ASSERT(ele_node != NULL);

    if (om_element->is_empty)
    {
        if (om_element->ns)
        {
            axis2_char_t *uri = axiom_namespace_get_uri(om_element->ns, env);
            axis2_char_t *prefix = axiom_namespace_get_prefix(om_element->ns, env);
            AXIS2_ASSERT(uri != NULL);

            if (prefix && (axutil_strcmp(prefix, "") != 0))
            {
                status = axiom_output_write(om_output, env, AXIOM_ELEMENT, 4,
                    axutil_string_get_buffer(om_element-> localname, env), uri, prefix, NULL);
            }
            else
            {
                status = axiom_output_write(om_output, env, AXIOM_ELEMENT, 4,
                    axutil_string_get_buffer(om_element-> localname, env), uri, NULL, NULL);
            }
        }
        else
        {
            status = axiom_output_write(om_output, env, AXIOM_ELEMENT, 4,
                axutil_string_get_buffer(om_element-> localname, env), NULL, NULL, NULL);
        }
    }
    else
    {
        if (om_element->ns)
        {
            axis2_char_t *uri = axiom_namespace_get_uri(om_element->ns, env);
            axis2_char_t *prefix = axiom_namespace_get_prefix(om_element->ns, env);
            AXIS2_ASSERT(uri != NULL);

            if (prefix && (axutil_strcmp(prefix, "") != 0))
            {
                status = axiom_output_write(om_output, env, AXIOM_ELEMENT, 3,
                    axutil_string_get_buffer(om_element-> localname, env), uri, prefix);
            }
            else
            {
                status = axiom_output_write(om_output, env, AXIOM_ELEMENT, 2,
                    axutil_string_get_buffer(om_element-> localname, env), uri);
            }
        }
        else
        {
            status = axiom_output_write(om_output, env, AXIOM_ELEMENT, 1,
                axutil_string_get_buffer(om_element-> localname, env));
        }
    }

    if (status != AXIS2_SUCCESS)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "element serialized failed");
        return AXIS2_FAILURE;
    }

    if (om_element->attributes)
    {
        axutil_hash_index_t *hi;
        void *val;
        for(hi = axutil_hash_first(om_element->attributes, env); hi; hi = axutil_hash_next(env, hi))
        {
            axutil_hash_this(hi, NULL, NULL, &val);
            AXIS2_ASSERT(val != NULL);

            if (axiom_attribute_serialize((axiom_attribute_t *)val, env, om_output) != AXIS2_SUCCESS)
            {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "element attribute serialize failed");
                AXIS2_FREE(env->allocator, hi);
                return AXIS2_FAILURE;
            }
        }
    }

    if (om_element->namespaces)
    {
        axutil_hash_index_t *hi;
        void *val;
        for(hi = axutil_hash_first(om_element->namespaces, env); hi; hi = axutil_hash_next(env, hi))
        {
            axutil_hash_this(hi, NULL, NULL, &val);
            AXIS2_ASSERT(val != NULL);

            if (axiom_namespace_serialize((axiom_namespace_t *)val, env, om_output) != AXIS2_SUCCESS)
            {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "element namespace serialize failed");
                AXIS2_FREE(env->allocator, hi);
                return AXIS2_FAILURE;
            }
        }
    }

    return AXIS2_SUCCESS;
}

/**
 * Serializes the end part of the given element. serialize_start_part must
 *     have been called before calling this method.
 *
 * @param om_element pointer to om_element
 * @param env environment MUST not be NULL
 * @param om_node pointer to this element node
 * @param om_output AXIOM output handler to be used in serializing
 *
 * @return status of the operation. AXIS2_SUCCESS on success else AXIS2_FAILURE
 */
axis2_status_t AXIS2_CALL
axiom_element_serialize_end_part(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axiom_output_t * om_output)
{
    AXIS2_ASSERT(env != NULL);
    AXIS2_ASSERT(om_element != NULL);
    AXIS2_ASSERT(om_output != NULL);

    return axiom_output_write(om_output, env, AXIOM_ELEMENT, 0);
}

/**
 * Set whether the element is empty or not
 * @param om_element pointer to om_element
 * @param env environment MUST not be NULL
 * @param is_empty AXIS2_TRUE if empty AXIS2_FALSE if not empty
 * @return VOID
 */
void AXIS2_CALL
axiom_element_set_is_empty(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axis2_bool_t is_empty)
{
    om_element->is_empty = is_empty;
}

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axiom_element_get_is_empty(
    axiom_element_t * om_element,
    const axutil_env_t * env)
{
    return om_element->is_empty;
}

/**
 * This method will declare the namespace without checking whether it is already declared. 
 * (This method is only used by codegen. We have to remove this method in future)
 *
 * @param om_element pointer to om_element
 * @param env environment MUST not be NULL
 * @param om_node pointer to this element node
 *
 * @return satus of the op. AXIS2_SUCCESS on success else AXIS2_FAILURE.
 *
 */
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_element_declare_namespace_assume_param_ownership(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axiom_namespace_t * ns)
{
    axis2_char_t *prefix = NULL;

    if (!ns || !om_element)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "namespace or om_element is NULL");
        return AXIS2_FAILURE;
    }

    if (!(om_element->namespaces))
    {
        om_element->namespaces = axutil_hash_make(env);
        if (!(om_element->namespaces))
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to create namespaces hash map");
            return AXIS2_FAILURE;
        }
    }
	
    prefix = axiom_namespace_get_prefix(ns, env);
    if (prefix)
        axutil_hash_set(om_element->namespaces, prefix, AXIS2_HASH_KEY_STRING, ns);
    else
    {
        /* create a key with empty string */
        axis2_char_t *key;
        key = AXIS2_MALLOC(env->allocator, sizeof(char) * 1);
        if (!key)
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Insufficient memory to create key to store namespace");
        }
        key[0] = '\0';
        axutil_hash_set(om_element->namespaces, key, AXIS2_HASH_KEY_STRING, ns);
    }
    axiom_namespace_increment_ref(ns, env);
    return AXIS2_SUCCESS;
}

#if 0
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_element_build(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axiom_node_t * om_ele_node)
{
    axiom_stax_builder_t *builder = NULL;
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);

    AXIS2_PARAM_CHECK(env->error, om_ele_node, AXIS2_FAILURE);
    if (axiom_node_get_node_type(om_ele_node, env) != AXIOM_ELEMENT)
        return AXIS2_FAILURE;

    builder = axiom_node_get_builder(om_ele_node, env);
    if (!builder)
        return AXIS2_FAILURE;

    while(!axiom_node_is_complete(om_ele_node, env)
        && !axiom_stax_builder_is_complete(builder, env))
    {
        void *value = NULL;
        value = axiom_stax_builder_next(builder, env);
        if (!value)
            return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}
#endif
/**
 * checks for the namespace in the context of this element
 * with the given prefix
 */

AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL
axiom_element_find_namespace_uri(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    const axis2_char_t * prefix,
    axiom_node_t * element_node)
{
    axiom_node_t *parent_node = NULL;
    axiom_namespace_t *ns = NULL;

    AXIS2_ENV_CHECK(env, NULL);
    AXIS2_PARAM_CHECK(env->error, element_node, NULL);
    AXIS2_PARAM_CHECK(env->error, prefix, NULL);

    if (om_element->namespaces)
    {
        ns = axutil_hash_get(om_element->namespaces, prefix, AXIS2_HASH_KEY_STRING);
        if (ns)
            return ns;
    }

    parent_node = axiom_node_get_parent(element_node, env);
    if ((parent_node) && (axiom_node_get_node_type(parent_node, env) == AXIOM_ELEMENT))
    {
        axiom_element_t *parent_ele = NULL;
        parent_ele = (axiom_element_t *)axiom_node_get_data_element(parent_node, env);
        if (parent_ele)
            return axiom_element_find_namespace_uri(parent_ele, env, prefix, parent_node);
    }
    return NULL;
}

AXIS2_EXTERN axutil_string_t *AXIS2_CALL
axiom_element_get_localname_str(
    axiom_element_t * om_element,
    const axutil_env_t * env)
{
    return om_element->localname;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_element_set_localname_str(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axutil_string_t * localname)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE);

    if (om_element->localname)
    {
        axutil_string_free(om_element->localname, env);
        om_element->localname = NULL;
    }

    om_element->localname = axutil_string_clone(localname, env);

    if (!(om_element->localname))
        return AXIS2_FAILURE;

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_element_set_namespace_with_no_find_in_current_scope(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axiom_namespace_t * om_ns)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, om_ns, AXIS2_FAILURE);
    om_element->ns = om_ns;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_element_set_namespace_assume_param_ownership(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axiom_namespace_t * ns)
{
    om_element->ns = ns;
    return AXIS2_SUCCESS;
}

/**
 * declared a default namespace explicitly
 */
AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL
axiom_element_declare_default_namespace(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axis2_char_t * uri)
{
    axiom_namespace_t *default_ns = NULL;
    AXIS2_ENV_CHECK(env, NULL);
    AXIS2_PARAM_CHECK(env->error, uri, NULL);

    if (axutil_strcmp(uri, "") == 0)
        return NULL;

    default_ns = axiom_namespace_create(env, uri, "");
    if (!default_ns)
        return NULL;

    if (!om_element->namespaces)
    {
        om_element->namespaces = axutil_hash_make(env);
        if (!(om_element->namespaces))
        {
            axiom_namespace_free(default_ns, env);
            return NULL;
        }
    }

    axutil_hash_set(om_element->namespaces, "", AXIS2_HASH_KEY_STRING, default_ns);
    axiom_namespace_increment_ref(default_ns, env);
    return default_ns;
}

AXIS2_EXTERN axiom_element_t *AXIS2_CALL
axiom_element_create_str(
    const axutil_env_t * env,
    axiom_node_t * parent,
    axutil_string_t * localname,
    axiom_namespace_t * ns,
    axiom_node_t ** node)
{
    axiom_element_t *element;

    if (!localname || !node)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "localname or node is NULL");
        return NULL;
    }

    (*node) = axiom_node_create(env);
    if (!(*node))
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to create axiom node");
        return NULL;
    }

    element = (axiom_element_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_element_t));
    if (!element)
    {
        AXIS2_FREE(env->allocator, (*node));
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Insufficient memory to create axiom element");
        return NULL;
    }

    memset(element, 0, sizeof(axiom_element_t));
    element->localname = axutil_string_clone(localname, env);
    /* clone can't be null so, no need to check for null validity*/

    if (parent)
        axiom_node_add_child(parent, env, (*node));

    axiom_node_set_node_type((*node), env, AXIOM_ELEMENT);
    axiom_node_set_data_element((*node), env, element);

    if (ns)
    {
        axis2_char_t *uri = NULL;
        axis2_char_t *prefix = NULL;

        uri = axiom_namespace_get_uri(ns, env);
        prefix = axiom_namespace_get_prefix(ns, env);

        element->ns = axiom_element_find_namespace(element, env, *node, uri, prefix);
        if (!(element->ns))
        {
            if (axiom_element_declare_namespace(element, env, *node, ns) == AXIS2_SUCCESS)
                element->ns = ns;
        }
        if (prefix && axutil_strcmp(prefix, "") == 0)
            element->ns = NULL;
    }

    return element;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_element_remove_attribute(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axiom_attribute_t * om_attribute)
{
    axutil_qname_t *qname = NULL;
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, om_attribute, AXIS2_FAILURE);

    qname = axiom_attribute_get_qname(om_attribute, env);
    if (qname && (om_element->attributes))
    {
        axis2_char_t *name = NULL;
        name = axutil_qname_to_string(qname, env);
        if (name)
        {
            axutil_hash_set(om_element->attributes, name, AXIS2_HASH_KEY_STRING, NULL);
            return AXIS2_SUCCESS;
        }
    }
    return AXIS2_FAILURE;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axiom_element_to_string(
    axiom_element_t * om_element,
    const axutil_env_t * env,
    axiom_node_t * element_node)
{
    return axiom_node_to_string(element_node, env);
}

