/*
 * 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)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Expression in NULL.");

        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
    {
        AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Expression successfully parsed");

        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)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "Parse error: AndEpxr expected - %s",
            expr->expr_str + expr->expr_ptr);

        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)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                "Parse error: AndEpxr expected - %s",
                expr->expr_str + expr->expr_ptr);

            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)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
             "Parse error: EqualityExpr expected - %s",
            expr->expr_str + expr->expr_ptr);

        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)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            	"Parse error: EqualityExpr expected - %s",
                expr->expr_str + expr->expr_ptr);

            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)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
        	"Parse error: UnionExpr expected - %s",
            expr->expr_str + expr->expr_ptr);

        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)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            	"Parse error: UnionExpr expected - %s",
                expr->expr_str + expr->expr_ptr);

            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)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
        	"Parse error: PathExpr expected - %s",
            expr->expr_str + expr->expr_ptr);

        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)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            	"Parse error: UnionExpr expected - %s",
                expr->expr_str + expr->expr_ptr);

            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 == '$')
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
        	"Parse error: Variables are not supported, yet -  %s",
            expr->expr_str + expr->expr_ptr);
    }
    else
    {
        return axiom_xpath_compile_function_call(env, expr);
    }

    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
    	"Parse error: Invalid Filter expression -  %s",
        expr->expr_str + expr->expr_ptr);

    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)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
        	"Parse error: FilterExpr expected -  %s",
            expr->expr_str + expr->expr_ptr);

        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)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            	"Parse error: RelativeLocation expected -  %s",
                expr->expr_str + expr->expr_ptr);

            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)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            	"Parse error: RelativeLocation expected -  %s",
                expr->expr_str + expr->expr_ptr);

            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)
            {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                	"Parse error: RelativeLocation expected -  %s",
                    expr->expr_str + expr->expr_ptr);

                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)
            {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                	"Parse error: RelativeLocation expected -  %s",
                    expr->expr_str + expr->expr_ptr);

                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)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            	"Parse error: RelativeLocation expected -  %s",
                expr->expr_str + expr->expr_ptr);

            return AXIOM_XPATH_PARSE_ERROR;
        }
    }

    if(op1 == AXIOM_XPATH_PARSE_ERROR)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
        	"Parse error: RelativeLocation expected -  %s",
            expr->expr_str + expr->expr_ptr);

        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)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
        	"Parse error: Step expected -  %s",
            expr->expr_str + expr->expr_ptr);

        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)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            	"Parse error: RelativeLocation expected -  %s",
                expr->expr_str + expr->expr_ptr);

            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)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            	"Parse error: RelativeLocation expected -  %s",
                expr->expr_str + expr->expr_ptr);

            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 = NULL;
    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)
                {
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                    	"Parse error: Invalid axis -  %s", name);
                    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)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
        	"Parse error: NodeTest expected -  %s",
            expr->expr_str + expr->expr_ptr);

        return AXIOM_XPATH_PARSE_ERROR;
    }

    op_predicate = axiom_xpath_compile_predicate(env, expr);

    if(op_predicate == AXIOM_XPATH_PARSE_ERROR)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
        	"Parse error: Predicate expected -  %s",
            expr->expr_str + expr->expr_ptr);

        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)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
        	"Parse error: NCName expected -  %s",
            expr->expr_str + expr->expr_ptr);

        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;
            node_test->name = name;
        }

        AXIOM_XPATH_SKIP_WHITESPACES;

        if(node_test->type == AXIOM_XPATH_NODE_TEST_NONE || AXIOM_XPATH_CURRENT != ')')
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            	"Parse error: Invalid node type -  %s", name);
            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)
            {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                	"Parse error: NCName expected -  %s",
                    expr->expr_str + expr->expr_ptr);

                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)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
        	"Parse error: NCName expected -  %s",
            expr->expr_str + expr->expr_ptr);

        return AXIOM_XPATH_PARSE_ERROR;
    }

    if(AXIOM_XPATH_CURRENT != '(')
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
        	"Parse error: '(' expected -  %s",
            expr->expr_str + expr->expr_ptr);
        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 != ')')
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
        	"Parse error: ')' expected -  %s",
            expr->expr_str + expr->expr_ptr);
        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 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
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unidentified axis name.");

        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)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
        	"Parse error: EqualExpr expected -  %s",
            expr->expr_str + expr->expr_ptr);

        return AXIOM_XPATH_PARSE_ERROR;
    }

    AXIOM_XPATH_SKIP_WHITESPACES;

    if(AXIOM_XPATH_CURRENT != ']')
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
        	"Parse error: ] expected -  %s",
            expr->expr_str + expr->expr_ptr);

        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)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
        	"Parse error: Predicate expected -  %s",
            expr->expr_str + expr->expr_ptr);

        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;
}
