/*
 * 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_node_internal.h"
#include "axiom_element_internal.h"
#include "axiom_stax_builder_internal.h"
#include <axiom_text.h>
#include <axiom_data_source.h>
#include <axiom_comment.h>
#include <axiom_processing_instruction.h>
#include <axiom_doctype.h>
#include <axiom_document.h>
#include <axiom_stax_builder.h>

struct axiom_node
{
    /* stax builder */
    axiom_stax_builder_t *builder;

    /* whether current node is the owner of stax builder. If so, it has to free it */
    axis2_bool_t own_builder;

    /** parent node */
    axiom_node_t *parent;

    /** previous sibling */
    axiom_node_t *prev_sibling;

    /** next sibling */
    axiom_node_t *next_sibling;

    /** first child */
    axiom_node_t *first_child;

    /** last child */
    axiom_node_t *last_child;

    /** node type, indicates the type stored in data_element */
    axiom_types_t node_type;

    /** done true means that this node is completely built , false otherwise */
    int done;

    /** instances of an om struct, whose type is defined by node type */
    void *data_element;

};

AXIS2_EXTERN axiom_node_t *AXIS2_CALL
axiom_node_create(
    const axutil_env_t * env)
{
    axiom_node_t *node = NULL;
    AXIS2_ENV_CHECK(env, NULL);

    node = (axiom_node_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_node_t));
    if(!node)
    {
        env->error->error_number = AXIS2_ERROR_NO_MEMORY;
        return NULL;
    }
    node->first_child = NULL;
    node->last_child = NULL;
    node->next_sibling = NULL;
    node->prev_sibling = NULL;
    node->parent = NULL;
    node->node_type = AXIOM_INVALID;
    node->done = AXIS2_FALSE;
    node->data_element = NULL;
    node->builder = NULL;
    node->own_builder = AXIS2_FALSE;
    return node;
}

AXIS2_EXTERN axiom_node_t* AXIS2_CALL
axiom_node_create_from_buffer(
    const axutil_env_t * env,
    axis2_char_t *buffer)
{
    axiom_xml_reader_t *reader = NULL;
    axiom_stax_builder_t *builder = NULL;
    axiom_document_t *document = NULL;
    axiom_node_t *om_node = NULL;

    reader = axiom_xml_reader_create_for_memory(env, buffer, axutil_strlen(buffer), "UTF-8",
        AXIS2_XML_PARSER_TYPE_BUFFER);

    if(!reader)
    {
        return NULL;
    }

    builder = axiom_stax_builder_create(env, reader);

    if(!builder)
    {
        return NULL;
    }
    document = axiom_stax_builder_get_document(builder, env);
    if(!document)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Document is null for deserialization");
        return NULL;
    }

    om_node = axiom_document_get_root_element(document, env);

    if(!om_node)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Root element of the document is not found");
        return NULL;
    }
    axiom_document_build_all(document, env);

    axiom_stax_builder_free_self(builder, env);

    return om_node;
}

static void
axiom_node_free_detached_subtree(
    axiom_node_t * om_node,
    const axutil_env_t * env)
{
    /* Free any child nodes first */
    if(om_node->first_child)
    {
        axiom_node_t *child_node = om_node->first_child, *next_sibling;
        while(child_node)
        {
            next_sibling = child_node->next_sibling;
            axiom_node_free_detached_subtree(child_node, env);
            child_node = next_sibling;
        }
    }

    if(om_node->node_type == AXIOM_ELEMENT)
    {
        if(om_node->data_element)
        {
            axiom_element_free((axiom_element_t *)(om_node->data_element), env);
        }
    }
    else if(om_node->node_type == AXIOM_COMMENT)
    {
        if(om_node->data_element)
        {
            axiom_comment_free((axiom_comment_t *)(om_node->data_element), env);
        }
    }
    else if(om_node->node_type == AXIOM_DOCTYPE)
    {
        /*axiom_doctype_free((axiom_doctype_t*)(om_node->data_element), env); */
    }
    else if(om_node->node_type == AXIOM_PROCESSING_INSTRUCTION)
    {
        if(om_node->data_element)
        {
            axiom_processing_instruction_free(
                (axiom_processing_instruction_t *)(om_node->data_element), env);
        }
    }
    else if(om_node->node_type == AXIOM_TEXT)
    {
        if(om_node->data_element)
        {
            axiom_text_free((axiom_text_t *)(om_node->data_element), env);
        }
    }
    else if(om_node->node_type == AXIOM_DATA_SOURCE)
    {
        if(om_node->data_element)
        {
            axiom_data_source_free((axiom_data_source_t *)(om_node->data_element), env);
        }
    }

	/* if the owner of the builder, then free the builder */
    if(om_node->own_builder)
    {
        axiom_stax_builder_free_internal(om_node->builder, env);
    }

    AXIS2_FREE(env->allocator, om_node);
}

/**
 *  This free function will free an om_element and all the children contained in it
 *  If the node is still attached to the tree, it will be detached first
 */
AXIS2_EXTERN void AXIS2_CALL
axiom_node_free_tree(
    axiom_node_t * om_node,
    const axutil_env_t * env)
{
    AXIS2_ENV_CHECK(env, void);
    if(!om_node)
    {
        return;
    }

    /* Detach this node before freeing it and its subtree. */
    axiom_node_detach_without_namespaces(om_node, env);

    /* Free this node and its subtree */
    axiom_node_free_detached_subtree(om_node, env);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_node_add_child(
    axiom_node_t * om_node,
    const axutil_env_t * env,
    axiom_node_t * child)
{
    AXIS2_PARAM_CHECK(env->error, child, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, om_node, AXIS2_FAILURE);

    if(child->parent)
    {
        child = axiom_node_detach(child, env);
    }

    if(!om_node->first_child)
    {
        om_node->first_child = child;
    }
    else
    {
        axiom_node_t *last_sib = om_node->last_child;
        last_sib->next_sibling = child;
        child->prev_sibling = last_sib;
    }

    child->parent = om_node;
    om_node->last_child = child;
    return AXIS2_SUCCESS;
}

/**
 * Detaches given node from the parent and reset the links. will not adjust the namespace as
 * in the case of axiom_node_detach.
 * @param om_node node to be detached, cannot be NULL.
 * @param env Environment. MUST NOT be NULL, .
 * @return a pointer to detached node,returns NULL on error
 */
AXIS2_EXTERN axiom_node_t *AXIS2_CALL
axiom_node_detach_without_namespaces(
    axiom_node_t * om_node,
    const axutil_env_t * env)
{
    axiom_node_t *parent = NULL;

    parent = om_node->parent;
    if(!parent)
    {
        /* Node is already detached */
        return om_node;
    }

    if(!om_node->prev_sibling)
    {
        parent->first_child = om_node->next_sibling;
    }
    else
    {
        axiom_node_t *prev_sib = NULL;
        prev_sib = om_node->prev_sibling;
        if(prev_sib)
        {
            prev_sib->next_sibling = om_node->next_sibling;
        }
    }

    if(om_node->next_sibling)
    {
        axiom_node_t *next_sibling = NULL;
        next_sibling = om_node->next_sibling;
        if(next_sibling)
        {
            next_sibling->prev_sibling = om_node->prev_sibling;
        }
    }

    if(parent->last_child && (parent->last_child == om_node))
    {
        parent->last_child = om_node->prev_sibling;
    }

    /* if the STAX builder's last node is what we are detaching, then we should adjust the
     * last node if previous sibling is available, set that as the builder's last node. Else set the
     * parent as the last node*/
    if(om_node->builder && (axiom_stax_builder_get_lastnode(om_node->builder, env) == om_node))
    {
        axiom_node_t *lastnode = parent;
        if(om_node->prev_sibling)
        {
            lastnode = om_node->prev_sibling;
        }
        axiom_stax_builder_set_lastnode(om_node->builder, env, lastnode);
    }

    /* If the node is the owner of the builder, keep a reference to the builder
     * the builder will be freed when this node is destroyed*/
    if(!om_node->own_builder)
        om_node->builder = NULL;

    om_node->parent = NULL;
    om_node->prev_sibling = NULL;
    om_node->next_sibling = NULL;
    return om_node;
}

/**
 * Detaches given node from the parent and reset the links. Will recreate "namespace defined in
 * the parent and used in detached node" within detached node itself
 * @param om_node node to be detached, cannot be NULL.
 * @param env Environment. MUST NOT be NULL, .
 * @return a pointer to detached node,returns NULL on error
 */
AXIS2_EXTERN axiom_node_t *AXIS2_CALL
axiom_node_detach(
    axiom_node_t * om_node,
    const axutil_env_t * env)
{
    axutil_hash_t *namespaces = NULL;
    axiom_element_t *om_element = NULL;

    if(!om_node)
    {
        return NULL;
    }

    /* If this is an element node, determine which namespaces are available to it
     from its parent nodes. */
    if((om_node->node_type == AXIOM_ELEMENT) && (om_element = om_node->data_element))
    {
        namespaces = axiom_element_gather_parent_namespaces(om_element, env, om_node);
    }

    /* Detach this node from its parent. */
    om_node = axiom_node_detach_without_namespaces(om_node, env);

    /* If this is an element node, ensure that any namespaces available to it or its
     children remain available after the detach. */
    if(om_node && namespaces)
    {
        axiom_element_redeclare_parent_namespaces(om_element, env, om_node, namespaces);
    }

    if(namespaces)
    {
        axutil_hash_free(namespaces, env);
    }

    return om_node;
}

/**
 Internal function , only used in om and soap
 not to be used by users
 */
axis2_status_t AXIS2_CALL
axiom_node_set_parent(
    axiom_node_t * om_node,
    const axutil_env_t * env,
    axiom_node_t * parent)
{

    if(parent == om_node->parent)
    { /* same parent already exist */
        return AXIS2_SUCCESS;
    }

    /* if a new parent is assigned in  place of existing one first the node should  be detached
     */
    if(om_node->parent)
    {
        om_node = axiom_node_detach(om_node, env);
    }

    om_node->parent = parent;

    return AXIS2_SUCCESS;
}

/**
 * This will insert a sibling just after the current information item
 * @param node the node in consideration
 * @param nodeto_insert the node that will be inserted
 */

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_node_insert_sibling_after(
    axiom_node_t * om_node,
    const axutil_env_t * env,
    axiom_node_t * node_to_insert)
{
    axiom_node_t *next_sib = NULL;

    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);

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

    if(!om_node->parent)
    {
        /* We shouldn't add a sibling because this node doesn't has a parent. 
         * This can be the root node of the tree*/
        return AXIS2_FAILURE;
    }

    node_to_insert->parent = om_node->parent;

    node_to_insert->prev_sibling = om_node;

    next_sib = om_node->next_sibling;

    if(next_sib)
    {
        next_sib->prev_sibling = node_to_insert;
    }

    node_to_insert->next_sibling = om_node->next_sibling;

    om_node->next_sibling = node_to_insert;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_node_insert_sibling_before(
    axiom_node_t * om_node,
    const axutil_env_t * env,
    axiom_node_t * node_to_insert)
{
    axiom_node_t *prev_sibling = NULL;

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

    if(!om_node->parent)
    {
        /* We shouldn't add a sibling because this node doesn't has a parent. 
         * This can be the root node of the tree*/
        return AXIS2_FAILURE;
    }

    node_to_insert->parent = om_node->parent;

    node_to_insert->prev_sibling = om_node->prev_sibling;

    node_to_insert->next_sibling = om_node;

    prev_sibling = om_node->prev_sibling;

    if(!prev_sibling)
    {
        axiom_node_t *parent = om_node->parent;
        parent->first_child = node_to_insert;
    }
    else
    {
        axiom_node_t *prev_sibling = om_node->prev_sibling;
        if(prev_sibling)
        {
            prev_sibling->next_sibling = node_to_insert;
        }
    }
    om_node->prev_sibling = node_to_insert;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_node_serialize(
    axiom_node_t * om_node,
    const axutil_env_t * env,
    axiom_output_t * om_output)
{

    int status = AXIS2_SUCCESS;
    axiom_node_t *temp_node = NULL;
    axiom_node_t *nodes[256];
    int count = 0;

    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);

    if(!om_node)
    {
        return AXIS2_SUCCESS;
    }

    nodes[count++] = om_node;

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

    do
    {

        if(om_node->node_type == AXIOM_ELEMENT)
        {
            if(om_node->data_element)
            {
                status = axiom_element_serialize_start_part(
                    (axiom_element_t *)(om_node-> data_element), env, om_output, om_node);
            }
            if(status != AXIS2_SUCCESS)
            {
                return status;
            }
        }
        else if(om_node->node_type == AXIOM_DATA_SOURCE)
        {
            if(om_node->data_element)
            {
                status = axiom_data_source_serialize(
                    (axiom_data_source_t *)(om_node->data_element), env, om_output);
            }
            if(status != AXIS2_SUCCESS)
            {
                return status;
            }
        }
        else if(om_node->node_type == AXIOM_TEXT)
        {
            if(om_node->data_element)
            {
                status = axiom_text_serialize((axiom_text_t *)(om_node-> data_element), env,
                    om_output);
            }
            if(status != AXIS2_SUCCESS)
            {
                return status;
            }
        }
        else if(om_node->node_type == AXIOM_COMMENT)
        {
            if(om_node->data_element)
            {
                status = axiom_comment_serialize((axiom_comment_t *)(om_node-> data_element), env,
                    om_output);
            }
            if(status != AXIS2_SUCCESS)
            {
                return status;
            }
        }
        else if(om_node->node_type == AXIOM_DOCTYPE)
        {
            if(om_node->data_element)
            {
                status = axiom_doctype_serialize((axiom_doctype_t *)(om_node-> data_element), env,
                    om_output);
            }
            if(status != AXIS2_SUCCESS)
            {
                return status;
            }
        }
        else if(om_node->node_type == AXIOM_PROCESSING_INSTRUCTION)
        {
            if(om_node->data_element)
            {
                status = axiom_processing_instruction_serialize(
                    (axiom_processing_instruction_t *)(om_node->data_element), env, om_output);
            }

            if(status != AXIS2_SUCCESS)
            {
                return status;
            }
        }

        temp_node = axiom_node_get_first_child(om_node, env);
        /* serialize children of this node */
        if(temp_node)
        {
            om_node = temp_node;
            nodes[count++] = om_node;
        }
        else
        {
            if(om_node->node_type == AXIOM_ELEMENT)
            {
                if(om_node->data_element)
                {
                    status = axiom_element_serialize_end_part(
                        (axiom_element_t *)(om_node-> data_element), env, om_output);
                }
                if(status != AXIS2_SUCCESS)
                {
                    return status;
                }
            }

            temp_node = axiom_node_get_next_sibling(om_node, env);
            if(temp_node)
            {
                om_node = temp_node;
                nodes[count - 1] = om_node;
            }
            else
            {
                while(count > 1 && !temp_node)
                {
                    count--;
                    om_node = nodes[count - 1];
                    if(om_node->node_type == AXIOM_ELEMENT)
                    {
                        if(om_node->data_element)
                        {
                            status = axiom_element_serialize_end_part(
                                (axiom_element_t *)(om_node->data_element), env, om_output);
                        }
                        if(status != AXIS2_SUCCESS)
                        {
                            return status;
                        }
                    }

                    temp_node = axiom_node_get_next_sibling(om_node, env);
                }

                if(temp_node && count > 1)
                {
                    om_node = temp_node;
                    nodes[count - 1] = om_node;
                }
                else
                {
                    count--;
                }
            }

        }
    }
    while(count > 0);

    return status;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_node_serialize_sub_tree(
    axiom_node_t * om_node,
    const axutil_env_t * env,
    axiom_output_t * om_output)
{

    int status = AXIS2_SUCCESS;
    axiom_node_t *temp_node = NULL;
    axiom_node_t *nodes[256];
    int count = 0;
    axutil_hash_t *namespaces = NULL;
    axutil_hash_t *namespaces_from_parents = NULL;

    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);

    if(!om_node)
    {
        return AXIS2_SUCCESS;
    }

    namespaces = axutil_hash_make(env);
    if(!namespaces)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "hash for namespaces creation failed");
        return AXIS2_FAILURE;
    }

    namespaces_from_parents = axutil_hash_make(env);
    if(!namespaces_from_parents)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "hash for namespaces_from_parents creation failed");
        return AXIS2_FAILURE;
    }

    nodes[count++] = om_node;

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

    do
    {

        if(om_node->node_type == AXIOM_ELEMENT)
        {
            if(om_node->data_element)
            {
                axutil_hash_t *temp_namespaces = NULL;
                axutil_hash_t *temp_attributes = NULL;
                axiom_namespace_t *namespace = NULL;
                status = axiom_element_serialize_start_part(
                    (axiom_element_t *)(om_node-> data_element), env, om_output, om_node);
                temp_namespaces = axiom_element_get_namespaces(
                    (axiom_element_t *)(om_node-> data_element), env);
                if(temp_namespaces)
                {
                    axutil_hash_t *new_hash = NULL;
                    new_hash = axutil_hash_overlay(temp_namespaces, env, namespaces);
                    if(namespaces)
                        axutil_hash_free(namespaces, env);
                    namespaces = new_hash;
                }
                namespace = axiom_element_get_namespace(
                    (axiom_element_t *)(om_node-> data_element), env, om_node);
                if(namespace)
                {
                    axiom_namespace_t *ns = NULL;
                    axis2_char_t *prefix = NULL;
                    prefix = axiom_namespace_get_prefix(namespace, env);
                    if(prefix)
                    {
                        ns = axutil_hash_get(namespaces, prefix, AXIS2_HASH_KEY_STRING);
                        if(!ns)
                        {
                            ns = axutil_hash_get(namespaces_from_parents, prefix,
                                AXIS2_HASH_KEY_STRING);
                            if(!ns)
                            {
                                axiom_namespace_serialize(namespace, env, om_output);
                                axutil_hash_set(namespaces_from_parents, prefix,
                                    AXIS2_HASH_KEY_STRING, namespace);
                            }
                        }
                    }
                }

                temp_attributes = axiom_element_get_all_attributes(
                    (axiom_element_t *)(om_node->data_element), env);
                if(temp_attributes)
                {
                    axutil_hash_index_t *hi;
                    void *val;
                    for(hi = axutil_hash_first(temp_attributes, env); hi; hi = axutil_hash_next(
                        env, hi))
                    {
                        axutil_hash_this(hi, NULL, NULL, &val);

                        if(val)
                        {
                            axiom_namespace_t *ns = NULL;
                            axis2_char_t *prefix = NULL;

                            namespace
                                = axiom_attribute_get_namespace((axiom_attribute_t *)val, env);

                            if(namespace)
                            {
                                prefix = axiom_namespace_get_prefix(namespace, env);
                                if(prefix)
                                {
                                    ns = axutil_hash_get(namespaces, prefix, AXIS2_HASH_KEY_STRING);
                                    if(!ns)
                                    {
                                        ns = axutil_hash_get(namespaces_from_parents, prefix,
                                            AXIS2_HASH_KEY_STRING);
                                        if(!ns)
                                        {
                                            axiom_namespace_serialize(namespace, env, om_output);
                                            axutil_hash_set(namespaces_from_parents, prefix,
                                                AXIS2_HASH_KEY_STRING, namespace);
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            status = AXIS2_FAILURE;
                        }
                    }
                }
            }
            if(status != AXIS2_SUCCESS)
            {
                break;
            }
        }
        else if(om_node->node_type == AXIOM_DATA_SOURCE)
        {
            if(om_node->data_element)
            {
                status = axiom_data_source_serialize(
                    (axiom_data_source_t *)(om_node->data_element), env, om_output);
            }
            if(status != AXIS2_SUCCESS)
            {
                break;
            }
        }
        else if(om_node->node_type == AXIOM_TEXT)
        {
            if(om_node->data_element)
            {
                status = axiom_text_serialize((axiom_text_t *)(om_node-> data_element), env,
                    om_output);
            }
            if(status != AXIS2_SUCCESS)
            {
                break;
            }
        }
        else if(om_node->node_type == AXIOM_COMMENT)
        {
            if(om_node->data_element)
            {
                status = axiom_comment_serialize((axiom_comment_t *)(om_node-> data_element), env,
                    om_output);
            }
            if(status != AXIS2_SUCCESS)
            {
                break;
            }
        }
        else if(om_node->node_type == AXIOM_DOCTYPE)
        {
            if(om_node->data_element)
            {
                status = axiom_doctype_serialize((axiom_doctype_t *)(om_node-> data_element), env,
                    om_output);
            }
            if(status != AXIS2_SUCCESS)
            {
                break;
            }
        }
        else if(om_node->node_type == AXIOM_PROCESSING_INSTRUCTION)
        {
            if(om_node->data_element)
            {
                status = axiom_processing_instruction_serialize(
                    (axiom_processing_instruction_t *)(om_node->data_element), env, om_output);
            }

            if(status != AXIS2_SUCCESS)
            {
                break;
            }
        }

        temp_node = axiom_node_get_first_child(om_node, env);
        /* serialize children of this node */
        if(temp_node)
        {
            om_node = temp_node;
            nodes[count++] = om_node;
        }
        else
        {
            if(om_node->node_type == AXIOM_ELEMENT)
            {
                if(om_node->data_element)
                {

                    axutil_hash_t *temp_attributes = NULL;
                    axiom_namespace_t *namespace = NULL;
                    /* at the writing of end part all the namespaces declared
                     specially to that element should be cancelled */

                    /* first checking the element namespace */
                    namespace = axiom_element_get_namespace(
                        (axiom_element_t *)(om_node-> data_element), env, om_node);
                    if(namespace)
                    {
                        axiom_namespace_t *ns = NULL;
                        axis2_char_t *prefix = NULL;
                        prefix = axiom_namespace_get_prefix(namespace, env);
                        if(prefix)
                        {
                            ns = axutil_hash_get(namespaces_from_parents, prefix,
                                AXIS2_HASH_KEY_STRING);
                            if(ns)
                            {
                                axutil_hash_set(namespaces_from_parents, prefix,
                                    AXIS2_HASH_KEY_STRING, NULL);
                            }
                        }
                    }

                    /* then checking the attribute namespaces */

                    temp_attributes = axiom_element_get_all_attributes(
                        (axiom_element_t *)(om_node->data_element), env);
                    if(temp_attributes)
                    {
                        axutil_hash_index_t *hi;
                        void *val;
                        for(hi = axutil_hash_first(temp_attributes, env); hi; hi
                            = axutil_hash_next(env, hi))
                        {
                            axutil_hash_this(hi, NULL, NULL, &val);

                            if(val)
                            {
                                axiom_namespace_t *ns = NULL;
                                axis2_char_t *prefix = NULL;

                                namespace = axiom_attribute_get_namespace((axiom_attribute_t *)val,
                                    env);

                                if(namespace)
                                {
                                    prefix = axiom_namespace_get_prefix(namespace, env);
                                    if(prefix)
                                    {
                                        ns = axutil_hash_get(namespaces_from_parents, prefix,
                                            AXIS2_HASH_KEY_STRING);
                                        if(ns)
                                        {
                                            axutil_hash_set(namespaces_from_parents, prefix,
                                                AXIS2_HASH_KEY_STRING, NULL);
                                        }
                                    }
                                }
                            }
                        }
                    }

                    status = axiom_element_serialize_end_part(
                        (axiom_element_t *)(om_node-> data_element), env, om_output);
                }
                if(status != AXIS2_SUCCESS)
                {
                    break;
                }
            }
            /* We need to make make sure that om_node is not the root when we take the next sibling */
            if(count > 1)
            {
                temp_node = axiom_node_get_next_sibling(om_node, env);
            }
            if(temp_node)
            {
                om_node = temp_node;
                nodes[count - 1] = om_node;
            }
            else
            {
                while(count > 1 && !temp_node)
                {
                    count--;
                    om_node = nodes[count - 1];
                    if(om_node->node_type == AXIOM_ELEMENT)
                    {
                        if(om_node->data_element)
                        {
                            axutil_hash_t *temp_attributes = NULL;
                            axiom_namespace_t *namespace = NULL;

                            /* similar to the earlier time, whenever the ending is happened
                             * namespaces declared specially to that element should be cancelled */

                            /* first checking the element namespace */
                            namespace = axiom_element_get_namespace(
                                (axiom_element_t *)(om_node-> data_element), env, om_node);
                            if(namespace)
                            {
                                axiom_namespace_t *ns = NULL;
                                axis2_char_t *prefix = NULL;
                                prefix = axiom_namespace_get_prefix(namespace, env);
                                if(prefix)
                                {
                                    ns = axutil_hash_get(namespaces_from_parents, prefix,
                                        AXIS2_HASH_KEY_STRING);
                                    if(ns)
                                    {
                                        axutil_hash_set(namespaces_from_parents, prefix,
                                            AXIS2_HASH_KEY_STRING, NULL);
                                    }
                                }
                            }

                            /* then checking the attribute namespaces */

                            temp_attributes = axiom_element_get_all_attributes(
                                (axiom_element_t *)(om_node->data_element), env);
                            if(temp_attributes)
                            {
                                axutil_hash_index_t *hi;
                                void *val;
                                for(hi = axutil_hash_first(temp_attributes, env); hi; hi
                                    = axutil_hash_next(env, hi))
                                {
                                    axutil_hash_this(hi, NULL, NULL, &val);

                                    if(val)
                                    {
                                        axiom_namespace_t *ns = NULL;
                                        axis2_char_t *prefix = NULL;

                                        namespace = axiom_attribute_get_namespace(
                                            (axiom_attribute_t *)val, env);

                                        if(namespace)
                                        {
                                            prefix = axiom_namespace_get_prefix(namespace, env);
                                            if(prefix)
                                            {
                                                ns = axutil_hash_get(namespaces_from_parents,
                                                    prefix, AXIS2_HASH_KEY_STRING);
                                                if(ns)
                                                {
                                                    axutil_hash_set(namespaces_from_parents,
                                                        prefix, AXIS2_HASH_KEY_STRING, NULL);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            status = axiom_element_serialize_end_part(
                                (axiom_element_t *)(om_node->data_element), env, om_output);
                        }
                        if(status != AXIS2_SUCCESS)
                        {
                            break;
                        }
                    }

                    temp_node = axiom_node_get_next_sibling(om_node, env);
                }

                if(temp_node && count > 1)
                {
                    om_node = temp_node;
                    nodes[count - 1] = om_node;
                }
                else
                {
                    count--;
                }
            }
        }
    }
    while(count > 0);

    axutil_hash_free(namespaces_from_parents, env);
    axutil_hash_free(namespaces, env);

    return status;
}

AXIS2_EXTERN axiom_node_t *AXIS2_CALL
axiom_node_get_parent(
    axiom_node_t * om_node,
    const axutil_env_t * env)
{
    return om_node->parent;
}

AXIS2_EXTERN axiom_node_t *AXIS2_CALL
axiom_node_get_first_child(
    axiom_node_t * om_node,
    const axutil_env_t * env)
{
    int token = 0;
    if(!om_node)
    {
        return NULL;
    }

    /**********************************************************/
    while(!(om_node->first_child) && !(om_node->done) && om_node->builder)
    {
        token = axiom_stax_builder_next_with_token(om_node->builder, env);
        if(token == -1)
        {
            return NULL;
        }
    }

    /**********************************************************/
    return om_node->first_child;
}

AXIS2_EXTERN axiom_node_t *AXIS2_CALL
axiom_node_get_first_element(
    axiom_node_t * om_node,
    const axutil_env_t * env)
{
    int token = 0;
    axiom_node_t *first_element;
    if(!om_node)
    {
        return NULL;
    }

    /**********************************************************/
    while(!(om_node->first_child) && !(om_node->done) && om_node->builder)
    {
        token = axiom_stax_builder_next_with_token(om_node->builder, env);
        if(token == -1)
        {
            return NULL;
        }
    }

    /**********************************************************/
    first_element = om_node->first_child;

    while(first_element && (axiom_node_get_node_type(first_element, env) != AXIOM_ELEMENT))
    {
        first_element = axiom_node_get_next_sibling(first_element, env);
    }

    return first_element;
}

AXIS2_EXTERN axiom_node_t *AXIS2_CALL
axiom_node_get_last_child(
    axiom_node_t * om_node,
    const axutil_env_t * env)
{
    return om_node->last_child;
}

AXIS2_EXTERN axiom_node_t *AXIS2_CALL
axiom_node_get_previous_sibling(
    axiom_node_t * om_node,
    const axutil_env_t * env)
{
    return om_node->prev_sibling;
}

AXIS2_EXTERN axiom_node_t *AXIS2_CALL
axiom_node_get_previous_sibling_element(
    axiom_node_t * om_node,
    const axutil_env_t * env)
{
    axiom_node_t * result = axiom_node_get_previous_sibling( om_node, env );
    while ( result && axiom_node_get_node_type(result, env) != AXIOM_ELEMENT )
        result = axiom_node_get_previous_sibling( result, env );
    return result;
}

AXIS2_EXTERN axiom_node_t *AXIS2_CALL
axiom_node_get_next_sibling(
    axiom_node_t * om_node,
    const axutil_env_t * env)
{
    int token = 0;
    if(!om_node)
    {
        return NULL;
    }

    /* we have to build the tree using stax builder if
     * (1) om_node's next_sibling is not given (if available, we can just return that)
     * (2) om_node is having a parent (otherwise, no concept of sibling)
     * (3) om_node is having a stax builder (otherwise, it is a programatically built node)
     * (4) parent is having a stax builder (otherwise, om_node is the only child,
     *          or sibling is programatically created)
     * (5) parent is not yet fully built
     */
    while((!om_node->next_sibling) && om_node->parent && om_node->parent->builder
        && om_node->builder && (!axiom_node_is_complete(om_node->parent, env)))
    {
        token = axiom_stax_builder_next_with_token(om_node->builder, env);
        if(token == -1)
        {
            return NULL;
        }
    }

    return om_node->next_sibling;
}

AXIS2_EXTERN axiom_node_t *AXIS2_CALL
axiom_node_get_next_sibling_element(
    axiom_node_t * om_node,
    const axutil_env_t * env)
{
    axiom_node_t * result = axiom_node_get_next_sibling( om_node, env );
    while ( result && axiom_node_get_node_type(result, env) != AXIOM_ELEMENT )
        result = axiom_node_get_next_sibling( result, env );
    return result;
}


AXIS2_EXTERN axiom_types_t AXIS2_CALL
axiom_node_get_node_type(
    axiom_node_t * om_node,
    const axutil_env_t * env)
{
    return om_node->node_type;
}

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axiom_node_is_complete(
    axiom_node_t * om_node,
    const axutil_env_t * env)
{
    return om_node->done;

}

AXIS2_EXTERN struct axiom_document *AXIS2_CALL
axiom_node_get_document(
    axiom_node_t * om_node,
    const axutil_env_t * env)
{
    if(om_node->builder)
    {
        return axiom_stax_builder_get_document(om_node->builder, env);
    }

    return NULL;
}

AXIS2_EXTERN void *AXIS2_CALL
axiom_node_get_data_element(
    axiom_node_t * om_node,
    const axutil_env_t * env)
{
    return om_node->data_element;
}

/**
 internal function , not to be used by users
 only sets the first_child link because this is needed by builder
 */
void AXIS2_CALL
axiom_node_set_first_child(
    axiom_node_t * om_node,
    const axutil_env_t * env,
    axiom_node_t * first_child)
{
    /** set the parent */
    axiom_node_set_parent(first_child, env, om_node);
    om_node->first_child = first_child;
}

/**
 internal function not to be used by users
 only sets the previous sibling link as it is needed by builders

 */
void AXIS2_CALL
axiom_node_set_previous_sibling(
    axiom_node_t * om_node,
    const axutil_env_t * env,
    axiom_node_t * prev_sibling)
{
    om_node->prev_sibling = prev_sibling;
}

/**
 internal function, not to be used by users
 only sets the next sibling link;
 */
void AXIS2_CALL
axiom_node_set_next_sibling(
    axiom_node_t * om_node,
    const axutil_env_t * env,
    axiom_node_t * next_sibling)
{
    om_node->next_sibling = next_sibling;
}

/**
 internal function not to be used by users
 sets the node type only used in soap and om
 */

axis2_status_t AXIS2_CALL
axiom_node_set_node_type(
    axiom_node_t * om_node,
    const axutil_env_t * env,
    axiom_types_t type)
{
    om_node->node_type = type;
    return AXIS2_SUCCESS;
}

/**
 internal function , not to be used by users
 only used in om and soap
 */
void AXIS2_CALL
axiom_node_set_data_element(
    axiom_node_t * om_node,
    const axutil_env_t * env,
    void *data_element)
{
    om_node->data_element = data_element;
}

/**
 internal function not to be used by users
 only sets the build status

 */
void AXIS2_CALL
axiom_node_set_complete(
    axiom_node_t * om_node,
    const axutil_env_t * env,
    axis2_bool_t done)
{
    om_node->done = done;
}

/**
 internal function only sets the builder reference ,
 should not be used by user
 */
void AXIS2_CALL
axiom_node_set_builder(
    axiom_node_t * om_node,
    const axutil_env_t * env,
    axiom_stax_builder_t * builder)
{
    /* builder == NULL is a valid case */
    om_node->builder = builder;
}

void AXIS2_CALL
axiom_node_assume_builder_ownership(
    axiom_node_t *om_node,
    const axutil_env_t * env)
{
    om_node->own_builder = AXIS2_TRUE;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axiom_node_to_string(
    axiom_node_t * om_node,
    const axutil_env_t * env)
{
    int status = AXIS2_SUCCESS;
    axiom_output_t *om_output = NULL;
    axiom_xml_writer_t *xml_writer = NULL;
    axis2_char_t *xml = NULL;
    AXIS2_ENV_CHECK(env, NULL);
    AXIS2_PARAM_CHECK(env->error, om_node, NULL);

    xml_writer = axiom_xml_writer_create_for_memory(env, NULL, AXIS2_TRUE, 0,
        AXIS2_XML_PARSER_TYPE_BUFFER);
    if(!xml_writer)
    {
        return NULL;
    }

    om_output = axiom_output_create(env, xml_writer);
    if(!om_output)
    {
        axiom_xml_writer_free(xml_writer, env);
        return NULL;
    }
    status = axiom_node_serialize(om_node, env, om_output);
    if(status == AXIS2_SUCCESS)
    {
        xml = axutil_strdup(env, (axis2_char_t *)axiom_xml_writer_get_xml(xml_writer, env));
    }
    axiom_output_free(om_output, env);
    return xml;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axiom_node_sub_tree_to_string(
    axiom_node_t * om_node,
    const axutil_env_t * env)
{
    int status = AXIS2_SUCCESS;
    axiom_output_t *om_output = NULL;
    axiom_xml_writer_t *xml_writer = NULL;
    axis2_char_t *xml = NULL;
    AXIS2_ENV_CHECK(env, NULL);
    AXIS2_PARAM_CHECK(env->error, om_node, NULL);

    xml_writer = axiom_xml_writer_create_for_memory(env, NULL, AXIS2_TRUE, 0,
        AXIS2_XML_PARSER_TYPE_BUFFER);
    if(!xml_writer)
    {
        return NULL;
    }

    om_output = axiom_output_create(env, xml_writer);
    if(!om_output)
    {
        axiom_xml_writer_free(xml_writer, env);
        return NULL;
    }
    status = axiom_node_serialize_sub_tree(om_node, env, om_output);
    if(status == AXIS2_SUCCESS)
    {
        xml = axutil_strdup(env, (axis2_char_t *)axiom_xml_writer_get_xml(xml_writer, env));
    }
    axiom_output_free(om_output, env);
    return xml;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axiom_node_to_string_non_optimized(
    axiom_node_t * om_node,
    const axutil_env_t * env)
{
    int status = AXIS2_SUCCESS;
    axiom_output_t *om_output = NULL;
    axiom_xml_writer_t *xml_writer = NULL;
    axis2_char_t *xml = NULL;
    AXIS2_ENV_CHECK(env, NULL);
    AXIS2_PARAM_CHECK(env->error, om_node, NULL);

    xml_writer = axiom_xml_writer_create_for_memory(env, NULL, AXIS2_TRUE, 0,
        AXIS2_XML_PARSER_TYPE_BUFFER);
    if(!xml_writer)
    {
        return NULL;
    }

    om_output = axiom_output_create(env, xml_writer);
    if(!om_output)
    {
        axiom_xml_writer_free(xml_writer, env);
        return NULL;
    }
    /*This is where we set the output to be non-optimized*/
    axiom_output_set_do_optimize(om_output, env, AXIS2_FALSE);
    status = axiom_node_serialize(om_node, env, om_output);
    if(status == AXIS2_SUCCESS)
    {
        xml = axutil_strdup(env, (axis2_char_t *)axiom_xml_writer_get_xml(xml_writer, env));
    }
    axiom_output_free(om_output, env);
    return xml;
}

AXIS2_EXTERN axiom_node_t * AXIS2_CALL
axiom_node_add_sibling(
	const axutil_env_t *env,
	axiom_node_t *nodeElem,
	axiom_node_t *nodeElemSibling)
{
	assert(env != NULL);

	AXIS2_ENV_CHECK(env, NULL);
	AXIS2_PARAM_CHECK(env->error, nodeElem, NULL);
	AXIS2_PARAM_CHECK(env->error, nodeElemSibling, NULL);

	axiom_node_t *next_sib = NULL;
	nodeElemSibling->parent = nodeElem->parent;
	nodeElemSibling->prev_sibling = nodeElem;
	next_sib = nodeElem->next_sibling;
	if (next_sib)
	{
		next_sib->prev_sibling = nodeElemSibling;
	}
	nodeElemSibling->next_sibling = nodeElem->next_sibling;
	nodeElem->next_sibling = nodeElemSibling;

	return nodeElem;
}
  
#if 0

/**
 internal function not to be used by users
 only used by om builder
 */
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_node_set_document(
    axiom_node_t * om_node,
    const axutil_env_t * env,
    struct axiom_document * om_doc)
{
    /* om_doc == NULL is a valid case */
    om_node->om_doc = om_doc;
    return AXIS2_SUCCESS;
}

/**
 * This is an internal function
 */
AXIS2_EXTERN axiom_stax_builder_t *AXIS2_CALL
axiom_node_get_builder(
    axiom_node_t * om_node,
    const axutil_env_t * env)
{
    if(!om_node)
    {
        return NULL;
    }
    return om_node->builder;
}

#endif

