/*
 * 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_xpath.h>
#include "xpath_internals.h"
#include "xpath_internals_parser.h"
#include <ctype.h>

/* Compile an XPath expression */
int
axiom_xpath_compile(
    const axutil_env_t *env,
    axiom_xpath_expression_t* expr)
{
    if(!expr || !expr->expr_str)
    {
#ifdef AXIOM_XPATH_DEBUG
        printf("Expression in NULL.\n");
#endif

        return AXIS2_FAILURE;
    }

    expr->expr_len = (int)axutil_strlen(expr->expr_str);

    expr->operations = axutil_array_list_create(env, 0);

    expr->expr_ptr = 0;

    expr->start = axiom_xpath_compile_orexpr(env, expr);

    if(expr->start == AXIOM_XPATH_PARSE_ERROR)
    {
        return AXIOM_XPATH_PARSE_ERROR;
    }
    else
    {
#ifdef AXIOM_XPATH_DEBUG
        printf("Expression successfully parsed\n");
#endif

        return AXIOM_XPATH_PARSE_SUCCESS;
    }
}

/* Parse Or Expression */
int
axiom_xpath_compile_orexpr(
    const axutil_env_t *env,
    axiom_xpath_expression_t* expr)
{
    int op1, op2;

    if(!AXIOM_XPATH_HAS_MORE)
    {
        return AXIOM_XPATH_PARSE_END;
    }

    op1 = axiom_xpath_compile_andexpr(env, expr);

    if(op1 == AXIOM_XPATH_PARSE_ERROR)
    {
#ifdef AXIOM_XPATH_DEBUG
        printf(
            "Parse error: AndEpxr expected - %s\n",
            expr->expr_str + expr->expr_ptr);
#endif

        return AXIOM_XPATH_PARSE_ERROR;
    }

    AXIOM_XPATH_SKIP_WHITESPACES;

    while(AXIOM_XPATH_CURRENT == 'o' && AXIOM_XPATH_NEXT(1) == 'r')
    {
        AXIOM_XPATH_READ(2);
        AXIOM_XPATH_SKIP_WHITESPACES;

        op2 = axiom_xpath_compile_andexpr(env, expr);

        if(op2 == AXIOM_XPATH_PARSE_ERROR)
        {
#ifdef AXIOM_XPATH_DEBUG
            printf(
                "Parse error: AndEpxr expected - %s\n",
                expr->expr_str + expr->expr_ptr);
#endif

            return AXIOM_XPATH_PARSE_ERROR;
        }

        op1 = AXIOM_XPATH_PUSH(AXIOM_XPATH_OPERATION_OR_EXPR, op1, op2);

        AXIOM_XPATH_SKIP_WHITESPACES;
    }

    return op1;
}

/* Parse And Expression */
int
axiom_xpath_compile_andexpr(
    const axutil_env_t *env,
    axiom_xpath_expression_t* expr)
{
    int op1, op2;

    if(!AXIOM_XPATH_HAS_MORE)
    {
        return AXIOM_XPATH_PARSE_END;
    }

    op1 = axiom_xpath_compile_equalexpr(env, expr);

    if(op1 == AXIOM_XPATH_PARSE_ERROR)
    {
#ifdef AXIOM_XPATH_DEBUG
        printf(
            "Parse error: EqualityExpr expected - %s\n",
            expr->expr_str + expr->expr_ptr);
#endif

        return AXIOM_XPATH_PARSE_ERROR;
    }

    AXIOM_XPATH_SKIP_WHITESPACES;

    while(AXIOM_XPATH_CURRENT == 'a' && AXIOM_XPATH_NEXT(1) == 'n' && AXIOM_XPATH_NEXT(1) == 'd')
    {
        AXIOM_XPATH_READ(2);
        AXIOM_XPATH_SKIP_WHITESPACES;

        op2 = axiom_xpath_compile_equalexpr(env, expr);

        if(op2 == AXIOM_XPATH_PARSE_ERROR)
        {
#ifdef AXIOM_XPATH_DEBUG
            printf(
                "Parse error: EqualityExpr expected - %s\n",
                expr->expr_str + expr->expr_ptr);
#endif

            return AXIOM_XPATH_PARSE_ERROR;
        }

        op1 = AXIOM_XPATH_PUSH(AXIOM_XPATH_OPERATION_AND_EXPR, op1, op2);

        AXIOM_XPATH_SKIP_WHITESPACES;
    }

    return op1;
}

/* Parse Equality Expression */
int
axiom_xpath_compile_equalexpr(
    const axutil_env_t *env,
    axiom_xpath_expression_t* expr)
{
    int op1, op2;

    if(!AXIOM_XPATH_HAS_MORE)
    {
        return AXIOM_XPATH_PARSE_END;
    }

    op1 = axiom_xpath_compile_union(env, expr);

    if(op1 == AXIOM_XPATH_PARSE_ERROR)
    {
#ifdef AXIOM_XPATH_DEBUG
        printf(
            "Parse error: UnionExpr expected - %s\n",
            expr->expr_str + expr->expr_ptr);
#endif

        return AXIOM_XPATH_PARSE_ERROR;
    }

    while(AXIOM_XPATH_CURRENT == '=')
    {
        AXIOM_XPATH_SKIP_WHITESPACES;
        AXIOM_XPATH_READ(1);
        AXIOM_XPATH_SKIP_WHITESPACES;

        op2 = axiom_xpath_compile_union(env, expr);

        if(op2 == AXIOM_XPATH_PARSE_ERROR)
        {
#ifdef AXIOM_XPATH_DEBUG
            printf(
                "Parse error: UnionExpr expected - %s\n",
                expr->expr_str + expr->expr_ptr);
#endif

            return AXIOM_XPATH_PARSE_ERROR;
        }

        op1 = AXIOM_XPATH_PUSH(AXIOM_XPATH_OPERATION_EQUAL_EXPR, op1, op2);

        AXIOM_XPATH_SKIP_WHITESPACES;
    }

    return op1;
}

/* Parse Union */
int
axiom_xpath_compile_union(
    const axutil_env_t *env,
    axiom_xpath_expression_t* expr)
{
    int op1, op2;

    if(!AXIOM_XPATH_HAS_MORE)
    {
        return AXIOM_XPATH_PARSE_END;
    }

    op1 = axiom_xpath_compile_path_expression(env, expr);

    if(op1 == AXIOM_XPATH_PARSE_ERROR)
    {
#ifdef AXIOM_XPATH_DEBUG
        printf(
            "Parse error: PathExpr expected - %s\n",
            expr->expr_str + expr->expr_ptr);
#endif

        return AXIOM_XPATH_PARSE_ERROR;
    }

    AXIOM_XPATH_SKIP_WHITESPACES;

    if(AXIOM_XPATH_CURRENT == '|')
    {
        AXIOM_XPATH_READ(1);
        AXIOM_XPATH_SKIP_WHITESPACES;
        op2 = axiom_xpath_compile_union(env, expr);

        if(op2 == AXIOM_XPATH_PARSE_ERROR)
        {
#ifdef AXIOM_XPATH_DEBUG
            printf(
                "Parse error: UnionExpr expected - %s\n",
                expr->expr_str + expr->expr_ptr);
#endif

            return AXIOM_XPATH_PARSE_ERROR;
        }

        return AXIOM_XPATH_PUSH(AXIOM_XPATH_OPERATION_UNION, op1, op2);
    }

    /* Just a location path */
    return op1;
}

/* Compile Filter expression */
int
axiom_xpath_compile_filter(
    const axutil_env_t *env,
    axiom_xpath_expression_t* expr)
{
    int op = AXIOM_XPATH_PARSE_END;

    if(AXIOM_XPATH_CURRENT == '(')
    {
        AXIOM_XPATH_READ(1);
        op = axiom_xpath_compile_orexpr(env, expr);
        AXIOM_XPATH_SKIP_WHITESPACES;
        if(AXIOM_XPATH_CURRENT == ')')
        {
            AXIOM_XPATH_READ(1);
            return op;
        }
        else
        {
            return AXIOM_XPATH_PARSE_ERROR;
        }
    }
    else if(AXIOM_XPATH_CURRENT == '\'' || AXIOM_XPATH_CURRENT == '\"')
    {
        return AXIOM_XPATH_PUSH_PAR(AXIOM_XPATH_OPERATION_LITERAL, axiom_xpath_compile_literal(env,
            expr), NULL, AXIOM_XPATH_PARSE_END);
    }
    else if(isdigit(AXIOM_XPATH_CURRENT) || (AXIOM_XPATH_CURRENT == '.' && isdigit(
        AXIOM_XPATH_NEXT(1))))
    {
        return AXIOM_XPATH_PUSH_PAR(AXIOM_XPATH_OPERATION_NUMBER, axiom_xpath_compile_number(env,
            expr), NULL, AXIOM_XPATH_PARSE_END);
    }
    else if(AXIOM_XPATH_CURRENT == '$')
    {
#ifdef AXIOM_XPATH_DEBUG
        printf(
            "Parse error: Variables are not supported, yet -  %s\n",
            expr->expr_str + expr->expr_ptr);
#endif
    }
    else
    {
        return axiom_xpath_compile_function_call(env, expr);
    }

#ifdef AXIOM_XPATH_DEBUG
    printf(
        "Parse error: Invalid Filter expression -  %s\n",
        expr->expr_str + expr->expr_ptr);
#endif

    return AXIOM_XPATH_PARSE_ERROR;
    /* TODO: functions and variables */
}

/* Parse Path expression (not a location path) */
int
axiom_xpath_path_compile_path_expression_filter(
    const axutil_env_t *env,
    axiom_xpath_expression_t* expr)
{
    int op_filter, op_next;

    op_filter = axiom_xpath_compile_filter(env, expr);

    if(op_filter == AXIOM_XPATH_PARSE_ERROR)
    {
#ifdef AXIOM_XPATH_DEBUG
        printf(
            "Parse error: FilterExpr expected -  %s\n",
            expr->expr_str + expr->expr_ptr);
#endif

        return AXIOM_XPATH_PARSE_ERROR;
    }

    AXIOM_XPATH_SKIP_WHITESPACES;

    if(AXIOM_XPATH_NEXT(0) == '/' && AXIOM_XPATH_NEXT(1) == '/')
    {
        AXIOM_XPATH_READ(2);

        op_next = axiom_xpath_compile_relative_location(env, expr);

        if(op_next == AXIOM_XPATH_PARSE_ERROR)
        {
#ifdef AXIOM_XPATH_DEBUG
            printf(
                "Parse error: RelativeLocation expected -  %s\n",
                expr->expr_str + expr->expr_ptr);
#endif

            return AXIOM_XPATH_PARSE_ERROR;
        }

        op_next = AXIOM_XPATH_WRAP_SELF_DESCENDANT(op_next);
    }
    else if(AXIOM_XPATH_NEXT(0) == '/')
    {
        AXIOM_XPATH_READ(1);

        op_next = axiom_xpath_compile_relative_location(env, expr);

        if(op_next == AXIOM_XPATH_PARSE_ERROR)
        {
#ifdef AXIOM_XPATH_DEBUG
            printf(
                "Parse error: RelativeLocation expected -  %s\n",
                expr->expr_str + expr->expr_ptr);
#endif

            return AXIOM_XPATH_PARSE_ERROR;
        }
    }
    else
    {
        op_next = AXIOM_XPATH_PARSE_END;
    }

    return AXIOM_XPATH_PUSH(AXIOM_XPATH_OPERATION_PATH_EXPRESSION, op_filter, op_next);
}

/* Parse Path expression */
int
axiom_xpath_compile_path_expression(
    const axutil_env_t *env,
    axiom_xpath_expression_t* expr)
{
    int temp_ptr = expr->expr_ptr;
    axis2_char_t *name;
    axis2_char_t *node_types[] = { "comment", "node", "processing-instruction", "text" };
    axis2_char_t filter_start[] = { '$', '\'', '\"', '(' };
    int i;

    /* if  | FilterExpr
     | FilterExpr '/' RelativeLocationPath
     | FilterExpr '//' RelativeLocationPath */
    for(i = 0; i < 4; i++)
    {
        if(AXIOM_XPATH_CURRENT == filter_start[i])
        {
            return axiom_xpath_path_compile_path_expression_filter(env, expr);
        }
    }

    if(isdigit(AXIOM_XPATH_CURRENT) || (AXIOM_XPATH_CURRENT == '.' && isdigit(AXIOM_XPATH_NEXT(1))))
    {
        return axiom_xpath_path_compile_path_expression_filter(env, expr);
    }

    /* Funciton calls */
    name = axiom_xpath_compile_ncname(env, expr);
    AXIOM_XPATH_SKIP_WHITESPACES;

    if(name != NULL && AXIOM_XPATH_CURRENT == '(')
    {
        expr->expr_ptr = temp_ptr;
        for(i = 0; i < 4; i++)
        {
            /* If node type */
            if(axutil_strcmp(name, node_types[i]) == 0)
            {
                return axiom_xpath_compile_location_path(env, expr);
            }
        }

        return axiom_xpath_path_compile_path_expression_filter(env, expr);
    }

    expr->expr_ptr = temp_ptr;

    return axiom_xpath_compile_location_path(env, expr);
}

/* Parses Location Path */
int
axiom_xpath_compile_location_path(
    const axutil_env_t *env,
    axiom_xpath_expression_t* expr)
{
    int op1;
    axiom_xpath_operation_type_t opr;

    if(!AXIOM_XPATH_HAS_MORE)
    {
        return AXIOM_XPATH_PARSE_END;
    }

    if(AXIOM_XPATH_CURRENT == '/')
    {
        /* Descendent */
        if(AXIOM_XPATH_NEXT(1) == '/')
        {
            opr = AXIOM_XPATH_OPERATION_CONTEXT_NODE;
            AXIOM_XPATH_READ(2);
            AXIOM_XPATH_SKIP_WHITESPACES;

            op1 = axiom_xpath_compile_relative_location(env, expr);

            if(op1 == AXIOM_XPATH_PARSE_ERROR)
            {
#ifdef AXIOM_XPATH_DEBUG
                printf(
                    "Parse error: RelativeLocation expected -  %s\n",
                    expr->expr_str + expr->expr_ptr);
#endif

                return AXIOM_XPATH_PARSE_ERROR;
            }

            op1 = AXIOM_XPATH_WRAP_SELF_DESCENDANT(op1);
        }
        else
        {
            opr = AXIOM_XPATH_OPERATION_ROOT_NODE;
            AXIOM_XPATH_READ(1);

            op1 = axiom_xpath_compile_relative_location(env, expr);

            if(op1 == AXIOM_XPATH_PARSE_ERROR)
            {
#ifdef AXIOM_XPATH_DEBUG
                printf(
                    "Parse error: RelativeLocation expected -  %s\n",
                    expr->expr_str + expr->expr_ptr);
#endif

                return AXIOM_XPATH_PARSE_ERROR;
            }
        }
    }
    else
    {
        opr = AXIOM_XPATH_OPERATION_CONTEXT_NODE;

        op1 = axiom_xpath_compile_relative_location(env, expr);

        if(op1 == AXIOM_XPATH_PARSE_ERROR)
        {
#ifdef AXIOM_XPATH_DEBUG
            printf(
                "Parse error: RelativeLocation expected -  %s\n",
                expr->expr_str + expr->expr_ptr);
#endif

            return AXIOM_XPATH_PARSE_ERROR;
        }
    }

    if(op1 == AXIOM_XPATH_PARSE_ERROR)
    {
#ifdef AXIOM_XPATH_DEBUG
        printf(
            "Parse error: RelativeLocation expected -  %s\n",
            expr->expr_str + expr->expr_ptr);
#endif

        return AXIOM_XPATH_PARSE_ERROR;
    }

    return AXIOM_XPATH_PUSH(opr, op1, AXIOM_XPATH_PARSE_END);
}

/* Parses Relative Location Path */
int
axiom_xpath_compile_relative_location(
    const axutil_env_t *env,
    axiom_xpath_expression_t* expr)
{
    int op_step, op_next;

    if(!AXIOM_XPATH_HAS_MORE)
    {
        return AXIOM_XPATH_PARSE_END;
    }

    op_step = axiom_xpath_compile_step(env, expr);
    op_next = AXIOM_XPATH_PARSE_END; /* Will change if there are more steps */

    if(op_step == AXIOM_XPATH_PARSE_ERROR)
    {
#ifdef AXIOM_XPATH_DEBUG
        printf(
            "Parse error: Step expected -  %s\n",
            expr->expr_str + expr->expr_ptr);
#endif

        return AXIOM_XPATH_PARSE_ERROR;
    }

    AXIOM_XPATH_SKIP_WHITESPACES;

    if(AXIOM_XPATH_NEXT(0) == '/' && AXIOM_XPATH_NEXT(1) == '/')
    {
        AXIOM_XPATH_READ(2);

        op_next = axiom_xpath_compile_relative_location(env, expr);

        if(op_next == AXIOM_XPATH_PARSE_ERROR)
        {
#ifdef AXIOM_XPATH_DEBUG
            printf(
                "Parse error: RelativeLocation expected -  %s\n",
                expr->expr_str + expr->expr_ptr);
#endif

            return AXIOM_XPATH_PARSE_ERROR;
        }

        op_next = AXIOM_XPATH_WRAP_SELF_DESCENDANT(op_next);
    }
    else if(AXIOM_XPATH_NEXT(0) == '/')
    {
        AXIOM_XPATH_READ(1);

        op_next = axiom_xpath_compile_relative_location(env, expr);

        if(op_next == AXIOM_XPATH_PARSE_ERROR)
        {
#ifdef AXIOM_XPATH_DEBUG
            printf(
                "Parse error: RelativeLocation expected -  %s\n",
                expr->expr_str + expr->expr_ptr);
#endif

            return AXIOM_XPATH_PARSE_ERROR;
        }
    }

    /* End of the location path */
    if(op_next == AXIOM_XPATH_PARSE_END)
    {
        op_next = AXIOM_XPATH_PUSH(AXIOM_XPATH_OPERATION_RESULT, AXIOM_XPATH_PARSE_END,
            AXIOM_XPATH_PARSE_END);
    }

    return AXIOM_XPATH_PUSH(AXIOM_XPATH_OPERATION_STEP, op_step, op_next);
}

/* Parses Step */
int
axiom_xpath_compile_step(
    const axutil_env_t *env,
    axiom_xpath_expression_t* expr)
{
    int op_predicate = AXIOM_XPATH_PARSE_END;
    axiom_xpath_node_test_t *node_test;
    int temp_ptr;
    axis2_char_t *name = NULL;
    axiom_xpath_axis_t axis = AXIOM_XPATH_AXIS_NONE;

    AXIOM_XPATH_SKIP_WHITESPACES;

    /* . and .. */
    if(AXIOM_XPATH_CURRENT == '.')
    {
        if(AXIOM_XPATH_NEXT(1) == '.')
        {
            AXIOM_XPATH_READ(2);
            axis = AXIOM_XPATH_AXIS_PARENT;
        }
        else
        {
            AXIOM_XPATH_READ(1);
            axis = AXIOM_XPATH_AXIS_SELF;
        }

        return AXIOM_XPATH_PUSH_PAR(AXIOM_XPATH_OPERATION_NODE_TEST,
            axiom_xpath_create_node_test_node(env), axiom_xpath_create_axis(env, axis),
            op_predicate);
    }
    else if(AXIOM_XPATH_CURRENT == '@')
    {
        axis = AXIOM_XPATH_AXIS_ATTRIBUTE;

        AXIOM_XPATH_READ(1);
        AXIOM_XPATH_SKIP_WHITESPACES;
    }
    else
    {
        temp_ptr = expr->expr_ptr;

        name = axiom_xpath_compile_ncname(env, expr);

        if(name)
        {
            AXIOM_XPATH_SKIP_WHITESPACES;

            /* An axis */
            if(AXIOM_XPATH_CURRENT == ':' && AXIOM_XPATH_NEXT(1) == ':')
            {
                axis = axiom_xpath_get_axis(env, name);

                if(axis == AXIOM_XPATH_AXIS_NONE)
                {
#ifdef AXIOM_XPATH_DEBUG
                    printf("Parse error: Invalid axis -  %s\n", name);
#endif

                    return AXIOM_XPATH_PARSE_ERROR;
                }

                AXIOM_XPATH_READ(2);
                AXIOM_XPATH_SKIP_WHITESPACES;
            }
            else
            {
                axis = AXIOM_XPATH_AXIS_CHILD;

                expr->expr_ptr = temp_ptr;
            }
        }
        else
        {
            axis = AXIOM_XPATH_AXIS_CHILD;

            expr->expr_ptr = temp_ptr;
        }
    }

    node_test = axiom_xpath_compile_node_test(env, expr);

    if(!node_test)
    {
#ifdef AXIOM_XPATH_DEBUG
        printf(
            "Parse error: NodeTest expected -  %s\n",
            expr->expr_str + expr->expr_ptr);
#endif

        return AXIOM_XPATH_PARSE_ERROR;
    }

    op_predicate = axiom_xpath_compile_predicate(env, expr);

    if(op_predicate == AXIOM_XPATH_PARSE_ERROR)
    {
#ifdef AXIOM_XPATH_DEBUG
        printf(
            "Parse error: Predicate expected -  %s\n",
            expr->expr_str + expr->expr_ptr);
#endif

        AXIS2_FREE(env->allocator, node_test);
        return AXIOM_XPATH_PARSE_ERROR;
    }

    return AXIOM_XPATH_PUSH_PAR(AXIOM_XPATH_OPERATION_NODE_TEST, node_test,
        axiom_xpath_create_axis(env, axis), op_predicate);
}

axiom_xpath_node_test_t*
axiom_xpath_compile_node_test(
    const axutil_env_t *env,
    axiom_xpath_expression_t* expr)
{
    axis2_char_t* name;
    axiom_xpath_node_test_t *node_test;

    node_test = AXIS2_MALLOC(env->allocator, sizeof(axiom_xpath_node_test_t));
    node_test->type = AXIOM_XPATH_NODE_TEST_NONE;
    node_test->prefix = NULL;
    node_test->name = NULL;
    node_test->lit = NULL;

    if(AXIOM_XPATH_CURRENT == '*')
    {
        AXIOM_XPATH_READ(1);

        node_test->type = AXIOM_XPATH_NODE_TEST_ALL;

        return node_test;
    }

    name = axiom_xpath_compile_ncname(env, expr);

    if(!name)
    {
#ifdef AXIOM_XPATH_DEBUG
        printf(
            "Parse error: NCName expected -  %s\n",
            expr->expr_str + expr->expr_ptr);
#endif

        AXIS2_FREE(env->allocator, node_test);

        return NULL;
    }

    /* Node type */

    if(AXIOM_XPATH_CURRENT == '(')
    {
        AXIOM_XPATH_READ(1);

        if(axutil_strcmp(name, "comment") == 0)
        {
            node_test->type = AXIOM_XPATH_NODE_TYPE_COMMENT;
        }
        if(axutil_strcmp(name, "node") == 0)
        {
            node_test->type = AXIOM_XPATH_NODE_TYPE_NODE;
        }
        if(axutil_strcmp(name, "processing-instruction") == 0)
        {
            node_test->type = AXIOM_XPATH_NODE_TYPE_PI;

            node_test->lit = axiom_xpath_compile_literal(env, expr);
        }
        if(axutil_strcmp(name, "text") == 0)
        {
            node_test->type = AXIOM_XPATH_NODE_TYPE_TEXT;
        }

        AXIOM_XPATH_SKIP_WHITESPACES;

        if(node_test->type == AXIOM_XPATH_NODE_TEST_NONE || AXIOM_XPATH_CURRENT != ')')
        {
#ifdef AXIOM_XPATH_DEBUG
            printf("Parse error: Invalid node type -  %s\n", name);
#endif

            AXIS2_FREE(env->allocator, node_test);

            return NULL;
        }

        AXIOM_XPATH_READ(1);
    }
    else
    {
        node_test->type = AXIOM_XPATH_NODE_TEST_STANDARD;

        if(AXIOM_XPATH_CURRENT == ':')
        {
            AXIOM_XPATH_READ(1);

            node_test->prefix = name;

            if(AXIOM_XPATH_CURRENT == '*')
            {
                AXIOM_XPATH_READ(1);

                node_test->type = AXIOM_XPATH_NODE_TEST_ALL;

                return node_test;
            }

            node_test->name = axiom_xpath_compile_ncname(env, expr);

            if(!node_test->name)
            {
#ifdef AXIOM_XPATH_DEBUG
                printf(
                    "Parse error: NCName expected -  %s\n",
                    expr->expr_str + expr->expr_ptr);
#endif

                AXIS2_FREE(env->allocator, node_test);

                return NULL;
            }
        }
        else
        {
            node_test->name = name;
        }
    }

    return node_test;
}

int
axiom_xpath_compile_function_call(
    const axutil_env_t *env,
    axiom_xpath_expression_t* expr)
{
    axis2_char_t *name;
    int op1 = AXIOM_XPATH_PARSE_END;

    name = axiom_xpath_compile_ncname(env, expr);

    if(!name)
    {
#ifdef AXIOM_XPATH_DEBUG
        printf(
            "Parse error: NCName expected -  %s\n",
            expr->expr_str + expr->expr_ptr);
#endif

        return AXIOM_XPATH_PARSE_ERROR;
    }

    if(AXIOM_XPATH_CURRENT != '(')
    {
#ifdef AXIOM_XPATH_DEBUG
        printf(
            "Parse error: '(' expected -  %s\n",
            expr->expr_str + expr->expr_ptr);
#endif

        return AXIOM_XPATH_PARSE_ERROR;
    }

    AXIOM_XPATH_READ(1);

    AXIOM_XPATH_SKIP_WHITESPACES;

    if(AXIOM_XPATH_CURRENT != ')')
    {
        op1 = axiom_xpath_compile_argument(env, expr);
    }

    if(AXIOM_XPATH_CURRENT != ')')
    {
#ifdef AXIOM_XPATH_DEBUG
        printf(
            "Parse error: ')' expected -  %s\n",
            expr->expr_str + expr->expr_ptr);
#endif

        return AXIOM_XPATH_PARSE_ERROR;
    }

    AXIOM_XPATH_READ(1);

    return AXIOM_XPATH_PUSH_PAR(AXIOM_XPATH_OPERATION_FUNCTION_CALL, name, NULL, op1);
}

int
axiom_xpath_compile_argument(
    const axutil_env_t *env,
    axiom_xpath_expression_t* expr)
{
    int op1 = AXIOM_XPATH_PARSE_END;
    int op2 = AXIOM_XPATH_PARSE_END;

    op1 = axiom_xpath_compile_orexpr(env, expr);

    AXIOM_XPATH_SKIP_WHITESPACES;

    if(AXIOM_XPATH_CURRENT == ',')
    {
        op2 = axiom_xpath_compile_argument(env, expr);
    }

    return AXIOM_XPATH_PUSH(AXIOM_XPATH_OPERATION_ARGUMENT, op1, op2);
}

axiom_xpath_node_test_t*
axiom_xpath_create_node_test_all(
    const axutil_env_t *env)
{
    axiom_xpath_node_test_t *node_test;

    node_test = AXIS2_MALLOC(env->allocator, sizeof(axiom_xpath_node_test_t));
    node_test->type = AXIOM_XPATH_NODE_TEST_ALL;
    node_test->prefix = NULL;
    node_test->name = NULL;
    node_test->lit = NULL;

    return node_test;
}

axiom_xpath_node_test_t*
axiom_xpath_create_node_test_node(
    const axutil_env_t *env)
{
    axiom_xpath_node_test_t *node_test;

    node_test = AXIS2_MALLOC(env->allocator, sizeof(axiom_xpath_node_test_t));
    node_test->type = AXIOM_XPATH_NODE_TYPE_NODE;
    node_test->prefix = NULL;
    node_test->name = NULL;
    node_test->lit = NULL;

    return node_test;
}

double*
axiom_xpath_compile_number(
    const axutil_env_t *env,
    axiom_xpath_expression_t* expr)
{
    double *ret = AXIS2_MALLOC(env->allocator, sizeof(double));
    double res = 0, dec = 0.1;
    axis2_bool_t dot = AXIS2_FALSE;

    *ret = 0;

    while(1)
    {
        if(isdigit(AXIOM_XPATH_CURRENT))
        {
            if(!dot)
            {
                res = res * 10 + (AXIOM_XPATH_CURRENT - '0');
            }
            else
            {
                res += dec * (AXIOM_XPATH_CURRENT - '0');
                dec /= 10;
            }
        }
        else if(AXIOM_XPATH_CURRENT == '.')
        {
            if(dot)
            {
                return ret;
            }
            else
            {
                dot = AXIS2_TRUE;
                dec = 0.1;
            }
        }
        else
        {
            break;
        }

        AXIOM_XPATH_READ(1);
    }

    *ret = res;
    return ret;
}

axis2_char_t*
axiom_xpath_compile_literal(
    const axutil_env_t *env,
    axiom_xpath_expression_t* expr)
{
    axis2_char_t lit[255];
    int i = 0;
    axis2_char_t del;

    if(AXIOM_XPATH_CURRENT == '\"')
    {
        del = '\"';
    }
    else if(AXIOM_XPATH_CURRENT == '\'')
    {
        del = '\'';
    }
    else
        return NULL;

    AXIOM_XPATH_READ(1);

    while(AXIOM_XPATH_HAS_MORE && AXIOM_XPATH_CURRENT != del)
    {
        lit[i] = AXIOM_XPATH_CURRENT;
        AXIOM_XPATH_READ(1);
        ++i;
    }

    if(AXIOM_XPATH_HAS_MORE)
    {
        AXIOM_XPATH_READ(1);
    }

    lit[i] = '\0';

    return axutil_strdup(env, lit);

}

/* Get axis for name */
axiom_xpath_axis_t
axiom_xpath_get_axis(
    const axutil_env_t *env,
    axis2_char_t* name)
{
    if(axutil_strcmp(name, "child") == 0)
    {
        return AXIOM_XPATH_AXIS_CHILD;
    }
    else if(axutil_strcmp(name, "descendant") == 0)
    {
        return AXIOM_XPATH_AXIS_DESCENDANT;
    }
    else if(axutil_strcmp(name, "parent") == 0)
    {
        return AXIOM_XPATH_AXIS_PARENT;
    }
    else if(axutil_strcmp(name, "ancestor") == 0)
    {
        return AXIOM_XPATH_AXIS_ANCESTOR;
    }
    else if(axutil_strcmp(name, "following-sibling") == 0)
    {
        return AXIOM_XPATH_AXIS_FOLLOWING_SIBLING;
    }
    else if(axutil_strcmp(name, "preceding-sibling") == 0)
    {
        return AXIOM_XPATH_AXIS_PRECEDING_SIBLING;
    }
    else if(axutil_strcmp(name, "following") == 0)
    {
        return AXIOM_XPATH_AXIS_FOLLOWING;
    }
    else if(axutil_strcmp(name, "preceding") == 0)
    {
        return AXIOM_XPATH_AXIS_PRECEDING;
    }
    else if(axutil_strcmp(name, "attribute") == 0)
    {
        return AXIOM_XPATH_AXIS_ATTRIBUTE;
    }
    else if(axutil_strcmp(name, "namespace") == 0)
    {
        return AXIOM_XPATH_AXIS_NAMESPACE;
    }
    else if(axutil_strcmp(name, "self") == 0)
    {
        return AXIOM_XPATH_AXIS_SELF;
    }
    else if(axutil_strcmp(name, "descendant-or-self") == 0)
    {
        return AXIOM_XPATH_AXIS_DESCENDANT_OR_SELF;
    }
    else if(axutil_strcmp(name, "ancestor-or-self") == 0)
    {
        return AXIOM_XPATH_AXIS_ANCESTOR_OR_SELF;
    }
    else
    {
#ifdef AXIOM_XPATH_DEBUG
        printf("Unidentified axis name.\n");
#endif

        return AXIOM_XPATH_AXIS_NONE;
    }
}

/* Parse Predicate */
int
axiom_xpath_compile_predicate(
    const axutil_env_t *env,
    axiom_xpath_expression_t* expr)
{
    int op1, op_next_predicate;

    AXIOM_XPATH_SKIP_WHITESPACES;

    if(!AXIOM_XPATH_HAS_MORE || AXIOM_XPATH_CURRENT != '[')
    {
        return AXIOM_XPATH_PARSE_END;
    }

    AXIOM_XPATH_READ(1);
    AXIOM_XPATH_SKIP_WHITESPACES;

    /* A PredicateExpr is evaluated by evaluating the Expr and converting the result to a boolean.
     If the result is a number, the result will be converted to true if the number is equal to the
     context position and will be converted to false otherwise; if the result is not a number,
     then the result will be converted as if by a call to the boolean function. */

    op1 = axiom_xpath_compile_orexpr(env, expr);

    if(op1 == AXIOM_XPATH_PARSE_ERROR)
    {
#ifdef AXIOM_XPATH_DEBUG
        printf(
            "Parse error: EqualExpr expected -  %s\n",
            expr->expr_str + expr->expr_ptr);
#endif

        return AXIOM_XPATH_PARSE_ERROR;
    }

    AXIOM_XPATH_SKIP_WHITESPACES;

    if(AXIOM_XPATH_CURRENT != ']')
    {
#ifdef AXIOM_XPATH_DEBUG
        printf(
            "Parse error: ] expected -  %s\n",
            expr->expr_str + expr->expr_ptr);
#endif

        return AXIOM_XPATH_PARSE_ERROR;
    }

    AXIOM_XPATH_READ(1);

    op_next_predicate = axiom_xpath_compile_predicate(env, expr);

    if(op_next_predicate == AXIOM_XPATH_PARSE_ERROR)
    {
#ifdef AXIOM_XPATH_DEBUG
        printf(
            "Parse error: Predicate expected -  %s\n",
            expr->expr_str + expr->expr_ptr);
#endif

        return AXIOM_XPATH_PARSE_ERROR;
    }

    return AXIOM_XPATH_PUSH(AXIOM_XPATH_OPERATION_PREDICATE, op1, op_next_predicate);
}

/* Parse Node Test */
axis2_char_t *
axiom_xpath_compile_ncname(
    const axutil_env_t *env,
    axiom_xpath_expression_t* expr)
{
    axis2_char_t name[255];
    int i = 0;

    if(!isalpha(AXIOM_XPATH_CURRENT) && AXIOM_XPATH_CURRENT != '_')
    {
        return NULL;
    }

    /* TODO: Add CombiningChar and Extender
     * Link http://www.w3.org/TR/REC-xml/#NT-NameChar */
    while(AXIOM_XPATH_HAS_MORE && (isalnum(AXIOM_XPATH_CURRENT) || AXIOM_XPATH_CURRENT == '_'
        || AXIOM_XPATH_CURRENT == '.' || AXIOM_XPATH_CURRENT == '-'))
    {
        name[i] = AXIOM_XPATH_CURRENT;
        AXIOM_XPATH_READ(1);
        ++i;
    }

    name[i] = '\0';

    return name;
}

/* Supporting functions */
int
axiom_xpath_add_operation(
    const axutil_env_t *env,
    axiom_xpath_expression_t* expr,
    axiom_xpath_operation_type_t op_type,
    int op1,
    int op2,
    void *par1,
    void *par2)
{
    axiom_xpath_operation_t *op;

    op = AXIS2_MALLOC(env->allocator, sizeof(axiom_xpath_operation_t));
    op->opr = op_type;
    op->op1 = op1;
    op->op2 = op2;

    op->pos = 0;

    op->par1 = par1;
    op->par2 = par2;

    axutil_array_list_add(expr->operations, env, op);

    return axutil_array_list_size(expr->operations, env) - 1;
}

axiom_xpath_axis_t *
axiom_xpath_create_axis(
    const axutil_env_t *env,
    axiom_xpath_axis_t axis)
{
    axiom_xpath_axis_t *axis_p = AXIS2_MALLOC(env->allocator, sizeof(axiom_xpath_axis_t));

    *axis_p = axis;
    return axis_p;
}
