/*
 * 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 <libxml/xmlwriter.h>
#include <axutil_utils.h>
#include <axutil_utils_defines.h>
#include <axutil_env.h>
#include <axiom_xml_writer.h>
#include <axutil_string.h>
#include <string.h>
#include <axutil_stack.h>
#include <axutil_hash.h>
#include <axutil_array_list.h>

/*******************************************************************************/

#define ENCODING "ISO-8859-1"

#define AXIS2_XMLNS_NAMESPACE_URI "http://www.w3.org/XML/1998/namespace"
#define AXIS2_XMLNS_PREFIX "xml"

typedef struct uri_prefix_element
{
    axis2_char_t *prefix;

    axis2_char_t *uri;

    axis2_char_t *real_prefix;

    axis2_char_t *key;

} uri_prefix_element_t;

typedef struct axis2_libxml2_writer_wrapper_impl
{
    axiom_xml_writer_t writer;

    xmlTextWriterPtr xml_writer;

    xmlBufferPtr buffer;

    xmlDocPtr doc;

    int writer_type;

    axis2_char_t *encoding;

    int is_prefix_defaulting;

    int compression;

    axutil_stack_t *stack;

    axis2_bool_t in_empty_element;

    axis2_bool_t in_start_element;

    axutil_hash_t *uri_prefix_map;

    uri_prefix_element_t *default_lang_namespace;

} axis2_libxml2_writer_wrapper_impl_t;

#define AXIS2_INTF_TO_IMPL(p) ((axis2_libxml2_writer_wrapper_impl_t*)p)

void AXIS2_CALL axis2_libxml2_writer_wrapper_free(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env);

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_start_element(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * localname);

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_end_start_element(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env);

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_start_element_with_namespace(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * localname,
    axis2_char_t * namespace_uri);

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_start_element_with_namespace_prefix(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * localname,
    axis2_char_t * namespace_uri,
    axis2_char_t * prefix);

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_empty_element(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * localname);

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_empty_element_with_namespace(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * localname,
    axis2_char_t * namespace_uri);

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_empty_element_with_namespace_prefix(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * localname,
    axis2_char_t * namespace_uri,
    axis2_char_t * prefix);

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_end_element(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env);

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_end_document(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env);

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_attribute(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * localname,
    axis2_char_t * value);

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_attribute_with_namespace(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * localname,
    axis2_char_t * value,
    axis2_char_t * namespace_uri);

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_attribute_with_namespace_prefix(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * localname,
    axis2_char_t * value,
    axis2_char_t * namespace_uri,
    axis2_char_t * prefix);

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_namespace(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * prefix,
    axis2_char_t * namespace_uri);

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_default_namespace(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * namespace_uri);

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_comment(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * value);

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_processing_instruction(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * target);

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_processing_instruction_data(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * target,
    axis2_char_t * data);

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_cdata(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * data);

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_dtd(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * dtd);

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_entity_ref(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * name);

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_start_document(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env);

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_start_document_with_version(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * version);

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_start_document_with_version_encoding(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * encoding,
    axis2_char_t * version);

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_characters(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * text);

axis2_char_t *AXIS2_CALL axis2_libxml2_writer_wrapper_get_prefix(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * uri);

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_set_prefix(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * prefix,
    axis2_char_t * uri);

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_set_default_prefix(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * uri);

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_encoded(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * text,
    int in_attr);

void *AXIS2_CALL axis2_libxml2_writer_wrapper_get_xml(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env);

unsigned int AXIS2_CALL axis2_libxml2_writer_wrapper_get_xml_size(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env);

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_flush(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env);

int AXIS2_CALL axis2_libxml2_writer_wrapper_get_type(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env);

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_raw(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * content);

static axis2_status_t
axis2_libxml2_writer_wrapper_push(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    const axis2_char_t * uri,
    const axis2_char_t * prefix);

static axis2_bool_t
axis2_libxml2_writer_wrapper_is_namespace_declared(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * key);

static void
uri_prefix_element_free(
    uri_prefix_element_t * up_element,
    const axutil_env_t * env);

static uri_prefix_element_t *
uri_prefix_element_create(
    const axutil_env_t * env,
    const axis2_char_t * uri,
    const axis2_char_t * prefix,
    const axis2_char_t * real_prefix,
    const axis2_char_t * key);

static void
create_key_from_uri_prefix(
    const axutil_env_t * env,
    const axis2_char_t * uri,
    const axis2_char_t * prefix,
    axis2_char_t * array);

static axis2_char_t *
axis2_libxml2_writer_wrapper_find_prefix(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * uri);

static uri_prefix_element_t *
axis2_libxml2_writer_wrapper_find_prefix_in_context(
    axutil_array_list_t * context,
    const axutil_env_t * env,
    axis2_char_t * uri);

static const axiom_xml_writer_ops_t axiom_xml_writer_ops_var = { axis2_libxml2_writer_wrapper_free,
    axis2_libxml2_writer_wrapper_write_start_element,
    axis2_libxml2_writer_wrapper_end_start_element,
    axis2_libxml2_writer_wrapper_write_start_element_with_namespace,
    axis2_libxml2_writer_wrapper_write_start_element_with_namespace_prefix,
    axis2_libxml2_writer_wrapper_write_empty_element,
    axis2_libxml2_writer_wrapper_write_empty_element_with_namespace,
    axis2_libxml2_writer_wrapper_write_empty_element_with_namespace_prefix,
    axis2_libxml2_writer_wrapper_write_end_element,
    axis2_libxml2_writer_wrapper_write_end_document, axis2_libxml2_writer_wrapper_write_attribute,
    axis2_libxml2_writer_wrapper_write_attribute_with_namespace,
    axis2_libxml2_writer_wrapper_write_attribute_with_namespace_prefix,
    axis2_libxml2_writer_wrapper_write_namespace,
    axis2_libxml2_writer_wrapper_write_default_namespace,
    axis2_libxml2_writer_wrapper_write_comment,
    axis2_libxml2_writer_wrapper_write_processing_instruction,
    axis2_libxml2_writer_wrapper_write_processing_instruction_data,
    axis2_libxml2_writer_wrapper_write_cdata, axis2_libxml2_writer_wrapper_write_dtd,
    axis2_libxml2_writer_wrapper_write_entity_ref,
    axis2_libxml2_writer_wrapper_write_start_document,
    axis2_libxml2_writer_wrapper_write_start_document_with_version,
    axis2_libxml2_writer_wrapper_write_start_document_with_version_encoding,
    axis2_libxml2_writer_wrapper_write_characters, axis2_libxml2_writer_wrapper_get_prefix,
    axis2_libxml2_writer_wrapper_set_prefix, axis2_libxml2_writer_wrapper_set_default_prefix,
    axis2_libxml2_writer_wrapper_write_encoded, axis2_libxml2_writer_wrapper_get_xml,
    axis2_libxml2_writer_wrapper_get_xml_size, axis2_libxml2_writer_wrapper_get_type,
    axis2_libxml2_writer_wrapper_write_raw, axis2_libxml2_writer_wrapper_flush };

AXIS2_EXTERN axiom_xml_writer_t *AXIS2_CALL
axiom_xml_writer_create(
    const axutil_env_t * env,
    axis2_char_t * filename,
    axis2_char_t * encoding,
    int is_prefix_default,
    int compression)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    AXIS2_ENV_CHECK(env, NULL);
    writer_impl = (axis2_libxml2_writer_wrapper_impl_t *)AXIS2_MALLOC(env->allocator,
        sizeof(axis2_libxml2_writer_wrapper_impl_t));
    if(!writer_impl)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create an XML writer wrapper");
        return NULL;
    }
    writer_impl->xml_writer = xmlNewTextWriterFilename(filename, compression);

    if(!(writer_impl->xml_writer))
    {
        AXIS2_FREE(env->allocator, writer_impl);
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_CREATING_XML_STREAM_WRITER, AXIS2_FAILURE);
        return NULL;
    }
    writer_impl->buffer = NULL;
    writer_impl->encoding = NULL;
    writer_impl->compression = 0;
    writer_impl->in_empty_element = AXIS2_FALSE;
    writer_impl->in_start_element = AXIS2_FALSE;
    writer_impl->stack = NULL;
    writer_impl->uri_prefix_map = NULL;
    writer_impl->default_lang_namespace = NULL;

    writer_impl->writer_type = AXIS2_XML_PARSER_TYPE_FILE;
    writer_impl->compression = compression;

    if(encoding)
    {
        writer_impl->encoding = axutil_strdup(env, encoding);
    }
    else
    {
        writer_impl->encoding = axutil_strdup(env, ENCODING);
    }

    writer_impl->uri_prefix_map = axutil_hash_make(env);
    if(!(writer_impl->uri_prefix_map))
    {
        axis2_libxml2_writer_wrapper_free(&(writer_impl->writer), env);
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create URI prefix hash map");
        return NULL;
    }
    writer_impl->writer.ops = &axiom_xml_writer_ops_var;
    return &(writer_impl->writer);
}

AXIS2_EXTERN axiom_xml_writer_t *AXIS2_CALL
axiom_xml_writer_create_for_memory(
    const axutil_env_t * env,
    axis2_char_t * encoding,
    int is_prefix_default,
    int compression,
    int type)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    AXIS2_ENV_CHECK(env, NULL);
    writer_impl = (axis2_libxml2_writer_wrapper_impl_t *)AXIS2_MALLOC(env->allocator,
        sizeof(axis2_libxml2_writer_wrapper_impl_t));
    if(!writer_impl)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create writer wrapper");
        return NULL;
    }

    writer_impl->encoding = NULL;
    writer_impl->buffer = NULL;
    writer_impl->doc = NULL;
    writer_impl->in_empty_element = AXIS2_FALSE;
    writer_impl->in_start_element = AXIS2_FALSE;
    writer_impl->stack = NULL;
    writer_impl->uri_prefix_map = NULL;
    writer_impl->default_lang_namespace = NULL;
    writer_impl->compression = compression;

    if(AXIS2_XML_PARSER_TYPE_BUFFER == type)
    {
        writer_impl->writer_type = AXIS2_XML_PARSER_TYPE_BUFFER;
        writer_impl->buffer = xmlBufferCreate();
        if(!(writer_impl->buffer))
        {
            axis2_libxml2_writer_wrapper_free(&(writer_impl->writer), env);
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                "No memory. Cannot create a buffer for writer wrapper");
            return NULL;
        }

        writer_impl->xml_writer = xmlNewTextWriterMemory(writer_impl->buffer, 0);
    }
    else if(AXIS2_XML_PARSER_TYPE_DOC == type)
    {
        writer_impl->writer_type = AXIS2_XML_PARSER_TYPE_DOC;
        writer_impl->xml_writer = xmlNewTextWriterDoc(&writer_impl->doc, 0);
    }
    else
    {
        axis2_libxml2_writer_wrapper_free(&(writer_impl->writer), env);
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_XML_PARSER_INVALID_MEM_TYPE, AXIS2_FAILURE);
        return NULL;
    }

    if(!(writer_impl->xml_writer))
    {
        axis2_libxml2_writer_wrapper_free(&(writer_impl->writer), env);
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_CREATING_XML_STREAM_WRITER, AXIS2_FAILURE);
        return NULL;
    }

    if(encoding)
    {
        writer_impl->encoding = axutil_strdup(env, encoding);
    }
    else
    {
        writer_impl->encoding = axutil_strdup(env, ENCODING);
    }

    writer_impl->uri_prefix_map = axutil_hash_make(env);
    if(!(writer_impl->uri_prefix_map))
    {
        axis2_libxml2_writer_wrapper_free(&(writer_impl->writer), env);
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create URI prefix hash map");
        return NULL;
    }
    writer_impl->stack = axutil_stack_create(env);
    if(!(writer_impl->stack))
    {
        axis2_libxml2_writer_wrapper_free(&(writer_impl->writer), env);
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "No memory. Cannot create the stack for writer wrapper");
        return NULL;
    }

    writer_impl->writer.ops = &axiom_xml_writer_ops_var;

    return &(writer_impl->writer);
}

void AXIS2_CALL
axis2_libxml2_writer_wrapper_free(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    writer_impl = AXIS2_INTF_TO_IMPL(writer);

    if(writer_impl->xml_writer)
    {
        xmlFreeTextWriter(writer_impl->xml_writer);
        writer_impl->xml_writer = NULL;
    }
    if(writer_impl->buffer)
    {
        xmlBufferFree(writer_impl->buffer);
        writer_impl->buffer = NULL;
    }
    if(writer_impl->encoding)
    {
        AXIS2_FREE(env->allocator, writer_impl->encoding);
        writer_impl->encoding = NULL;
    }
    if(writer_impl->uri_prefix_map)
    {
        axutil_hash_free(writer_impl->uri_prefix_map, env);
        writer_impl->uri_prefix_map = NULL;
    }
    if(writer_impl->stack)
    {
        axutil_stack_free(writer_impl->stack, env);
        writer_impl->stack = NULL;
    }
    if(writer_impl->default_lang_namespace)
    {
        uri_prefix_element_free(writer_impl->default_lang_namespace, env);
        writer_impl->default_lang_namespace = NULL;
    }

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

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_start_element(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * localname)
{
    int status = 0;
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE);
    writer_impl = AXIS2_INTF_TO_IMPL(writer);

    writer_impl->in_start_element = AXIS2_TRUE;

    status = xmlTextWriterStartElement(writer_impl->xml_writer, (xmlChar *)localname);
    if(status < 0)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_START_ELEMENT, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_end_start_element(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    /* nothing to do ,
     it is automatically taken care by the libxml2 writer */
    return AXIS2_SUCCESS;
}

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_start_element_with_namespace(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * localname,
    axis2_char_t * namespace_uri)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    int status = 0;
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, namespace_uri, AXIS2_FAILURE);

    writer_impl = AXIS2_INTF_TO_IMPL(writer);

    status = xmlTextWriterStartElementNS(writer_impl->xml_writer,
        NULL, BAD_CAST localname, NULL);

    if(status < 0)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_START_ELEMENT_WITH_NAMESPACE, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_start_element_with_namespace_prefix(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * localname,
    axis2_char_t * namespace_uri,
    axis2_char_t * prefix)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    int status = 0;
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, namespace_uri, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, prefix, AXIS2_FAILURE);

    writer_impl = AXIS2_INTF_TO_IMPL(writer);
    writer_impl->in_start_element = AXIS2_TRUE;

    status = xmlTextWriterStartElementNS(writer_impl->xml_writer,
        BAD_CAST prefix,
        BAD_CAST localname, BAD_CAST NULL);
    if(status < 0)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_START_ELEMENT_WITH_NAMESPACE_PREFIX,
            AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_empty_element(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * localname)
{
    int status = 0;
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE);
    writer_impl = AXIS2_INTF_TO_IMPL(writer);

    status = xmlTextWriterStartElement(writer_impl->xml_writer, (xmlChar *)localname);

    if(status < 0)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_EMPTY_ELEMENT, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    status = xmlTextWriterEndElement(writer_impl->xml_writer);
    if(status < 0)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_EMPTY_ELEMENT, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_empty_element_with_namespace(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * localname,
    axis2_char_t * namespace_uri)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    int status = 0;
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, namespace_uri, AXIS2_FAILURE);

    writer_impl = AXIS2_INTF_TO_IMPL(writer);

    status = xmlTextWriterStartElementNS(writer_impl->xml_writer,
        NULL, BAD_CAST localname,
        BAD_CAST namespace_uri);

    if(status < 0)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_EMPTY_ELEMENT_WITH_NAMESPACE, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    status = xmlTextWriterEndElement(writer_impl->xml_writer);
    if(status < 0)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_EMPTY_ELEMENT_WITH_NAMESPACE, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }

    return AXIS2_SUCCESS;
}

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_empty_element_with_namespace_prefix(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * localname,
    axis2_char_t * namespace_uri,
    axis2_char_t * prefix)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    int status = 0;
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, namespace_uri, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, prefix, AXIS2_FAILURE);

    writer_impl = AXIS2_INTF_TO_IMPL(writer);

    status = xmlTextWriterStartElementNS(writer_impl->xml_writer,
        BAD_CAST prefix,
        BAD_CAST localname, BAD_CAST NULL);
    if(status < 0)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_START_ELEMENT_WITH_NAMESPACE_PREFIX,
            AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    status = xmlTextWriterEndElement(writer_impl->xml_writer);
    if(status < 0)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_EMPTY_ELEMENT_WITH_NAMESPACE_PREFIX,
            AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_end_element(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    int status = 0;

    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);

    writer_impl = AXIS2_INTF_TO_IMPL(writer);

    writer_impl->in_start_element = AXIS2_FALSE;
    /* write an empty element in case the element is empty, 
     status = xmlTextWriterFullEndElement(writer_impl->xml_writer);
     Above call write it like <a></a>.
     Call below will write it like <a/> */
    status = xmlTextWriterEndElement(writer_impl->xml_writer);
    if(status < 0)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_END_ELEMENT, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_end_document(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    int status = 0;
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);

    writer_impl = AXIS2_INTF_TO_IMPL(writer);
    status = xmlTextWriterEndDocument(writer_impl->xml_writer);
    if(status < 0)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_END_DOCUMENT, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_attribute(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * localname,
    axis2_char_t * value)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    int status = 0;
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE);
    if(!value)
    {
        value = "";
    }

    writer_impl = AXIS2_INTF_TO_IMPL(writer);
    status = xmlTextWriterWriteAttribute(writer_impl->xml_writer,
        BAD_CAST localname, BAD_CAST value);
    if(status < 0)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_ATTRIBUTE, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_attribute_with_namespace(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * localname,
    axis2_char_t * value,
    axis2_char_t * namespace_uri)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    int status = 0;
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, namespace_uri, AXIS2_FAILURE);

    if(!value)
    {
        value = "";
    }

    writer_impl = AXIS2_INTF_TO_IMPL(writer);
    status = xmlTextWriterWriteAttributeNS(writer_impl->xml_writer,
        NULL, BAD_CAST localname,
        BAD_CAST NULL, BAD_CAST value);
    if(status < 0)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_ATTRIBUTE_WITH_NAMESPACE, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_attribute_with_namespace_prefix(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * localname,
    axis2_char_t * value,
    axis2_char_t * namespace_uri,
    axis2_char_t * prefix)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    int status = 0;
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, namespace_uri, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, prefix, AXIS2_FAILURE);

    if(!value)
    {
        value = "";
    }
    writer_impl = AXIS2_INTF_TO_IMPL(writer);
    status = xmlTextWriterWriteAttributeNS(writer_impl->xml_writer,
        BAD_CAST prefix, BAD_CAST localname,
        BAD_CAST NULL, BAD_CAST value);
    if(status < 0)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_ATTRIBUTE_WITH_NAMESPACE_PREFIX, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}

/** need to work on this */
axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_namespace(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * prefix,
    axis2_char_t * namespace_uri)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    int status = 0;
    char *xmlnsprefix = NULL;

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

    writer_impl = AXIS2_INTF_TO_IMPL(writer);

    if(prefix && (axutil_strcmp(prefix, "") != 0))
    {
        xmlnsprefix = (axis2_char_t *)AXIS2_MALLOC(env->allocator, (sizeof(char) * (axutil_strlen(
            prefix) + 7)));
        sprintf(xmlnsprefix, "xmlns:%s", prefix);
    }
    else
    {
        xmlnsprefix = axutil_strdup(env, "xmlns");
    }

    status = xmlTextWriterWriteAttribute(writer_impl->xml_writer,
        BAD_CAST xmlnsprefix,
        BAD_CAST namespace_uri);
    AXIS2_FREE(env->allocator, xmlnsprefix);
    xmlnsprefix = NULL;

    if(status < 0)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_ATTRIBUTE_WITH_NAMESPACE_PREFIX, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }

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

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_default_namespace(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * namespace_uri)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    int status = 0;
    axis2_char_t *xmlns = NULL;
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, namespace_uri, AXIS2_FAILURE)
    xmlns = AXIS2_MALLOC(env->allocator,
        sizeof(axis2_char_t) * (strlen("xmlns") + 1));
    sprintf(xmlns, "xmlns");
    status = xmlTextWriterWriteAttribute(writer_impl->xml_writer,
        (const xmlChar *) xmlns,
        BAD_CAST namespace_uri);

    if(xmlns)
    {
        AXIS2_FREE(env->allocator, xmlns);
        xmlns = NULL;
    }
    if(status < 0)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_DEFAULT_NAMESPACE, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_comment(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * value)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    int status = 0;
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, value, AXIS2_FAILURE);

    writer_impl = AXIS2_INTF_TO_IMPL(writer);
    status = xmlTextWriterWriteComment(writer_impl->xml_writer, BAD_CAST value);
    if(status < 0)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_COMMENT, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_processing_instruction(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * target)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    int status = 0;
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, target, AXIS2_FAILURE);
    writer_impl = AXIS2_INTF_TO_IMPL(writer);

    status = xmlTextWriterStartPI(writer_impl->xml_writer, BAD_CAST target);
    if(status < 0)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_PROCESSING_INSTRUCTION, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_processing_instruction_data(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * target,
    axis2_char_t * data)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    int status = 0;
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, target, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, data, AXIS2_FAILURE);
    writer_impl = AXIS2_INTF_TO_IMPL(writer);

    status = xmlTextWriterWritePI(writer_impl->xml_writer,
        BAD_CAST target, BAD_CAST data);
    if(status < 0)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_PROCESSING_INSTRUCTION, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_cdata(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * data)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    int status = 0;
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, data, AXIS2_FAILURE);

    writer_impl = AXIS2_INTF_TO_IMPL(writer);

    status = xmlTextWriterWriteCDATA(writer_impl->xml_writer, BAD_CAST data);
    if(status < 0)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_CDATA, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_dtd(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * dtd)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    int status = 0;
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, dtd, AXIS2_FAILURE);

    status = xmlTextWriterStartDTD(writer_impl->xml_writer,
        BAD_CAST dtd, NULL, NULL);
    if(status < 0)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_DTD, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_entity_ref(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * name)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, name, AXIS2_FAILURE);
    return AXIS2_FAILURE;
}

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_start_document(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env)
{
    axis2_libxml2_writer_wrapper_impl_t *wrapper_impl = NULL;
    int status = 0;
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);

    wrapper_impl = AXIS2_INTF_TO_IMPL(writer);
    status = xmlTextWriterStartDocument(wrapper_impl->xml_writer, NULL, NULL, NULL);
    if(status < 0)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_START_DOCUMENT, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_start_document_with_version(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * version)
{
    axis2_libxml2_writer_wrapper_impl_t *wrapper_impl = NULL;
    int status = 0;
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, version, AXIS2_FAILURE);

    wrapper_impl = AXIS2_INTF_TO_IMPL(writer);
    status = xmlTextWriterStartDocument(wrapper_impl->xml_writer, version, NULL, NULL);
    if(status < 0)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_START_DOCUMENT, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_start_document_with_version_encoding(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * encoding,
    axis2_char_t * version)
{
    axis2_libxml2_writer_wrapper_impl_t *wrapper_impl = NULL;
    int status = 0;
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);

    wrapper_impl = AXIS2_INTF_TO_IMPL(writer);
    status = xmlTextWriterStartDocument(wrapper_impl->xml_writer, version, encoding, NULL);
    if(status < 0)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_START_DOCUMENT, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_characters(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * text)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    int status = 0;

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

    writer_impl = AXIS2_INTF_TO_IMPL(writer);

    status = xmlTextWriterWriteString(writer_impl->xml_writer, BAD_CAST text);
    if(status < 0)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_START_DOCUMENT, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}

axis2_char_t *AXIS2_CALL
axis2_libxml2_writer_wrapper_get_prefix(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * uri)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    AXIS2_PARAM_CHECK(env->error, uri, NULL);
    writer_impl = AXIS2_INTF_TO_IMPL(writer);
    if(!uri || axutil_strcmp(uri, "") == 0)
    {
        return NULL;
    }
    return axis2_libxml2_writer_wrapper_find_prefix(writer, env, uri);
}

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_set_prefix(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * prefix,
    axis2_char_t * uri)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;

    axis2_bool_t is_declared = AXIS2_FALSE;
    axis2_char_t key[1024];

    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, prefix, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, uri, AXIS2_FAILURE);
    writer_impl = AXIS2_INTF_TO_IMPL(writer);
    if(axutil_strcmp(uri, "") == 0)
    {
        return AXIS2_FAILURE;
    }

    create_key_from_uri_prefix(env, uri, prefix, key);

    is_declared = axis2_libxml2_writer_wrapper_is_namespace_declared(writer, env, key);
    if(!is_declared)
    {
        return axis2_libxml2_writer_wrapper_push(writer, env, uri, prefix);
    }
    return AXIS2_FAILURE;
}

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_set_default_prefix(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * uri)
{
    axis2_bool_t is_declared = AXIS2_FALSE;

    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, uri, AXIS2_FAILURE);
    if(axutil_strcmp(uri, "") == 0)
    {
        return AXIS2_FAILURE;
    }
    is_declared = axis2_libxml2_writer_wrapper_is_namespace_declared(writer, env, uri);
    if(!is_declared)
    {
        return axis2_libxml2_writer_wrapper_push(writer, env, uri, NULL);
    }
    return AXIS2_FAILURE;
}

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_encoded(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * text,
    int in_attr)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, text, AXIS2_FAILURE);
    writer_impl = AXIS2_INTF_TO_IMPL(writer);
    return AXIS2_FAILURE;
}

void *AXIS2_CALL
axis2_libxml2_writer_wrapper_get_xml(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    writer_impl = AXIS2_INTF_TO_IMPL(writer);
    if(writer_impl->writer_type == AXIS2_XML_PARSER_TYPE_BUFFER)
    {
        int output_bytes = 0;
        output_bytes = xmlTextWriterFlush(writer_impl->xml_writer);
        return writer_impl->buffer->content;
    }
    else if(writer_impl->writer_type == AXIS2_XML_PARSER_TYPE_DOC)
    {
        return (void *)writer_impl->doc;
    }
    else if(writer_impl->writer_type == AXIS2_XML_PARSER_TYPE_FILE)
    {
        return NULL;
    }

    return NULL;
}

unsigned int AXIS2_CALL
axis2_libxml2_writer_wrapper_get_xml_size(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    writer_impl = AXIS2_INTF_TO_IMPL(writer);

    if(writer_impl->writer_type == AXIS2_XML_PARSER_TYPE_BUFFER)
    {
        return writer_impl->buffer->use;
    }
    else
    {
        return 0;
    }
}

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_flush(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    writer_impl = AXIS2_INTF_TO_IMPL(writer);
    if(writer_impl->xml_writer)
    {
        int ret = 0;
        ret = xmlTextWriterFlush(writer_impl->xml_writer);
        if(ret > -1)
            return AXIS2_SUCCESS;
    }

    return AXIS2_FAILURE;
}

int AXIS2_CALL
axis2_libxml2_writer_wrapper_get_type(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    writer_impl = AXIS2_INTF_TO_IMPL(writer);

    return writer_impl->writer_type;
}

static axis2_status_t
axis2_libxml2_writer_wrapper_push(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    const axis2_char_t * uri,
    const axis2_char_t * prefix)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    axutil_array_list_t *current_list = NULL;
    axis2_char_t key[1024];
    const axis2_char_t *temp_prefix = NULL;
    writer_impl = AXIS2_INTF_TO_IMPL(writer);
    if(!prefix || axutil_strcmp(prefix, "") == 0)
    {
        temp_prefix = "default";
    }
    else
    {
        temp_prefix = prefix;
    }

    if(writer_impl->stack)
    {
        current_list = (axutil_array_list_t *)axutil_stack_get(writer_impl->stack, env);

        if(current_list)
        {
            uri_prefix_element_t *ele = NULL;
            create_key_from_uri_prefix(env, uri, prefix, key);

            ele = uri_prefix_element_create(env, uri, temp_prefix, prefix, key);
            if(ele)
            {
                axutil_array_list_add(current_list, env, ele);
                axutil_hash_set(writer_impl->uri_prefix_map, ele->key, AXIS2_HASH_KEY_STRING,
                    ele->prefix);
            }
        }
    }
    return AXIS2_SUCCESS;
}

static axis2_bool_t
axis2_libxml2_writer_wrapper_is_namespace_declared(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * key)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    AXIS2_ENV_CHECK(env, AXIS2_FALSE);
    writer_impl = AXIS2_INTF_TO_IMPL(writer);
    if(writer_impl->uri_prefix_map && NULL != key)
    {
        void *ret = NULL;
        ret = axutil_hash_get(writer_impl->uri_prefix_map, key, AXIS2_HASH_KEY_STRING);
        if(ret)
        {
            return AXIS2_TRUE;
        }
    }
    return AXIS2_FALSE;
}

static void
uri_prefix_element_free(
    uri_prefix_element_t * up_element,
    const axutil_env_t * env)
{
    if(up_element)
    {
        if(up_element->uri)
        {
            AXIS2_FREE(env->allocator, up_element->uri);
            up_element->uri = NULL;
        }
        if(up_element->prefix)
        {
            AXIS2_FREE(env->allocator, up_element->prefix);
            up_element->prefix = NULL;
        }
        if(up_element->key)
        {
            AXIS2_FREE(env->allocator, up_element->key);
            up_element->key = NULL;
        }
        if(up_element->real_prefix)
        {
            AXIS2_FREE(env->allocator, up_element->real_prefix);
            up_element->real_prefix = NULL;
        }
        AXIS2_FREE(env->allocator, up_element);
        up_element = NULL;
    }
    return;
}

static uri_prefix_element_t *
uri_prefix_element_create(
    const axutil_env_t * env,
    const axis2_char_t * uri,
    const axis2_char_t * prefix,
    const axis2_char_t * real_prefix,
    const axis2_char_t * key)
{
    uri_prefix_element_t *up_element = NULL;
    up_element = (uri_prefix_element_t *)AXIS2_MALLOC(env->allocator, sizeof(uri_prefix_element_t));

    if(!uri)
    {
        return NULL;
    }

    if(!up_element)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create URI prefix element %s",
            uri);
        return NULL;
    }
    up_element->key = NULL;
    up_element->prefix = NULL;
    up_element->uri = NULL;
    up_element->real_prefix = NULL;

    up_element->uri = axutil_strdup(env, uri);
    if(!up_element->uri)
    {
        uri_prefix_element_free(up_element, env);
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }
    up_element->prefix = axutil_strdup(env, prefix);
    if(prefix && !up_element->prefix)
    {
        uri_prefix_element_free(up_element, env);
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }
    up_element->key = axutil_strdup(env, key);
    if(key && !up_element->key)
    {
        uri_prefix_element_free(up_element, env);
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }
    up_element->real_prefix = axutil_strdup(env, real_prefix);

    return up_element;
}

static void
create_key_from_uri_prefix(
    const axutil_env_t * env,
    const axis2_char_t * uri,
    const axis2_char_t * prefix,
    axis2_char_t * array)
{
    if(!prefix)
    {
        prefix = "";
    }
    sprintf(array, "%s%s%s", uri, "|", prefix);
}

static axis2_char_t *
axis2_libxml2_writer_wrapper_find_prefix(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * uri)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    int size = 0;
    int i = 0;

    writer_impl = AXIS2_INTF_TO_IMPL(writer);

    if(!writer_impl->stack)
    {
        return NULL;
    }
    size = axutil_stack_size(writer_impl->stack, env);
    if(size <= 0)
    {
        return NULL;
    }

    for(i = size - 1; i < 0; i--)
    {
        axutil_array_list_t *context = NULL;
        void *value = NULL;
        value = axutil_stack_get_at(writer_impl->stack, env, i);
        if(value)
        {
            uri_prefix_element_t *up_ele = NULL;
            context = (axutil_array_list_t *)value;
            up_ele = axis2_libxml2_writer_wrapper_find_prefix_in_context(context, env, uri);
            if(up_ele)
            {
                return up_ele->real_prefix;
            }
        }
    }
    return NULL;
}

static uri_prefix_element_t *
axis2_libxml2_writer_wrapper_find_prefix_in_context(
    axutil_array_list_t * context,
    const axutil_env_t * env,
    axis2_char_t * uri)
{
    int size = 0;
    int i = 0;
    if(!context)
    {
        return NULL;
    }
    size = axutil_array_list_size(context, env);
    for(i = 0; i < size; i++)
    {
        uri_prefix_element_t *ele = NULL;
        void *value = NULL;
        value = axutil_array_list_get(context, env, i);
        if(value)
        {
            ele = (uri_prefix_element_t *)value;
            if(ele->uri && axutil_strcmp(uri, ele->uri))
            {
                return ele;
            }
        }
    }
    return NULL;
}

axis2_status_t AXIS2_CALL
axis2_libxml2_writer_wrapper_write_raw(
    axiom_xml_writer_t * writer,
    const axutil_env_t * env,
    axis2_char_t * content)
{
    axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL;
    int status = 0;
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, content, AXIS2_FAILURE);

    writer_impl = AXIS2_INTF_TO_IMPL(writer);
    status = xmlTextWriterWriteRaw(writer_impl->xml_writer, BAD_CAST content);
    if(status < 0)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_DATA_SOURCE, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}
