/*
 * 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);
    context->stack = NULL;

    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);
            if (res_node)
            {
                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)
    {
        AXIS2_LOG_ERROR(context->env->log, AXIS2_LOG_SI,
        	"Node test operator empty");

        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)
    {
        AXIS2_LOG_ERROR(context->env->log, AXIS2_LOG_SI,
        	"axis is NULL in the step operator");
        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->value);
                AXIS2_FREE(context->env->allocator, res);
                return AXIS2_TRUE;
            }
            else
            {
                AXIS2_FREE(context->env->allocator, res->value);
                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)
    {
        AXIS2_LOG_ERROR(context->env->log, AXIS2_LOG_SI,
        	"Both context node and attribute are NULL. May be a literal or a number.");
        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)
    {
        AXIS2_LOG_ERROR(context->env->log, AXIS2_LOG_SI,
        	"Function %s not found", (char *)op->par1);

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