/*
 * 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_mime_parser.h>
#include <axutil_string.h>
#include <axiom_data_handler.h>
#include <stdio.h>
#include <ctype.h>    
#include <axutil_http_chunked_stream.h>
#include <axiom_mtom_caching_callback.h>
#include <axutil_class_loader.h>
#include <axutil_url.h>

struct axiom_mime_parser
{
    /* This will keep the attachment and its info*/
    axutil_hash_t *mime_parts_map;

    /* This is the actual SOAP part len */
    size_t soap_body_len;

    /* The SOAP part of the message */
    axis2_char_t *soap_body_str;

    /* The size of the buffer we give to the callback to
     * read data */
    size_t buffer_size;

    /* The number of buffers */
    int max_buffers;

    /* The attachment dir name, in the case of caching */
    axis2_char_t *attachment_dir;

    /*A pointer to the caching callback */
    axiom_mtom_caching_callback_t *mtom_caching_callback;

    /* The caching callback name specified */
    axis2_char_t *callback_name;

    axis2_char_t **buf_array;

    size_t *len_array;

    int current_buf_num;

    axis2_bool_t end_of_mime;

    axis2_char_t *mime_boundary;

};

struct axiom_search_info
{
    /*String need to be searched*/
    const axis2_char_t *search_str;

    /*The buffers and the lengths need to be searched*/
    axis2_char_t *buffer1;
    size_t len1;
    axis2_char_t *buffer2;
    size_t len2;

    /*Flag to keep what type of search is this buffer has done*/
    axis2_bool_t primary_search;

    /*The offset where we found the pattern entirely in one buffer*/
    size_t match_len1;

    /*when pattern contains in two buffers the length of partial pattern
     in buffer2 */
    size_t match_len2;

    /*Whether we need caching or not*/
    axis2_bool_t cached;

    /*A pointer to a user provided storage to which we cache the attachment*/
    void *handler;

    /* Size of the binary when writing to the buffer*/
    size_t binary_size;
};

typedef struct axiom_search_info axiom_search_info_t;

#define AXIOM_MIME_PARSER_CONTENT_ID "content-id"
#define AXIOM_MIME_PARSER_CONTENT_TYPE "content-type"

#define AXIOM_MIME_PARSER_END_OF_MIME_MAX_COUNT 1000

static axis2_char_t *
axiom_mime_parser_search_for_soap(
    const axutil_env_t * env,
    AXIS2_READ_INPUT_CALLBACK callback,
    void *callback_ctx,
    int *buf_num,
    size_t *len_array,
    axis2_char_t **buf_array,
    axiom_search_info_t *search_info,
    size_t size,
    axis2_char_t *mime_boundary,
    axiom_mime_parser_t *mime_parser);

static axis2_char_t *
axiom_mime_parser_search_for_crlf(
    const axutil_env_t * env,
    AXIS2_READ_INPUT_CALLBACK callback,
    void *callback_ctx,
    int *buf_num,
    size_t *len_array,
    axis2_char_t **buf_array,
    axiom_search_info_t *search_info,
    size_t size,
    axiom_mime_parser_t *mime_parser);

static size_t
axiom_mime_parser_calculate_part_len(
    const axutil_env_t *env,
    int buf_num,
    size_t *len_list,
    int maker,
    axis2_char_t *pos,
    axis2_char_t *buf);

static axis2_char_t *
axiom_mime_parser_create_part(
    const axutil_env_t *env,
    size_t part_len,
    int buf_num,
    size_t *len_list,
    int marker,
    axis2_char_t *pos,
    axis2_char_t **buf_list,
    axiom_mime_parser_t *mime_parser);

static axis2_char_t *
axiom_mime_parser_search_string(
    axiom_search_info_t *search_info,
    const axutil_env_t *env);

static axis2_char_t *
axiom_mime_parser_search_for_attachment(
    axiom_mime_parser_t *mime_parser,
    const axutil_env_t * env,
    AXIS2_READ_INPUT_CALLBACK callback,
    void *callback_ctx,
    int *buf_num,
    size_t *len_array,
    axis2_char_t **buf_array,
    axiom_search_info_t *search_info,
    size_t size,
    axis2_char_t *mime_boundary,
    axis2_char_t *mime_id,
    void *user_param);

static axis2_status_t
axiom_mime_parser_store_attachment(
    const axutil_env_t *env,
    axiom_mime_parser_t *mime_parser,
    axis2_char_t *mime_id,
    axis2_char_t *mime_type,
    axis2_char_t *mime_binary,
    size_t mime_binary_len,
    axis2_bool_t cached);

static void
axiom_mime_parser_clear_buffers(
    const axutil_env_t *env,
    axis2_char_t **buf_list,
    int free_from,
    int free_to);

static axis2_status_t
axiom_mime_parser_cache_to_buffer(
    const axutil_env_t *env,
    axis2_char_t *buf,
    size_t buf_len,
    axiom_search_info_t *search_info,
    axiom_mime_parser_t *mime_parser);

static axis2_bool_t
axiom_mime_parser_is_more_data(
    axiom_mime_parser_t *mime_parser,
    const axutil_env_t *env,
    axis2_callback_info_t *callback_info);

static axis2_char_t *
axiom_mime_parser_process_mime_headers(
    const axutil_env_t *env,
    axiom_mime_parser_t *mime_parser,
    axis2_char_t **mime_id,
    axis2_char_t *mime_headers);

static axis2_status_t
axiom_mime_parser_cache_to_file(
    const axutil_env_t* env,
    axis2_char_t *buf,
    size_t buf_len,
    void *handler);

static void*
axiom_mime_parser_initiate_callback(
    axiom_mime_parser_t *mime_parser,
    const axutil_env_t *env,
    axis2_char_t *mime_id,
    void *user_param);

AXIS2_EXTERN axiom_mime_parser_t *AXIS2_CALL
axiom_mime_parser_create(
    const axutil_env_t * env)
{
    axiom_mime_parser_t *mime_parser = NULL;

    AXIS2_ENV_CHECK(env, NULL);
    mime_parser = (axiom_mime_parser_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_mime_parser_t));

    if(!mime_parser)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }

    mime_parser->mime_parts_map = NULL;
    mime_parser->soap_body_len = 0;
    mime_parser->soap_body_str = NULL; /* shallow copy */
    mime_parser->buffer_size = 1;
    mime_parser->max_buffers = AXIOM_MIME_PARSER_MAX_BUFFERS;
    mime_parser->attachment_dir = NULL;
    mime_parser->mtom_caching_callback = NULL;
    mime_parser->callback_name = NULL;
    mime_parser->buf_array = NULL;
    mime_parser->len_array = NULL;
    mime_parser->current_buf_num = 0;
    mime_parser->end_of_mime = AXIS2_FALSE;
    mime_parser->mime_boundary = NULL;

    mime_parser->mime_parts_map = axutil_hash_make(env);
    if(!(mime_parser->mime_parts_map))
    {
        axiom_mime_parser_free(mime_parser, env);
        return NULL;
    }

    return mime_parser;
}

AXIS2_EXTERN void AXIS2_CALL
axiom_mime_parser_free(
    axiom_mime_parser_t * mime_parser,
    const axutil_env_t * env)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);

    /* The map is passed on to SOAP builder, and SOAP builder take over the
     ownership of the map */

    /* We will unload the callback at the end */

    if(mime_parser->mtom_caching_callback)
    {
        axutil_param_t *param = NULL;
        param = mime_parser->mtom_caching_callback->param;

        AXIOM_MTOM_CACHING_CALLBACK_FREE(mime_parser->mtom_caching_callback, env);
        mime_parser->mtom_caching_callback = NULL;

        if(param)
        {
            axutil_param_free(param, env);
            param = NULL;
        }
    }

    if(mime_parser->buf_array)
    {
        AXIS2_FREE(env->allocator, mime_parser->buf_array);
        mime_parser->buf_array = NULL;
    }

    if(mime_parser->len_array)
    {
        AXIS2_FREE(env->allocator, mime_parser->len_array);
        mime_parser->len_array = NULL;
    }

	if(mime_parser->mime_boundary)
	{
		AXIS2_FREE(env->allocator, mime_parser->mime_boundary);
	}

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

    return;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_mime_parser_parse_for_soap(
    axiom_mime_parser_t * mime_parser,
    const axutil_env_t * env,
    AXIS2_READ_INPUT_CALLBACK callback,
    void *callback_ctx,
    axis2_char_t * mime_boundary)
{
    size_t size = 0;
    axis2_char_t *soap_str = NULL;
    size_t soap_len = 0;
    size_t temp_mime_boundary_size = 0;
    axis2_char_t *temp_mime_boundary = NULL;
    axis2_char_t **buf_array = NULL;
    size_t *len_array = NULL;
    int buf_num = 0;
    axis2_char_t *pos = NULL;
    axiom_search_info_t *search_info = NULL;
    int part_start = 0;
    axis2_bool_t end_of_mime = AXIS2_FALSE;
    size_t len = 0;
    axis2_char_t *buffer = NULL;
    size_t malloc_len = 0;
    axis2_callback_info_t *callback_info = NULL;

    callback_info = (axis2_callback_info_t *)callback_ctx;

    /* The user will specify the mime_parser->buffer_size */

    size = AXIOM_MIME_PARSER_BUFFER_SIZE * (mime_parser->buffer_size);

    /*An array to keep the set of buffers*/

    buf_array = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t *) * (mime_parser->max_buffers));

    if(!buf_array)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Failed in creating buffer array");
        return AXIS2_FAILURE;
    }

    /*Keeps the corresponding lengths of buffers in buf_array*/

    len_array = AXIS2_MALLOC(env->allocator, sizeof(size_t) * (mime_parser->max_buffers));

    if(!len_array)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Failed in creating length array");
        return AXIS2_FAILURE;
    }

    mime_parser->buf_array = buf_array;
    mime_parser->len_array = len_array;

    temp_mime_boundary = axutil_stracat(env, "--", mime_boundary);
    temp_mime_boundary_size = strlen(mime_boundary) + 2;

    /*This struct keeps the pre-post search informations*/
    search_info = AXIS2_MALLOC(env->allocator, sizeof(axiom_search_info_t));

    /* The first buffer is created */
    buf_array[buf_num] = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (size + 1));

    /* The buffer is filled from the callback */

    if(buf_array[buf_num])
    {
        len = callback(buf_array[buf_num], (int)size, (void *)callback_ctx);
    }
    if(len > 0)
    {
        len_array[buf_num] = len;
    }
    else
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error reading from the stream");
        return AXIS2_FAILURE;
    }

    /*starting buffer for the current search*/
    part_start = buf_num;

    /*We are passing the address of the buf_num , beacause that value 
     is changing inside the method.*/

    /* Following call to the method will search first \r\n\r\n */

    pos = axiom_mime_parser_search_for_crlf(env, callback, callback_ctx, &buf_num, len_array,
        buf_array, search_info, size, mime_parser);

    if(!pos)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in the message.");
        return AXIS2_FAILURE;
    }

    /* The patteren contains in one buffer */

    if((search_info->match_len2 == 0))
    {
        /*Readjusting the buffers for the next search and discarding the prevoius 
         buffers*/

        /* We need the remaining part in the buffer after the \r\n\r\n*/

        malloc_len = buf_array[buf_num] + len_array[buf_num] - pos - 4;
        if(malloc_len < 0)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in parsing.");
            return AXIS2_FAILURE;
        }
        else
        {
            /* Here we will create a new buffer of predefined size fill the 
             * first portion from the remaining part after previous search
             * and then fill the remaining from the callback */

            buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (size + 1));

            if(malloc_len > 0)
            {
                memcpy(buffer, pos + 4, malloc_len);
            }

            /* Here we need to check for more data, because if the message is too small
             * comapred to the reading size there may be no data in the stream , instead
             * all the remaining data may be in the buffer.And if there are no more data
             * we will set the len to be 0. Otherwise len_array will contain wrong lenghts.
             */

            if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info))
            {
                /* There is more data so fill the remaining from the  stream*/

                len = callback(buffer + malloc_len, (int)(size - malloc_len), (void *)callback_ctx);
            }
            else
            {
                len = 0;
            }

            /* We do not need the data in the previous buffers once we found a particular
             * string and after worked with those buffers */

            axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num);

            /* Adding the new buffer to the buffer list */

            if(len >= 0)
            {
                buf_array[buf_num] = buffer;
                len_array[buf_num] = malloc_len + len;
            }
        }
    }

    /*The pattern divides among two buffers*/

    else if(search_info->match_len2 > 0)
    {
        malloc_len = len_array[buf_num] - search_info->match_len2;
        if(malloc_len < 0)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in parsing.");
            return AXIS2_FAILURE;
        }
        else
        {
            buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (size + 1));

            /* Here the buf_num is the second buffer. We will copy the remaining data
             * after the partial string in the second buffer */

            if(malloc_len > 0)
            {
                memcpy(buffer, buf_array[buf_num] + search_info->match_len2, malloc_len);
            }
            if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info))
            {
                len = callback(buffer + malloc_len, (int)(size - malloc_len), (void *)callback_ctx);
            }
            else
            {
                len = 0;
            }
            axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num);
            if(len >= 0)
            {
                buf_array[buf_num] = buffer;
                len_array[buf_num] = malloc_len + len;
            }
        }
    }
    else
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in parsing.");
        return AXIS2_FAILURE;
    }

    /*Resetting the previous search data and getting ready 
     for the next search */

    part_start = buf_num;
    pos = NULL;
    malloc_len = 0;

    search_info->match_len1 = 0;
    search_info->match_len2 = 0;

    /*In order to extract the soap envelope we need to search for the first
     --MIMEBOUNDARY  */

    pos = axiom_mime_parser_search_for_soap(env, callback, callback_ctx, &buf_num, len_array,
        buf_array, search_info, size, temp_mime_boundary, mime_parser);

    if(!pos)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error while searching for the SOAP part ");
        return AXIS2_FAILURE;
    }

    if(search_info->match_len2 == 0)
    {
        /*Calculating the length of the SOAP str*/

        soap_len = axiom_mime_parser_calculate_part_len(env, buf_num, len_array, part_start, pos,
            buf_array[buf_num]);
        if(soap_len > 0)
        {
            /* Get the SOAP string from the starting and end buffers containing 
             * the SOAP  part */

            soap_str = axiom_mime_parser_create_part(env, soap_len, buf_num, len_array, part_start,
                pos, buf_array, mime_parser);
            if(!soap_str)
            {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                    "Error while creating the SOAP part from the message ");
                return AXIS2_FAILURE;
            }

            malloc_len = len_array[buf_num] - search_info->match_len1 - temp_mime_boundary_size;
            if(malloc_len < 0)
            {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in parsing for mime.");
                return AXIS2_FAILURE;
            }
            else
            {
                /* This will fill the new buffer with remaining data after the
                 * SOAP */

                buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (size + 1));

                memset(buffer, 0, size + 1);
                if(malloc_len > 0)
                {
                    memcpy(buffer, pos + temp_mime_boundary_size, malloc_len);
                }
                if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info))
                {
                    len = callback(buffer + malloc_len,(int)(size - malloc_len),(void *)callback_ctx);
                }
                else
                {
                    len = 0;
                }
                axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num);
                if(len >= 0)
                {
                    buf_array[buf_num] = buffer;
                    len_array[buf_num] = malloc_len + len;
                }
            }
        }
        else
        {
            return AXIS2_FAILURE;
        }
    }

    /* This is the condition where the --MIMEBOUNDARY is divided among two
     * buffers */

    else if(search_info->match_len2 > 0)
    {
        soap_len = axiom_mime_parser_calculate_part_len(env, buf_num - 1, len_array, part_start,
            pos, buf_array[buf_num - 1]);

        if(soap_len > 0)
        {
            /* Here we pass buf_num-1 because buf_num does not have any thing we want to
             * for this particular part. It begins with the latter part of the search string */

            soap_str = axiom_mime_parser_create_part(env, soap_len, buf_num - 1, len_array,
                part_start, pos, buf_array, mime_parser);
            if(!soap_str)
            {
                return AXIS2_FAILURE;
            }

            malloc_len = len_array[buf_num] - search_info->match_len2;
            if(malloc_len < 0)
            {
                return AXIS2_FAILURE;
            }
            else
            {
                buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (size + 1));

                if(malloc_len > 0)
                {
                    memcpy(buffer, buf_array[buf_num] + search_info->match_len2, malloc_len);
                }

                if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info))
                {
                    len = callback(buffer + malloc_len,(int)(size - malloc_len),(void *)callback_ctx);
                }
                else
                {
                    len = 0;
                }
                axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num);
                if(len >= 0)
                {
                    buf_array[buf_num] = buffer;
                    len_array[buf_num] = malloc_len + len;
                }
            }
        }
        else
        {
            return AXIS2_FAILURE;
        }
    }

    mime_parser->soap_body_str = soap_str;
    mime_parser->soap_body_len = soap_len;
    mime_parser->current_buf_num = buf_num;

    /* There are multipart/related messages which does not contain attachments 
     * The only mime_part is the soap envelope. So for those messages the mime
     * boundary after the soap will end up with --
     * So we will check that here and if we found then the logic inside the 
     * while loop will not be executed */

    end_of_mime = (AXIOM_MIME_BOUNDARY_BYTE == *(buf_array[buf_num])) && (AXIOM_MIME_BOUNDARY_BYTE
        == *(buf_array[buf_num] + 1));
    if(end_of_mime)
    {
        AXIS2_FREE(env->allocator, buf_array[buf_num]);
        buf_array[buf_num] = NULL;
    }

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

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

    mime_parser->end_of_mime = end_of_mime;

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axutil_hash_t *AXIS2_CALL
axiom_mime_parser_parse_for_attachments(
    axiom_mime_parser_t * mime_parser,
    const axutil_env_t * env,
    AXIS2_READ_INPUT_CALLBACK callback,
    void *callback_ctx,
    axis2_char_t * mime_boundary,
    void *user_param)
{
    int count = 0;
    axiom_search_info_t *search_info = NULL;
    axis2_char_t *pos = NULL;
    int part_start = 0;
    axis2_char_t **buf_array = NULL;
    size_t *len_array = NULL;
    int buf_num = 0;
    size_t size = 0;
    size_t malloc_len = 0;
    axis2_callback_info_t *callback_info = NULL;
    axis2_char_t *temp_mime_boundary = NULL;
    size_t temp_mime_boundary_size = 0;
    axis2_bool_t end_of_mime = AXIS2_FALSE;

    callback_info = (axis2_callback_info_t *)callback_ctx;

    search_info = AXIS2_MALLOC(env->allocator, sizeof(axiom_search_info_t));

    size = AXIOM_MIME_PARSER_BUFFER_SIZE * (mime_parser->buffer_size);

    buf_array = mime_parser->buf_array;
    len_array = mime_parser->len_array;
    buf_num = mime_parser->current_buf_num;

    /*<SOAP></SOAP>--MIMEBOUNDARY
     mime_headr1:.......
     mime_headr2:....

     Binarstart.................
     ...............--MIMEBOUNDARY
     */

    /* This loop will extract all the attachments in the message. The condition
     * with the count is needed because if the sender not marked the end of the 
     * attachment with -- then this loop may run infinitely. To prevent that
     * this additional condition has been put */

    temp_mime_boundary = axutil_stracat(env, "--", mime_boundary);
    temp_mime_boundary_size = strlen(mime_boundary) + 2;

    while((!(mime_parser->end_of_mime)) && count < AXIOM_MIME_PARSER_END_OF_MIME_MAX_COUNT)
    {
        /*First we will search for \r\n\r\n*/
        axis2_char_t *mime_id = NULL;
        axis2_char_t *mime_type = NULL;
        size_t mime_headers_len = 0;
        size_t mime_binary_len = 0;
        axis2_char_t *mime_binary = NULL;
        axis2_char_t *mime_headers = NULL;
        axis2_char_t *buffer = NULL;
        int len = 0;
        axis2_status_t status = AXIS2_FAILURE;

        search_info->match_len1 = 0;
        search_info->match_len2 = 0;
        pos = NULL;
        part_start = buf_num;

        malloc_len = 0;

        count++;

        pos = axiom_mime_parser_search_for_crlf(env, callback, callback_ctx, &buf_num, len_array,
            buf_array, search_info, size, mime_parser);

        if(!pos)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in parsing for mime.");
            return NULL;
        }

        /*The pattern contains in one buffer*/
        if(search_info->match_len2 == 0)
        {
            /*We found it . so lets seperates the details of this binary into 
             mime headers.*/

            mime_headers_len = axiom_mime_parser_calculate_part_len(env, buf_num, len_array,
                part_start, pos, buf_array[buf_num]);
            if(mime_headers_len > 0)
            {
                mime_headers = axiom_mime_parser_create_part(env, mime_headers_len, buf_num,
                    len_array, part_start, pos, buf_array, mime_parser);

                if(!mime_headers)
                {
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in parsing for mime headers.");
                    return NULL;
                }
                malloc_len = buf_array[buf_num] + len_array[buf_num] - pos - 4;

                /*This should be > 0 , > 0 means there is some part to copy = 0 means
                 there is nothing to copy*/
                if(malloc_len < 0)
                {
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in parsing for mime headers");
                    return NULL;
                }

                else
                {
                    buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (size + 1));

                    if(malloc_len > 0)
                    {
                        memcpy(buffer, pos + 4, malloc_len);
                    }

                    if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info))
                    {
                        len = callback(buffer + malloc_len,(int)(size - malloc_len),(void *)callback_ctx);
                    }
                    else
                    {
                        len = 0;
                    }
                    axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num);
                    if(len >= 0)
                    {
                        buf_array[buf_num] = buffer;
                        len_array[buf_num] = malloc_len + len;
                    }
                }
            }
            else
            {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in parsing for mime headers.");
                return NULL;
            }
        }

        else if(search_info->match_len2 > 0)
        {
            /*Now we extract the mime headers */

            mime_headers_len = axiom_mime_parser_calculate_part_len(env, buf_num - 1, len_array,
                part_start, pos, buf_array[buf_num - 1]);

            if(mime_headers_len > 0)
            {
                mime_headers = axiom_mime_parser_create_part(env, mime_headers_len, buf_num - 1,
                    len_array, part_start, pos, buf_array, mime_parser);
                if(!mime_headers)
                {
                    return NULL;
                }

                malloc_len = len_array[buf_num] - search_info->match_len2;
                if(malloc_len < 0)
                {
                    return NULL;
                }
                else
                {
                    buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (size + 1));

                    if(malloc_len > 0)
                    {
                        memcpy(buffer, buf_array[buf_num] + search_info->match_len2, malloc_len);
                    }
                    if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info))
                    {
                        len = callback(buffer + malloc_len,(int)(size - malloc_len),(void*)callback_ctx);
                    }
                    else
                    {
                        len = 0;
                    }
                    axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num);
                    if(len >= 0)
                    {
                        buf_array[buf_num] = buffer;
                        len_array[buf_num] = malloc_len + len;
                    }
                }
            }
            else
            {
                return NULL;
            }
        }
        else
        {
            return NULL;
        }

        pos = NULL;

        search_info->match_len1 = 0;
        search_info->match_len2 = 0;

        part_start = buf_num;
        malloc_len = 0;

        mime_type
            = axiom_mime_parser_process_mime_headers(env, mime_parser, &mime_id, mime_headers);

        if(!mime_id)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                "Error in parsing for mime headers.Mime id did not find");
            return NULL;
        }

        if(!mime_type)
        {
            AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Mime type did not find");
        }

        /*We extract the mime headers. So lets search for the attachment.*/

        pos = axiom_mime_parser_search_for_attachment(mime_parser, env, callback, callback_ctx,
            &buf_num, len_array, buf_array, search_info, size, temp_mime_boundary, mime_id,
            user_param);

        if(pos)
        {
            /*If it is small we are not caching. Hence the attachment 
             is in memory. So store it in a buffer. */

            if(!search_info->cached)
            {
                if(search_info->match_len2 == 0)
                {
                    /* mime_binary contains the attachment when it does not 
                     * cached */

                    mime_binary_len = axiom_mime_parser_calculate_part_len(env, buf_num, len_array,
                        part_start, pos, buf_array[buf_num]);
                    if(mime_binary_len > 0)
                    {
                        mime_binary = axiom_mime_parser_create_part(env, mime_binary_len, buf_num,
                            len_array, part_start, pos, buf_array, mime_parser);
                        if(!mime_binary)
                        {
                            return NULL;
                        }
                    }
                    else
                    {
                        return NULL;
                    }
                }

                else if(search_info->match_len2 > 0)
                {
                    mime_binary_len = axiom_mime_parser_calculate_part_len(env, buf_num - 1,
                        len_array, part_start, pos, buf_array[buf_num - 1]);

                    if(mime_binary_len > 0)
                    {
                        mime_binary = axiom_mime_parser_create_part(env, mime_binary_len, buf_num
                            - 1, len_array, part_start, pos, buf_array, mime_parser);
                        if(!mime_binary)
                        {
                            return NULL;
                        }
                    }
                    else
                    {
                        return NULL;
                    }
                }
            }

            /* The functionality below is common when it is cached or not. It deals with remaining
             * after a particualr attachment, Those may be related to a end of mime_boundary or 
             * another attachment */

            if(search_info->match_len2 == 0)
            {
                malloc_len = len_array[buf_num] - search_info->match_len1 - temp_mime_boundary_size;
                if(malloc_len < 0)
                {
                    return NULL;
                }
                else
                {
                    buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (size + 1));

                    if(malloc_len > 0)
                    {
                        memcpy(buffer, pos + temp_mime_boundary_size, malloc_len);
                    }

                    /*When the last buffer only containing -- we know this is the end 
                     of the attachments. Hence we don't need to read again*/

                    if(malloc_len != 2)
                    {
                        if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info))
                        {
                            len = callback(buffer + malloc_len,(int)(size - malloc_len),(void*)callback_ctx);
                        }
                        else
                        {
                            len = 0;
                        }
                        if(len >= 0)
                        {
                            len_array[buf_num] = malloc_len + len;
                        }
                    }

                    /* This means there is another attachment */
                    else
                    {
                        len_array[buf_num] = malloc_len;
                    }
                    axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num);
                    buf_array[buf_num] = buffer;
                }
            }
            else if(search_info->match_len2 > 0)
            {
                malloc_len = len_array[buf_num] - search_info->match_len2;

                if(malloc_len < 0)
                {
                    return NULL;
                }
                else
                {
                    buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (size + 1));

                    if(malloc_len > 0)
                    {
                        memcpy(buffer, buf_array[buf_num] + search_info->match_len2, malloc_len);
                    }
                    if(malloc_len != 2)
                    {
                        if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info))
                        {
                            len = callback(buffer + malloc_len,(int)(size - malloc_len),(void *)callback_ctx);
                        }
                        else
                        {
                            len = 0;
                        }
                        if(len >= 0)
                        {
                            len_array[buf_num] = malloc_len + len;
                        }
                    }
                    else
                    {
                        len_array[buf_num] = malloc_len;
                    }
                    axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num);
                    buf_array[buf_num] = buffer;
                }
            }
        }
        else
        {
            return NULL;
        }

        /*We have the attachment now either cached or not. So lets put it in the mime_parts 
         * hash map with the mime_id. Remember at this moment we have already processed the 
         * mime_headers and mime_id is already there */

        /* In the case user has not specified the callback or the attachment dir . So we cached it to a memory
         * buffer. Hence the data_handler type we need to create is different */

        if((search_info->cached) && (!mime_parser->attachment_dir) && (!mime_parser->callback_name))
        {
            mime_binary = (axis2_char_t *)search_info->handler;
            mime_binary_len = search_info->binary_size;
        }

        /* Storing the attachment in the hash map with the id*/

        status = axiom_mime_parser_store_attachment(env, mime_parser, mime_id, mime_type,
            mime_binary, mime_binary_len, search_info->cached);

        /*Check wether we encounter --MIMEBOUNDARY-- to find the end of mime*/

        if(buf_array[buf_num])
        {
            /* Here we check for the end of mime */

            end_of_mime = (AXIOM_MIME_BOUNDARY_BYTE == *(buf_array[buf_num]))
                && (AXIOM_MIME_BOUNDARY_BYTE == *(buf_array[buf_num] + 1));
            if(end_of_mime)
            {
                AXIS2_FREE(env->allocator, buf_array[buf_num]);
                buf_array[buf_num] = NULL;
            }
            mime_parser->end_of_mime = end_of_mime;
        }

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

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

    /*Do the necessary cleaning */

    /*if (buf_array)
     {
     AXIS2_FREE(env->allocator, buf_array);
     buf_array = NULL;
     }

     if (len_array)
     {
     AXIS2_FREE(env->allocator, len_array);
     len_array = NULL;
     }*/

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

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

    return mime_parser->mime_parts_map;

}

/*This method will search for \r\n\r\n */

static axis2_char_t *
axiom_mime_parser_search_for_crlf(
    const axutil_env_t * env,
    AXIS2_READ_INPUT_CALLBACK callback,
    void *callback_ctx,
    int *buf_num,
    size_t *len_array,
    axis2_char_t **buf_array,
    axiom_search_info_t *search_info,
    size_t size,
    axiom_mime_parser_t *mime_parser)
{
    axis2_char_t *found = NULL;
    int len = 0;

    search_info->search_str = "\r\n\r\n";
    search_info->buffer1 = NULL;
    search_info->buffer2 = NULL;
    search_info->len1 = 0;
    search_info->len2 = 0;
    search_info->match_len1 = 0;
    search_info->match_len2 = 0;
    search_info->primary_search = AXIS2_FALSE;
    search_info->cached = AXIS2_FALSE;
    search_info->handler = NULL;
    search_info->binary_size = 0;

    /*First do a search in the first buffer*/

    if(buf_array[*buf_num])
    {
        search_info->buffer1 = buf_array[*buf_num];
        search_info->len1 = len_array[*buf_num];
        found = axiom_mime_parser_search_string(search_info, env);
    }

    while(!found)
    {
        /*Let's read another buffer and do a boundary search in both*/

        *buf_num = *buf_num + 1;
        buf_array[*buf_num] = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (size + 1));

        if(buf_array[*buf_num])
        {
            len = callback(buf_array[*buf_num], (int)size, (void *)callback_ctx);
        }
        if(len > 0)
        {
            len_array[*buf_num] = len;
            search_info->buffer2 = buf_array[*buf_num];
            search_info->len2 = len;
            found = axiom_mime_parser_search_string(search_info, env);
        }
        else
        {
            break;
        }
        if(!found)
        {
            /*Let's do a full search in the second buffer*/

            search_info->buffer1 = buf_array[*buf_num];
            search_info->len1 = len_array[*buf_num];
            search_info->primary_search = AXIS2_FALSE;
            search_info->buffer2 = NULL;
            search_info->len2 = 0;
            found = axiom_mime_parser_search_string(search_info, env);
        }
    }

    return found;
}

/* This method will search for the mime_boundary after the SOAP part 
 * of the message */

static axis2_char_t *
axiom_mime_parser_search_for_soap(
    const axutil_env_t * env,
    AXIS2_READ_INPUT_CALLBACK callback,
    void *callback_ctx,
    int *buf_num,
    size_t *len_array,
    axis2_char_t **buf_array,
    axiom_search_info_t *search_info,
    size_t size,
    axis2_char_t *mime_boundary,
    axiom_mime_parser_t *mime_parser)
{
    axis2_char_t *found = NULL;
    int len = 0;

    /* What we need to search is the mime_boundary */

    search_info->search_str = mime_boundary;
    search_info->buffer1 = NULL;
    search_info->buffer2 = NULL;
    search_info->len1 = 0;
    search_info->len2 = 0;
    search_info->match_len1 = 0;
    search_info->match_len2 = 0;
    search_info->primary_search = AXIS2_FALSE;

    if(buf_array[*buf_num])
    {
        search_info->buffer1 = buf_array[*buf_num];
        search_info->len1 = len_array[*buf_num];
        found = axiom_mime_parser_search_string(search_info, env);

        /* Inside this search primary_search flag will be set to TRUE */
    }

    while(!found)
    {
        /* We need to create the second buffer and do the search for the 
         * mime_boundary in the both the buffers */

        *buf_num = *buf_num + 1;
        buf_array[*buf_num] = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (size + 1));

        if(buf_array[*buf_num])
        {
            len = callback(buf_array[*buf_num], (int)size, (void *)callback_ctx);
        }
        if(len > 0)
        {
            /* In this search we are matching end part of the first
             * buffer and starting part of the previous buffer */
            len_array[*buf_num] = len;
            search_info->buffer2 = buf_array[*buf_num];
            search_info->len2 = len;
            found = axiom_mime_parser_search_string(search_info, env);
        }
        else
        {
            break;
        }
        if(!found)
        {
            search_info->buffer1 = buf_array[*buf_num];
            search_info->len1 = len_array[*buf_num];
            search_info->primary_search = AXIS2_FALSE;
            search_info->buffer2 = NULL;
            search_info->len2 = 0;
            found = axiom_mime_parser_search_string(search_info, env);
        }
    }

    return found;
}

/*The caching is done in this function. Caching happens when we did not 
 find the mime_boundary in initial two buffers. So the maximum size
 that we are keeping in memory is 2 * size. This size can be configurable from
 the aixs.xml. The caching may starts when the search failed with the
 second buffer.
 In this logic first we will search for a callback to cache. If it is not
 there then we will search for a directory to save the file. If it is also
 not there then the attachment will be in memory.
 */

static axis2_char_t *
axiom_mime_parser_search_for_attachment(
    axiom_mime_parser_t *mime_parser,
    const axutil_env_t * env,
    AXIS2_READ_INPUT_CALLBACK callback,
    void *callback_ctx,
    int *buf_num,
    size_t *len_array,
    axis2_char_t **buf_array,
    axiom_search_info_t *search_info,
    size_t size,
    axis2_char_t *mime_boundary,
    axis2_char_t *mime_id,
    void *user_param)
{
    axis2_char_t *found = NULL;
    int len = 0;
    axis2_status_t status = AXIS2_FAILURE;
    axis2_char_t *temp = NULL;
    size_t temp_length = 0;
    axis2_char_t *file_name = NULL;

    search_info->search_str = mime_boundary;
    search_info->buffer1 = NULL;
    search_info->buffer2 = NULL;
    search_info->len1 = 0;
    search_info->len2 = 0;
    search_info->match_len1 = 0;
    search_info->match_len2 = 0;
    search_info->primary_search = AXIS2_FALSE;
    search_info->cached = AXIS2_FALSE;
    search_info->handler = NULL;

    /*First search in the incoming buffer*/

    if(buf_array[*buf_num])
    {
        search_info->buffer1 = buf_array[*buf_num];
        search_info->len1 = len_array[*buf_num];
        found = axiom_mime_parser_search_string(search_info, env);
    }

    while(!found)
    {
        if(search_info->cached)
        {
            if(mime_parser->callback_name)
            {
                if(!(search_info->handler))
                {
                    /* If the callback is not loaded yet then we load it*/
                    if(!mime_parser->mtom_caching_callback)
                    {
                        search_info->handler = axiom_mime_parser_initiate_callback(mime_parser,
                            env, mime_id, user_param);
                        if(!(search_info->handler))
                        {
                            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                "Caching Callback is not loaded");
                            return NULL;
                        }
                    }
                }
                /*So lets cache the previous buffer which has undergone the
                 full search and the partial search.  */

                if(mime_parser->mtom_caching_callback)
                {
                    /* Caching callback is loaded. So we can cache the previous buffer */
                    status
                        = AXIOM_MTOM_CACHING_CALLBACK_CACHE(mime_parser->mtom_caching_callback,
                            env, buf_array[*buf_num - 1], (int)len_array[*buf_num - 1],
                            search_info->handler);
                }
            }

            else if(mime_parser->attachment_dir)
            {
                if(!(search_info->handler))
                {
                    /* If the File is not opened yet we will open it*/

                    axis2_char_t *encoded_mime_id = NULL;

                    /* Some times content-ids urls, hence we need to encode them 
                     * becasue we can't create files with / */

                    encoded_mime_id = AXIS2_MALLOC(env->allocator, (sizeof(axis2_char_t))
                        * (strlen(mime_id)));
                    memset(encoded_mime_id, 0, strlen(mime_id));
                    encoded_mime_id = axutil_url_encode(env, encoded_mime_id, mime_id, (int)strlen(
                        mime_id));
                    if(!encoded_mime_id)
                    {
                        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Mime Id encoding failed");
                        return NULL;
                    }

                    file_name = axutil_stracat(env, mime_parser->attachment_dir, encoded_mime_id);
                    AXIS2_FREE(env->allocator, encoded_mime_id);
                    encoded_mime_id = NULL;

                    if(!file_name)
                    {
                        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Caching file name creation error");
                        return NULL;
                    }
                    search_info->handler = (void *)fopen(file_name, "ab+");
                    if(!(search_info->handler))
                    {
                        return NULL;
                    }
                }

                /*So lets cache the previous buffer which has undergone the
                 full search and the partial search.  */

                status = axiom_mime_parser_cache_to_file(env, buf_array[*buf_num - 1],
                    len_array[*buf_num - 1], search_info->handler);
            }

            else
            {
                /* Here the user has not specified the caching File location. So we are 
                 * not going to cache. Instead we store the attachment in the buffer */
                status = axiom_mime_parser_cache_to_buffer(env, buf_array[*buf_num - 1],
                    len_array[*buf_num - 1], search_info, mime_parser);
            }

            if(status == AXIS2_FAILURE)
            {
                return NULL;
            }
            /*Here we interchange the buffers.*/

            temp = buf_array[*buf_num - 1];
            buf_array[*buf_num - 1] = buf_array[*buf_num];
            buf_array[*buf_num] = temp;
            temp_length = len_array[*buf_num - 1];
            len_array[*buf_num - 1] = len_array[*buf_num];
            len_array[*buf_num] = temp_length;
            if(buf_array[*buf_num])
            {
                /*The cached buffer is the one which get filled.*/
                len = callback(buf_array[*buf_num], (int)size, (void *)callback_ctx);
            }
        }

        /*Size of the data in memory not yet risen to the caching threasold
         *So we can create the second buffer */
        else
        {
            *buf_num = *buf_num + 1;
            buf_array[*buf_num] = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (size + 1));

            if(buf_array[*buf_num])
            {
                len = callback(buf_array[*buf_num], (int)size, (void *)callback_ctx);
            }
        }

        /*Doing  a complete search in newly cretaed buffer*/

        if(len > 0)
        {
            len_array[*buf_num] = len;
            search_info->buffer2 = buf_array[*buf_num];
            search_info->len2 = len;
            found = axiom_mime_parser_search_string(search_info, env);
        }
        else
        {
            break;
        }

        /* Now there are two buffers. If the searching string is not 
         * here then we must cache the first buffer */

        if(!found)
        {
            /*So now we must start caching*/
            search_info->buffer1 = buf_array[*buf_num];
            search_info->len1 = len_array[*buf_num];
            search_info->primary_search = AXIS2_FALSE;
            search_info->buffer2 = NULL;
            search_info->len2 = 0;
            found = axiom_mime_parser_search_string(search_info, env);
            if(!found)
            {
                /* So at the begining of the next search we start
                 * that only after caching this data */
                search_info->cached = AXIS2_TRUE;
            }
        }
    }

    /* Here we are out of the loop. If there is no error then this means 
     * the searching string is found */
    if(search_info->cached && found)
    {
        /* If the attachment is cached then we need to cache the 
         * final buffer */

        if(search_info->match_len2 == 0)
        {
            /* This is the case where we found the whole string in one buffer 
             * So we need to cache previous buffer and the data up to the starting
             * point of the search string in the current buffer */

            /* deduct last 2 CRLF character.
             * For buffering case, it will be done when creating datahandler.*/

            if(mime_parser->mtom_caching_callback)
            {
                status = AXIOM_MTOM_CACHING_CALLBACK_CACHE(mime_parser->mtom_caching_callback, env,
                    buf_array[*buf_num - 1], (int)len_array[*buf_num - 1], search_info->handler);
                if(status == AXIS2_SUCCESS)
                {
                    status
                        = AXIOM_MTOM_CACHING_CALLBACK_CACHE(mime_parser->mtom_caching_callback,
                            env, buf_array[*buf_num], (int)(found - buf_array[*buf_num] - 2),
                            search_info->handler);
                }
            }

            else if(mime_parser->attachment_dir)
            {
                status = axiom_mime_parser_cache_to_file(env, buf_array[*buf_num - 1],
                    len_array[*buf_num - 1], search_info->handler);
                if(status == AXIS2_SUCCESS)
                {
                    status = axiom_mime_parser_cache_to_file(env, buf_array[*buf_num], found
                        - buf_array[*buf_num] - 2, search_info->handler);
                }
            }

            /* If the callback or a file is not there then the data is appended to the buffer */

            else
            {
                status = axiom_mime_parser_cache_to_buffer(env, buf_array[*buf_num - 1],
                    len_array[*buf_num - 1], search_info, mime_parser);
                if(status == AXIS2_SUCCESS)
                {
                    status = axiom_mime_parser_cache_to_buffer(env, buf_array[*buf_num], found
                        - buf_array[*buf_num], search_info, mime_parser);
                }
            }
        }
        else if(search_info->match_len2 > 0)
        {
            /*Here the curent buffer has partial mime boundary. So we need 
             to cache only the previous buffer. */

            if(mime_parser->mtom_caching_callback)
            {
                status = AXIOM_MTOM_CACHING_CALLBACK_CACHE(mime_parser->mtom_caching_callback, env,
                    buf_array[*buf_num - 1], (int)(search_info->match_len1 - 2), search_info->handler);
            }

            else if(mime_parser->attachment_dir)
            {
                status = axiom_mime_parser_cache_to_file(env, buf_array[*buf_num - 1],
                    search_info->match_len1 - 2, search_info->handler);
            }
            else
            {
                status = axiom_mime_parser_cache_to_buffer(env, buf_array[*buf_num - 1],
                    search_info->match_len1, search_info, mime_parser);
            }
        }
        else
        {
            return NULL;
        }

        if(status == AXIS2_FAILURE)
        {
            return NULL;
        }
    }

    /* Parsing is done so lets close the relative handlers */

    if(search_info->handler)
    {
        if(mime_parser->mtom_caching_callback)
        {
            status = AXIOM_MTOM_CACHING_CALLBACK_CLOSE_HANDLER(mime_parser->mtom_caching_callback,
                env, search_info->handler);
            if(status == AXIS2_FAILURE)
            {
                return NULL;
            }
        }

        else if(mime_parser->attachment_dir)
        {
            if(fclose((FILE *)(search_info->handler)) == 0)
            {
                status = AXIS2_SUCCESS;
            }
            else
            {
                status = AXIS2_FAILURE;
            }

            AXIS2_FREE(env->allocator, file_name);
            file_name = NULL;

            if(status == AXIS2_FAILURE)
            {
                return NULL;
            }
        }
    }
    return found;
}

/*following two functions are used to extract important information 
 from the buffer list. eg: SOAP, MIME_HEADERS*/

/*marker is the starting buffer of the required 
 part and pos is the end point of that part  */

static size_t
axiom_mime_parser_calculate_part_len(
    const axutil_env_t *env,
    int buf_num,
    size_t *len_list,
    int marker,
    axis2_char_t *pos,
    axis2_char_t *buf)
{
    size_t part_len = 0;
    int i = 0;

    for(i = marker; i < buf_num; i++)
    {
        part_len += len_list[i];
    }

    part_len = part_len + (pos - buf);

    return part_len;
}

static axis2_char_t *
axiom_mime_parser_create_part(
    const axutil_env_t *env,
    size_t part_len,
    int buf_num,
    size_t *len_list,
    int marker,
    axis2_char_t *pos,
    axis2_char_t **buf_list,
    axiom_mime_parser_t *mime_parser)
{
    /*We will copy the set of buffers which contains the required part.
     This part can be the SOAP message , mime headers or the mime 
     binary in the case of none cahced.*/

    axis2_char_t *part_str = NULL;
    int i = 0;
    size_t temp = 0;

    part_str = AXIS2_MALLOC(env->allocator, sizeof(char) * (part_len + 1));

    if(!part_str)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Failed in creating buffer");
        return NULL;
    }

    /* Copy from the part starting buffer to the 
     * curent buffer */

    for(i = marker; i < buf_num; i++)
    {
        if(buf_list[i])
        {
            memcpy(part_str + temp, buf_list[i], len_list[i]);
            temp += len_list[i];
        }
    }
    /* Finally we are copying from the final portion */

    memcpy(part_str + temp, buf_list[i], pos - buf_list[i]);

    part_str[part_len] = '\0';

    return part_str;
}

AXIS2_EXTERN axutil_hash_t *AXIS2_CALL
axiom_mime_parser_get_mime_parts_map(
    axiom_mime_parser_t * mime_parser,
    const axutil_env_t * env)
{
    return mime_parser->mime_parts_map;
}

AXIS2_EXTERN size_t AXIS2_CALL
axiom_mime_parser_get_soap_body_len(
    axiom_mime_parser_t * mime_parser,
    const axutil_env_t * env)
{
    return mime_parser->soap_body_len;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axiom_mime_parser_get_soap_body_str(
    axiom_mime_parser_t * mime_parser,
    const axutil_env_t * env)
{
    return mime_parser->soap_body_str;
}

/*This is the new search function. This will first do a
 search for the entire search string.Then will do a search
 for the partial string which can be divided among two buffers.*/

static axis2_char_t *
axiom_mime_parser_search_string(
    axiom_search_info_t *search_info,
    const axutil_env_t *env)
{
    axis2_char_t *pos = NULL;
    axis2_char_t *old_pos = NULL;
    axis2_char_t *found = NULL;
    size_t str_length = 0;
    size_t search_length = 0;

    str_length = strlen(search_info->search_str);

    /*First lets search the entire buffer*/
    if(!search_info->primary_search)
    {
        old_pos = search_info->buffer1;

        do
        {
            /*find the first byte. We need to adhere to this
             approach rather than straightaway using strstr
             because the buffer1 can be containg binary data*/

            pos = NULL;

            search_length = search_info->buffer1 + search_info->len1 - old_pos - str_length + 1;

            if(search_length < 0)
            {
                break;
            }

            if(old_pos)
            {
                pos = memchr(old_pos, *(search_info->search_str), search_length);
            }

            /* found it so lets check the remaining */

            if(pos)
            {
                found = axutil_strstr(pos, search_info->search_str);
                if(found)
                {
                    search_info->match_len1 = found - search_info->buffer1;
                    break;
                }
                else
                {
                    old_pos = pos + 1;
                }
            }
        }
        while(pos);
    }

    search_info->primary_search = AXIS2_TRUE;

    if(found)
    {
        return found;
    }

    /*So we didn't find the string in the buffer
     lets check whether it is divided in two buffers*/

    else
    {
        size_t offset = 0;
        pos = NULL;
        old_pos = NULL;
        found = NULL;
        search_length = 0;

        if(search_info->buffer2)
        {
            old_pos = search_info->buffer1 + search_info->len1 - str_length + 1;
            do
            {
                /*First check the starting byte*/
                pos = NULL;
                found = NULL;

                search_length = search_info->buffer1 + search_info->len1 - old_pos;

                if(search_length < 0)
                {
                    break;
                }

                pos = memchr(old_pos, *(search_info->search_str), search_length);

                if(pos)
                {
                    offset = search_info->buffer1 + search_info->len1 - pos;

                    /*First match the beginng to offset in buffer1*/

                    if(offset > 0)
                    {
                        if(memcmp(pos, search_info->search_str, offset) == 0)
                        {
                            found = pos;
                        }

                        /*We found something in buffer1 so lets match the
                         remaining in buffer2*/

                        if(found)
                        {
                            if(memcmp(search_info->buffer2, search_info->search_str + offset,
                                str_length - offset) == 0)
                            {
                                search_info->match_len2 = str_length - offset;
                                search_info->match_len1 = found - search_info->buffer1;
                                break;
                            }
                            else
                            {
                                old_pos = pos + 1;
                            }
                        }
                        else
                        {
                            old_pos = pos + 1;
                        }
                    }
                }
            }
            while(pos);

            /* We will set this to AXIS2_FALSE so when the next time this
             * search method is called it will do a full search first for buffer1 */
            search_info->primary_search = AXIS2_FALSE;

            return found;
        }
        else
        {
            return NULL;
        }
    }
}

/* This method creates a data_handler out of the attachment 
 * and store the data_handler in the mime_parts map */

static axis2_status_t
axiom_mime_parser_store_attachment(
    const axutil_env_t *env,
    axiom_mime_parser_t *mime_parser,
    axis2_char_t *mime_id,
    axis2_char_t *mime_type,
    axis2_char_t *mime_binary,
    size_t mime_binary_len,
    axis2_bool_t cached)
{
    if(mime_parser->mime_parts_map)
    {
        if(mime_id)
        {
            axiom_data_handler_t *data_handler = NULL;

            /* Handling the case where attachment is cached using a callback */

            if(mime_parser->callback_name && cached)
            {
                data_handler = axiom_data_handler_create(env, NULL, mime_type);
                if(data_handler)
                {
                    axiom_data_handler_set_cached(data_handler, env, AXIS2_TRUE);
                    axiom_data_handler_set_data_handler_type(data_handler, env,
                        AXIOM_DATA_HANDLER_TYPE_CALLBACK);
                }
            }

            /* Handling the case where attachment is cached to a file*/

            else if(mime_parser->attachment_dir && cached)
            {
                axis2_char_t *attachment_location = NULL;
                axis2_char_t *encoded_mime_id = NULL;

                /* Some times content-ids urls, hence we need to encode them 
                 * becasue we can't create files with / */

                encoded_mime_id = AXIS2_MALLOC(env->allocator, (sizeof(axis2_char_t)) * (strlen(
                    mime_id)));
                memset(encoded_mime_id, 0, strlen(mime_id));
                encoded_mime_id = axutil_url_encode(
                    env, encoded_mime_id, mime_id, (int)strlen(mime_id));
                if(!encoded_mime_id)
                {
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Mime Id encoding failed");
                    return AXIS2_FAILURE;
                }

                attachment_location = axutil_stracat(env, mime_parser->attachment_dir,
                    encoded_mime_id);

                AXIS2_FREE(env->allocator, encoded_mime_id);
                encoded_mime_id = NULL;

                if(attachment_location)
                {

                    data_handler = axiom_data_handler_create(env, attachment_location, mime_type);
                    if(data_handler)
                    {
                        axiom_data_handler_set_cached(data_handler, env, AXIS2_TRUE);

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

            /* Attachment is in memory, either it is small to be cached or
             * user does not provided the attachment cached directory */

            else if(mime_binary)
            {
                data_handler = axiom_data_handler_create(env, NULL, mime_type);
                if(data_handler)
                {
                    axiom_data_handler_set_binary_data(data_handler, env, mime_binary,
                        mime_binary_len - 2);
                }
            }
            axiom_data_handler_set_mime_id(data_handler, env, mime_id);

            axutil_hash_set(mime_parser->mime_parts_map, mime_id, AXIS2_HASH_KEY_STRING,
                data_handler);
            if(mime_type)
            {
                AXIS2_FREE(env->allocator, mime_type);
            }
        }
        else
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Mime Id or Mime rype not found");
            return AXIS2_FAILURE;
            /*axis2_char_t temp_boundry[1024];
             sprintf(temp_boundry, "--%s--", mime_boundary);
             if (body_mime && axutil_strstr(body_mime, temp_boundry))
             {
             break;
             }*/
        }
        return AXIS2_SUCCESS;
    }
    else
    {
        return AXIS2_FAILURE;
    }
}

/* This method will process the mime_headers for a particualr
 attacment and return the mime_id  */

static axis2_char_t *
axiom_mime_parser_process_mime_headers(
    const axutil_env_t *env,
    axiom_mime_parser_t *mime_parser,
    axis2_char_t **mime_id,
    axis2_char_t *mime_headers)
{
    axis2_char_t *id = NULL;
    axis2_char_t *type = NULL;
    axis2_char_t *pos = NULL;

    /* Get the MIME ID */
    if(mime_headers)
    {
        id = axutil_strcasestr(mime_headers, AXIOM_MIME_HEADER_CONTENT_ID);
        type = axutil_strcasestr(mime_headers, AXIOM_MIME_HEADER_CONTENT_TYPE);
        if(type)
        {
            axis2_char_t *end = NULL;
            axis2_char_t *temp_type = NULL;
            type += axutil_strlen(AXIOM_MIME_HEADER_CONTENT_TYPE);
            while(type && *type && *type != ':')
            {
                type++;
            }
            type++;
            while(type && *type && *type == ' ')
            {
                type++;
            }
            end = type;
            while(end && *end && !isspace((int)*end))
            {
                end++;
            }
            if((end - type) > 0)
            {
                temp_type = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * ((end - type) + 1));
                if(!temp_type)
                {
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                        "No memory. Failed in creating Content-Type");
                    return NULL;
                }
                memcpy(temp_type, type, (end - type));
                temp_type[end - type] = '\0';
                type = temp_type;
            }
        }
        if(id)
        {
            id += axutil_strlen(AXIOM_MIME_HEADER_CONTENT_ID);
            while(id && *id && *id != ':')
            {
                id++;
            }
            if(id)
            {
                while(id && *id && *id != '<')
                {
                    id++;
                }
                id++;
                pos = axutil_strstr(id, ">");
                if(pos)
                {
                    int mime_id_len = 0;
                    mime_id_len = (int)(pos - id);
                    *mime_id = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * mime_id_len + 1);
                    /* The MIME ID will be freed by the SOAP builder */
                    if(*mime_id)
                    {
                        memcpy(*mime_id, id, mime_id_len);
                        (*mime_id)[mime_id_len] = '\0';
                    }
                    else
                    {
                        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                            "No memory. Failed in creating MIME ID");
                        return NULL;
                    }
                }
            }
        }
        else
        {
            /*axis2_char_t temp_boundry[1024];
             sprintf(temp_boundry, "--%s--", mime_boundary);
             if (body_mime && axutil_strstr(body_mime, temp_boundry))
             {
             break;
             }*/
            return NULL;
        }
        return type;
    }
    else
    {
        return NULL;
    }
}

/*This is used to free some unwanted buffers. For example we did
 not want the buffers which contains the data before the soap
 envelope starts. */

static void
axiom_mime_parser_clear_buffers(
    const axutil_env_t *env,
    axis2_char_t **buf_list,
    int free_from,
    int free_to)
{
    int i = 0;

    for(i = free_from; i <= free_to; i++)
    {
        if(buf_list[i])
        {
            AXIS2_FREE(env->allocator, buf_list[i]);
            buf_list[i] = NULL;
        }
    }
    return;
}

/* Instead of caching to a file this method will cache it
 * to a buffer */

static axis2_status_t
axiom_mime_parser_cache_to_buffer(
    const axutil_env_t *env,
    axis2_char_t *buf,
    size_t buf_len,
    axiom_search_info_t *search_info,
    axiom_mime_parser_t *mime_parser)
{
    axis2_char_t *data_buffer = NULL;
    axis2_char_t *temp_buf = NULL;
    size_t mime_binary_len = 0;

    temp_buf = (axis2_char_t *)search_info->handler;
    mime_binary_len = search_info->binary_size + buf_len;

    if(mime_binary_len > 0)
    {
        data_buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (mime_binary_len));

        if(data_buffer)
        {
            if(temp_buf && search_info->binary_size > 0)
            {
                memcpy(data_buffer, temp_buf, search_info->binary_size);
                AXIS2_FREE(env->allocator, temp_buf);
                temp_buf = NULL;
            }
            memcpy(data_buffer + (search_info->binary_size), buf, buf_len);
            search_info->binary_size = mime_binary_len;
            search_info->handler = (void *)data_buffer;

            return AXIS2_SUCCESS;
        }
        else
        {
            return AXIS2_FAILURE;
        }
    }
    else
    {
        return AXIS2_FAILURE;
    }
}

AXIS2_EXTERN void AXIS2_CALL
axiom_mime_parser_set_buffer_size(
    axiom_mime_parser_t *mime_parser,
    const axutil_env_t *env,
    int size)
{
    mime_parser->buffer_size = size;
}

AXIS2_EXTERN void AXIS2_CALL
axiom_mime_parser_set_max_buffers(
    axiom_mime_parser_t *mime_parser,
    const axutil_env_t *env,
    int num)
{
    mime_parser->max_buffers = num;
}

AXIS2_EXTERN void AXIS2_CALL
axiom_mime_parser_set_attachment_dir(
    axiom_mime_parser_t *mime_parser,
    const axutil_env_t *env,
    axis2_char_t *attachment_dir)
{
    mime_parser->attachment_dir = attachment_dir;
}

/* Set the path of the caching callnack to be loaded */

AXIS2_EXTERN void AXIS2_CALL
axiom_mime_parser_set_caching_callback_name(
    axiom_mime_parser_t *mime_parser,
    const axutil_env_t *env,
    axis2_char_t *callback_name)
{
    mime_parser->callback_name = callback_name;
}

AXIS2_EXTERN void AXIS2_CALL
axiom_mime_parser_set_mime_boundary(
    axiom_mime_parser_t *mime_parser,
    const axutil_env_t *env,
    axis2_char_t *mime_boundary)
{
    mime_parser->mime_boundary = mime_boundary;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axiom_mime_parser_get_mime_boundary(
    axiom_mime_parser_t *mime_parser,
    const axutil_env_t *env)
{
    return mime_parser->mime_boundary;
}

/* Load the caching callback dll */

static void*
axiom_mime_parser_initiate_callback(
    axiom_mime_parser_t *mime_parser,
    const axutil_env_t *env,
    axis2_char_t *mime_id,
    void *user_param)
{
    axutil_dll_desc_t *dll_desc = NULL;
    axutil_param_t *impl_info_param = NULL;
    void *ptr = NULL;

    if(mime_parser->callback_name)
    {
        AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Trying to load module = %s",
            mime_parser->callback_name);
        dll_desc = axutil_dll_desc_create(env);
        axutil_dll_desc_set_name(dll_desc, env, mime_parser->callback_name);
        impl_info_param = axutil_param_create(env, NULL, dll_desc);
        /*Set the free function*/
        axutil_param_set_value_free(impl_info_param, env, axutil_dll_desc_free_void_arg);
        axutil_class_loader_init(env);
        ptr = axutil_class_loader_create_dll(env, impl_info_param);

        if(!ptr)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to load the module %s. ERROR",
                mime_parser->callback_name);
            return NULL;
        }

        mime_parser->mtom_caching_callback = (axiom_mtom_caching_callback_t *)ptr;
        mime_parser->mtom_caching_callback->param = impl_info_param;
        mime_parser->mtom_caching_callback->user_param = user_param;

        return AXIOM_MTOM_CACHING_CALLBACK_INIT_HANDLER(mime_parser->mtom_caching_callback, env,
            mime_id);
    }

    else
    {
        return NULL;
    }

}

/* This method will tell whether there are more data in the 
 * stream */

static axis2_bool_t
axiom_mime_parser_is_more_data(
    axiom_mime_parser_t *mime_parser,
    const axutil_env_t *env,
    axis2_callback_info_t *callback_info)
{
    /* In the case of axutil_http_chunked stream it is the 
     * end of chunk */

    if(callback_info->chunked_stream)
    {
        if(axutil_http_chunked_stream_get_end_of_chunks(callback_info->chunked_stream, env))
        {
            return AXIS2_FALSE;
        }
        else
        {
            return AXIS2_TRUE;
        }
    }

    /* When we are using content length or any wrapped 
     * stream it will be the unread_length */

    else if(callback_info->unread_len == 0)
    {
        return AXIS2_FALSE;
    }
    else
    {
        return AXIS2_TRUE;
    }
}

static axis2_status_t
axiom_mime_parser_cache_to_file(
    const axutil_env_t* env,
    axis2_char_t *buf,
    size_t buf_len,
    void *handler)
{
    size_t len = 0;
    FILE *fp = NULL;

    fp = (FILE *)handler;

    len = fwrite(buf, 1, buf_len, fp);
    if(len < 0)
    {
        return AXIS2_FAILURE;
    }
    else
    {
        return AXIS2_SUCCESS;
    }
}

