/*
 * 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_engine.h"
#include "xpath_internals_iterators.h"

/* Evaluates the expath expression */
axiom_xpath_result_t *
axiom_xpath_run(
    axiom_xpath_context_t *context)
{
    axiom_xpath_result_t* res;

    /* Initialize result ret */
    res = AXIS2_MALLOC(context->env->allocator, sizeof(axiom_xpath_result_t));

    res->flag = 0;

    res->nodes = axutil_array_list_create(context->env, 0);

    /* Expression is empty */
    if(context->expr->start == AXIOM_XPATH_PARSE_END)
    {
        return res;
    }

    context->stack = axutil_stack_create(context->env);

    axiom_xpath_evaluate_operation(context, context->expr->start);

    /* Add nodes to the result set from the stack */
    while(axutil_stack_size(context->stack, context->env) > 0)
    {
        axutil_array_list_add(res->nodes, context->env,
            axutil_stack_pop(context->stack, context->env));
    }

    axutil_stack_free(context->stack, context->env);

    return res;
}

/* Casting functions; these make use of the casting functions defined in xpath.h */
void
axiom_xpath_cast_boolean(
    axiom_xpath_result_node_t *node,
    axiom_xpath_context_t *context)
{
    axis2_bool_t v = axiom_xpath_cast_node_to_boolean(context->env, node);

    AXIOM_XPATH_CAST_SET_VALUE(axis2_bool_t, v);

    node->type = AXIOM_XPATH_TYPE_BOOLEAN;
}

void
axiom_xpath_cast_number(
    axiom_xpath_result_node_t *node,
    axiom_xpath_context_t *context)
{
    double v = axiom_xpath_cast_node_to_number(context->env, node);

    AXIOM_XPATH_CAST_SET_VALUE(double, v);

    node->type = AXIOM_XPATH_TYPE_NUMBER;
}

void
axiom_xpath_cast_string(
    axiom_xpath_result_node_t *node,
    axiom_xpath_context_t *context)
{
    node->value = axiom_xpath_cast_node_to_string(context->env, node);

    node->type = AXIOM_XPATH_TYPE_TEXT;
}

/* Evaluate whether two results are equal

 If either node is a boolean other is casted to a boolean;
 Otherwise, if either node is a number other is casted to a number;
 Otherwise, both nodes are casted to strings.*/
axis2_bool_t
axiom_xpath_compare_equal(
    axiom_xpath_result_node_t *node1,
    axiom_xpath_result_node_t *node2,
    axiom_xpath_context_t *context)
{
    if(node1->type == AXIOM_XPATH_TYPE_BOOLEAN || node2->type == AXIOM_XPATH_TYPE_BOOLEAN)
    {
        axiom_xpath_cast_boolean(node1, context);
        axiom_xpath_cast_boolean(node2, context);

        if(*(axis2_bool_t*)(node1->value) == *(axis2_bool_t*)(node2->value))
        {
            return AXIS2_TRUE;
        }
        else
        {
            return AXIS2_FALSE;
        }
    }

    if(node1->type == AXIOM_XPATH_TYPE_NUMBER || node2->type == AXIOM_XPATH_TYPE_NUMBER)
    {
        axiom_xpath_cast_number(node1, context);
        axiom_xpath_cast_number(node2, context);

        if(*(double *)(node1->value) == *(double *)(node2->value))
        {
            return AXIS2_TRUE;
        }
        else
        {
            return AXIS2_FALSE;
        }
    }

    axiom_xpath_cast_string(node1, context);
    axiom_xpath_cast_string(node2, context);

    if(axutil_strcmp((axis2_char_t *)(node1->value), (axis2_char_t *)(node2->value)) == 0)
    {
        return AXIS2_TRUE;
    }
    else
    {
        return AXIS2_FALSE;
    }
}

/* Convert a node set to boolean */
axis2_bool_t
axiom_xpath_convert_to_boolean(
    axutil_array_list_t *node_set,
    axiom_xpath_context_t *context)
{
    if(axutil_array_list_size(node_set, context->env) == 0)
    {
        return AXIS2_FALSE;
    }
    else if(axutil_array_list_size(node_set, context->env) >= 2)
    {
        return AXIS2_TRUE;
    }
    else
    {
        axiom_xpath_result_node_t *node = axutil_array_list_get(node_set, context->env, 0);
        axiom_xpath_cast_boolean(node, context);

        return *(axis2_bool_t *)node->value;
    }
}

/* Operators */

/* Literal */
int
axiom_xpath_literal_operator(
    axiom_xpath_context_t *context,
    axiom_xpath_operation_t * op)
{
    axiom_xpath_result_node_t *node;

    node = AXIS2_MALLOC(context->env->allocator, sizeof(axiom_xpath_result_node_t));

    /* Set the context node to NULL */
    /* This is not required; it gives some problems */
    /* context->node = NULL;*/

    node->value = op->par1;
    node->type = AXIOM_XPATH_TYPE_TEXT;

    axutil_stack_push(context->stack, context->env, node);

    return 1;
}

/* Number */
int
axiom_xpath_number_operator(
    axiom_xpath_context_t *context,
    axiom_xpath_operation_t * op)
{
    axiom_xpath_result_node_t *node;

    node = AXIS2_MALLOC(context->env->allocator, sizeof(axiom_xpath_result_node_t));

    /* Set the context node to NULL */
    /* This is not required; it gives some problems */
    /* context->node = NULL;*/

    node->value = op->par1;
    node->type = AXIOM_XPATH_TYPE_NUMBER;

    axutil_stack_push(context->stack, context->env, node);

    return 1;
}

/* Path Expression */
int
axiom_xpath_path_expression_operator(
    axiom_xpath_context_t *context,
    axiom_xpath_operation_t * op)
{
    int filter_res_n, n_nodes = 0;
    axiom_xpath_operation_t *rel_loc_op;
    axiom_xpath_operator_t rel_loc_func;
    axutil_array_list_t *arr;
    axiom_xpath_result_node_t *res_node;
    int i;

    /* Filter operation */
    if(op->op1 == AXIOM_XPATH_PARSE_END)
    {
        return 0;
    }

    filter_res_n = axiom_xpath_evaluate_operation(context, op->op1);

    /* Relative location path */
    if(op->op2 == AXIOM_XPATH_PARSE_END)
    {
        return filter_res_n;
    }

    rel_loc_op = AXIOM_XPATH_OPR_GET(op->op2);
    rel_loc_func = axiom_xpath_get_operator(rel_loc_op);

    /* Array list to add all results from the filter expression */
    arr = axutil_array_list_create(context->env, 0);

    for(i = 0; i < filter_res_n; i++)
    {
        axutil_array_list_add(arr, context->env, axutil_stack_pop(context->stack, context->env));
    }

    /* Evaluate relative location path for all results from the
     filter expression */
    for(i = 0; i < axutil_array_list_size(arr, context->env); i++)
    {
        res_node = (axiom_xpath_result_node_t *)axutil_array_list_get(arr, context->env, i);

        if(res_node->type == AXIOM_XPATH_TYPE_NODE)
        {
            context->node = (axiom_node_t *)res_node->value;
            context->position = i + 1;
            context->size = filter_res_n;

            n_nodes += rel_loc_func(context, rel_loc_op);
        }

        AXIS2_FREE(context->env->allocator, res_node);
    }

    axutil_array_list_free(arr, context->env);

    return n_nodes;
}

/* Or Expression */
int
axiom_xpath_orexpr_operator(
    axiom_xpath_context_t *context,
    axiom_xpath_operation_t * op)
{
    axiom_xpath_result_node_t *node;
    axiom_xpath_result_node_t *res_node;
    int n_nodes[2];
    int i, j;
    int op12[2];
    axutil_array_list_t *arr[2];

    op12[0] = op->op1;
    op12[1] = op->op2;

    /* Evaluate both operands and get number of results */
    for(i = 0; i < 2; i++)
    {
        if(op12[i] == AXIOM_XPATH_PARSE_END)
        {
            continue;
        }

        n_nodes[i] = axiom_xpath_evaluate_operation(context, op12[i]);
    }

    for(i = 1; i >= 0; i--)
    {
        arr[i] = axutil_array_list_create(context->env, 0);

        for(j = 0; j < n_nodes[i]; j++)
        {
            axutil_array_list_add(arr[i], context->env, axutil_stack_pop(context->stack,
                context->env));
        }
    }

    node = AXIS2_MALLOC(context->env->allocator, sizeof(axiom_xpath_result_node_t));

    node->type = AXIOM_XPATH_TYPE_BOOLEAN;
    node->value = NULL;

    /* Checking equality
     - If any node from the first set is equal to any node from the second set
     the result is true */
    if(axiom_xpath_convert_to_boolean(arr[0], context) || axiom_xpath_convert_to_boolean(arr[1],
        context))
    {
        AXIOM_XPATH_CAST_SET_VALUE(axis2_bool_t, AXIS2_TRUE);

        axutil_stack_push(context->stack, context->env, node);
    }
    else
    {
        AXIOM_XPATH_CAST_SET_VALUE(axis2_bool_t, AXIS2_FALSE);

        axutil_stack_push(context->stack, context->env, node);
    }

    for (i = 1; i >= 0; i--)
    {
        for (j = 0; j < n_nodes[i]; j++)
        {
            res_node = (axiom_xpath_result_node_t *)axutil_array_list_get(arr[i], context->env, j);
            AXIS2_FREE(context->env->allocator, res_node);
        }

        axutil_array_list_free(arr[i], context->env);
    }

    return 1;
}

/* And Expression */
int
axiom_xpath_andexpr_operator(
    axiom_xpath_context_t *context,
    axiom_xpath_operation_t * op)
{
    axiom_xpath_result_node_t *node;
    axiom_xpath_result_node_t *res_node;
    int n_nodes[2];
    int i, j;
    int op12[2];
    axutil_array_list_t *arr[2];

    op12[0] = op->op1;
    op12[1] = op->op2;

    /* Evaluate both operands and get number of results */
    for(i = 0; i < 2; i++)
    {
        if(op12[i] == AXIOM_XPATH_PARSE_END)
        {
            continue;
        }

        n_nodes[i] = axiom_xpath_evaluate_operation(context, op12[i]);
    }

    for(i = 1; i >= 0; i--)
    {
        arr[i] = axutil_array_list_create(context->env, 0);

        for(j = 0; j < n_nodes[i]; j++)
        {
            axutil_array_list_add(arr[i], context->env, axutil_stack_pop(context->stack,
                context->env));
        }
    }

    node = AXIS2_MALLOC(context->env->allocator, sizeof(axiom_xpath_result_node_t));

    node->type = AXIOM_XPATH_TYPE_BOOLEAN;
    node->value = NULL;

    /* Checking equality
     - If any node from the first set is equal to any node from the second set
     the result is true */
    if(axiom_xpath_convert_to_boolean(arr[0], context) && axiom_xpath_convert_to_boolean(arr[1],
        context))
    {
        AXIOM_XPATH_CAST_SET_VALUE(axis2_bool_t, AXIS2_TRUE);

        axutil_stack_push(context->stack, context->env, node);
    }
    else
    {
        AXIOM_XPATH_CAST_SET_VALUE(axis2_bool_t, AXIS2_FALSE);

        axutil_stack_push(context->stack, context->env, node);
    }

    for (i = 1; i >= 0; i--)
    {
        for (j = 0; j < n_nodes[i]; j++)
        {
            res_node = (axiom_xpath_result_node_t *)axutil_array_list_get(arr[i], context->env, j);
            AXIS2_FREE(context->env->allocator, res_node);
        }

        axutil_array_list_free(arr[i], context->env);
    }

    return 1;
}

/* Equal Expression */
int
axiom_xpath_equalexpr_operator(
    axiom_xpath_context_t *context,
    axiom_xpath_operation_t * op)
{
    axiom_xpath_result_node_t *node;
    axiom_xpath_result_node_t *res_node;
    int n_nodes[2];
    int i, j;
    int op12[2];
    axutil_array_list_t *arr[2];

    op12[0] = op->op1;
    op12[1] = op->op2;

    /* Evaluate both operands and get number of results */
    for(i = 0; i < 2; i++)
    {
        if(op12[i] == AXIOM_XPATH_PARSE_END)
        {
            continue;
        }

        n_nodes[i] = axiom_xpath_evaluate_operation(context, op12[i]);
    }

    for(i = 1; i >= 0; i--)
    {
        arr[i] = axutil_array_list_create(context->env, 0);

        for(j = 0; j < n_nodes[i]; j++)
        {
            axutil_array_list_add(arr[i], context->env, axutil_stack_pop(context->stack,
                context->env));
        }
    }

    node = AXIS2_MALLOC(context->env->allocator, sizeof(axiom_xpath_result_node_t));

    node->type = AXIOM_XPATH_TYPE_BOOLEAN;
    node->value = NULL;

    /* Checking equality
     - If any node from the first set is equal to any node from the second set
     the result is true */
    for(i = 0; i < n_nodes[0]; i++)
    {
        for(j = 0; j < n_nodes[1]; j++)
        {
            if(axiom_xpath_compare_equal(axutil_array_list_get(arr[0], context->env, i),
                axutil_array_list_get(arr[1], context->env, j), context))
            {
                AXIOM_XPATH_CAST_SET_VALUE(axis2_bool_t, AXIS2_TRUE);

                axutil_stack_push(context->stack, context->env, node);

                break;
            }
        }

        if(j < n_nodes[1])
        {
            break;
        }
    }

    if(!node->value)
    {
        AXIOM_XPATH_CAST_SET_VALUE(axis2_bool_t, AXIS2_FALSE);

        axutil_stack_push(context->stack, context->env, node);
    }

    for (i = 1; i >= 0; i--)
    {
        for (j = 0; j < n_nodes[i]; j++)
        {
            res_node =(axiom_xpath_result_node_t *)axutil_array_list_get(arr[i], context->env, j);
            AXIS2_FREE(context->env->allocator, res_node);
        }

        axutil_array_list_free(arr[i], context->env);
    }

    return 1;
}

/* Union */
int
axiom_xpath_union_operator(
    axiom_xpath_context_t *context,
    axiom_xpath_operation_t * op)
{
    int n_nodes = 0;
    int i;
    int op12[2];

    op12[0] = op->op1;
    op12[1] = op->op2;

    for(i = 0; i < 2; i++)
    {
        if(op12[i] == AXIOM_XPATH_PARSE_END)
        {
            continue;
        }

        n_nodes += axiom_xpath_evaluate_operation(context, op12[i]);
    }

    return n_nodes;
}

/* Set context node depending on whether relative or absolute location path */
int
axiom_xpath_start_node_operator(
    axiom_xpath_context_t *context,
    axiom_xpath_operation_t * op)
{
    int n_nodes = 0;

    if(op->op1 == AXIOM_XPATH_PARSE_END)
    {
        return 0;
    }

    if(op->opr == AXIOM_XPATH_OPERATION_ROOT_NODE)
    {
        context->node = context->root_node;
        n_nodes += axiom_xpath_evaluate_operation(context, op->op1);
    }
    else if(op->opr == AXIOM_XPATH_OPERATION_CONTEXT_NODE)
    {
        n_nodes += axiom_xpath_evaluate_operation(context, op->op1);
    }

    return n_nodes;
}

/* Step */
int
axiom_xpath_step_operator(
    axiom_xpath_context_t *context,
    axiom_xpath_operation_t * op)
{
    axiom_xpath_operation_t * node_test_op;
    axiom_xpath_iterator_t iter;
    axiom_xpath_axis_t axis;

    if(op->op1 == AXIOM_XPATH_PARSE_END)
    {
#ifdef AXIOM_XPATH_DEBUG
        printf("Node test operator empty\n");
#endif

        return AXIOM_XPATH_EVALUATION_ERROR;
    }

    if(op->op2 == AXIOM_XPATH_PARSE_END)
    {
        return 0;
    }

    /* Get the name */
    node_test_op = AXIOM_XPATH_OPR_GET(op->op1);

    /* Get the axis */
    if(!node_test_op->par2)
    {
#ifdef AXIOM_XPATH_DEBUG
        printf("axis is NULL in the step operator\n");
#endif
        return AXIOM_XPATH_EVALUATION_ERROR;
    }
    axis = *((axiom_xpath_axis_t *)node_test_op->par2);

    /* Get the iteration for the axis */
    iter = axiom_xpath_get_iterator(axis);

    return iter(context, op->op1 /* node test */, op->op2 /* next step */, node_test_op->op1 /* predicate */);
}

/* Predicates */
axis2_bool_t
axiom_xpath_evaluate_predicate_condition(
    axiom_xpath_context_t *context,
    int n_nodes)
{
    axiom_xpath_result_node_t *res;
    int i;

    if(n_nodes <= 0)
    {
        return AXIS2_FALSE;
    }
    else if(n_nodes > 1)
    {
        for(i = 0; i < n_nodes; i++)
        {
            res = (axiom_xpath_result_node_t *)axutil_stack_pop(context->stack, context->env);

            if (res->type > AXIOM_XPATH_TYPE_NAMESPACE)
            {
                AXIS2_FREE(context->env->allocator, res->value);
            }

            AXIS2_FREE(context->env->allocator, res);
        }

        return AXIS2_TRUE;
    }
    else
    {
        res = (axiom_xpath_result_node_t *)axutil_stack_pop(context->stack, context->env);

        if(res->type == AXIOM_XPATH_TYPE_NUMBER)
        {
            if(*(double *)(res->value) == context->position)
            {
                AXIS2_FREE(context->env->allocator, res);
                return AXIS2_TRUE;
            }
            else
            {
                AXIS2_FREE(context->env->allocator, res);
                return AXIS2_FALSE;
            }
        }
        else if(res->type == AXIOM_XPATH_TYPE_BOOLEAN)
        {
            if(*(axis2_bool_t *)(res->value))
            {
                AXIS2_FREE(context->env->allocator, res);
                return AXIS2_TRUE;
            }
            else
            {
                AXIS2_FREE(context->env->allocator, res);
                return AXIS2_FALSE;
            }
        }
        else
        {
            AXIS2_FREE(context->env->allocator, res);
            return AXIS2_TRUE;
        }
    }
}

/* Predicate */
int
axiom_xpath_evaluate_predicate(
    axiom_xpath_context_t *context,
    int op_next,
    int op_predicate)
{
    int n_res;
    axis2_bool_t res;

    axiom_xpath_operation_t * pred_op;
    axiom_node_t *context_node = context->node;

    if(op_predicate == AXIOM_XPATH_PARSE_END)
    {
        return axiom_xpath_evaluate_operation(context, op_next);
    }
    else
    {
        pred_op = AXIOM_XPATH_OPR_GET(op_predicate);

        pred_op->pos++;

        /* Evaluate the predicate */
        if(pred_op->op1 != AXIOM_XPATH_PARSE_END)
        {
            n_res = axiom_xpath_evaluate_operation(context, pred_op->op1);
            context->position = pred_op->pos;

            res = axiom_xpath_evaluate_predicate_condition(context, n_res);
        }
        else
        {
            res = AXIS2_TRUE;
        }
        /* 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. */

        /* Transform the result to number or boolean ? */

        if(res)
        {
            context->node = context_node;

            return axiom_xpath_evaluate_predicate(context, op_next, pred_op->op2);
        }
    }

    return 0;
}

/* Node test match */
axis2_bool_t
axiom_xpath_node_test_match(
    axiom_xpath_context_t *context,
    axiom_xpath_node_test_t *node_test)
{
    axiom_types_t type;
    axiom_element_t *element = NULL;
    axis2_char_t *name = NULL;
    axiom_namespace_t *ns = NULL, *xpath_ns = NULL;

    if(!context->node && !context->attribute && !context->ns)
    {
#ifdef AXIOM_XPATH_DEBUG
        printf("Both context node and attribute are NULL.");
        printf(" May be a literal or a number.\n");
#endif
        return AXIS2_FALSE;
    }
    else if(context->node)
    {
        /* Test if the node matches */
        type = axiom_node_get_node_type(context->node, context->env);

        if(type == AXIOM_ELEMENT)
        {
            element = axiom_node_get_data_element(context->node, context->env);

            name = axiom_element_get_localname(element, context->env);

            ns = axiom_element_get_namespace(element, context->env, context->node);
        }

        if(node_test->type == AXIOM_XPATH_NODE_TEST_NONE)
        {
            return AXIS2_FALSE;
        }
        else
        {
            if(node_test->type == AXIOM_XPATH_NODE_TEST_ALL || node_test->type
                == AXIOM_XPATH_NODE_TEST_STANDARD)
            {
                if(type != AXIOM_ELEMENT)
                {
                    return AXIS2_FALSE;
                }

                /* Check namespace */
                if(node_test->type == AXIOM_XPATH_NODE_TEST_ALL)
                {
                    if(!ns && node_test->prefix)
                    {
                        return AXIS2_FALSE;
                    }
                }
                else
                {
                    if((ns && !node_test->prefix) || (!ns && node_test->prefix))
                    {
                        return AXIS2_FALSE;
                    }
                }

                if(ns && node_test->prefix)
                {
                    xpath_ns = axiom_xpath_get_namespace(context, node_test->prefix);

                    if(!xpath_ns)
                    {
                        return AXIS2_FALSE;
                    }

                    if(axutil_strcmp(axiom_namespace_get_uri(ns, context->env),
                        axiom_namespace_get_uri(xpath_ns, context->env)))
                    {
                        return AXIS2_FALSE;
                    }
                }

                /* Check local name */
                if(node_test->type == AXIOM_XPATH_NODE_TEST_ALL)
                {
                    return AXIS2_TRUE;
                }
                else if(node_test->type == AXIOM_XPATH_NODE_TEST_STANDARD)
                {
                    if(name && axutil_strcmp(node_test->name, name) == 0)
                    {
                        return AXIS2_TRUE;
                    }
                    else
                    {
                        return AXIS2_FALSE;
                    }
                }
            }
            else if(node_test->type == AXIOM_XPATH_NODE_TYPE_COMMENT)
            {
                if(type == AXIOM_COMMENT)
                {
                    return AXIS2_TRUE;
                }
                else
                {
                    return AXIS2_FALSE;
                }
            }
            else if(node_test->type == AXIOM_XPATH_NODE_TYPE_PI)
            {
                if(type == AXIOM_PROCESSING_INSTRUCTION)
                {
                    return AXIS2_TRUE;
                }
                else
                {
                    return AXIS2_FALSE;
                }
            }
            else if(node_test->type == AXIOM_XPATH_NODE_TYPE_NODE)
            {
                if(type == AXIOM_ELEMENT)
                {
                    return AXIS2_TRUE;
                }
                else
                {
                    return AXIS2_FALSE;
                }
            }
            else if(node_test->type == AXIOM_XPATH_NODE_TYPE_TEXT)
            {
                if(type == AXIOM_TEXT)
                {
                    return AXIS2_TRUE;
                }
                else
                {
                    return AXIS2_FALSE;
                }
            }
        }
    }
    /* Attributes */
    else if(context->attribute)
    {
        name = axiom_attribute_get_localname(context->attribute, context->env);
        ns = axiom_attribute_get_namespace(context->attribute, context->env);

        if(node_test->type == AXIOM_XPATH_NODE_TEST_NONE)
        {
            return AXIS2_FALSE;
        }
        else
        {
            /* Check namespace */
            if(node_test->type == AXIOM_XPATH_NODE_TEST_ALL)
            {
                if(!ns && node_test->prefix)
                {
                    return AXIS2_FALSE;
                }
            }
            else
            {
                if((ns && !node_test->prefix) || (!ns && node_test->prefix))
                {
                    return AXIS2_FALSE;
                }
            }

            if(ns && node_test->prefix)
            {
                xpath_ns = axiom_xpath_get_namespace(context, node_test->prefix);

                if(!xpath_ns)
                {
                    return AXIS2_FALSE;
                }

                if(axutil_strcmp(axiom_namespace_get_uri(ns, context->env),
                    axiom_namespace_get_uri(xpath_ns, context->env)))
                {
                    return AXIS2_FALSE;
                }
            }

            /* Check local name */
            if(node_test->type == AXIOM_XPATH_NODE_TEST_ALL)
            {
                return AXIS2_TRUE;
            }
            else if(node_test->type == AXIOM_XPATH_NODE_TEST_STANDARD)
            {
                if(name && axutil_strcmp(node_test->name, name) == 0)
                {
                    return AXIS2_TRUE;
                }
                else
                {
                    return AXIS2_FALSE;
                }
            }
        }
    }

    /* Namespace */
    else if(context->ns)
    {
        /* Prefix is checked ??? If changed to uri the cast
         method in xpath.c needs to be changed as well */
        name = axiom_namespace_get_prefix(context->ns, context->env);
        ns = NULL;

        if(node_test->type == AXIOM_XPATH_NODE_TEST_NONE)
        {
            return AXIS2_FALSE;
        }
        else
        {
            /* Check namespace */
            if(node_test->type == AXIOM_XPATH_NODE_TEST_ALL)
            {
                if(!ns && node_test->prefix)
                {
                    return AXIS2_FALSE;
                }
            }
            else
            {
                if((ns && !node_test->prefix) || (!ns && node_test->prefix))
                {
                    return AXIS2_FALSE;
                }
            }

            if(ns && node_test->prefix)
            {
                xpath_ns = axiom_xpath_get_namespace(context, node_test->prefix);

                if(!xpath_ns)
                {
                    return AXIS2_FALSE;
                }

                if(axutil_strcmp(axiom_namespace_get_uri(ns, context->env),
                    axiom_namespace_get_uri(xpath_ns, context->env)))
                {
                    return AXIS2_FALSE;
                }
            }

            /* Check local name */
            if(node_test->type == AXIOM_XPATH_NODE_TEST_ALL)
            {
                return AXIS2_TRUE;
            }
            else if(node_test->type == AXIOM_XPATH_NODE_TEST_STANDARD)
            {
                if(name && axutil_strcmp(node_test->name, name) == 0)
                {
                    return AXIS2_TRUE;
                }
                else
                {
                    return AXIS2_FALSE;
                }
            }
        }
    }

    return AXIS2_FALSE;
}

int
axiom_xpath_function_call_operator(
    axiom_xpath_context_t *context,
    axiom_xpath_operation_t * op)
{
    axiom_xpath_function_t func = axiom_xpath_get_function(context, op->par1);
    int n_args = 0;

    if(!func)
    {
#ifdef AXIOM_XPATH_DEBUG
        printf("Function %s not found\n", (char *)op->par1);
#endif

        return AXIOM_XPATH_EVALUATION_ERROR;
    }

    if(op->op1 != AXIOM_XPATH_PARSE_END)
    {
        n_args = axiom_xpath_evaluate_operation(context, op->op1);
    }

    return func(context, n_args);
}

int
axiom_xpath_argument_operator(
    axiom_xpath_context_t *context,
    axiom_xpath_operation_t * op)
{
    int n_args = 0;

    if(op->op1 != AXIOM_XPATH_PARSE_END)
    {
        n_args += axiom_xpath_evaluate_operation(context, op->op1);
    }

    if(op->op2 != AXIOM_XPATH_PARSE_END)
    {
        n_args += axiom_xpath_evaluate_operation(context, op->op1);
    }

    return n_args;
}

/* Collect the current node to the results list */
int
axiom_xpath_collect_operator(
    axiom_xpath_context_t *context,
    axiom_xpath_operation_t * op)
{
    axiom_xpath_result_node_t *node;

    node = AXIS2_MALLOC(context->env->allocator, sizeof(axiom_xpath_result_node_t));

    if(context->node)
    {
        node->value = context->node;
        node->type = AXIOM_XPATH_TYPE_NODE;
    }
    else if(context->attribute)
    {
        node->value = context->attribute;
        node->type = AXIOM_XPATH_TYPE_ATTRIBUTE;
    }
    else if(context->ns)
    {
        node->value = context->ns;
        node->type = AXIOM_XPATH_TYPE_NAMESPACE;
    }

    axutil_stack_push(context->stack, context->env, node);

    return 1;
}

/* Returns a pointer to the respective processing function */
axiom_xpath_operator_t
axiom_xpath_get_operator(
    axiom_xpath_operation_t * op)
{
    switch(op->opr)
    {
        case AXIOM_XPATH_OPERATION_STEP:
            return axiom_xpath_step_operator;

        case AXIOM_XPATH_OPERATION_ROOT_NODE:
        case AXIOM_XPATH_OPERATION_CONTEXT_NODE:
            return axiom_xpath_start_node_operator;

        case AXIOM_XPATH_OPERATION_RESULT:
            return axiom_xpath_collect_operator;

        case AXIOM_XPATH_OPERATION_UNION:
            return axiom_xpath_union_operator;

        case AXIOM_XPATH_OPERATION_OR_EXPR:
            return axiom_xpath_orexpr_operator;

        case AXIOM_XPATH_OPERATION_AND_EXPR:
            return axiom_xpath_andexpr_operator;

        case AXIOM_XPATH_OPERATION_EQUAL_EXPR:
            return axiom_xpath_equalexpr_operator;

        case AXIOM_XPATH_OPERATION_LITERAL:
            return axiom_xpath_literal_operator;

        case AXIOM_XPATH_OPERATION_NUMBER:
            return axiom_xpath_number_operator;

        case AXIOM_XPATH_OPERATION_PATH_EXPRESSION:
            return axiom_xpath_path_expression_operator;

        case AXIOM_XPATH_OPERATION_FUNCTION_CALL:
            return axiom_xpath_function_call_operator;

        case AXIOM_XPATH_OPERATION_ARGUMENT:
            return axiom_xpath_argument_operator;

        default:
#ifdef AXIOM_XPATH_DEBUG
            printf("Unidentified operation.\n");
#endif

            return NULL;
    }
}

/* Returns a pointer to the respective processing function */
axiom_xpath_iterator_t
axiom_xpath_get_iterator(
    axiom_xpath_axis_t axis)
{
    switch(axis)
    {
        case AXIOM_XPATH_AXIS_CHILD:
            return axiom_xpath_child_iterator;

        case AXIOM_XPATH_AXIS_DESCENDANT:
            return axiom_xpath_descendant_iterator;

        case AXIOM_XPATH_AXIS_PARENT:
            return axiom_xpath_parent_iterator;

        case AXIOM_XPATH_AXIS_ANCESTOR:
            return axiom_xpath_ancestor_iterator;

        case AXIOM_XPATH_AXIS_FOLLOWING_SIBLING:
            return axiom_xpath_following_sibling_iterator;

        case AXIOM_XPATH_AXIS_PRECEDING_SIBLING:
            return axiom_xpath_preceding_sibling_iterator;

        case AXIOM_XPATH_AXIS_FOLLOWING:
            return axiom_xpath_following_iterator;

        case AXIOM_XPATH_AXIS_PRECEDING:
            return axiom_xpath_preceding_iterator;

        case AXIOM_XPATH_AXIS_ATTRIBUTE:
            return axiom_xpath_attribute_iterator;

        case AXIOM_XPATH_AXIS_NAMESPACE:
            return axiom_xpath_namespace_iterator;

        case AXIOM_XPATH_AXIS_SELF:
            return axiom_xpath_self_iterator;

        case AXIOM_XPATH_AXIS_DESCENDANT_OR_SELF:
            return axiom_xpath_descendant_self_iterator;

        case AXIOM_XPATH_AXIS_ANCESTOR_OR_SELF:
            return axiom_xpath_ancestor_self_iterator;

        default:
#ifdef AXIOM_XPATH_DEBUG
            printf("Unidentified axis.\n");
#endif

            return NULL;
    }
}

int
axiom_xpath_evaluate_operation(
    axiom_xpath_context_t *context,
    int op)
{
    axiom_xpath_operation_t * operation;
    axiom_xpath_operator_t function;

    /* Get a pointer to the operation */
    operation = AXIOM_XPATH_OPR_GET(op);

    /* Get the funciton which processes the operations */
    function = axiom_xpath_get_operator(operation);

    return function(context, operation);
}
