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 <axiom_xml_reader.h>
  #include <libxml/xmlreader.h>
  #include <libxml/parser.h>
  #include <axutil_utils_defines.h>
  #include <axutil_utils.h>
  #include <string.h>
  #include <axutil_string.h>
  
  
  int AXIS2_CALL axis2_libxml2_reader_wrapper_next(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env);
  
  void AXIS2_CALL axis2_libxml2_reader_wrapper_free(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env);
  
  int AXIS2_CALL axis2_libxml2_reader_wrapper_get_attribute_count(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env);
  
  axis2_char_t *AXIS2_CALL
  axis2_libxml2_reader_wrapper_get_attribute_name_by_number(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env,
      int i);
  
  axis2_char_t *AXIS2_CALL
  axis2_libxml2_reader_wrapper_get_attribute_prefix_by_number(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env,
      int i);
  
  axis2_char_t *AXIS2_CALL
  axis2_libxml2_reader_wrapper_get_attribute_value_by_number(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env,
      int i);
  
  axis2_char_t *AXIS2_CALL
  axis2_libxml2_reader_wrapper_get_attribute_namespace_by_number(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env,
      int i);
  
  axis2_char_t *AXIS2_CALL axis2_libxml2_reader_wrapper_get_value(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env);
  
  int AXIS2_CALL axis2_libxml2_reader_wrapper_get_namespace_count(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env);
  
  axis2_char_t *AXIS2_CALL
  axis2_libxml2_reader_wrapper_get_namespace_uri_by_number(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env,
      int i);
  
  axis2_char_t *AXIS2_CALL
  axis2_libxml2_reader_wrapper_get_namespace_prefix_by_number(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env,
      int i);
  
  axis2_char_t *AXIS2_CALL axis2_libxml2_reader_wrapper_get_prefix(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env);
  
  axis2_char_t *AXIS2_CALL axis2_libxml2_reader_wrapper_get_name(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env);
  
  axis2_char_t *AXIS2_CALL axis2_libxml2_reader_wrapper_get_pi_target(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env);
  
  axis2_char_t *AXIS2_CALL axis2_libxml2_reader_wrapper_get_pi_data(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env);
  
  axis2_char_t *AXIS2_CALL axis2_libxml2_reader_wrapper_get_dtd(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env);
  
  void AXIS2_CALL axis2_libxml2_reader_wrapper_xml_free(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env,
      void *data);
  
  axis2_char_t *AXIS2_CALL axis2_libxml2_reader_wrapper_get_char_set_encoding(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env);
  
  axis2_char_t *AXIS2_CALL axis2_libxml2_reader_wrapper_get_namespace_uri(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env);
  
  axis2_char_t *AXIS2_CALL
  axis2_libxml2_reader_wrapper_get_namespace_uri_by_prefix(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env,
      axis2_char_t * prefix);
  
  axis2_status_t axis2_libxml2_reader_wrapper_fill_maps(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env);
  
  void axis2_libxml2_reader_wrapper_error_handler(
      void *arg,
      const char *msg,
      int severities,
      void *locator_ptr);
  
  static int axis2_libxml2_reader_wrapper_read_input_callback(
      void *ctx,
      char *buffer,
      int size);
  
  static int axis2_libxml2_reader_wrapper_close_input_callback(
      void *ctx);
  
  typedef struct axis2_libxml2_reader_wrapper_impl_t
  {
      axiom_xml_reader_t parser;
  
      xmlTextReaderPtr reader;
  
      int current_event;
      int current_attribute_count;
      int current_namespace_count;
      int event_map[18];
  
      void *ctx;
      /* assuming that max ns and attribute will be 20 */
  
      int *namespace_map;
      int *attribute_map;
  
      AXIS2_READ_INPUT_CALLBACK read_input_callback;
  
      AXIS2_CLOSE_INPUT_CALLBACK close_input_callback;
  
  }
  axis2_libxml2_reader_wrapper_impl_t;
  
  #define AXIS2_INTF_TO_IMPL(p) ((axis2_libxml2_reader_wrapper_impl_t*)p)
  #define AXIS2_IMPL_TO_INTF(p) &(p->parser)
  
  static const axiom_xml_reader_ops_t axiom_xml_reader_ops_var = {
      axis2_libxml2_reader_wrapper_next,
      axis2_libxml2_reader_wrapper_free,
      axis2_libxml2_reader_wrapper_get_attribute_count,
      axis2_libxml2_reader_wrapper_get_attribute_name_by_number,
      axis2_libxml2_reader_wrapper_get_attribute_prefix_by_number,
      axis2_libxml2_reader_wrapper_get_attribute_value_by_number,
      axis2_libxml2_reader_wrapper_get_attribute_namespace_by_number,
      axis2_libxml2_reader_wrapper_get_value,
      axis2_libxml2_reader_wrapper_get_namespace_count,
      axis2_libxml2_reader_wrapper_get_namespace_uri_by_number,
      axis2_libxml2_reader_wrapper_get_namespace_prefix_by_number,
      axis2_libxml2_reader_wrapper_get_prefix,
      axis2_libxml2_reader_wrapper_get_name,
      axis2_libxml2_reader_wrapper_get_pi_target,
      axis2_libxml2_reader_wrapper_get_pi_data,
      axis2_libxml2_reader_wrapper_get_dtd,
      axis2_libxml2_reader_wrapper_xml_free,
      axis2_libxml2_reader_wrapper_get_char_set_encoding,
      axis2_libxml2_reader_wrapper_get_namespace_uri,
      axis2_libxml2_reader_wrapper_get_namespace_uri_by_prefix
  };
  
  static axis2_status_t
  axis2_libxml2_reader_wrapper_init_map(
      axis2_libxml2_reader_wrapper_impl_t * parser)
  {
      int i = 0;
      if (parser)
      {
          for (i = 0; i < 18; i++)
          {
              parser->event_map[i] = -1;
          }
  
          parser->event_map[XML_READER_TYPE_ELEMENT] =
              AXIOM_XML_READER_START_ELEMENT;
  
          parser->event_map[XML_READER_TYPE_ELEMENT] =
              AXIOM_XML_READER_START_ELEMENT;
  
          parser->event_map[XML_READER_TYPE_DOCUMENT] =
              AXIOM_XML_READER_START_DOCUMENT;
  
          parser->event_map[XML_READER_TYPE_TEXT] = AXIOM_XML_READER_CHARACTER;
  
          parser->event_map[XML_READER_TYPE_CDATA] = AXIOM_XML_READER_CHARACTER;
  
          parser->event_map[XML_READER_TYPE_SIGNIFICANT_WHITESPACE] =
              AXIOM_XML_READER_SPACE;
  
          parser->event_map[XML_READER_TYPE_WHITESPACE] = AXIOM_XML_READER_SPACE;
  
          parser->event_map[XML_READER_TYPE_END_ELEMENT] =
              AXIOM_XML_READER_END_ELEMENT;
  
          parser->event_map[XML_READER_TYPE_ENTITY_REFERENCE] =
              AXIOM_XML_READER_ENTITY_REFERENCE;
  
          parser->event_map[XML_READER_TYPE_END_ENTITY] = AXIOM_XML_READER_SPACE;
  
          parser->event_map[XML_READER_TYPE_ENTITY] = AXIOM_XML_READER_SPACE;
  
          parser->event_map[XML_READER_TYPE_PROCESSING_INSTRUCTION] =
              AXIOM_XML_READER_PROCESSING_INSTRUCTION;
  
          parser->event_map[XML_READER_TYPE_COMMENT] = AXIOM_XML_READER_COMMENT;
  
          parser->event_map[XML_READER_TYPE_DOCUMENT_TYPE] =
              AXIOM_XML_READER_DOCUMENT_TYPE;
          return AXIS2_SUCCESS;
      }
      return AXIS2_FAILURE;
  }
  
  AXIS2_EXTERN axis2_status_t AXIS2_CALL
  axiom_xml_reader_init()
  {
      xmlInitParser();
      return AXIS2_SUCCESS;
  }
  
  AXIS2_EXTERN axis2_status_t AXIS2_CALL
  axiom_xml_reader_cleanup()
  {
      xmlCleanupParser();
      return AXIS2_SUCCESS;
  }
  
  static axis2_libxml2_reader_wrapper_impl_t*
  libxml2_reader_wrapper_create(const axutil_env_t *env)
  {
  	axis2_libxml2_reader_wrapper_impl_t *wrapper_impl = NULL;
  	wrapper_impl = (axis2_libxml2_reader_wrapper_impl_t *)AXIS2_MALLOC(env->allocator,
  		sizeof(axis2_libxml2_reader_wrapper_impl_t));
  
  	if (!wrapper_impl)
  	{
  		AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
  		AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create libxml2 reader wrapper");
  		return NULL;
  	}
  	memset(wrapper_impl, 0, sizeof(axis2_libxml2_reader_wrapper_impl_t));
  	wrapper_impl->attribute_map = NULL;
  	wrapper_impl->namespace_map = NULL;
  	wrapper_impl->close_input_callback = NULL;
  	wrapper_impl->read_input_callback = NULL;
  	wrapper_impl->ctx = NULL;
  	wrapper_impl->current_namespace_count = 0;
  	wrapper_impl->current_attribute_count = 0;
  	wrapper_impl->current_event = -1;
  	return wrapper_impl;
  }
  
  
  AXIS2_EXTERN axiom_xml_reader_t *AXIS2_CALL
  axiom_xml_reader_create_for_file(
      const axutil_env_t * env,
      char *filename,
      const axis2_char_t * encoding)
  {
  
      axis2_libxml2_reader_wrapper_impl_t *wrapper_impl = NULL;
      AXIS2_ENV_CHECK(env, NULL);
      AXIS2_PARAM_CHECK(env->error, filename, NULL);
  
      wrapper_impl = libxml2_reader_wrapper_create(env);
      if (!wrapper_impl)
      {
          return NULL;
      }
  
      wrapper_impl->reader = xmlReaderForFile(filename, encoding, XML_PARSE_RECOVER);
      if (!(wrapper_impl->reader))
      {
          AXIS2_FREE(env->allocator, wrapper_impl);
          AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_CREATING_XML_STREAM_READER,
                          AXIS2_FAILURE);
          return NULL;
      }
  
      xmlTextReaderSetErrorHandler(wrapper_impl->reader,
                                   (xmlTextReaderErrorFunc)
                                   axis2_libxml2_reader_wrapper_error_handler,
                                   (void *) env);
      wrapper_impl->current_event = -1;
      wrapper_impl->ctx = NULL;
      axis2_libxml2_reader_wrapper_init_map(wrapper_impl);
  
      wrapper_impl->parser.ops = &axiom_xml_reader_ops_var;
      return &(wrapper_impl->parser);
  }
  
  AXIS2_EXTERN axiom_xml_reader_t *AXIS2_CALL
  axiom_xml_reader_create_for_io(
      const axutil_env_t * env,
      AXIS2_READ_INPUT_CALLBACK read_input_callback,
      AXIS2_CLOSE_INPUT_CALLBACK close_input_callback,
      void *ctx,
      const axis2_char_t * encoding)
  {
      axis2_libxml2_reader_wrapper_impl_t *wrapper_impl = NULL;
  
      AXIS2_ENV_CHECK(env, NULL);
  
      if (!read_input_callback)
      {
          return NULL;
      }
  
      wrapper_impl = libxml2_reader_wrapper_create(env);
      if (!wrapper_impl)
      {
          return NULL;
      }
      wrapper_impl->close_input_callback = NULL;
      wrapper_impl->read_input_callback = NULL;
      wrapper_impl->read_input_callback = read_input_callback;
      wrapper_impl->close_input_callback = close_input_callback;
      wrapper_impl->ctx = ctx;
      if (wrapper_impl->close_input_callback)
      {
          wrapper_impl->reader =
              xmlReaderForIO(axis2_libxml2_reader_wrapper_read_input_callback,
                             axis2_libxml2_reader_wrapper_close_input_callback,
                             wrapper_impl, NULL, encoding, XML_PARSE_RECOVER);
      }
      else
      {
          wrapper_impl->reader =
              xmlReaderForIO(axis2_libxml2_reader_wrapper_read_input_callback,
                             NULL, wrapper_impl, NULL, encoding,
                             XML_PARSE_RECOVER);
      }
      if (!(wrapper_impl->reader))
      {
          AXIS2_FREE(env->allocator, wrapper_impl);
          AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_CREATING_XML_STREAM_READER,
                          AXIS2_FAILURE);
          return NULL;
      }
  
      xmlTextReaderSetErrorHandler(wrapper_impl->reader,
                                   (xmlTextReaderErrorFunc)
                                   axis2_libxml2_reader_wrapper_error_handler,
                                   (void *) env);
  
      wrapper_impl->current_event = -1;
  
      axis2_libxml2_reader_wrapper_init_map(wrapper_impl);
  
      wrapper_impl->parser.ops = &axiom_xml_reader_ops_var;
      return &(wrapper_impl->parser);
  }
  
  AXIS2_EXTERN axiom_xml_reader_t *AXIS2_CALL
  axiom_xml_reader_create_for_memory(
      const axutil_env_t * env,
      void *container,
      int size,
      const axis2_char_t * encoding,
      int type)
  {
      axis2_libxml2_reader_wrapper_impl_t *wrapper_impl = NULL;
  
      AXIS2_PARAM_CHECK(env->error, container, NULL);
  
      wrapper_impl = libxml2_reader_wrapper_create(env);
      if (!wrapper_impl)
      {
          return NULL;
      }
      wrapper_impl->close_input_callback = NULL;
      wrapper_impl->read_input_callback = NULL;
      wrapper_impl->ctx = NULL;
  
      if (AXIS2_XML_PARSER_TYPE_BUFFER == type)
      {
          wrapper_impl->reader =
              xmlReaderForMemory((axis2_char_t *) container, size, NULL, encoding,
                                 XML_PARSE_RECOVER);
      }
      else if (AXIS2_XML_PARSER_TYPE_DOC == type)
      {
          wrapper_impl->reader = xmlReaderWalker((xmlDocPtr) container);
      }
      else
      {
          AXIS2_FREE(env->allocator, wrapper_impl);
          AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_XML_PARSER_INVALID_MEM_TYPE,
                          AXIS2_FAILURE);
          return NULL;
      }
  
      if (!(wrapper_impl->reader))
      {
          AXIS2_FREE(env->allocator, wrapper_impl);
          AXIS2_HANDLE_ERROR(env,
                          AXIS2_ERROR_CREATING_XML_STREAM_READER, AXIS2_FAILURE);
          return NULL;
      }
  
      if (AXIS2_XML_PARSER_TYPE_BUFFER == type)
      {
          xmlTextReaderSetErrorHandler(wrapper_impl->reader,
                                       (xmlTextReaderErrorFunc)
                                       axis2_libxml2_reader_wrapper_error_handler,
                                       (void *) env);
      }
  
      wrapper_impl->current_event = -1;
  
      axis2_libxml2_reader_wrapper_init_map(wrapper_impl);
  
      wrapper_impl->parser.ops = &axiom_xml_reader_ops_var;
      return &(wrapper_impl->parser);
  }
  
  int AXIS2_CALL
  axis2_libxml2_reader_wrapper_next(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env)
  {
      int ret_val = 0;
      int node = 2;
      int empty_check = 0;
      axis2_libxml2_reader_wrapper_impl_t *parser_impl;
      AXIS2_ENV_CHECK(env, -1);
      parser_impl = AXIS2_INTF_TO_IMPL(parser);
      ret_val = xmlTextReaderRead(parser_impl->reader);
      if (ret_val == 0)
      {
          AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "xml stream is over ");
      }
      if (ret_val == -1)
      {
          AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                          " error occurred in reading xml stream ");
          return -1;
      }
  
      if (ret_val == 1)
      {
          node = xmlTextReaderNodeType(parser_impl->reader);
          parser_impl->current_event = parser_impl->event_map[node];
          parser_impl->current_attribute_count = 0;
          parser_impl->current_namespace_count = 0;
  
          if (node == XML_READER_TYPE_ELEMENT)
          {
              empty_check = xmlTextReaderIsEmptyElement(parser_impl->reader);
              axis2_libxml2_reader_wrapper_fill_maps(parser, env);
          }
          if (empty_check == 1)
          {
              parser_impl->current_event = AXIOM_XML_READER_EMPTY_ELEMENT;
              return AXIOM_XML_READER_EMPTY_ELEMENT;
          }
          return parser_impl->event_map[node];
      }
      else
      {
          return -1;
      }
  }
  
  
  /**
  * If your application crashes here, it may be due to an earlier call to
  * xmlCleanupParser() function. In client API, op_client create function has a call
  * to axiom_xml_reader_init and op_client_free function has a call to axiom_xml_reader_cleanup
  * function. You can avoid the call to axiom_xml_reader_cleanup using 
  * axis2_options_set_xml_parser_reset function in client API.
  * refer to jira issue:  https://issues.apache.org/jira/browse/AXIS2C-884
  */
  void AXIS2_CALL
  axis2_libxml2_reader_wrapper_free(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env)
  {
  	axis2_libxml2_reader_wrapper_impl_t *parser_impl = NULL;
  	parser_impl = AXIS2_INTF_TO_IMPL(parser);
      if (parser_impl->ctx)
      {
          AXIS2_FREE(env->allocator, parser_impl->ctx);
      }
  
      if (parser_impl->reader)
      {
          xmlTextReaderClose(parser_impl->reader);
          xmlFreeTextReader(parser_impl->reader);
      }
  	if(parser_impl->namespace_map)
  	{
  		AXIS2_FREE(env->allocator,parser_impl->namespace_map);
  		parser_impl->namespace_map = NULL;
  	}
  	if(parser_impl->attribute_map)
  	{
  		AXIS2_FREE(env->allocator, parser_impl->attribute_map);
  		parser_impl->attribute_map = NULL;
  	}
      AXIS2_FREE(env->allocator, AXIS2_INTF_TO_IMPL(parser));
      return;
  }
  
  int AXIS2_CALL
  axis2_libxml2_reader_wrapper_get_attribute_count(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env)
  {
      axis2_libxml2_reader_wrapper_impl_t *parser_impl = NULL;
      AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
      parser_impl = AXIS2_INTF_TO_IMPL(parser);
      if (parser_impl->current_event == AXIOM_XML_READER_START_ELEMENT ||
          parser_impl->current_event == AXIOM_XML_READER_EMPTY_ELEMENT)
      {
          return parser_impl->current_attribute_count;
      }
      else
      {
          return 0;
      }
  }
  
  axis2_char_t *AXIS2_CALL
  axis2_libxml2_reader_wrapper_get_attribute_name_by_number(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env,
      int i)
  {
      axis2_libxml2_reader_wrapper_impl_t *parser_impl;
      AXIS2_ENV_CHECK(env, NULL);
      parser_impl = AXIS2_INTF_TO_IMPL(parser);
  
      if (parser_impl->current_attribute_count > 0 &&
          parser_impl->current_attribute_count >= i)
      {
          int ret = xmlTextReaderMoveToAttributeNo(parser_impl->reader,
                                                   parser_impl->attribute_map[i]);
          if (ret == 1)
          {
              return (axis2_char_t *) xmlTextReaderLocalName(parser_impl->reader);
          }
          else
          {
              return NULL;
          }
      }
      return NULL;
  }
  
  axis2_char_t *AXIS2_CALL
  axis2_libxml2_reader_wrapper_get_attribute_prefix_by_number(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env,
      int i)
  {
      axis2_libxml2_reader_wrapper_impl_t *parser_impl = NULL;
      AXIS2_ENV_CHECK(env, NULL);
      parser_impl = AXIS2_INTF_TO_IMPL(parser);
  
      if (parser_impl->current_attribute_count > 0 &&
          parser_impl->current_attribute_count >= i)
      {
          int ret = xmlTextReaderMoveToAttributeNo(parser_impl->reader,
                                                   parser_impl->attribute_map[i]);
          if (ret == 1)
          {
              return (axis2_char_t *) xmlTextReaderPrefix(parser_impl->reader);
          }
          else
          {
              return NULL;
          }
      }
      return NULL;
  }
  
  axis2_char_t *AXIS2_CALL
  axis2_libxml2_reader_wrapper_get_attribute_value_by_number(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env,
      int i)
  {
  
      axis2_libxml2_reader_wrapper_impl_t *parser_impl;
      AXIS2_ENV_CHECK(env, NULL);
      parser_impl = AXIS2_INTF_TO_IMPL(parser);
  
      if (parser_impl->current_attribute_count > 0 &&
          parser_impl->current_attribute_count >= i)
      {
          int ret = xmlTextReaderMoveToAttributeNo(parser_impl->reader,
                                                   parser_impl->attribute_map[i]);
          if (ret == 1)
          {
              return (axis2_char_t *) xmlTextReaderValue(parser_impl->reader);
          }
          else
          {
              return NULL;
          }
      }
      return NULL;
  }
  
  axis2_char_t *AXIS2_CALL
  axis2_libxml2_reader_wrapper_get_attribute_namespace_by_number(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env,
      int i)
  {
      axis2_libxml2_reader_wrapper_impl_t *parser_impl;
      AXIS2_ENV_CHECK(env, NULL);
      parser_impl = AXIS2_INTF_TO_IMPL(parser);
  
      if (parser_impl->current_attribute_count > 0 &&
          parser_impl->current_attribute_count >= i)
      {
          int ret = xmlTextReaderMoveToAttributeNo(parser_impl->reader,
                                                   parser_impl->attribute_map[i]);
  
          if (ret == 1)
          {
              return (axis2_char_t *) xmlTextReaderNamespaceUri(parser_impl->
                                                                reader);
          }
          else
          {
              return NULL;
          }
      }
      return NULL;
  }
  
  axis2_char_t *AXIS2_CALL
  axis2_libxml2_reader_wrapper_get_value(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env)
  {
      axis2_libxml2_reader_wrapper_impl_t *parser_impl = NULL;
  
      AXIS2_ENV_CHECK(env, NULL);
      parser_impl = AXIS2_INTF_TO_IMPL(parser);
      return (axis2_char_t *) xmlTextReaderValue(parser_impl->reader);
  
  }
  
  int AXIS2_CALL
  axis2_libxml2_reader_wrapper_get_namespace_count(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env)
  {
      axis2_libxml2_reader_wrapper_impl_t *parser_impl = NULL;
      AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
      parser_impl = AXIS2_INTF_TO_IMPL(parser);
      if (parser_impl->current_event == AXIOM_XML_READER_START_ELEMENT ||
          parser_impl->current_event == AXIOM_XML_READER_EMPTY_ELEMENT)
      {
          return parser_impl->current_namespace_count;
      }
      else
      {
          return 0;
      }
  }
  
  axis2_char_t *AXIS2_CALL
  axis2_libxml2_reader_wrapper_get_namespace_uri_by_number(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env,
      int i)
  {
      axis2_libxml2_reader_wrapper_impl_t *parser_impl = NULL;
      AXIS2_ENV_CHECK(env, NULL);
      parser_impl = AXIS2_INTF_TO_IMPL(parser);
  
      if (parser_impl->current_namespace_count > 0 &&
          parser_impl->current_namespace_count >= i)
      {
  
          int ret = xmlTextReaderMoveToAttributeNo(parser_impl->reader,
                                                   parser_impl->namespace_map[i]);
          if (ret == 1)
          {
              return (axis2_char_t *) xmlTextReaderValue(parser_impl->reader);
          }
          else
              return NULL;
      }
      return NULL;
  }
  
  axis2_char_t *AXIS2_CALL
  axis2_libxml2_reader_wrapper_get_namespace_prefix_by_number(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env,
      int i)
  {
      axis2_libxml2_reader_wrapper_impl_t *parser_impl = NULL;
      AXIS2_ENV_CHECK(env, NULL);
      parser_impl = AXIS2_INTF_TO_IMPL(parser);
  
      if (parser_impl->current_namespace_count > 0 &&
          parser_impl->current_namespace_count >= i)
      {
          int ret = xmlTextReaderMoveToAttributeNo(parser_impl->reader,
                                                   parser_impl->namespace_map[i]);
  
          if (ret == 1)
          {
              return (axis2_char_t *) xmlTextReaderLocalName(parser_impl->reader);
          }
          else
          {
              return NULL;
          }
      }
      return NULL;
  }
  
  axis2_char_t *AXIS2_CALL
  axis2_libxml2_reader_wrapper_get_prefix(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env)
  {
      axis2_libxml2_reader_wrapper_impl_t *parser_impl = NULL;
      parser_impl = AXIS2_INTF_TO_IMPL(parser);
      xmlTextReaderMoveToElement(parser_impl->reader);
      return (axis2_char_t *) xmlTextReaderPrefix(parser_impl->reader);
  }
  
  axis2_char_t *AXIS2_CALL
  axis2_libxml2_reader_wrapper_get_name(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env)
  {
      axis2_libxml2_reader_wrapper_impl_t *parser_impl = NULL;
      parser_impl = AXIS2_INTF_TO_IMPL(parser);
      xmlTextReaderMoveToElement(parser_impl->reader);
      return (axis2_char_t *) xmlTextReaderLocalName(parser_impl->reader);
  }
  
  axis2_char_t *AXIS2_CALL
  axis2_libxml2_reader_wrapper_get_pi_target(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env)
  {
      axis2_libxml2_reader_wrapper_impl_t *parser_impl = NULL;
      parser_impl = AXIS2_INTF_TO_IMPL(parser);
      if (parser_impl->current_event == AXIOM_XML_READER_PROCESSING_INSTRUCTION)
      {
          return (axis2_char_t *) xmlTextReaderLocalName(parser_impl->reader);
      }
      else
      {
          return NULL;
      }
  }
  
  axis2_char_t *AXIS2_CALL
  axis2_libxml2_reader_wrapper_get_dtd(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env)
  {
      axis2_libxml2_reader_wrapper_impl_t *parser_impl = NULL;
      parser_impl = AXIS2_INTF_TO_IMPL(parser);
      if (parser_impl->current_event == AXIOM_XML_READER_DOCUMENT_TYPE)
      {
          return (axis2_char_t *) xmlTextReaderLocalName(parser_impl->reader);
      }
      else
      {
          return NULL;
      }
  }
  
  axis2_char_t *AXIS2_CALL
  axis2_libxml2_reader_wrapper_get_pi_data(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env)
  {
      axis2_libxml2_reader_wrapper_impl_t *parser_impl = NULL;
      parser_impl = AXIS2_INTF_TO_IMPL(parser);
      if (parser_impl->current_event == AXIOM_XML_READER_PROCESSING_INSTRUCTION)
      {
          return (axis2_char_t *) xmlTextReaderValue(parser_impl->reader);
      }
      else
      {
          return NULL;
      }
  }
  
  void AXIS2_CALL
  axis2_libxml2_reader_wrapper_xml_free(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env,
      void *data)
  {
      AXIS2_ENV_CHECK(env, void);
      if (data)
          xmlFree(data);
      return;
  }
  
  axis2_char_t *AXIS2_CALL
  axis2_libxml2_reader_wrapper_get_char_set_encoding(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env)
  {
      axis2_libxml2_reader_wrapper_impl_t *reader_impl = NULL;
      reader_impl = AXIS2_INTF_TO_IMPL(parser);
      return (axis2_char_t *) xmlTextReaderConstEncoding(reader_impl->reader);
  }
  
  axis2_char_t *AXIS2_CALL
  axis2_libxml2_reader_wrapper_get_namespace_uri(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env)
  {
      axis2_libxml2_reader_wrapper_impl_t *parser_impl = NULL;
      parser_impl = AXIS2_INTF_TO_IMPL(parser);
      return (axis2_char_t *) xmlTextReaderNamespaceUri(parser_impl->reader);
  }
  
  axis2_char_t *AXIS2_CALL
  axis2_libxml2_reader_wrapper_get_namespace_uri_by_prefix(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env,
      axis2_char_t * prefix)
  {
      axis2_libxml2_reader_wrapper_impl_t *parser_impl = NULL;
      parser_impl = AXIS2_INTF_TO_IMPL(parser);
      if (!prefix || axutil_strcmp(prefix, "") == 0)
      {
          return NULL;
      }
      return (axis2_char_t *) xmlTextReaderLookupNamespace(parser_impl->reader,
                                                           (const xmlChar *)
                                                           prefix);
  }
  
  axis2_status_t
  axis2_libxml2_reader_wrapper_fill_maps(
      axiom_xml_reader_t * parser,
      const axutil_env_t * env)
  {
      int libxml2_attribute_count = 0;
      int attr_count = 0;
      int ns_count = 0;
      int i = 0;
      char *q_name = NULL;
      axis2_libxml2_reader_wrapper_impl_t *parser_impl = NULL;
  	int map_size = 0;
      AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
      parser_impl = AXIS2_INTF_TO_IMPL(parser);
  
      libxml2_attribute_count = xmlTextReaderAttributeCount(parser_impl->reader);
      if (libxml2_attribute_count == 0)
      {
  		parser_impl->current_attribute_count = 0;
  		parser_impl->current_namespace_count = 0;
          return AXIS2_SUCCESS;
      }
  	map_size = libxml2_attribute_count +1;
  	if(parser_impl->namespace_map)
  	{
  		AXIS2_FREE(env->allocator, parser_impl->namespace_map);
  		parser_impl->namespace_map = NULL;
  	}
  	if(parser_impl->attribute_map)
  	{
  		AXIS2_FREE(env->allocator, parser_impl->attribute_map);
  		parser_impl->attribute_map = NULL;
  	}	
  	parser_impl->attribute_map = AXIS2_MALLOC(env->allocator, sizeof(int)* map_size);
  	memset(parser_impl->attribute_map, 0, map_size*sizeof(int));
  
  	parser_impl->namespace_map = AXIS2_MALLOC(env->allocator, sizeof(int)*map_size);
  	memset(parser_impl->namespace_map,0, map_size*sizeof(int));
  	
      for (i = 0; i < map_size ; i++)
      {
          parser_impl->namespace_map[i] = -1;
          parser_impl->attribute_map[i] = -1;
      }
  
      for (i = 0; i < libxml2_attribute_count; i++)
      {
          xmlTextReaderMoveToAttributeNo(parser_impl->reader, i);
          q_name = (char *) xmlTextReaderName(parser_impl->reader);
          if (q_name)
          {
              if ((strcmp(q_name, "xmlns") == 0) ||
                  (strncmp(q_name, "xmlns:", 6) == 0))
              {
                  /* found a namespace */
                  ns_count++;
                  parser_impl->namespace_map[ns_count] = i;
              }
              else
              {
                  /* found an attribute */
                  attr_count++;
                  parser_impl->attribute_map[attr_count] = i;
              }
  
              xmlFree(q_name);
              q_name = NULL;
          }
  
          parser_impl->current_attribute_count = attr_count;
          parser_impl->current_namespace_count = ns_count;
      }
      return AXIS2_SUCCESS;
  }
  
  static int
  axis2_libxml2_reader_wrapper_read_input_callback(
      void *ctx,
      char *buffer,
      int size)
  {
      return ((axis2_libxml2_reader_wrapper_impl_t *) ctx)->
          read_input_callback(buffer, size,
                              ((axis2_libxml2_reader_wrapper_impl_t *) ctx)->ctx);
  }
  
  void
  axis2_libxml2_reader_wrapper_error_handler(
      void *arg,
      const char *msg,
      int severities,
      void *locator_ptr)
  {
      const axutil_env_t *env = NULL;
      env = (const axutil_env_t *) arg;
  
      switch (severities)
      {
      case XML_PARSER_SEVERITY_VALIDITY_WARNING:
          {
              AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s VALIDITY WARNTING",
                              msg);
          }
          break;
      case XML_PARSER_SEVERITY_VALIDITY_ERROR:
          {
              AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s -- VALIDITY ERROR",
                              msg);
          }
          break;
      case XML_PARSER_SEVERITY_WARNING:
          {
              AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s -- VALIDITY ERROR",
                              msg);
          }
          break;
      case XML_PARSER_SEVERITY_ERROR:
          {
              AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s -- SEVERITY_ERROR",
                              msg);
          }
          break;
      default:
          break;
      }
  }
  
  static int
  axis2_libxml2_reader_wrapper_close_input_callback(
      void *ctx)
  {
      return ((axis2_libxml2_reader_wrapper_impl_t *) ctx)->
          close_input_callback(((axis2_libxml2_reader_wrapper_impl_t *) ctx)->
                               ctx);
  }
  