/*
 * 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)
    {
        axutil_array_list_free(expr->operations, env);

        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

        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 axutil_strdup(env, 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;
}
