/*
 * 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.
 */
package org.apache.vxquery.xmlquery.translator;

import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.namespace.QName;

import org.apache.commons.lang3.mutable.Mutable;
import org.apache.commons.lang3.mutable.MutableObject;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator;
import org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan;
import org.apache.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
import org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable;
import org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
import org.apache.hyracks.algebricks.core.algebra.expressions.AggregateFunctionCallExpression;
import org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
import org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
import org.apache.hyracks.algebricks.core.algebra.expressions.UnnestingFunctionCallExpression;
import org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.DistributeResultOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.EmptyTupleSourceOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.SelectOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator;
import org.apache.hyracks.algebricks.core.algebra.plan.ALogicalPlanImpl;
import org.apache.hyracks.data.std.primitive.DoublePointable;
import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
import org.apache.hyracks.data.std.util.ByteArrayAccessibleOutputStream;
import org.apache.vxquery.compiler.CompilerControlBlock;
import org.apache.vxquery.compiler.algebricks.VXQueryConstantValue;
import org.apache.vxquery.context.StaticContext;
import org.apache.vxquery.context.StaticContextImpl;
import org.apache.vxquery.context.ThinStaticContextImpl;
import org.apache.vxquery.context.XQueryVariable;
import org.apache.vxquery.datamodel.builders.atomic.StringValueBuilder;
import org.apache.vxquery.datamodel.values.ValueTag;
import org.apache.vxquery.exceptions.ErrorCode;
import org.apache.vxquery.exceptions.SystemException;
import org.apache.vxquery.functions.BuiltinFunctions;
import org.apache.vxquery.functions.BuiltinOperators;
import org.apache.vxquery.functions.ExternalFunction;
import org.apache.vxquery.functions.Function;
import org.apache.vxquery.functions.Signature;
import org.apache.vxquery.functions.UserDefinedXQueryFunction;
import org.apache.vxquery.metadata.QueryResultSetDataSink;
import org.apache.vxquery.runtime.functions.cast.CastToDecimalOperation;
import org.apache.vxquery.types.AnyItemType;
import org.apache.vxquery.types.AnyNodeType;
import org.apache.vxquery.types.AnyType;
import org.apache.vxquery.types.AtomicType;
import org.apache.vxquery.types.AttributeType;
import org.apache.vxquery.types.BuiltinTypeConstants;
import org.apache.vxquery.types.BuiltinTypeRegistry;
import org.apache.vxquery.types.CommentType;
import org.apache.vxquery.types.DocumentType;
import org.apache.vxquery.types.ElementType;
import org.apache.vxquery.types.EmptySequenceType;
import org.apache.vxquery.types.ItemType;
import org.apache.vxquery.types.NameTest;
import org.apache.vxquery.types.NodeType;
import org.apache.vxquery.types.ProcessingInstructionType;
import org.apache.vxquery.types.Quantifier;
import org.apache.vxquery.types.SchemaType;
import org.apache.vxquery.types.SequenceType;
import org.apache.vxquery.types.TextType;
import org.apache.vxquery.types.TypeUtils;
import org.apache.vxquery.xmlquery.ast.ASTNode;
import org.apache.vxquery.xmlquery.ast.ASTTag;
import org.apache.vxquery.xmlquery.ast.ArrayConstructor;
import org.apache.vxquery.xmlquery.ast.AtomicTypeNode;
import org.apache.vxquery.xmlquery.ast.AttributeTestNode;
import org.apache.vxquery.xmlquery.ast.AxisStepNode;
import org.apache.vxquery.xmlquery.ast.BaseUriDeclNode;
import org.apache.vxquery.xmlquery.ast.BoundarySpaceDeclNode;
import org.apache.vxquery.xmlquery.ast.CDataSectionNode;
import org.apache.vxquery.xmlquery.ast.ComputedAttributeConstructorNode;
import org.apache.vxquery.xmlquery.ast.ComputedCommentConstructorNode;
import org.apache.vxquery.xmlquery.ast.ComputedDocumentConstructorNode;
import org.apache.vxquery.xmlquery.ast.ComputedElementConstructorNode;
import org.apache.vxquery.xmlquery.ast.ComputedPIConstructorNode;
import org.apache.vxquery.xmlquery.ast.ComputedTextConstructorNode;
import org.apache.vxquery.xmlquery.ast.ConstructionDeclNode;
import org.apache.vxquery.xmlquery.ast.ContentCharsNode;
import org.apache.vxquery.xmlquery.ast.CopyNamespacesDeclNode;
import org.apache.vxquery.xmlquery.ast.DefaultCollationDeclNode;
import org.apache.vxquery.xmlquery.ast.DefaultElementNamespaceDeclNode;
import org.apache.vxquery.xmlquery.ast.DefaultFunctionNamespaceDeclNode;
import org.apache.vxquery.xmlquery.ast.DirectAttributeConstructorNode;
import org.apache.vxquery.xmlquery.ast.DirectCommentConstructorNode;
import org.apache.vxquery.xmlquery.ast.DirectElementConstructorNode;
import org.apache.vxquery.xmlquery.ast.DirectPIConstructorNode;
import org.apache.vxquery.xmlquery.ast.DocumentTestNode;
import org.apache.vxquery.xmlquery.ast.ElementTestNode;
import org.apache.vxquery.xmlquery.ast.EmptyOrderDeclNode;
import org.apache.vxquery.xmlquery.ast.EnclosedExprNode;
import org.apache.vxquery.xmlquery.ast.ExprNode;
import org.apache.vxquery.xmlquery.ast.ExtensionExprNode;
import org.apache.vxquery.xmlquery.ast.FLWORClauseNode;
import org.apache.vxquery.xmlquery.ast.FLWORExprNode;
import org.apache.vxquery.xmlquery.ast.FilterExprNode;
import org.apache.vxquery.xmlquery.ast.ForClauseNode;
import org.apache.vxquery.xmlquery.ast.ForVarDeclNode;
import org.apache.vxquery.xmlquery.ast.FunctionDeclNode;
import org.apache.vxquery.xmlquery.ast.FunctionExprNode;
import org.apache.vxquery.xmlquery.ast.IfExprNode;
import org.apache.vxquery.xmlquery.ast.InfixExprNode;
import org.apache.vxquery.xmlquery.ast.InfixExprNode.InfixOperator;
import org.apache.vxquery.xmlquery.ast.LetClauseNode;
import org.apache.vxquery.xmlquery.ast.LetVarDeclNode;
import org.apache.vxquery.xmlquery.ast.LibraryModuleNode;
import org.apache.vxquery.xmlquery.ast.LiteralNode;
import org.apache.vxquery.xmlquery.ast.MainModuleNode;
import org.apache.vxquery.xmlquery.ast.ModuleImportNode;
import org.apache.vxquery.xmlquery.ast.ModuleNode;
import org.apache.vxquery.xmlquery.ast.NCNameNode;
import org.apache.vxquery.xmlquery.ast.NameTestNode;
import org.apache.vxquery.xmlquery.ast.NamespaceDeclNode;
import org.apache.vxquery.xmlquery.ast.OptionDeclNode;
import org.apache.vxquery.xmlquery.ast.OrderSpecNode;
import org.apache.vxquery.xmlquery.ast.OrderbyClauseNode;
import org.apache.vxquery.xmlquery.ast.OrderedExprNode;
import org.apache.vxquery.xmlquery.ast.OrderingModeDeclNode;
import org.apache.vxquery.xmlquery.ast.PITestNode;
import org.apache.vxquery.xmlquery.ast.ParamNode;
import org.apache.vxquery.xmlquery.ast.ParenthesizedExprNode;
import org.apache.vxquery.xmlquery.ast.PathExprNode;
import org.apache.vxquery.xmlquery.ast.PrologNode;
import org.apache.vxquery.xmlquery.ast.QNameNode;
import org.apache.vxquery.xmlquery.ast.QuantifiedExprNode;
import org.apache.vxquery.xmlquery.ast.QuantifiedExprNode.QuantifierType;
import org.apache.vxquery.xmlquery.ast.QuantifiedVarDeclNode;
import org.apache.vxquery.xmlquery.ast.QueryBodyNode;
import org.apache.vxquery.xmlquery.ast.RelativePathExprNode;
import org.apache.vxquery.xmlquery.ast.SchemaImportNode;
import org.apache.vxquery.xmlquery.ast.SequenceTypeNode;
import org.apache.vxquery.xmlquery.ast.SingleTypeNode;
import org.apache.vxquery.xmlquery.ast.TypeDeclNode;
import org.apache.vxquery.xmlquery.ast.TypeExprNode;
import org.apache.vxquery.xmlquery.ast.UnaryExprNode;
import org.apache.vxquery.xmlquery.ast.UnorderedExprNode;
import org.apache.vxquery.xmlquery.ast.ValidateExprNode;
import org.apache.vxquery.xmlquery.ast.VarDeclNode;
import org.apache.vxquery.xmlquery.ast.VarRefNode;
import org.apache.vxquery.xmlquery.ast.VersionDeclNode;
import org.apache.vxquery.xmlquery.ast.WhereClauseNode;
import org.apache.vxquery.xmlquery.query.Module;
import org.apache.vxquery.xmlquery.query.ModuleType;
import org.apache.vxquery.xmlquery.query.XMLQueryCompilerConstants;
import org.apache.vxquery.xmlquery.query.XQueryConstants;
import org.apache.vxquery.xmlquery.query.XQueryConstants.PathType;
import org.apache.vxquery.xmlquery.query.XQueryConstants.TypeQuantifier;

public class XMLQueryTranslator {
    private static final Pattern UNQUOTER = Pattern
            .compile("(&lt;)|(&gt;)|(&apos;)|(&amp;)|(&quot;)|(\"\")|('')|(&#\\d+;)|(&#x(?:[A-Fa-f0-9])+;)");

    private final CompilerControlBlock ccb;

    private final StaticContext rootCtx;

    private StaticContext moduleCtx;

    private IVariableScope rootVarScope;

    private StaticContext currCtx;

    private int varCounter;

    private final ByteArrayAccessibleOutputStream baaos;

    private final DataOutput dOut;

    private final StringValueBuilder stringVB;

    public XMLQueryTranslator(CompilerControlBlock ccb) {
        this.ccb = ccb;
        varCounter = 0;
        rootCtx = ccb.getStaticContext();

        baaos = new ByteArrayAccessibleOutputStream();
        dOut = new DataOutputStream(baaos);
        stringVB = new StringValueBuilder();
    }

    private void pushContext() {
        currCtx = new ThinStaticContextImpl(currCtx);
    }

    private void popContext() {
        currCtx = currCtx.getParent();
    }

    public Module translateModule(ModuleNode moduleNode) throws SystemException {
        Module module = new Module();

        moduleCtx = new StaticContextImpl(rootCtx);
        moduleCtx.registerVariable(new XQueryVariable(XMLQueryCompilerConstants.DOT_VAR_NAME,
                SequenceType.create(AnyItemType.INSTANCE, Quantifier.QUANT_ONE), newLogicalVariable()));
        rootVarScope = new RootVariableScope();
        currCtx = moduleCtx;
        module.setModuleContext(moduleCtx);
        module.setCompilerControlBlock(ccb);

        VersionDeclNode ver = moduleNode.getVersion();
        if (ver != null) {
            if (!"1.0".equals(ver.getVersion())) {
                throw new SystemException(ErrorCode.XQST0031, ver.getSourceLocation());
            }
        }

        switch (moduleNode.getTag()) {
            case LIBRARY_MODULE: {
                module.setModuleType(ModuleType.LIBRARY);
                LibraryModuleNode lmNode = (LibraryModuleNode) moduleNode;
                String prefix = lmNode.getModuleDecl().getPrefix();
                String uri = unquote(lmNode.getModuleDecl().getTargetNS());
                if (prefix != null) {
                    currCtx.registerNamespaceUri(prefix, uri);
                }
                module.setNamespaceUri(uri);
                break;
            }

            case MAIN_MODULE: {
                module.setModuleType(ModuleType.MAIN);
                break;
            }

            default:
                throw new IllegalStateException("Unknown module type: " + moduleNode.getTag());
        }

        PrologNode prologNode = moduleNode.getProlog();
        parsePrologPass1(prologNode);
        parsePrologPass2(prologNode);

        ILogicalPlan plan = null;
        switch (moduleNode.getTag()) {
            case LIBRARY_MODULE:
                throw new SystemException(ErrorCode.TODO);

            case MAIN_MODULE:
                plan = translateMainModule((MainModuleNode) moduleNode);
        }

        module.setBody(plan);
        return module;
    }

    @SuppressWarnings("unchecked")
    private void parsePrologPass1(PrologNode prologNode) throws SystemException {
        if (prologNode != null) {
            List<ASTNode> decls = prologNode.getDecls();
            for (ASTNode d : decls) {
                switch (d.getTag()) {
                    case DEFAULT_ELEMENT_NAMESPACE_DECLARATION: {
                        DefaultElementNamespaceDeclNode node = (DefaultElementNamespaceDeclNode) d;
                        moduleCtx.setDefaultElementNamespaceUri(node.getUri());
                        break;
                    }

                    case DEFAULT_FUNCTION_NAMESPACE_DECLARATION: {
                        DefaultFunctionNamespaceDeclNode node = (DefaultFunctionNamespaceDeclNode) d;
                        moduleCtx.setDefaultFunctionNamespaceUri(node.getUri());
                        break;
                    }

                    case BOUNDARY_SPACE_DECLARATION: {
                        BoundarySpaceDeclNode node = (BoundarySpaceDeclNode) d;
                        moduleCtx.setBoundarySpaceProperty(node.getMode());
                        break;
                    }

                    case DEFAULT_COLLATION_DECLARATION: {
                        DefaultCollationDeclNode node = (DefaultCollationDeclNode) d;
                        moduleCtx.setDefaultCollation(node.getCollation());
                        break;
                    }

                    case BASE_URI_DECLARATION: {
                        BaseUriDeclNode node = (BaseUriDeclNode) d;
                        moduleCtx.setBaseUri(node.getUri());
                        break;
                    }

                    case CONSTRUCTION_DECLARATION: {
                        ConstructionDeclNode node = (ConstructionDeclNode) d;
                        moduleCtx.setConstructionModeProperty(node.getMode());
                        break;
                    }

                    case ORDERING_MODE_DECLARATION: {
                        OrderingModeDeclNode node = (OrderingModeDeclNode) d;
                        moduleCtx.setOrderingModeProperty(node.getMode());
                        break;
                    }

                    case EMPTY_ORDER_DECLARATION: {
                        EmptyOrderDeclNode node = (EmptyOrderDeclNode) d;
                        moduleCtx.setEmptyOrderProperty(node.getMode());
                        break;
                    }

                    case COPY_NAMESPACES_DECLARATION: {
                        CopyNamespacesDeclNode node = (CopyNamespacesDeclNode) d;
                        moduleCtx.setCopyNamespacesModeProperty(node.getMode());
                        break;
                    }

                    case NAMESPACE_DECLARATION: {
                        NamespaceDeclNode node = (NamespaceDeclNode) d;
                        moduleCtx.registerNamespaceUri(node.getPrefix(), unquote(node.getUri()));
                        break;
                    }

                    case SCHEMA_IMPORT: {
                        SchemaImportNode node = (SchemaImportNode) d;
                        if (node.isDefaultElementNamespace()) {
                            moduleCtx.setDefaultElementNamespaceUri(node.getTargetNS());
                        }
                        if (node.getPrefix() != null) {
                            moduleCtx.registerNamespaceUri(node.getPrefix(), unquote(node.getTargetNS()));
                        }
                        moduleCtx.registerSchemaImport(node.getTargetNS(), node.getLocations());
                        break;
                    }

                    case MODULE_IMPORT: {
                        ModuleImportNode node = (ModuleImportNode) d;
                        if (node.getPrefix() != null) {
                            moduleCtx.registerNamespaceUri(node.getPrefix(), unquote(node.getTargetNS()));
                        }
                        moduleCtx.registerModuleImport(node.getTargetNS(), node.getLocations());
                        break;
                    }

                    case VARIABLE_DECLARATION: {
                        VarDeclNode node = (VarDeclNode) d;
                        QName name = createQName(node.getName());
                        SequenceType type = SequenceType.create(AnyItemType.INSTANCE, Quantifier.QUANT_STAR);
                        if (node.getType() != null) {
                            type = createSequenceType(node.getType());
                        }
                        LogicalVariable lVar = newLogicalVariable();
                        XQueryVariable var = new XQueryVariable(name, type, lVar);
                        moduleCtx.registerVariable(var);
                        break;
                    }

                    case FUNCTION_DECLARATION: {
                        FunctionDeclNode node = (FunctionDeclNode) d;
                        boolean external = node.getBody() == null;
                        QName name = createQName(node.getName(), moduleCtx.getDefaultFunctionNamespaceUri());
                        String uri = name.getNamespaceURI();
                        if (XQueryConstants.FN_NSURI.equals(uri) || XQueryConstants.XS_NSURI.equals(uri)
                                || XQueryConstants.XSI_NSURI.equals(uri) || XQueryConstants.XML_NSURI.equals(uri)) {
                            throw new SystemException(ErrorCode.XQST0045, node.getSourceLocation());
                        }
                        SequenceType rType = SequenceType.create(AnyItemType.INSTANCE, Quantifier.QUANT_STAR);
                        if (node.getReturnType() != null) {
                            rType = createSequenceType(node.getReturnType());
                        }
                        Pair<QName, SequenceType> paramTypes[] = new Pair[node.getParameters().size()];
                        for (int i = 0; i < paramTypes.length; ++i) {
                            ParamNode pNode = node.getParameters().get(i);
                            QName pName = createQName(pNode.getName());
                            SequenceType pType = SequenceType.create(AnyItemType.INSTANCE, Quantifier.QUANT_STAR);
                            if (pNode.getType() != null) {
                                pType = createSequenceType(pNode.getType());
                            }
                            paramTypes[i] = Pair.<QName, SequenceType> of(pName, pType);
                        }
                        Signature sign = new Signature(rType, paramTypes);
                        Function f = external ? new ExternalFunction(name, sign)
                                : new UserDefinedXQueryFunction(name, sign, null);
                        moduleCtx.registerFunction(f);
                        break;
                    }

                    case OPTION_DECLARATION: {
                        OptionDeclNode node = (OptionDeclNode) d;
                        QName name = createQName(node.getName());
                        moduleCtx.setOption(name, node.getValue());
                        break;
                    }

                    default:
                        throw new IllegalStateException("Unknown node: " + d.getTag());
                }
            }
        }
    }

    private void parsePrologPass2(PrologNode prologNode) throws SystemException {
        if (prologNode != null) {
            List<ASTNode> decls = prologNode.getDecls();
            for (ASTNode d : decls) {
                switch (d.getTag()) {
                    case VARIABLE_DECLARATION: {
                        VarDeclNode node = (VarDeclNode) d;
                        // TODO Support Global variables
                        break;
                    }

                    case FUNCTION_DECLARATION: {
                        FunctionDeclNode node = (FunctionDeclNode) d;
                        boolean external = node.getBody() == null;
                        if (!external) {
                            QName name = createQName(node.getName(), moduleCtx.getDefaultFunctionNamespaceUri());
                            int arity = node.getParameters().size();
                            UserDefinedXQueryFunction f = (UserDefinedXQueryFunction) moduleCtx.lookupFunction(name,
                                    arity);
                            Signature sign = f.getSignature();
                            TranslationContext tCtx = new TranslationContext(null, new EmptyTupleSourceOperator());
                            XQueryVariable[] params = new XQueryVariable[arity];
                            for (int i = 0; i < arity; ++i) {
                                ParamNode pNode = node.getParameters().get(i);
                                QName pName = createQName(pNode.getName());
                                SequenceType pType = SequenceType.create(AnyItemType.INSTANCE, Quantifier.QUANT_STAR);
                                if (pNode.getType() != null) {
                                    pType = createSequenceType(pNode.getType());
                                }
                                XQueryVariable pVar = new XQueryVariable(pName, pType, newLogicalVariable());
                                params[i] = pVar;
                                tCtx.varScope.registerVariable(pVar);
                            }
                            f.setParameters(params);
                            LogicalVariable var = translateExpression(node.getBody(), tCtx);
                            ILogicalExpression expr = treat(vre(var), sign.getReturnType());
                            var = createAssignment(expr, tCtx);
                            f.setBody(new ALogicalPlanImpl(mutable(tCtx.op)));
                        }
                        break;
                    }
                }
            }
        }
    }

    private SequenceType createSequenceType(ASTNode type) throws SystemException {
        switch (type.getTag()) {
            case TYPE_DECLARATION: {
                TypeDeclNode tDecl = (TypeDeclNode) type;
                return createSequenceType(tDecl.getType());
            }

            case SEQUENCE_TYPE: {
                SequenceTypeNode sType = (SequenceTypeNode) type;

                if (sType.getItemType() == null) {
                    return SequenceType.create(AnyItemType.INSTANCE, Quantifier.QUANT_STAR);
                }

                TypeQuantifier tq = sType.getQuantifier();
                Quantifier q = Quantifier.QUANT_ONE;
                if (tq != null) {
                    switch (tq) {
                        case QUANT_QUESTION:
                            q = Quantifier.QUANT_QUESTION;
                            break;

                        case QUANT_PLUS:
                            q = Quantifier.QUANT_PLUS;
                            break;

                        case QUANT_STAR:
                            q = Quantifier.QUANT_STAR;
                            break;
                    }
                }

                ItemType iType = createItemType(sType.getItemType());
                return SequenceType.create(iType, q);
            }

            case EMPTY_SEQUENCE_TYPE: {
                return SequenceType.create(EmptySequenceType.INSTANCE, Quantifier.QUANT_ZERO);
            }

            case SINGLE_TYPE: {
                SingleTypeNode stNode = (SingleTypeNode) type;
                ItemType iType = createItemType(stNode.getAtomicType());
                return SequenceType.create(iType,
                        stNode.isOptional() ? Quantifier.QUANT_QUESTION : Quantifier.QUANT_ONE);
            }

            default:
                throw new IllegalStateException("Unknown node: " + type.getTag());
        }
    }

    private ItemType createItemType(ASTNode itemType) throws SystemException {
        switch (itemType.getTag()) {
            case ITEM_TYPE:
                return AnyItemType.INSTANCE;

            case ATOMIC_TYPE: {
                AtomicTypeNode atNode = (AtomicTypeNode) itemType;
                QName tName = createQName(atNode.getName());
                SchemaType sType = moduleCtx.lookupSchemaType(tName);
                if (sType == null || !sType.isAtomicType()) {
                    throw new SystemException(ErrorCode.XPST0051, atNode.getSourceLocation());
                }
                return (ItemType) sType;
            }

            case ANY_NODE_TEST:
                return AnyNodeType.INSTANCE;

            case DOCUMENT_TEST: {
                DocumentTestNode dt = (DocumentTestNode) itemType;
                if (dt.getElementTest() == null) {
                    return DocumentType.ANYDOCUMENT;
                }
                ElementType eType = (ElementType) createItemType(dt.getElementTest());
                return new DocumentType(eType);
            }

            case TEXT_TEST:
                return TextType.INSTANCE;

            case COMMENT_TEST:
                return CommentType.INSTANCE;

            case PI_TEST: {
                PITestNode pit = (PITestNode) itemType;
                if (pit.getTarget() == null) {
                    return ProcessingInstructionType.ANYPI;
                }
                return new ProcessingInstructionType(createUTF8String(pit.getTarget()));
            }

            case ATTRIBUTE_TEST: {
                AttributeTestNode at = (AttributeTestNode) itemType;
                if (at.getNameTest() == null) {
                    return AttributeType.ANYATTRIBUTE;
                }
                NameTestNode ntNode = at.getNameTest();
                NameTest nt = NameTest.STAR_NAMETEST;
                if (ntNode.getPrefix() == null && ntNode.getLocalName() == null) {
                    if (at.getTypeName() == null) {
                        return AttributeType.ANYATTRIBUTE;
                    }
                } else {
                    String uri;
                    if (!"".equals(ntNode.getPrefix())) {
                        uri = currCtx.lookupNamespaceUri(ntNode.getPrefix());
                        if (uri == null) {
                            throw new SystemException(ErrorCode.XPST0081, ntNode.getSourceLocation());
                        }
                    } else {
                        uri = "";
                    }

                    nt = new NameTest(createUTF8String(uri), createUTF8String(ntNode.getLocalName()));
                }
                SchemaType cType = BuiltinTypeRegistry.XS_ANY_ATOMIC;
                if (at.getTypeName() != null) {
                    cType = moduleCtx.lookupSchemaType(createQName(at.getTypeName()));
                    if (cType == null) {
                        throw new SystemException(ErrorCode.XPST0051, at.getSourceLocation());
                    }
                }
                return new AttributeType(nt, cType);
            }

            case SCHEMA_ATTRIBUTE_TEST: {
                throw new UnsupportedOperationException("schema-attribute(...) is not supported");
            }

            case ELEMENT_TEST: {
                ElementTestNode et = (ElementTestNode) itemType;
                if (et.getNameTest() == null) {
                    return ElementType.ANYELEMENT;
                }
                NameTestNode ntNode = et.getNameTest();
                NameTest nt = NameTest.STAR_NAMETEST;
                if (ntNode.getPrefix() == null && ntNode.getLocalName() == null) {
                    if (et.getTypeName() == null) {
                        return ElementType.ANYELEMENT;
                    }
                } else {
                    String uri;
                    if (!"".equals(ntNode.getPrefix())) {
                        uri = currCtx.lookupNamespaceUri(ntNode.getPrefix());
                        if (uri == null) {
                            throw new SystemException(ErrorCode.XPST0081, ntNode.getSourceLocation());
                        }
                    } else {
                        uri = "";
                    }
                    nt = new NameTest(createUTF8String(uri), createUTF8String(ntNode.getLocalName()));
                }
                SchemaType cType = AnyType.INSTANCE;
                if (et.getTypeName() != null) {
                    cType = moduleCtx.lookupSchemaType(createQName(et.getTypeName()));
                    if (cType == null) {
                        throw new SystemException(ErrorCode.XPST0051, et.getSourceLocation());
                    }
                }
                return new ElementType(nt, cType, et.isNillable());
            }

            case SCHEMA_ELEMENT_TEST: {
                throw new UnsupportedOperationException("schema-element(...) is not supported");
            }

            default:
                throw new IllegalStateException("Unknown node: " + itemType.getTag());
        }
    }

    private byte[] createUTF8String(String str) {
        ArrayBackedValueStorage abvs = new ArrayBackedValueStorage();
        StringValueBuilder svb = new StringValueBuilder();
        try {
            svb.write(str, abvs.getDataOutput());
        } catch (IOException e) {
            throw new IllegalStateException(e);
        }
        return Arrays.copyOf(abvs.getByteArray(), abvs.getLength());
    }

    private ILogicalPlan translateMainModule(MainModuleNode moduleNode) throws SystemException {
        QueryBodyNode qbn = moduleNode.getQueryBody();
        ASTNode queryBody = qbn.getExpression();
        TranslationContext tCtx = new TranslationContext(null, new EmptyTupleSourceOperator());
        LogicalVariable lVar = translateExpression(queryBody, tCtx);
        LogicalVariable iLVar = newLogicalVariable();
        UnnestOperator unnest = new UnnestOperator(iLVar, mutable(ufce(BuiltinOperators.ITERATE, vre(lVar))));
        unnest.getInputs().add(mutable(tCtx.op));
        List<Mutable<ILogicalExpression>> exprs = new ArrayList<Mutable<ILogicalExpression>>();
        exprs.add(mutable(vre(iLVar)));
        QueryResultSetDataSink sink = new QueryResultSetDataSink(ccb.getResultSetId(), null);
        DistributeResultOperator op = new DistributeResultOperator(exprs, sink);
        op.getInputs().add(mutable(unnest));
        ALogicalPlanImpl lp = new ALogicalPlanImpl(mutable(op));

        return lp;
    }

    private LogicalVariable translateExpression(ASTNode value, TranslationContext tCtx) throws SystemException {
        switch (value.getTag()) {
            case EXPRESSION: {
                ExprNode node = (ExprNode) value;
                return translateExprNode(tCtx, node);
            }

            case UNARY_EXPRESSION: {
                UnaryExprNode ueNode = (UnaryExprNode) value;
                return translateUnaryExprNode(tCtx, ueNode);
            }

            case INFIX_EXPRESSION: {
                InfixExprNode ie = (InfixExprNode) value;
                return translateInfixExprNode(tCtx, ie);
            }

            case ENCLOSED_EXPRESSION: {
                EnclosedExprNode ee = (EnclosedExprNode) value;
                return translateEnclosedExprNode(tCtx, ee);
            }

            case PATH_EXPRESSION:
                return translatePathExpr((PathExprNode) value, tCtx);

            case FUNCTION_EXPRESSION: {
                FunctionExprNode fnNode = (FunctionExprNode) value;
                return translateFunctionExprNode(tCtx, fnNode);
            }

            case TYPE_EXPRESSION: {
                TypeExprNode teNode = (TypeExprNode) value;
                return translateTypeExprNode(tCtx, teNode);
            }

            case EXTENSION_EXPRESSION: {
                ExtensionExprNode eNode = (ExtensionExprNode) value;
                return translateExtensionExprNode(tCtx, eNode);
            }

            case PARENTHESIZED_EXPRESSION: {
                ParenthesizedExprNode peNode = (ParenthesizedExprNode) value;
                return translateParenthisizedExprNode(tCtx, peNode);
            }

            case LITERAL: {
                LiteralNode lNode = (LiteralNode) value;
                return translateLiteralNode(tCtx, lNode);
            }

            case DIRECT_PI_CONSTRUCTOR: {
                DirectPIConstructorNode dpicNode = (DirectPIConstructorNode) value;
                return translateDirectPIConstructorNode(tCtx, dpicNode);
            }

            case DIRECT_COMMENT_CONSTRUCTOR: {
                DirectCommentConstructorNode dccNode = (DirectCommentConstructorNode) value;
                return translateDirectCommentConstructorNode(tCtx, dccNode);
            }

            case DIRECT_ELEMENT_CONSTRUCTOR: {
                DirectElementConstructorNode decNode = (DirectElementConstructorNode) value;
                return translateDirectElementConstructorNode(tCtx, decNode);
            }

            case DIRECT_ATTRIBUTE_CONSTRUCTOR: {
                DirectAttributeConstructorNode dacNode = (DirectAttributeConstructorNode) value;
                return translateDirectAttributeConstructorNode(tCtx, dacNode);
            }

            case CONTEXT_ITEM:
                return tCtx.varScope.lookupVariable(XMLQueryCompilerConstants.DOT_VAR_NAME).getLogicalVariable();

            case IF_EXPRESSION: {
                IfExprNode ieNode = (IfExprNode) value;
                return translateIfExprNode(tCtx, ieNode);
            }

            case VARIABLE_REFERENCE: {
                VarRefNode vrNode = (VarRefNode) value;
                return translateVarRefNode(tCtx, vrNode);
            }

            case FLWOR_EXPRESSION: {
                FLWORExprNode fNode = (FLWORExprNode) value;
                return translateFLWORExprNode(tCtx, fNode);
            }

            case QUANTIFIED_EXPRESSION: {
                QuantifiedExprNode qeNode = (QuantifiedExprNode) value;
                return translateQuantifiedExprNode(tCtx, qeNode);
            }

                /*
                        case TYPESWITCH_EXPRESSION: {
                            TypeswitchExprNode teNode = (TypeswitchExprNode) value;
                            Expression sExpr = translateExpression(teNode.getSwitchExpr());
                            ForLetVariable tVar = new ForLetVariable(VarTag.LET, createVarName(), sExpr);
                            tVar.setDeclaredStaticType(SequenceType.create(AnyItemType.INSTANCE, Quantifier.QUANT_STAR));
                            pushVariableScope();
                            varScope.registerVariable(tVar);
                            List<TypeswitchExpression.Case> cases = new ArrayList<TypeswitchExpression.Case>();
                            for (CaseClauseNode ccNode : teNode.getCaseClauses()) {
                                SequenceType type = createSequenceType(ccNode.getType());
                                ForLetVariable caseVar = null;
                                pushVariableScope();
                                if (ccNode.getCaseVar() != null) {
                                    caseVar = new ForLetVariable(VarTag.LET, createQName(ccNode.getCaseVar()), new TreatExpression(
                                            currCtx, new VariableReferenceExpression(currCtx, tVar), type));
                                    caseVar.setDeclaredStaticType(type);
                                    varScope.registerVariable(caseVar);
                                }
                                Expression cExpr = translateExpression(ccNode.getValueExpr());
                                TypeswitchExpression.Case c = new TypeswitchExpression.Case(caseVar, type, cExpr);
                                cases.add(c);
                                popVariableScope();
                            }
                            Expression dExpr = translateExpression(teNode.getDefaultClause());
                            popVariableScope();
                            return new TypeswitchExpression(currCtx, tVar, cases, dExpr);
                        }
                        */

            case COMPUTED_TEXT_CONSTRUCTOR: {
                ComputedTextConstructorNode cNode = (ComputedTextConstructorNode) value;
                return translateComputedTextConstructorNode(tCtx, cNode);
            }

            case COMPUTED_PI_CONSTRUCTOR: {
                ComputedPIConstructorNode cNode = (ComputedPIConstructorNode) value;
                return translateComputedPIConstructorNode(tCtx, cNode);
            }

            case COMPUTED_COMMENT_CONSTRUCTOR: {
                ComputedCommentConstructorNode cNode = (ComputedCommentConstructorNode) value;
                return translateComputedCommentConstructorNode(tCtx, cNode);
            }

            case COMPUTED_DOCUMENT_CONSTRUCTOR: {
                ComputedDocumentConstructorNode cNode = (ComputedDocumentConstructorNode) value;
                return translateComputedDocumentConstructorNode(tCtx, cNode);
            }

            case COMPUTED_ELEMENT_CONSTRUCTOR: {
                ComputedElementConstructorNode cNode = (ComputedElementConstructorNode) value;
                return translateComputedElementConstructorNode(tCtx, cNode);
            }

            case ARRAY_CONSTRUCTOR: {
                ArrayConstructor aNode = (ArrayConstructor) value;
                return translateArrayConstructor(tCtx, aNode);
            }

            case COMPUTED_ATTRIBUTE_CONSTRUCTOR: {
                ComputedAttributeConstructorNode cNode = (ComputedAttributeConstructorNode) value;
                return translateComputedAttributeConstructorNode(tCtx, cNode);
            }

            case QNAME: {
                QNameNode qnNode = (QNameNode) value;
                return translateQNameNode(tCtx, qnNode);
            }

            case NCNAME: {
                NCNameNode ncnNode = (NCNameNode) value;
                return translateNCNameNode(tCtx, ncnNode);
            }

            case CDATA_SECTION: {
                CDataSectionNode cdsNode = (CDataSectionNode) value;
                return translateCDataSectionNode(tCtx, cdsNode);
            }

            case ORDERED_EXPRESSION: {
                OrderedExprNode oeNode = (OrderedExprNode) value;
                return translateOrderedExprNode(tCtx, oeNode);
            }

            case UNORDERED_EXPRESSION: {
                UnorderedExprNode ueNode = (UnorderedExprNode) value;
                return translateUnorderedExprNode(tCtx, ueNode);
            }

            case VALIDATE_EXPRESSION: {
                ValidateExprNode vNode = (ValidateExprNode) value;
                return translateValidateExprNode(tCtx, vNode);
            }

            default:
                throw new IllegalStateException("Unknown node: " + value.getTag());

        }
    }

    private LogicalVariable translateQuantifiedExprNode(TranslationContext tCtx, QuantifiedExprNode qeNode)
            throws SystemException {
        tCtx = tCtx.pushContext();
        int pushCount = 0;
        for (QuantifiedVarDeclNode qvdNode : qeNode.getVariables()) {
            ILogicalExpression seq = vre(translateExpression(qvdNode.getSequence(), tCtx));
            tCtx.pushVariableScope();
            LogicalVariable forLVar = newLogicalVariable();
            UnnestOperator unnest = new UnnestOperator(forLVar, mutable(ufce(BuiltinOperators.ITERATE, seq)));
            SequenceType forVarType = SequenceType.create(AnyItemType.INSTANCE, Quantifier.QUANT_ONE);
            if (qvdNode.getType() != null) {
                forVarType = createSequenceType(qvdNode.getType());
            }
            XQueryVariable forVar = new XQueryVariable(createQName(qvdNode.getVariable()), forVarType, forLVar);
            tCtx.varScope.registerVariable(forVar);
            unnest.getInputs().add(mutable(tCtx.op));
            tCtx.op = unnest;
            ++pushCount;
        }
        ILogicalExpression satExpr = sfce(BuiltinFunctions.FN_BOOLEAN_1,
                vre(translateExpression(qeNode.getSatisfiesExpr(), tCtx)));
        if (qeNode.getQuant() == QuantifierType.EVERY) {
            satExpr = sfce(BuiltinFunctions.FN_NOT_1, satExpr);
        }
        SelectOperator select = new SelectOperator(mutable(satExpr), false, null);
        select.getInputs().add(mutable(tCtx.op));
        tCtx.op = select;
        List<LogicalVariable> vars = new ArrayList<LogicalVariable>();
        List<Mutable<ILogicalExpression>> exprs = new ArrayList<Mutable<ILogicalExpression>>();
        LogicalVariable var = newLogicalVariable();
        vars.add(var);
        exprs.add(mutable(afce(BuiltinOperators.SEQUENCE, false,
                ce(SequenceType.create(BuiltinTypeRegistry.XS_BOOLEAN, Quantifier.QUANT_ONE), Boolean.TRUE))));
        AggregateOperator aop = new AggregateOperator(vars, exprs);
        aop.getInputs().add(mutable(tCtx.op));
        tCtx.op = aop;
        for (int i = 0; i < pushCount; ++i) {
            tCtx.popVariableScope();
        }
        tCtx = tCtx.popContext();
        LogicalVariable lVar = createAssignment(sfce(
                qeNode.getQuant() == QuantifierType.EVERY ? BuiltinFunctions.FN_EMPTY_1 : BuiltinFunctions.FN_EXISTS_1,
                vre(var)), tCtx);
        return lVar;
    }

    private LogicalVariable translateUnorderedExprNode(TranslationContext tCtx, UnorderedExprNode ueNode)
            throws SystemException {
        LogicalVariable lVar = createAssignment(
                sfce(BuiltinOperators.UNORDERED, vre(translateExpression(ueNode.getExpr(), tCtx))), tCtx);
        return lVar;
    }

    private LogicalVariable translateOrderedExprNode(TranslationContext tCtx, OrderedExprNode oeNode)
            throws SystemException {
        LogicalVariable lVar = createAssignment(
                sfce(BuiltinOperators.ORDERED, vre(translateExpression(oeNode.getExpr(), tCtx))), tCtx);
        return lVar;
    }

    private LogicalVariable translateCDataSectionNode(TranslationContext tCtx, CDataSectionNode cdsNode)
            throws SystemException {
        LogicalVariable lVar = createAssignment(sfce(BuiltinOperators.TEXT_CONSTRUCTOR,
                ce(SequenceType.create(BuiltinTypeRegistry.XS_UNTYPED_ATOMIC, Quantifier.QUANT_ONE),
                        cdsNode.getContent())),
                tCtx);
        return lVar;
    }

    private LogicalVariable translateNCNameNode(TranslationContext tCtx, NCNameNode ncnNode) throws SystemException {
        LogicalVariable lVar = createAssignment(
                ce(SequenceType.create(BuiltinTypeRegistry.XS_STRING, Quantifier.QUANT_ONE), ncnNode.getName()), tCtx);
        return lVar;
    }

    private LogicalVariable translateQNameNode(TranslationContext tCtx, QNameNode qnNode) throws SystemException {
        LogicalVariable lVar = createAssignment(
                ce(SequenceType.create(BuiltinTypeRegistry.XS_QNAME, Quantifier.QUANT_ONE), createQName(qnNode)), tCtx);
        return lVar;
    }

    private LogicalVariable translateValidateExprNode(TranslationContext tCtx, ValidateExprNode vNode)
            throws SystemException {
        XQueryConstants.ValidationMode mode = vNode.getMode();
        Function fn = mode == null || XQueryConstants.ValidationMode.STRICT.equals(mode)
                ? BuiltinOperators.VALIDATE_STRICT : BuiltinOperators.VALIDATE_LAX;
        LogicalVariable lVar = createAssignment(sfce(fn, vre(translateExpression(vNode.getExpr(), tCtx))), tCtx);
        return lVar;
    }

    private LogicalVariable translateComputedAttributeConstructorNode(TranslationContext tCtx,
            ComputedAttributeConstructorNode cNode) throws SystemException {
        ILogicalExpression name = cast(vre(translateExpression(cNode.getName(), tCtx)),
                SequenceType.create(BuiltinTypeRegistry.XS_QNAME, Quantifier.QUANT_ONE));
        ASTNode content = cNode.getContent();
        ILogicalExpression cExpr = content == null ? sfce(BuiltinOperators.CONCATENATE)
                : vre(translateExpression(content, tCtx));
        LogicalVariable lVar = createAssignment(sfce(BuiltinOperators.ATTRIBUTE_CONSTRUCTOR, name, cExpr), tCtx);
        return lVar;
    }

    private LogicalVariable translateComputedElementConstructorNode(TranslationContext tCtx,
            ComputedElementConstructorNode cNode) throws SystemException {
        ILogicalExpression name = cast(vre(translateExpression(cNode.getName(), tCtx)),
                SequenceType.create(BuiltinTypeRegistry.XS_QNAME, Quantifier.QUANT_ONE));
        ASTNode content = cNode.getContent();
        ILogicalExpression cExpr = content == null ? sfce(BuiltinOperators.CONCATENATE)
                : vre(translateExpression(content, tCtx));
        LogicalVariable lVar = createAssignment(sfce(BuiltinOperators.ELEMENT_CONSTRUCTOR, name, cExpr), tCtx);
        return lVar;
    }

    private LogicalVariable translateArrayConstructor(TranslationContext tCtx, ArrayConstructor aNode)
            throws SystemException {
        ASTNode expression = aNode.getExpression();
        ILogicalExpression aExpr = expression == null ? sfce(BuiltinOperators.CONCATENATE)
                : vre(translateExpression(expression, tCtx));
        LogicalVariable lVar = createAssignment(sfce(BuiltinOperators.ARRAY_CONSTRUCTOR, aExpr), tCtx);
        return lVar;
    }

    private LogicalVariable translateComputedDocumentConstructorNode(TranslationContext tCtx,
            ComputedDocumentConstructorNode cNode) throws SystemException {
        LogicalVariable lVar = createAssignment(
                sfce(BuiltinOperators.DOCUMENT_CONSTRUCTOR, vre(translateExpression(cNode.getContent(), tCtx))), tCtx);
        return lVar;
    }

    private LogicalVariable translateComputedCommentConstructorNode(TranslationContext tCtx,
            ComputedCommentConstructorNode cNode) throws SystemException {
        ASTNode content = cNode.getContent();
        LogicalVariable lVar = createAssignment(
                sfce(BuiltinOperators.COMMENT_CONSTRUCTOR,
                        content == null ? sfce(BuiltinOperators.CONCATENATE) : vre(translateExpression(content, tCtx))),
                tCtx);
        return lVar;
    }

    private LogicalVariable translateComputedPIConstructorNode(TranslationContext tCtx, ComputedPIConstructorNode cNode)
            throws SystemException {
        ASTNode content = cNode.getContent();
        LogicalVariable lVar = createAssignment(
                sfce(BuiltinOperators.PI_CONSTRUCTOR, vre(translateExpression(cNode.getTarget(), tCtx)),
                        content == null ? sfce(BuiltinOperators.CONCATENATE) : vre(translateExpression(content, tCtx))),
                tCtx);
        return lVar;
    }

    private LogicalVariable translateComputedTextConstructorNode(TranslationContext tCtx,
            ComputedTextConstructorNode cNode) throws SystemException {
        ASTNode content = cNode.getContent();
        LogicalVariable lVar = createAssignment(sfce(BuiltinOperators.TEXT_CONSTRUCTOR,
                content == null
                        ? ce(SequenceType.create(BuiltinTypeRegistry.XS_UNTYPED_ATOMIC, Quantifier.QUANT_ONE), "")
                        : vre(translateExpression(content, tCtx))),
                tCtx);
        return lVar;
    }

    private LogicalVariable translateFLWORExprNode(TranslationContext tCtx, FLWORExprNode fNode)
            throws SystemException {
        tCtx = tCtx.pushContext();
        List<FLWORClauseNode> cNodes = fNode.getClauses();
        int pushCount = 0;
        for (FLWORClauseNode cNode : cNodes) {
            switch (cNode.getTag()) {
                case FOR_CLAUSE: {
                    ForClauseNode fcNode = (ForClauseNode) cNode;
                    for (ForVarDeclNode fvdNode : fcNode.getVariables()) {
                        ILogicalExpression seq = vre(translateExpression(fvdNode.getSequence(), tCtx));
                        tCtx.pushVariableScope();
                        LogicalVariable forLVar = newLogicalVariable();
                        LogicalVariable posLVar = fvdNode.getPosVar() != null ? newLogicalVariable() : null;
                        UnnestOperator unnest = new UnnestOperator(forLVar,
                                mutable(ufce(BuiltinOperators.ITERATE, seq)), posLVar, BuiltinTypeRegistry.XS_INTEGER,
                                new VXQueryPositionWriter());
                        SequenceType forVarType = SequenceType.create(AnyItemType.INSTANCE, Quantifier.QUANT_ONE);
                        if (fvdNode.getType() != null) {
                            forVarType = createSequenceType(fvdNode.getType());
                        }
                        XQueryVariable forVar = new XQueryVariable(createQName(fvdNode.getForVar()), forVarType,
                                forLVar);
                        tCtx.varScope.registerVariable(forVar);
                        XQueryVariable posVar = null;
                        if (fvdNode.getPosVar() != null) {
                            posVar = new XQueryVariable(createQName(fvdNode.getPosVar()),
                                    SequenceType.create(BuiltinTypeRegistry.XS_INTEGER, Quantifier.QUANT_ONE), posLVar);
                            tCtx.varScope.registerVariable(posVar);
                        }
                        assert fvdNode.getScoreVar() == null;
                        unnest.getInputs().add(mutable(tCtx.op));
                        tCtx.op = unnest;
                        ++pushCount;
                    }
                    break;
                }
                case LET_CLAUSE: {
                    LetClauseNode lcNode = (LetClauseNode) cNode;
                    for (LetVarDeclNode lvdNode : lcNode.getVariables()) {
                        LogicalVariable seqVar = translateExpression(lvdNode.getSequence(), tCtx);
                        tCtx.pushVariableScope();
                        SequenceType letVarType = SequenceType.create(AnyItemType.INSTANCE, Quantifier.QUANT_STAR);
                        if (lvdNode.getType() != null) {
                            letVarType = createSequenceType(lvdNode.getType());
                        }
                        XQueryVariable letVar = new XQueryVariable(createQName(lvdNode.getLetVar()), letVarType,
                                seqVar);
                        tCtx.varScope.registerVariable(letVar);
                        ++pushCount;
                    }
                    break;
                }
                case WHERE_CLAUSE: {
                    WhereClauseNode wcNode = (WhereClauseNode) cNode;
                    ILogicalExpression condExpr = sfce(BuiltinFunctions.FN_BOOLEAN_1,
                            vre(translateExpression(wcNode.getCondition(), tCtx)));
                    SelectOperator select = new SelectOperator(mutable(condExpr), false, null);
                    select.getInputs().add(mutable(tCtx.op));
                    tCtx.op = select;
                    break;
                }
                case ORDERBY_CLAUSE: {
                    OrderbyClauseNode ocNode = (OrderbyClauseNode) cNode;
                    List<org.apache.hyracks.algebricks.common.utils.Pair<OrderOperator.IOrder, Mutable<ILogicalExpression>>> oExprs = new ArrayList<org.apache.hyracks.algebricks.common.utils.Pair<OrderOperator.IOrder, Mutable<ILogicalExpression>>>();
                    List<String> collations = new ArrayList<String>();
                    for (OrderSpecNode osNode : ocNode.getOrderSpec()) {
                        ILogicalExpression aExpr = data(vre(translateExpression(osNode.getExpression(), tCtx)));
                        ILogicalExpression oExpr = vre(createAssignment(aExpr, tCtx));
                        OrderOperator.IOrder o = OrderOperator.ASC_ORDER;
                        XQueryConstants.OrderDirection oDir = osNode.getDirection();
                        if (oDir != null) {
                            switch (oDir) {
                                case ASCENDING:
                                    o = OrderOperator.ASC_ORDER;
                                    break;
                                case DESCENDING:
                                    o = OrderOperator.DESC_ORDER;
                                    break;
                            }
                        }
                        /*
                        StaticContext.EmptyOrderProperty eoProp = osNode.getEmptyOrder();
                        if (eoProp != null) {
                            switch (osNode.getEmptyOrder()) {
                                case GREATEST:
                                    eOrders.add(FLWORExpression.EmptyOrder.GREATEST);
                                    break;
                                case LEAST:
                                    eOrders.add(FLWORExpression.EmptyOrder.LEAST);
                                    break;
                            }
                        } else {
                            eOrders.add(FLWORExpression.EmptyOrder.DEFAULT);
                        }
                        collations.add(osNode.getCollation());
                        */
                        oExprs.add(
                                new org.apache.hyracks.algebricks.common.utils.Pair<OrderOperator.IOrder, Mutable<ILogicalExpression>>(
                                        o, mutable(oExpr)));
                    }
                    OrderOperator order = new OrderOperator(oExprs);
                    order.getInputs().add(mutable(tCtx.op));
                    tCtx.op = order;
                    break;
                }
                default:
                    throw new IllegalStateException("Unknown clause: " + cNode.getTag());
            }
        }
        ILogicalExpression rExpr = vre(translateExpression(fNode.getReturnExpr(), tCtx));
        List<LogicalVariable> vars = new ArrayList<LogicalVariable>();
        List<Mutable<ILogicalExpression>> exprs = new ArrayList<Mutable<ILogicalExpression>>();
        LogicalVariable var = newLogicalVariable();
        vars.add(var);
        exprs.add(mutable(afce(BuiltinOperators.SEQUENCE, false, rExpr)));
        AggregateOperator aop = new AggregateOperator(vars, exprs);
        aop.getInputs().add(mutable(tCtx.op));
        tCtx.op = aop;
        for (int i = 0; i < pushCount; ++i) {
            tCtx.popVariableScope();
        }
        tCtx = tCtx.popContext();
        return var;
    }

    private LogicalVariable translateVarRefNode(TranslationContext tCtx, VarRefNode vrNode) throws SystemException {
        QName vName = createQName(vrNode.getVariable());
        XQueryVariable var = tCtx.varScope.lookupVariable(vName);
        if (var == null) {
            throw new SystemException(ErrorCode.XPST0008, vrNode.getSourceLocation());
        }
        LogicalVariable lVar = createAssignment(treat(vre(var.getLogicalVariable()), var.getType()), tCtx);
        return lVar;
    }

    private LogicalVariable translateIfExprNode(TranslationContext tCtx, IfExprNode ieNode) throws SystemException {
        ILogicalExpression cond = sfce(BuiltinFunctions.FN_BOOLEAN_1,
                vre(translateExpression(ieNode.getIfExpr(), tCtx)));
        ILogicalExpression tExpr = vre(translateExpression(ieNode.getThenExpr(), tCtx));
        ILogicalExpression eExpr = vre(translateExpression(ieNode.getElseExpr(), tCtx));
        LogicalVariable lVar = createAssignment(sfce(BuiltinOperators.IF_THEN_ELSE, cond, tExpr, eExpr), tCtx);
        return lVar;
    }

    private LogicalVariable translateDirectAttributeConstructorNode(TranslationContext tCtx,
            DirectAttributeConstructorNode dacNode) throws SystemException {
        QName aQName = createQName(dacNode.getName());
        ILogicalExpression name = ce(SequenceType.create(BuiltinTypeRegistry.XS_QNAME, Quantifier.QUANT_ONE), aQName);
        List<ILogicalExpression> content = new ArrayList<ILogicalExpression>();
        for (ASTNode aVal : dacNode.getValue()) {
            switch (aVal.getTag()) {
                case CONTENT_CHARS: {
                    String contentChars = ((ContentCharsNode) aVal).getContent();
                    ILogicalExpression cce = ce(
                            SequenceType.create(BuiltinTypeRegistry.XS_UNTYPED_ATOMIC, Quantifier.QUANT_ONE),
                            contentChars);
                    content.add(cce);
                    break;
                }

                default:
                    content.add(data(vre(translateExpression(aVal, tCtx))));
            }
        }
        ILogicalExpression contentExpr = content.size() == 1 ? content.get(0)
                : sfce(BuiltinOperators.CONCATENATE, content.toArray(new ILogicalExpression[content.size()]));
        LogicalVariable lVar = createAssignment(sfce(BuiltinOperators.ATTRIBUTE_CONSTRUCTOR, name, contentExpr), tCtx);
        return lVar;
    }

    private LogicalVariable translateDirectElementConstructorNode(TranslationContext tCtx,
            DirectElementConstructorNode decNode) throws SystemException {
        QNameNode startName = decNode.getStartTagName();
        QNameNode endName = decNode.getEndTagName();
        if (endName != null && (!startName.getPrefix().equals(endName.getPrefix())
                || !startName.getLocalName().equals(endName.getLocalName()))) {
            throw new SystemException(ErrorCode.XPST0003, endName.getSourceLocation());
        }
        pushContext();
        for (DirectAttributeConstructorNode acNode : decNode.getAttributes()) {
            QNameNode aName = acNode.getName();
            if ("xmlns".equals(aName.getPrefix())) {
                List<ASTNode> values = acNode.getValue();
                if (values.size() != 1 || !ASTTag.CONTENT_CHARS.equals(values.get(0).getTag())) {
                    throw new SystemException(ErrorCode.XQST0022, acNode.getSourceLocation());
                }

                currCtx.registerNamespaceUri(aName.getLocalName(),
                        unquote(((ContentCharsNode) values.get(0)).getContent()));
            }
        }
        List<ILogicalExpression> content = new ArrayList<ILogicalExpression>();
        for (DirectAttributeConstructorNode acNode : decNode.getAttributes()) {
            QNameNode aName = acNode.getName();
            if (!"xmlns".equals(aName.getPrefix())) {
                content.add(vre(translateExpression(acNode, tCtx)));
            }
        }
        ILogicalExpression name = ce(SequenceType.create(BuiltinTypeRegistry.XS_QNAME, Quantifier.QUANT_ONE),
                createQName(startName, moduleCtx.getDefaultElementNamespaceUri()));
        for (ASTNode cVal : decNode.getContent()) {
            switch (cVal.getTag()) {
                case CONTENT_CHARS: {
                    String contentChars = ((ContentCharsNode) cVal).getContent();
                    ILogicalExpression cce = ce(
                            SequenceType.create(BuiltinTypeRegistry.XS_UNTYPED_ATOMIC, Quantifier.QUANT_ONE),
                            contentChars);
                    content.add(sfce(BuiltinOperators.TEXT_CONSTRUCTOR, cce));
                    break;
                }

                default:
                    content.add(vre(translateExpression(cVal, tCtx)));
            }
        }
        popContext();
        ILogicalExpression contentExpr = content.size() == 1 ? content.get(0)
                : sfce(BuiltinOperators.CONCATENATE, content.toArray(new ILogicalExpression[content.size()]));
        LogicalVariable lVar = createAssignment(sfce(BuiltinOperators.ELEMENT_CONSTRUCTOR, name, contentExpr), tCtx);
        return lVar;
    }

    private LogicalVariable translateDirectCommentConstructorNode(TranslationContext tCtx,
            DirectCommentConstructorNode dccNode) throws SystemException {
        String content = dccNode.getContent();
        LogicalVariable lVar = createAssignment(sfce(BuiltinOperators.COMMENT_CONSTRUCTOR,
                ce(SequenceType.create(BuiltinTypeRegistry.XS_STRING, Quantifier.QUANT_ONE), content)), tCtx);
        return lVar;
    }

    private LogicalVariable translateDirectPIConstructorNode(TranslationContext tCtx, DirectPIConstructorNode dpicNode)
            throws SystemException {
        String target = dpicNode.getTarget();
        String content = dpicNode.getContent();
        LogicalVariable lVar = createAssignment(sfce(BuiltinOperators.PI_CONSTRUCTOR,
                ce(SequenceType.create(BuiltinTypeRegistry.XS_STRING, Quantifier.QUANT_ONE), target),
                ce(SequenceType.create(BuiltinTypeRegistry.XS_STRING, Quantifier.QUANT_ONE), content)), tCtx);
        return lVar;
    }

    private LogicalVariable translateLiteralNode(TranslationContext tCtx, LiteralNode lNode) throws SystemException {
        String image = lNode.getImage();
        LiteralNode.LiteralType lType = lNode.getType();
        SequenceType t = null;
        Object value = null;
        switch (lType) {
            case DECIMAL:
                t = SequenceType.create(BuiltinTypeRegistry.XS_DECIMAL, Quantifier.QUANT_ONE);
                value = Double.parseDouble(image);
                break;
            case DOUBLE:
                t = SequenceType.create(BuiltinTypeRegistry.XS_DOUBLE, Quantifier.QUANT_ONE);
                value = Double.parseDouble(image);
                break;
            case INTEGER:
                t = SequenceType.create(BuiltinTypeRegistry.XS_INTEGER, Quantifier.QUANT_ONE);
                try {
                    value = Long.parseLong(image);
                } catch (NumberFormatException nfe) {
                    throw new SystemException(ErrorCode.FOAR0002);
                }
                break;
            case STRING:
                t = SequenceType.create(BuiltinTypeRegistry.XS_STRING, Quantifier.QUANT_ONE);
                value = unquote(image);
                break;
            default:
                throw new IllegalStateException("Unknown type: " + lType);
        }
        LogicalVariable lVar = createAssignment(ce(t, value), tCtx);
        return lVar;
    }

    private LogicalVariable translateParenthisizedExprNode(TranslationContext tCtx, ParenthesizedExprNode peNode)
            throws SystemException {
        ASTNode eNode = peNode.getExpr();
        if (eNode == null) {
            return createConcatenation(Collections.<LogicalVariable> emptyList(), tCtx);
        }
        return translateExpression(peNode.getExpr(), tCtx);
    }

    private LogicalVariable translateExtensionExprNode(TranslationContext tCtx, ExtensionExprNode eNode)
            throws SystemException {
        if (eNode.getExpr() == null) {
            throw new SystemException(ErrorCode.XQST0079, eNode.getSourceLocation());
        }
        return translateExpression(eNode.getExpr(), tCtx);
    }

    private LogicalVariable translateTypeExprNode(TranslationContext tCtx, TypeExprNode teNode) throws SystemException {
        LogicalVariable var = translateExpression(teNode.getExpr(), tCtx);
        SequenceType type = createSequenceType(teNode.getType());
        ILogicalExpression expr = null;
        switch (teNode.getOperator()) {
            case CAST:
                expr = cast(vre(var), type);
                break;

            case CASTABLE:
                expr = castable(vre(var), type);
                break;

            case INSTANCEOF:
                expr = instanceOf(vre(var), type);
                break;

            case TREAT:
                expr = treat(vre(var), type);
                break;

            default:
                throw new IllegalStateException("Unknown type operator: " + teNode.getOperator());
        }
        LogicalVariable lVar = createAssignment(expr, tCtx);
        return lVar;
    }

    private LogicalVariable translateFunctionExprNode(TranslationContext tCtx, FunctionExprNode fnNode)
            throws SystemException {
        List<LogicalVariable> args = new ArrayList<LogicalVariable>();
        for (ASTNode an : fnNode.getArguments()) {
            args.add(translateExpression(an, tCtx));
        }
        QName name = createQName(fnNode.getName());
        SchemaType type = moduleCtx.lookupSchemaType(name);
        if (type != null && args.size() < 2) {
            if (!type.isAtomicType()) {
                throw new SystemException(ErrorCode.XPST0051, fnNode.getName().getSourceLocation());
            }
            LogicalVariable var = args.isEmpty()
                    ? tCtx.varScope.lookupVariable(XMLQueryCompilerConstants.DOT_VAR_NAME).getLogicalVariable()
                    : args.get(0);
            ILogicalExpression expr = cast(vre(var), SequenceType.create((ItemType) type, Quantifier.QUANT_QUESTION));
            return createAssignment(expr, tCtx);
        }
        QName fName = createQName(fnNode.getName(), moduleCtx.getDefaultFunctionNamespaceUri());
        if (BuiltinFunctions.FN_POSITION_QNAME.equals(fName)) {
            XQueryVariable var = tCtx.varScope.lookupVariable(XMLQueryCompilerConstants.POS_VAR_NAME);
            return var.getLogicalVariable();
        }
        if (BuiltinFunctions.FN_LAST_QNAME.equals(fName)) {
            XQueryVariable var = tCtx.varScope.lookupVariable(XMLQueryCompilerConstants.LAST_VAR_NAME);
            return var.getLogicalVariable();
        }
        int nArgs = fnNode.getArguments().size();
        Function fn = moduleCtx.lookupFunction(fName, nArgs);
        if (fn != null && fn.useContextImplicitly()) {
            args.add(tCtx.varScope.lookupVariable(XMLQueryCompilerConstants.DOT_VAR_NAME).getLogicalVariable());
            fn = moduleCtx.lookupFunction(fName, nArgs + 1);
        }
        if (fn == null) {
            Function[] fns = moduleCtx.lookupFunctions(fName);
            if (fns != null) {
                for (int i = 0; i < fns.length && i <= nArgs; ++i) {
                    if (fns[i] != null && fns[i].getSignature().isVarArgs()) {
                        fn = fns[i];
                        break;
                    }
                }
            }
        }
        if (fn == null) {
            throw new SystemException(ErrorCode.XPST0017, fnNode.getName().getSourceLocation());
        }
        Signature sign = fn.getSignature();
        List<Mutable<ILogicalExpression>> argExprs = new ArrayList<Mutable<ILogicalExpression>>();
        for (int i = 0; i < args.size(); ++i) {
            SequenceType argType = sign.getParameterType(i);
            argExprs.add(mutable(normalize(vre(args.get(i)), argType)));
        }
        LogicalVariable lVar = createAssignment(new ScalarFunctionCallExpression(fn, argExprs), tCtx);
        return lVar;
    }

    private LogicalVariable translateEnclosedExprNode(TranslationContext tCtx, EnclosedExprNode ee)
            throws SystemException {
        return translateExpression(ee.getExpression(), tCtx);
    }

    private LogicalVariable translateInfixExprNode(TranslationContext tCtx, InfixExprNode ie) throws SystemException {
        Function operator = getOperator(ie.getOperator());
        Signature sign = operator.getSignature();
        LogicalVariable varLeft = translateExpression(ie.getLeftExpr(), tCtx);
        LogicalVariable varRight = translateExpression(ie.getRightExpr(), tCtx);
        ILogicalExpression arg1 = normalize(vre(varLeft), sign.getParameterType(0));
        ILogicalExpression arg2 = normalize(vre(varRight), sign.getParameterType(1));
        if (BuiltinOperators.EXCEPT.equals(operator) || BuiltinOperators.INTERSECT.equals(operator)) {
            arg1 = sfce(BuiltinOperators.SORT_DISTINCT_NODES_ASC, arg1);
            arg2 = sfce(BuiltinOperators.SORT_DISTINCT_NODES_ASC, arg2);
        }
        ILogicalExpression result = sfce(operator, arg1, arg2);
        if (BuiltinOperators.UNION.equals(operator)) {
            result = sfce(BuiltinOperators.SORT_DISTINCT_NODES_ASC, result);
        }
        LogicalVariable lVar = createAssignment(result, tCtx);
        return lVar;
    }

    private LogicalVariable translateUnaryExprNode(TranslationContext tCtx, UnaryExprNode ueNode)
            throws SystemException {
        boolean neg = false;
        for (UnaryExprNode.Sign s : ueNode.getSigns()) {
            if (UnaryExprNode.Sign.MINUS.equals(s)) {
                neg = !neg;
            }
        }
        LogicalVariable var = translateExpression(ueNode.getExpr(), tCtx);
        if (neg) {
            ILogicalExpression nExpr = normalize(vre(var),
                    BuiltinOperators.NUMERIC_UNARY_MINUS.getSignature().getParameterType(0));
            ILogicalExpression negExpr = sfce(BuiltinOperators.NUMERIC_UNARY_MINUS, nExpr);
            var = createAssignment(negExpr, tCtx);
        }
        return var;
    }

    private LogicalVariable translateExprNode(TranslationContext tCtx, ExprNode node) throws SystemException {
        return createConcatenation(translateExpressionList(node.getExpressions(), tCtx), tCtx);
    }

    private LogicalVariable translatePathExpr(PathExprNode pe, TranslationContext tCtx) throws SystemException {
        ILogicalExpression ctxExpr = null;
        PathType type = pe.getPathType();
        if (type != null) {
            XQueryVariable dotVar = tCtx.varScope.lookupVariable(XMLQueryCompilerConstants.DOT_VAR_NAME);
            ILogicalExpression root = sfce(BuiltinFunctions.FN_ROOT_1, vre(dotVar.getLogicalVariable()));
            if (PathType.SLASH.equals(type)) {
                ctxExpr = root;
            } else {
                ctxExpr = sfce(BuiltinOperators.DESCENDANT_OR_SELF,
                        treat(root, SequenceType.create(AnyNodeType.INSTANCE, Quantifier.QUANT_STAR)));
            }
        }

        if (pe.getPaths() != null) {
            for (RelativePathExprNode rpen : pe.getPaths()) {
                boolean asc = true;
                if (PathType.SLASH_SLASH.equals(rpen.getPathType())) {
                    tCtx = tCtx.pushContext();
                    tCtx.pushVariableScope();
                    iterateOver(ctxExpr, tCtx);
                    ctxExpr = vre(
                            tCtx.varScope.lookupVariable(XMLQueryCompilerConstants.DOT_VAR_NAME).getLogicalVariable());
                    ctxExpr = sfce(BuiltinOperators.DESCENDANT_OR_SELF,
                            treat(ctxExpr, SequenceType.create(AnyNodeType.INSTANCE, Quantifier.QUANT_STAR)));
                    List<LogicalVariable> vars = new ArrayList<LogicalVariable>();
                    List<Mutable<ILogicalExpression>> exprs = new ArrayList<Mutable<ILogicalExpression>>();
                    LogicalVariable var = newLogicalVariable();
                    vars.add(var);
                    exprs.add(mutable(afce(BuiltinOperators.SEQUENCE, false, ctxExpr)));
                    AggregateOperator aop = new AggregateOperator(vars, exprs);
                    aop.getInputs().add(mutable(tCtx.op));
                    tCtx.op = aop;
                    tCtx = tCtx.popContext();
                    ctxExpr = vre(var);
                }
                boolean popScope = false;
                if (ctxExpr != null) {
                    popScope = true;
                    tCtx = tCtx.pushContext();
                    tCtx.pushVariableScope();
                    iterateOver(ctxExpr, tCtx);
                    ctxExpr = null;
                }

                List<ASTNode> predicates = null;

                ASTNode pathNode = rpen.getPath();
                if (ASTTag.AXIS_STEP.equals(pathNode.getTag())) {
                    AxisStepNode axisNode = (AxisStepNode) pathNode;
                    predicates = axisNode.getPredicates();
                    AxisStepNode.Axis axis = axisNode.getAxis();
                    if (ctxExpr == null) {
                        ctxExpr = vre(tCtx.varScope.lookupVariable(XMLQueryCompilerConstants.DOT_VAR_NAME)
                                .getLogicalVariable());
                    }
                    Function axisFn = translateAxis(axis);
                    NodeType nt = translateNodeTest(axis, axisNode.getNodeTest());
                    int ntCode = currCtx.encodeSequenceType(SequenceType.create(nt, Quantifier.QUANT_ONE));
                    ctxExpr = sfce(axisFn,
                            treat(ctxExpr, SequenceType.create(AnyNodeType.INSTANCE, Quantifier.QUANT_STAR)),
                            ce(SequenceType.create(BuiltinTypeRegistry.XS_INT, Quantifier.QUANT_ONE), ntCode));
                    asc = isForwardAxis(axis);
                } else if (ASTTag.FILTER_EXPRESSION.equals(pathNode.getTag())) {
                    FilterExprNode filterNode = (FilterExprNode) pathNode;
                    predicates = filterNode.getPredicates();
                    ctxExpr = vre(translateExpression(filterNode.getExpr(), tCtx));
                } else {
                    throw new IllegalStateException("Unknown path node: " + pathNode.getTag());
                }
                if (predicates != null && !predicates.isEmpty()) {
                    ctxExpr = vre(createAssignment(ctxExpr, tCtx));
                    ctxExpr = sfce(asc ? BuiltinOperators.SORT_DISTINCT_NODES_ASC_OR_ATOMICS
                            : BuiltinOperators.SORT_DISTINCT_NODES_DESC_OR_ATOMICS, ctxExpr);
                    iterateOver(ctxExpr, tCtx);
                    int i = 0;
                    ILogicalExpression selectCondition = null;
                    for (ASTNode pn : predicates) {
                        // Handles integer, boolean expression, path expression exists
                        // TODO Support inner focus between predicates.
                        LogicalVariable pLVar = translateExpression(pn, tCtx);
                        ILogicalExpression tTest = instanceOf(vre(pLVar),
                                SequenceType.create(BuiltinTypeRegistry.XSEXT_NUMERIC, Quantifier.QUANT_ONE));
                        ILogicalExpression posTest = sfce(BuiltinOperators.VALUE_EQ, vre(pLVar), vre(tCtx.varScope
                                .lookupVariable(XMLQueryCompilerConstants.POS_VAR_NAME).getLogicalVariable()));
                        ILogicalExpression boolTestTmp = vre(pLVar);
                        if (tCtx.op.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
                            ILogicalExpression expression = ((AssignOperator) tCtx.op).getExpressions().get(0)
                                    .getValue();
                            if (expression.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL
                                    && ((AbstractFunctionCallExpression) expression).getFunctionIdentifier()
                                            .equals(BuiltinOperators.CHILD.getFunctionIdentifier())) {
                                boolTestTmp = sfce(BuiltinFunctions.FN_COUNT_1, boolTestTmp);
                            }
                        }
                        ILogicalExpression boolTest = sfce(BuiltinFunctions.FN_BOOLEAN_1, boolTestTmp);
                        ILogicalExpression condition = sfce(BuiltinOperators.IF_THEN_ELSE, tTest, posTest, boolTest);
                        if (i++ == 0) {
                            selectCondition = condition;
                        } else {
                            selectCondition = sfce(BuiltinOperators.AND, selectCondition, condition);
                        }
                    }
                    SelectOperator select = new SelectOperator(mutable(selectCondition), false, null);
                    select.getInputs().add(mutable(tCtx.op));
                    tCtx.op = select;
                    ctxExpr = vre(
                            tCtx.varScope.lookupVariable(XMLQueryCompilerConstants.DOT_VAR_NAME).getLogicalVariable());
                }
                if (popScope) {
                    tCtx.popVariableScope();
                    List<LogicalVariable> vars = new ArrayList<LogicalVariable>();
                    List<Mutable<ILogicalExpression>> exprs = new ArrayList<Mutable<ILogicalExpression>>();
                    LogicalVariable var = newLogicalVariable();
                    vars.add(var);
                    exprs.add(mutable(afce(BuiltinOperators.SEQUENCE, false, ctxExpr)));
                    AggregateOperator aop = new AggregateOperator(vars, exprs);
                    aop.getInputs().add(mutable(tCtx.op));
                    tCtx.op = aop;
                    tCtx = tCtx.popContext();
                    ctxExpr = vre(var);
                    ctxExpr = sfce(asc ? BuiltinOperators.SORT_DISTINCT_NODES_ASC_OR_ATOMICS
                            : BuiltinOperators.SORT_DISTINCT_NODES_DESC_OR_ATOMICS, vre(var));
                }
            }
        }
        LogicalVariable lVar = createAssignment(ctxExpr, tCtx);
        return lVar;
    }

    private void iterateOver(ILogicalExpression ctxExpr, TranslationContext tCtx) {
        LogicalVariable seqLVar = createAssignment(ctxExpr, tCtx);
        LogicalVariable lastLVar = createAssignment(sfce(BuiltinFunctions.FN_COUNT_1, vre(seqLVar)), tCtx);
        tCtx.varScope.registerVariable(new XQueryVariable(XMLQueryCompilerConstants.LAST_VAR_NAME,
                SequenceType.create(BuiltinTypeRegistry.XS_INTEGER, Quantifier.QUANT_ONE), lastLVar));
        LogicalVariable forLVar = newLogicalVariable();
        LogicalVariable posLVar = newLogicalVariable();
        UnnestOperator unnest = new UnnestOperator(forLVar, mutable(ufce(BuiltinOperators.ITERATE, vre(seqLVar))),
                posLVar, BuiltinTypeRegistry.XS_INTEGER, new VXQueryPositionWriter());
        SequenceType forVarType = SequenceType.create(AnyItemType.INSTANCE, Quantifier.QUANT_ONE);
        XQueryVariable forVar = new XQueryVariable(XMLQueryCompilerConstants.DOT_VAR_NAME, forVarType, forLVar);
        tCtx.varScope.registerVariable(forVar);
        SequenceType posVarType = SequenceType.create(BuiltinTypeRegistry.XS_INTEGER, Quantifier.QUANT_ONE);
        XQueryVariable posVar = new XQueryVariable(XMLQueryCompilerConstants.POS_VAR_NAME, posVarType, posLVar);
        tCtx.varScope.registerVariable(posVar);
        unnest.getInputs().add(mutable(tCtx.op));
        tCtx.op = unnest;
    }

    private boolean isForwardAxis(AxisStepNode.Axis axis) {
        switch (axis) {
            case ABBREV:
            case CHILD:
            case ABBREV_ATTRIBUTE:
            case ATTRIBUTE:
            case DESCENDANT:
            case DESCENDANT_OR_SELF:
            case FOLLOWING:
            case FOLLOWING_SIBLING:
            case SELF:
                return true;

            case ANCESTOR:
            case ANCESTOR_OR_SELF:
            case DOT_DOT:
            case PARENT:
            case PRECEDING:
            case PRECEDING_SIBLING:
                return false;

            default:
                throw new IllegalStateException("Unknown axis: " + axis);
        }
    }

    private NodeType translateNodeTest(AxisStepNode.Axis axis, ASTNode nodeTest) throws SystemException {
        NodeType nt = AnyNodeType.INSTANCE;
        if (nodeTest != null) {
            switch (nodeTest.getTag()) {
                case NAME_TEST: {
                    NameTestNode ntn = (NameTestNode) nodeTest;
                    String uri = null;
                    if (ntn.getPrefix() != null) {
                        if (!"".equals(ntn.getPrefix())) {
                            uri = currCtx.lookupNamespaceUri(ntn.getPrefix());
                            if (uri == null) {
                                throw new SystemException(ErrorCode.XPST0081, ntn.getSourceLocation());
                            }
                        } else {
                            uri = "";
                        }
                    }
                    String localName = ntn.getLocalName();
                    NameTest nameTest = new NameTest(uri == null ? null : createUTF8String(uri),
                            localName == null ? null : createUTF8String(ntn.getLocalName()));
                    if (axis == AxisStepNode.Axis.ATTRIBUTE || axis == AxisStepNode.Axis.ABBREV_ATTRIBUTE) {
                        nt = new AttributeType(nameTest, BuiltinTypeRegistry.XS_ANY_ATOMIC);
                    } else {
                        nt = new ElementType(nameTest, AnyType.INSTANCE, true);
                    }
                    break;
                }

                case ANY_NODE_TEST:
                case DOCUMENT_TEST:
                case TEXT_TEST:
                case COMMENT_TEST:
                case PI_TEST:
                case ATTRIBUTE_TEST:
                case SCHEMA_ATTRIBUTE_TEST:
                case ELEMENT_TEST:
                case SCHEMA_ELEMENT_TEST:
                    nt = (NodeType) createItemType(nodeTest);
                    break;

                default:
                    throw new IllegalStateException("Unknown node: " + nodeTest.getTag());
            }
        }
        return nt;
    }

    private Function translateAxis(AxisStepNode.Axis axis) {
        switch (axis) {
            case ABBREV:
            case CHILD:
                return BuiltinOperators.CHILD;

            case ABBREV_ATTRIBUTE:
            case ATTRIBUTE:
                return BuiltinOperators.ATTRIBUTE;

            case ANCESTOR:
                return BuiltinOperators.ANCESTOR;

            case ANCESTOR_OR_SELF:
                return BuiltinOperators.ANCESTOR_OR_SELF;

            case DESCENDANT:
                return BuiltinOperators.DESCENDANT;

            case DESCENDANT_OR_SELF:
                return BuiltinOperators.DESCENDANT_OR_SELF;

            case DOT_DOT:
            case PARENT:
                return BuiltinOperators.PARENT;

            case FOLLOWING:
                return BuiltinOperators.FOLLOWING;

            case FOLLOWING_SIBLING:
                return BuiltinOperators.FOLLOWING_SIBLING;

            case PRECEDING:
                return BuiltinOperators.PRECEDING;

            case PRECEDING_SIBLING:
                return BuiltinOperators.PRECEDING_SIBLING;

            case SELF:
                return BuiltinOperators.SELF;

            default:
                throw new IllegalStateException("Unknown axis: " + axis);
        }
    }

    private static String unquote(String image) throws SystemException {
        StringBuilder buffer = new StringBuilder();
        char quoteChar = image.charAt(0);
        image = image.substring(1, image.length() - 1);
        Matcher m = UNQUOTER.matcher(image);
        int i = 0;
        while (m.find()) {
            int start = m.start();
            int end = m.end();
            if (i < start) {
                buffer.append(image, i, start);
            }
            if (m.start(1) >= 0) {
                buffer.append('<');
            } else if (m.start(2) >= 0) {
                buffer.append('>');
            } else if (m.start(3) >= 0) {
                buffer.append('\'');
            } else if (m.start(4) >= 0) {
                buffer.append('&');
            } else if (m.start(5) >= 0) {
                buffer.append('"');
            } else if (m.start(6) >= 0) {
                buffer.append(quoteChar == '"' ? '"' : "\"\"");
            } else if (m.start(7) >= 0) {
                buffer.append(quoteChar == '\'' ? '\'' : "''");
            } else if (m.start(8) >= 0) {
                try {
                    buffer.appendCodePoint(Integer.parseInt(image.substring(start + 2, end - 1)));
                } catch (NumberFormatException e) {
                    throw new SystemException(ErrorCode.XQST0090);
                }
            } else if (m.start(9) >= 0) {
                try {
                    buffer.appendCodePoint(Integer.parseInt(image.substring(start + 3, end - 1), 16));
                } catch (NumberFormatException e) {
                    throw new SystemException(ErrorCode.XQST0090);
                }
            }
            i = m.end();
        }
        if (i < image.length()) {
            buffer.append(image, i, image.length());
        }
        return buffer.toString();
    }

    private QName createQName(QNameNode qnNode) throws SystemException {
        return createQName(qnNode, "");
    }

    private QName createQName(QNameNode qnNode, String defaultUri) throws SystemException {
        String prefix = qnNode.getPrefix();
        String local = qnNode.getLocalName();

        String uri;
        if (!"".equals(prefix)) {
            uri = currCtx.lookupNamespaceUri(prefix);
            if (uri == null) {
                throw new SystemException(ErrorCode.XPST0081, qnNode.getSourceLocation());
            }
        } else {
            uri = defaultUri;
        }
        return new QName(uri, local, prefix);
    }

    private static ILogicalExpression afce(Function fn, boolean isTwoStep, ILogicalExpression... argExprs) {
        List<Mutable<ILogicalExpression>> args = new ArrayList<Mutable<ILogicalExpression>>();
        for (ILogicalExpression e : argExprs) {
            args.add(mutable(e));
        }
        return new AggregateFunctionCallExpression(fn, isTwoStep, args);
    }

    private static ILogicalExpression ufce(Function fn, ILogicalExpression... argExprs) {
        List<Mutable<ILogicalExpression>> args = new ArrayList<Mutable<ILogicalExpression>>();
        for (ILogicalExpression e : argExprs) {
            args.add(mutable(e));
        }
        return new UnnestingFunctionCallExpression(fn, args);
    }

    private static ILogicalExpression sfce(Function fn, ILogicalExpression... argExprs) {
        List<Mutable<ILogicalExpression>> args = new ArrayList<Mutable<ILogicalExpression>>();
        for (ILogicalExpression e : argExprs) {
            args.add(mutable(e));
        }
        return new ScalarFunctionCallExpression(fn, args);
    }

    private Function getOperator(InfixOperator operator) {
        switch (operator) {
            case AND:
                return BuiltinOperators.AND;

            case DIV:
                return BuiltinOperators.DIVIDE;

            case EXCEPT:
                return BuiltinOperators.EXCEPT;

            case FOLLOWS:
                return BuiltinOperators.NODE_AFTER;

            case GENERAL_EQ:
                return BuiltinOperators.GENERAL_EQ;

            case GENERAL_GE:
                return BuiltinOperators.GENERAL_GE;

            case GENERAL_GT:
                return BuiltinOperators.GENERAL_GT;

            case GENERAL_LE:
                return BuiltinOperators.GENERAL_LE;

            case GENERAL_LT:
                return BuiltinOperators.GENERAL_LT;

            case GENERAL_NE:
                return BuiltinOperators.GENERAL_NE;

            case IDIV:
                return BuiltinOperators.IDIV;

            case INTERSECT:
                return BuiltinOperators.INTERSECT;

            case IS:
                return BuiltinOperators.IS_SAME_NODE;

            case MINUS:
                return BuiltinOperators.SUBTRACT;

            case MOD:
                return BuiltinOperators.MOD;

            case MULTIPLY:
                return BuiltinOperators.MULTIPLY;

            case OR:
                return BuiltinOperators.OR;

            case PLUS:
                return BuiltinOperators.ADD;

            case PRECEDES:
                return BuiltinOperators.NODE_BEFORE;

            case RANGE:
                return BuiltinOperators.TO;

            case UNION:
                return BuiltinOperators.UNION;

            case VALUE_EQ:
                return BuiltinOperators.VALUE_EQ;

            case VALUE_GE:
                return BuiltinOperators.VALUE_GE;

            case VALUE_GT:
                return BuiltinOperators.VALUE_GT;

            case VALUE_LE:
                return BuiltinOperators.VALUE_LE;

            case VALUE_LT:
                return BuiltinOperators.VALUE_LT;

            case VALUE_NE:
                return BuiltinOperators.VALUE_NE;
        }
        throw new IllegalStateException("Unknown operator: " + operator);
    }

    private ILogicalExpression ce(SequenceType type, Object value) throws SystemException {
        try {
            ItemType it = type.getItemType();
            if (it.isAtomicType()) {
                AtomicType at = (AtomicType) it;
                byte[] bytes = null;
                switch (at.getTypeId()) {
                    case BuiltinTypeConstants.XS_BOOLEAN_TYPE_ID: {
                        baaos.reset();
                        dOut.write((byte) ValueTag.XS_BOOLEAN_TAG);
                        dOut.writeByte(((Boolean) value).booleanValue() ? 1 : 0);
                        break;
                    }
                    case BuiltinTypeConstants.XS_INT_TYPE_ID: {
                        baaos.reset();
                        dOut.write((byte) ValueTag.XS_INT_TAG);
                        dOut.writeInt(((Number) value).intValue());
                        break;
                    }
                    case BuiltinTypeConstants.XS_INTEGER_TYPE_ID: {
                        baaos.reset();
                        dOut.write((byte) ValueTag.XS_INTEGER_TAG);
                        dOut.writeLong(((Number) value).longValue());
                        break;
                    }
                    case BuiltinTypeConstants.XS_DOUBLE_TYPE_ID: {
                        baaos.reset();
                        dOut.write((byte) ValueTag.XS_DOUBLE_TAG);
                        dOut.writeDouble(((Number) value).doubleValue());
                        break;
                    }
                    case BuiltinTypeConstants.XS_STRING_TYPE_ID: {
                        baaos.reset();
                        dOut.write((byte) ValueTag.XS_STRING_TAG);
                        stringVB.write((CharSequence) value, dOut);
                        break;
                    }
                    case BuiltinTypeConstants.XS_DECIMAL_TYPE_ID: {
                        baaos.reset();
                        // TODO Remove the creation of the separate byte array.
                        DoublePointable doublep = (DoublePointable) DoublePointable.FACTORY.createPointable();
                        doublep.set(new byte[DoublePointable.TYPE_TRAITS.getFixedLength()], 0,
                                DoublePointable.TYPE_TRAITS.getFixedLength());
                        doublep.setDouble(((Number) value).doubleValue());
                        CastToDecimalOperation castToDecimal = new CastToDecimalOperation();
                        castToDecimal.convertDouble(doublep, dOut);
                        break;
                    }
                    case BuiltinTypeConstants.XS_QNAME_TYPE_ID: {
                        QName qname = (QName) value;
                        baaos.reset();
                        dOut.write((byte) ValueTag.XS_QNAME_TAG);
                        stringVB.write(qname.getNamespaceURI(), dOut);
                        stringVB.write(qname.getPrefix(), dOut);
                        stringVB.write(qname.getLocalPart(), dOut);
                        break;
                    }
                    case BuiltinTypeConstants.XS_UNTYPED_ATOMIC_TYPE_ID: {
                        baaos.reset();
                        dOut.write((byte) ValueTag.XS_UNTYPED_ATOMIC_TAG);
                        stringVB.write((CharSequence) value, dOut);
                        break;
                    }
                    default:
                        throw new SystemException(ErrorCode.SYSE0001);
                }
                bytes = Arrays.copyOf(baaos.getByteArray(), baaos.size());
                return new ConstantExpression(new VXQueryConstantValue(type, bytes));
            }
            throw new UnsupportedOperationException();
        } catch (IOException e) {
            throw new SystemException(ErrorCode.SYSE0001, e);
        }
    }

    private static ILogicalExpression vre(LogicalVariable var) {
        if (var == null) {
            throw new NullPointerException();
        }
        return new VariableReferenceExpression(var);
    }

    private LogicalVariable createConcatenation(List<LogicalVariable> vars, TranslationContext tCtx) {
        if (vars.size() == 1) {
            return vars.get(0);
        }
        return createFunctionCall(BuiltinOperators.CONCATENATE, vars, tCtx);
    }

    private LogicalVariable createFunctionCall(Function fn, List<LogicalVariable> vars, TranslationContext tCtx) {
        return createAssignment(createFunctionCall(fn, vars), tCtx);
    }

    private LogicalVariable createAssignment(ILogicalExpression expr, TranslationContext tCtx) {
        if (expr.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
            return ((VariableReferenceExpression) expr).getVariableReference();
        }
        LogicalVariable result = newLogicalVariable();
        AssignOperator aOp = new AssignOperator(result, mutable(expr));
        aOp.getInputs().add(mutable(tCtx.op));
        tCtx.op = aOp;
        return result;
    }

    private static ILogicalExpression createFunctionCall(Function fn, List<LogicalVariable> vars) {
        List<Mutable<ILogicalExpression>> args = new ArrayList<Mutable<ILogicalExpression>>();
        for (LogicalVariable var : vars) {
            args.add(mutable(new VariableReferenceExpression(var)));
        }
        return new ScalarFunctionCallExpression(fn, args);
    }

    private ILogicalExpression normalize(ILogicalExpression expr, SequenceType type) throws SystemException {
        if (type.getItemType().isAtomicType()) {
            ILogicalExpression atomizedExpr = new ScalarFunctionCallExpression(BuiltinFunctions.FN_DATA_1,
                    Collections.singletonList(mutable(expr)));
            AtomicType aType = (AtomicType) type.getItemType();
            if (TypeUtils.isSubtypeTypeOf(aType, BuiltinTypeRegistry.XS_BOOLEAN)) {
                return new ScalarFunctionCallExpression(BuiltinFunctions.FN_BOOLEAN_1,
                        Collections.singletonList(mutable(atomizedExpr)));
            }
            return promote(atomizedExpr, type);
        } else {
            return treat(expr, type);
        }
    }

    private ILogicalExpression data(ILogicalExpression expr) throws SystemException {
        return new ScalarFunctionCallExpression(BuiltinFunctions.FN_DATA_1, Collections.singletonList(mutable(expr)));
    }

    private ILogicalExpression promote(ILogicalExpression expr, SequenceType type) throws SystemException {
        int typeCode = currCtx.lookupSequenceType(type);
        return sfce(BuiltinOperators.PROMOTE, expr,
                ce(SequenceType.create(BuiltinTypeRegistry.XS_INT, Quantifier.QUANT_ONE), typeCode));
    }

    private ILogicalExpression treat(ILogicalExpression expr, SequenceType type) throws SystemException {
        int typeCode = currCtx.lookupSequenceType(type);
        return sfce(BuiltinOperators.TREAT, expr,
                ce(SequenceType.create(BuiltinTypeRegistry.XS_INT, Quantifier.QUANT_ONE), typeCode));
    }

    private ILogicalExpression cast(ILogicalExpression expr, SequenceType type) throws SystemException {
        int typeCode = currCtx.lookupSequenceType(type);
        return sfce(BuiltinOperators.CAST, data(expr),
                ce(SequenceType.create(BuiltinTypeRegistry.XS_INT, Quantifier.QUANT_ONE), typeCode));
    }

    private ILogicalExpression castable(ILogicalExpression expr, SequenceType type) throws SystemException {
        int typeCode = currCtx.lookupSequenceType(type);
        return sfce(BuiltinOperators.CASTABLE, expr,
                ce(SequenceType.create(BuiltinTypeRegistry.XS_INT, Quantifier.QUANT_ONE), typeCode));
    }

    private ILogicalExpression instanceOf(ILogicalExpression expr, SequenceType type) throws SystemException {
        int typeCode = currCtx.lookupSequenceType(type);
        return sfce(BuiltinOperators.INSTANCE_OF, expr,
                ce(SequenceType.create(BuiltinTypeRegistry.XS_INT, Quantifier.QUANT_ONE), typeCode));
    }

    private List<LogicalVariable> translateExpressionList(List<ASTNode> expressions, TranslationContext tCtx)
            throws SystemException {
        List<LogicalVariable> result = new ArrayList<LogicalVariable>();
        for (ASTNode e : expressions) {
            result.add(translateExpression(e, tCtx));
        }
        return result;
    }

    private static Mutable<ILogicalExpression> mutable(ILogicalExpression expr) {
        return new MutableObject<ILogicalExpression>(expr);
    }

    private static Mutable<ILogicalOperator> mutable(ILogicalOperator op) {
        return new MutableObject<ILogicalOperator>(op);
    }

    private LogicalVariable newLogicalVariable() {
        return new LogicalVariable(varCounter++);
    }

    private class RootVariableScope implements IVariableScope {
        @Override
        public IVariableScope getParentScope() {
            return null;
        }

        @Override
        public XQueryVariable lookupVariable(QName name) {
            return moduleCtx.lookupVariable(name);
        }

        @Override
        public void registerVariable(XQueryVariable var) {
            moduleCtx.registerVariable(var);
        }
    }

    private class TranslationContext {
        private final TranslationContext parent;

        private ILogicalOperator op;

        private IVariableScope varScope;

        public TranslationContext(TranslationContext parent, ILogicalOperator op) {
            this.parent = parent;
            this.op = op;
            varScope = parent == null ? rootVarScope : parent.varScope;
        }

        TranslationContext pushContext() {
            SubplanOperator sOp = new SubplanOperator();
            sOp.getInputs().add(mutable(op));
            op = sOp;
            NestedTupleSourceOperator ntsOp = new NestedTupleSourceOperator(mutable(sOp));
            TranslationContext childCtx = new TranslationContext(this, ntsOp);
            return childCtx;
        }

        TranslationContext popContext() {
            SubplanOperator sOp = (SubplanOperator) parent.op;
            sOp.setRootOp(mutable(op));
            return parent;
        }

        void pushVariableScope() {
            varScope = new ExpressionVariableScope(varScope);
        }

        void popVariableScope() {
            varScope = varScope.getParentScope();
        }
    }

    private interface IVariableScope {
        public IVariableScope getParentScope();

        public XQueryVariable lookupVariable(QName name);

        public void registerVariable(XQueryVariable var);
    }

    private static class ExpressionVariableScope implements IVariableScope {
        private final IVariableScope parent;

        private final Map<QName, XQueryVariable> varMap;

        public ExpressionVariableScope(IVariableScope parent) {
            this.parent = parent;
            varMap = new HashMap<QName, XQueryVariable>();
        }

        @Override
        public IVariableScope getParentScope() {
            return parent;
        }

        @Override
        public XQueryVariable lookupVariable(QName name) {
            if (varMap.containsKey(name)) {
                return varMap.get(name);
            }
            return parent.lookupVariable(name);
        }

        @Override
        public void registerVariable(XQueryVariable var) {
            varMap.put(var.getName(), var);
        }
    }
}
