text: 
  /*
   * 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;
  }
  