← Back to team overview

zorba-coders team mailing list archive

[Merge] lp:~zorba-coders/zorba/expr-matching into lp:zorba

 

Markos Zaharioudakis has proposed merging lp:~zorba-coders/zorba/expr-matching into lp:zorba.

Commit message:
Index matching for value-equality indexes

Requested reviews:
  Markos Zaharioudakis (markos-za)

For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/expr-matching/+merge/141028

Index matching for value-equality indexes
-- 
https://code.launchpad.net/~zorba-coders/zorba/expr-matching/+merge/141028
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'src/compiler/api/compiler_api.h'
--- src/compiler/api/compiler_api.h	2012-10-08 12:09:36 +0000
+++ src/compiler/api/compiler_api.h	2012-12-21 04:09:22 +0000
@@ -23,9 +23,13 @@
 #include "common/shared_types.h"
 #include <zorba/api_shared_types.h>
 
-namespace zorba {
-
-
+namespace zorba 
+{
+
+
+/********************************************************************************
+
+********************************************************************************/
 class XQueryCompiler
 {
 public:
@@ -59,7 +63,6 @@
       ulong& nextDynamicVarId,
       audit::ScopedRecord& aAuditRecord);
 
-protected:
   expr* normalize(parsenode_t ast);
 
   expr* optimize(expr* expr);
@@ -72,6 +75,9 @@
 };
 
 
+/********************************************************************************
+
+********************************************************************************/
 class XQueryCompilerSubsystem
 {
   friend class GlobalEnvironment;

=== modified file 'src/compiler/api/compilercb.h'
--- src/compiler/api/compilercb.h	2012-12-06 22:49:35 +0000
+++ src/compiler/api/compilercb.h	2012-12-21 04:09:22 +0000
@@ -253,6 +253,8 @@
 
   ExprManager* getExprManager() const { return theEM; }
 
+  uint8_t getVisitId() { return theNextVisitId++; }
+
   //
   // Pragmas
   //

=== modified file 'src/compiler/codegen/plan_visitor.cpp'
--- src/compiler/codegen/plan_visitor.cpp	2012-12-18 15:09:02 +0000
+++ src/compiler/codegen/plan_visitor.cpp	2012-12-21 04:09:22 +0000
@@ -995,7 +995,7 @@
 
               if (i > 0 &&
                   v.get_clause(i-1)->get_kind() != flwor_clause::order_clause &&
-                  v.get_clause(i-1)->get_kind() != flwor_clause::group_clause)
+                  v.get_clause(i-1)->get_kind() != flwor_clause::groupby_clause)
               {
                 orderby_clause* mat = theCCB->theEM->
                 create_orderby_clause(v.get_sctx(),
@@ -1011,7 +1011,7 @@
 
               if (i == numClauses -1 ||
                   (i < numClauses - 1 &&
-                   v.get_clause(i+1)->get_kind() != flwor_clause::group_clause))
+                   v.get_clause(i+1)->get_kind() != flwor_clause::groupby_clause))
               {
                 orderby_clause* mat = theCCB->theEM->
                 create_orderby_clause(v.get_sctx(),
@@ -1029,7 +1029,7 @@
           break;
         }
         case flwor_clause::where_clause:
-        case flwor_clause::group_clause:
+        case flwor_clause::groupby_clause:
         case flwor_clause::order_clause:
         case flwor_clause::count_clause:
         {
@@ -1046,7 +1046,7 @@
 
       if (v.get_return_expr()->is_sequential() &&
           lastClause->get_kind() != flwor_clause::order_clause &&
-          lastClause->get_kind() != flwor_clause::group_clause)
+          lastClause->get_kind() != flwor_clause::groupby_clause)
       {
         orderby_clause* mat = theCCB->theEM->
         create_orderby_clause(v.get_sctx(),
@@ -1098,9 +1098,9 @@
       break;
     }
 
-    case flwor_clause::group_clause:
+    case flwor_clause::groupby_clause:
     {
-      const group_clause* gc = reinterpret_cast<const group_clause*>(c);
+      const groupby_clause* gc = reinterpret_cast<const groupby_clause*>(c);
 
       const flwor_clause::rebind_list_t& gvars = gc->get_grouping_vars();
       const flwor_clause::rebind_list_t& ngvars = gc->get_nongrouping_vars();
@@ -1242,11 +1242,11 @@
     break;
   }
 
-  case flwor_clause::group_clause:
+  case flwor_clause::groupby_clause:
   {
-    const group_clause* gbc = static_cast<const group_clause *>(c);
-    const group_clause::rebind_list_t& grouping_vars = gbc->get_grouping_vars();
-    const group_clause::rebind_list_t& nongrouping_vars = gbc->get_nongrouping_vars();
+    const groupby_clause* gbc = static_cast<const groupby_clause *>(c);
+    const groupby_clause::rebind_list_t& grouping_vars = gbc->get_grouping_vars();
+    const groupby_clause::rebind_list_t& nongrouping_vars = gbc->get_nongrouping_vars();
 
     for (unsigned i = 0; i < grouping_vars.size(); ++i)
     {
@@ -1689,7 +1689,7 @@
   //
   // GROUPBY
   //
-  else if (c.get_kind() == flwor_clause::group_clause)
+  else if (c.get_kind() == flwor_clause::groupby_clause)
   {
     std::vector<flwor::GroupingSpec> gspecs;
     std::vector<flwor::NonGroupingSpec> ngspecs;
@@ -1825,7 +1825,7 @@
     //
     // GROUPBY
     //
-    case flwor_clause::group_clause:
+    case flwor_clause::groupby_clause:
     {
       std::vector<flwor::GroupingSpec> gspecs;
       std::vector<flwor::NonGroupingSpec> ngspecs;
@@ -1954,10 +1954,10 @@
     std::vector<flwor::GroupingSpec>& gspecs,
     std::vector<flwor::NonGroupingSpec>& ngspecs)
 {
-  const group_clause* gbc = static_cast<const group_clause*>(clauseVarMap->theClause);
+  const groupby_clause* gbc = static_cast<const groupby_clause*>(clauseVarMap->theClause);
 
-  const group_clause::rebind_list_t& gvars = gbc->get_grouping_vars();
-  const group_clause::rebind_list_t& ngvars = gbc->get_nongrouping_vars();
+  const groupby_clause::rebind_list_t& gvars = gbc->get_grouping_vars();
+  const groupby_clause::rebind_list_t& ngvars = gbc->get_nongrouping_vars();
 
   const std::vector<std::string>& collations = gbc->get_collations();
 
@@ -2158,6 +2158,71 @@
                                 false));
 }
 
+
+/***************************************************************************//**
+
+********************************************************************************/
+bool begin_visit(expr_match_expr& v)
+{
+  CODEGEN_TRACE_IN("");
+  return true;
+}
+
+void end_visit(expr_match_expr& v)
+{
+  CODEGEN_TRACE_OUT("");
+
+  csize numVars = v.num_vars();
+
+  checked_vector<PlanIter_t> args;
+  args.reserve(numVars+2);
+
+  std::vector<int> isGlobalVar(numVars);
+
+  for (csize i = numVars; i > 0; --i)
+  {
+    isGlobalVar[i-1] = false;
+
+    expr* arg = v.get_arg_expr(i-1);
+
+    if (arg->get_expr_kind() == var_expr_kind)
+    {
+      var_expr* varArg = static_cast<var_expr*>(arg);
+
+      if (varArg->get_kind() == var_expr::prolog_var)
+        isGlobalVar[i-1] = true;
+    }
+
+    if (!isGlobalVar[i-1])
+    {
+      args.push_back(pop_itstack());
+    }
+    else
+    {
+      pop_itstack();
+    }
+  }
+
+  args.push_back(pop_itstack());
+  args.push_back(pop_itstack());
+
+  reverse(args.begin(), args.end());
+
+  store::NsBindings localBindings;
+  v.getNSCtx()->getAllBindings(localBindings);
+
+  push_itstack(new MatchIterator(sctx,
+                                 qloc,
+                                 args,
+                                 v.get_var_names(),
+                                 v.get_var_types(),
+                                 isGlobalVar,
+                                 v.get_inner_scripting_kind(),
+                                 localBindings,
+                                 v.getNodeCopy()));
+}
+
+
 #ifdef ZORBA_WITH_DEBUGGER
 bool begin_visit(debugger_expr& v)
 {
@@ -2428,8 +2493,8 @@
 void end_visit(instanceof_expr& v)
 {
   CODEGEN_TRACE_OUT("");
-  PlanIter_t p = pop_itstack ();
-  push_itstack (new InstanceOfIterator (sctx, qloc, p, v.get_target_type ()));
+  PlanIter_t p = pop_itstack();
+  push_itstack (new InstanceOfIterator (sctx, qloc, p, v.get_target_type()));
 }
 
 

=== modified file 'src/compiler/expression/expr.cpp'
--- src/compiler/expression/expr.cpp	2012-10-31 08:02:16 +0000
+++ src/compiler/expression/expr.cpp	2012-12-21 04:09:22 +0000
@@ -66,6 +66,7 @@
 DEF_EXPR_ACCEPT (promote_expr)
 DEF_EXPR_ACCEPT (trycatch_expr)
 DEF_EXPR_ACCEPT (eval_expr)
+//DEF_EXPR_ACCEPT (expr_match_expr)
 DEF_EXPR_ACCEPT (function_trace_expr)
 DEF_EXPR_ACCEPT (if_expr)
 DEF_EXPR_ACCEPT (instanceof_expr)
@@ -1114,6 +1115,43 @@
 }
 
 
+/*******************************************************************************
+
+********************************************************************************/
+expr_match_expr::expr_match_expr(
+    CompilerCB* ccb,
+    static_context* sctx,
+    user_function* udf,
+    const QueryLoc& loc,
+    expr* query,
+    expr* view,
+    expr_script_kind_t scriptingKind,
+    namespace_context* nsCtx)
+  :
+  eval_expr(ccb, sctx, udf, loc, query, scriptingKind, nsCtx),
+  theViewExpr(view)
+{
+  theKind = expr_match_expr_kind;
+
+  compute_scripting_kind();
+}
+
+
+void expr_match_expr::compute_scripting_kind()
+{
+  checkSimpleExpr(theViewExpr);
+}
+
+
+void expr_match_expr::accept(expr_visitor& v)
+{                      
+  if (v.begin_visit(*this))
+    accept_children(v);
+                     
+  v.end_visit(*this);
+}
+
+
 #ifdef ZORBA_WITH_DEBUGGER
 /*******************************************************************************
 

=== modified file 'src/compiler/expression/expr.h'
--- src/compiler/expression/expr.h	2012-10-24 11:32:56 +0000
+++ src/compiler/expression/expr.h	2012-12-21 04:09:22 +0000
@@ -189,7 +189,7 @@
 };
 
 
-/***************************************************************************//**
+/*******************************************************************************
   Base for cast, treat, promote, castable, instanceof
 ********************************************************************************/
 class cast_or_castable_base_expr : public expr
@@ -222,8 +222,8 @@
 };
 
 
-/***************************************************************************//**
-  Base for cast, treat, promote
+/*******************************************************************************
+  Base for cast, promote, treat
 ********************************************************************************/
 class cast_base_expr : public cast_or_castable_base_expr
 {
@@ -241,7 +241,7 @@
 };
 
 
-/***************************************************************************//**
+/*******************************************************************************
   CastExpr ::= UnaryExpr ( "cast" "as" SingleType )?
 
   SingleType ::= AtomicType "?"?
@@ -271,65 +271,12 @@
 
 
 /***************************************************************************//**
-  TreatExpr ::= CastableExpr ( "treat" "as" SequenceType )?
-
-  theCheckPrime : Normally, this is true. If false, then during runtime, only
-                  the cardinality of theInputExpr will be checked w.r.t. the
-                  quantifier of theTargetType. theCheckPrime is set to false
-                  by the optimizer, if it discovers that the prime type of the
-                  static type of theInputExpr is a subtype of the prime type of
-                  theTargetType.
-
-  theFnQName    : Stores the QName of the function, if the treat expr is used
-                  to cast the function's body to its result type
-********************************************************************************/
-class treat_expr : public cast_base_expr
-{
-  friend class ExprManager;
-  friend class ExprIterator;
-  friend class expr;
-
-protected:
-  TreatErrorKind  theErrorKind;
-  bool            theCheckPrime;
-  store::Item_t   theQName;
-
-protected:
-  treat_expr(
-      CompilerCB* ccb,
-      static_context* sctx,
-      user_function* udf,
-      const QueryLoc&,
-      expr*,
-      const xqtref_t&,
-      TreatErrorKind err,
-      bool check_prime = true,
-      store::Item* qname = NULL);
-
-public:
-  TreatErrorKind get_err() const { return theErrorKind; }
-
-  bool get_check_prime() const { return theCheckPrime; }
-
-  void set_check_prime(bool check_prime) { theCheckPrime = check_prime; }
-
-  void set_qname(const store::Item_t& qname) { theQName = qname; }
-
-  store::Item_t get_qname() const { return theQName; }
-
-  void accept(expr_visitor&);
-
-  std::ostream& put(std::ostream&) const;
-};
-
-
-/***************************************************************************//**
   This is an internal zorba expr. Its semantics are the following:
 
   1. Let "input sequence" be the result of theInputExpr, and "output sequence"
      be the result of the promote_expr.
 
-  2. The input sequence is assumed to be mepty or consist of atomic items only.
+  2. The input sequence is assumed to be empty or consist of atomic items only.
 
   4. theTargetType is always a subtype of xs:anyAtomicType*
 
@@ -346,17 +293,20 @@
      - If the actual type is untypedAtomic and the target type is not QName,
        F(I) = cast(I, target type), else
      - If the actual type is (subtype of) decimal and the target type is float,
-       F(I) = cast(I, target type), else
+       F(I) = cast(I, float), else
      - If the actual type is (subtype of) decimal or float and the target type is double,
-       F(I) = cast(I, target type), else
+       F(I) = cast(I, double), else
      - If the actual type is anyURI and the target type is string,
        F(I) = cast(I, string), else
      - F(I) = raise error
 
   4. Put F(I) in the output sequence.
 
-  theFnQName:
-  -----------
+  theErrorKind :
+  --------------
+
+  theQName:
+  ---------
   Stores the QName of the function, if the promote expr is used to cast the
   function's body to its result type
 
@@ -396,6 +346,62 @@
 
 
 /***************************************************************************//**
+  TreatExpr ::= CastableExpr ( "treat" "as" SequenceType )?
+
+  theCheckPrime :
+  ---------------
+  Normally, this is true. If false, then during runtime, only the cardinality of
+  theInputExpr will be checked w.r.t. the quantifier of theTargetType. 
+  theCheckPrime is set to false by the optimizer, if it discovers that the prime
+  type of the static type of theInputExpr is a subtype of the prime type of 
+  theTargetType.
+
+  theQName :
+  ------------
+  Stores the QName of the function, if the treat expr is used to cast the
+  function's body to its result type
+********************************************************************************/
+class treat_expr : public cast_base_expr
+{
+  friend class ExprManager;
+  friend class ExprIterator;
+  friend class expr;
+
+protected:
+  TreatErrorKind  theErrorKind;
+  bool            theCheckPrime;
+  store::Item_t   theQName;
+
+protected:
+  treat_expr(
+      CompilerCB* ccb,
+      static_context* sctx,
+      user_function* udf,
+      const QueryLoc&,
+      expr*,
+      const xqtref_t&,
+      TreatErrorKind err,
+      bool check_prime = true,
+      store::Item* qname = NULL);
+
+public:
+  TreatErrorKind get_err() const { return theErrorKind; }
+
+  bool get_check_prime() const { return theCheckPrime; }
+
+  void set_check_prime(bool check_prime) { theCheckPrime = check_prime; }
+
+  void set_qname(const store::Item_t& qname) { theQName = qname; }
+
+  store::Item_t get_qname() const { return theQName; }
+
+  void accept(expr_visitor&);
+
+  std::ostream& put(std::ostream&) const;
+};
+
+
+/***************************************************************************//**
   Base for castable, instanceof
 ********************************************************************************/
 class castable_base_expr : public cast_or_castable_base_expr
@@ -447,6 +453,7 @@
   InstanceofExpr ::= TreatExpr ( "instance" "of" SequenceType )?
 
   theCheckPrimeOnly :
+  -------------------
   Normally, this is false. It is set to true only if this is an instanceof expr
   that is created during the translation of a PredicateList (see translator.cpp).
   This flag is used during the PartialEval rule.
@@ -1217,6 +1224,42 @@
 };
 
 
+/***************************************************************************//**
+
+********************************************************************************/
+class expr_match_expr : public eval_expr
+{
+  friend class ExprIterator;
+  friend class expr;
+  friend class ExprManager;
+
+protected:
+  expr   * theViewExpr;
+
+protected:
+  expr_match_expr(
+      CompilerCB* ccb,
+      static_context* sctx,
+      user_function* udf,
+      const QueryLoc& loc,
+      expr* query,
+      expr* view,
+      expr_script_kind_t scriptingKind,
+      namespace_context* nsCtx);
+
+public:
+  void compute_scripting_kind();
+
+  expr* get_query_expr() const { return theExpr; }
+
+  expr* get_view_expr() const { return theViewExpr; }
+
+  void accept(expr_visitor&);
+
+  std::ostream& put(std::ostream&) const;
+};
+
+
 #ifdef ZORBA_WITH_DEBUGGER
 /***************************************************************************//**
   debugger expression

=== modified file 'src/compiler/expression/expr_base.cpp'
--- src/compiler/expression/expr_base.cpp	2012-12-06 22:49:35 +0000
+++ src/compiler/expression/expr_base.cpp	2012-12-21 04:09:22 +0000
@@ -966,7 +966,7 @@
 
         break;
       }
-      case flwor_clause::group_clause:
+      case flwor_clause::groupby_clause:
       case flwor_clause::count_clause:
       {
         if (found)
@@ -1109,6 +1109,7 @@
   }
 
   case eval_expr_kind:
+  case expr_match_expr_kind:
     return false; // TODO
 
   case var_decl_expr_kind:
@@ -1165,45 +1166,63 @@
   qname. This method is used to extract the qname from the expression that is
   given as an arg to collection and index related functions.
 ********************************************************************************/
-const store::Item* expr::getQName(static_context* sctx) const
+const store::Item* expr::getQName() const
 {
-  RootTypeManager& rtm = GENV_TYPESYSTEM;
-
-  TypeManager* tm = sctx->get_typemanager();
-
   if (get_expr_kind() == const_expr_kind)
   {
     const const_expr* qnameExpr = static_cast<const const_expr*>(this);
 
-    xqtref_t valueType = tm->create_value_type(qnameExpr->get_val());
+    store::SchemaTypeCode valueType = qnameExpr->get_val()->getTypeCode();
 
-    if (TypeOps::is_subtype(tm, *valueType, *rtm.QNAME_TYPE_ONE, get_loc()))
+    if (TypeOps::is_subtype(valueType, store::XS_QNAME))
     {
       return qnameExpr->get_val();
     }
   }
+  else if (get_var() != NULL)
+  {
+    const var_expr* var = get_var();
+
+    if (var->get_kind() == var_expr::prolog_var &&
+        var->num_set_exprs() == 1 &&
+        var->get_set_expr(0)->get_expr_kind() == var_decl_expr_kind)
+    {
+      const var_decl_expr* decl = 
+      static_cast<const var_decl_expr*>(var->get_set_expr(0));
+
+      return decl->get_init_expr()->getQName();
+    }
+  }
+  else if (get_expr_kind() == treat_expr_kind)
+  {
+    const treat_expr* treatExpr = static_cast<const treat_expr*>(this);
+    const expr* argExpr = treatExpr->get_input();
+    return argExpr->getQName();
+  }
   else if (get_expr_kind() == promote_expr_kind)
   {
     // We get here if the optimizer is turned off.
 
     const promote_expr* promoteExpr = static_cast<const promote_expr*>(this);
-
     const expr* argExpr = promoteExpr->get_input();
-    const fo_expr* dataExpr = dynamic_cast<const fo_expr*>(argExpr);
-
-    if (dataExpr != NULL &&
-        dataExpr->get_func()->getKind() == FunctionConsts::FN_DATA_1)
+    
+    if (argExpr->get_expr_kind() == fo_expr_kind)
     {
-      argExpr = dataExpr->get_arg(0);
+      const fo_expr* dataExpr = static_cast<const fo_expr*>(argExpr);
 
-      if (argExpr->get_expr_kind() == const_expr_kind)
+      if (dataExpr->get_func()->getKind() == FunctionConsts::FN_DATA_1)
       {
-        const const_expr* qnameExpr = static_cast<const const_expr*>(argExpr);
-        xqtref_t valueType = tm->create_value_type(qnameExpr->get_val());
+        argExpr = dataExpr->get_arg(0);
 
-        if (TypeOps::is_subtype(tm, *valueType, *rtm.QNAME_TYPE_ONE, get_loc()))
+        if (argExpr->get_expr_kind() == const_expr_kind)
         {
-          return qnameExpr->get_val();
+          const const_expr* qnameExpr = static_cast<const const_expr*>(argExpr);
+          store::SchemaTypeCode valueType = qnameExpr->get_val()->getTypeCode();
+
+          if (TypeOps::is_subtype(valueType, store::XS_QNAME))
+          {
+            return qnameExpr->get_val();
+          }
         }
       }
     }

=== modified file 'src/compiler/expression/expr_base.h'
--- src/compiler/expression/expr_base.h	2012-12-06 22:49:35 +0000
+++ src/compiler/expression/expr_base.h	2012-12-21 04:09:22 +0000
@@ -105,6 +105,7 @@
   while_expr_kind,
 
   eval_expr_kind,
+  expr_match_expr_kind,
   debugger_expr_kind,
   wrapper_expr_kind,
   function_trace_expr_kind,
@@ -396,7 +397,7 @@
 
   const var_expr* get_var() const;
 
-  const store::Item* getQName(static_context* sctx) const;
+  const store::Item* getQName() const;
 
   void clear_annotations();
 

=== modified file 'src/compiler/expression/expr_classes.h'
--- src/compiler/expression/expr_classes.h	2012-09-19 21:16:15 +0000
+++ src/compiler/expression/expr_classes.h	2012-12-21 04:09:22 +0000
@@ -67,6 +67,7 @@
   class flowctl_expr;
 
   class eval_expr;
+  class expr_match_expr;
   class debugger_expr;
   class function_trace_expr;
   class wrapper_expr;

=== modified file 'src/compiler/expression/expr_clone.cpp'
--- src/compiler/expression/expr_clone.cpp	2012-12-11 00:22:26 +0000
+++ src/compiler/expression/expr_clone.cpp	2012-12-21 04:09:22 +0000
@@ -252,7 +252,7 @@
     const flwor_expr* e = static_cast<const flwor_expr*>(this);
 
     flwor_expr* cloneExpr = theCCB->theEM->
-    create_flwor_expr(theSctx, udf, theLoc, e->theIsGeneral);
+    create_flwor_expr(theSctx, udf, theLoc, e->is_general());
 
     csize numClauses = e->num_clauses();
 
@@ -732,6 +732,37 @@
 
     break;
   }
+  case expr_match_expr_kind:
+  {
+    const expr_match_expr* e = static_cast<const expr_match_expr*>(this);
+
+    newExpr = theCCB->theEM->
+    create_expr_match_expr(theSctx,
+                           udf,
+                           theLoc,
+                           e->theExpr->clone(udf, subst),
+                           e->theViewExpr->clone(udf, subst),
+                           e->theInnerScriptingKind,
+                           e->theNSCtx.getp());
+
+    expr_match_expr* newEval = static_cast<expr_match_expr*>(newExpr);
+
+    newEval->setNodeCopy(e->theDoNodeCopy);
+
+    newEval->theOuterVarNames = e->theOuterVarNames;
+    newEval->theOuterVarTypes = e->theOuterVarTypes;
+
+    csize numVars = e->theOuterVarNames.size();
+
+    newEval->theArgs.resize(numVars);
+
+    for (csize i = 0; i < numVars; ++i)
+    {
+      newEval->theArgs[i] = e->theArgs[i]->clone(udf, subst);
+    }
+
+    break;
+  }
   case wrapper_expr_kind:
   {
     const wrapper_expr* e = static_cast<const wrapper_expr*>(this);

=== modified file 'src/compiler/expression/expr_consts.h'
--- src/compiler/expression/expr_consts.h	2012-10-24 11:32:56 +0000
+++ src/compiler/expression/expr_consts.h	2012-12-21 04:09:22 +0000
@@ -28,7 +28,8 @@
   PROMOTE_TYPE_PROMOTION,
   PROMOTE_JSONIQ_ARRAY_SELECTOR,
   PROMOTE_JSONIQ_OBJECT_SELECTOR,
-  PROMOTE_JSONIQ_SELECTOR
+  PROMOTE_JSONIQ_SELECTOR,
+  PROMOTE_INDEX_KEY
 };
 
 
@@ -164,18 +165,34 @@
 };
 
 
+/*******************************************************************************
+  ATTENTION !!! 
+  The ordering of the enum values in IKMPORTANT. DO NOT CHANGE IT.
+  ATTENTION !!!
+********************************************************************************/
 class CompareConsts
 {
 public:
   enum CompareType
   {
-    UNKNOWN,
-    VALUE_EQUAL, GENERAL_EQUAL, NODE_EQUAL,
-    VALUE_NOT_EQUAL, GENERAL_NOT_EQUAL, NODE_NOT_EQUAL,
-    VALUE_LESS, GENERAL_LESS,
-    VALUE_LESS_EQUAL, GENERAL_LESS_EQUAL,
-    VALUE_GREATER, GENERAL_GREATER,
-    VALUE_GREATER_EQUAL, GENERAL_GREATER_EQUAL
+    UNKNOWN = 0,
+
+    VALUE_EQUAL           = 1,
+    GENERAL_EQUAL         = 2,
+    NODE_EQUAL            = 3,
+    VALUE_NOT_EQUAL       = 4,
+    GENERAL_NOT_EQUAL     = 5,
+    NODE_NOT_EQUAL        = 6,
+
+    VALUE_LESS            = 7,
+    GENERAL_LESS          = 8,
+    VALUE_LESS_EQUAL      = 9,
+    GENERAL_LESS_EQUAL    = 10,
+
+    VALUE_GREATER         = 11,
+    GENERAL_GREATER       = 12,
+    VALUE_GREATER_EQUAL   = 13,
+    GENERAL_GREATER_EQUAL = 14
   };
 };
 

=== modified file 'src/compiler/expression/expr_iter.cpp'
--- src/compiler/expression/expr_iter.cpp	2012-12-12 07:36:20 +0000
+++ src/compiler/expression/expr_iter.cpp	2012-12-21 04:09:22 +0000
@@ -203,9 +203,9 @@
           return;
         }
 
-        case flwor_clause::group_clause:
+        case flwor_clause::groupby_clause:
         {
-          group_clause* gc = static_cast<group_clause *>(c);
+          groupby_clause* gc = static_cast<groupby_clause *>(c);
 
           theGroupVarsIter = gc->theGroupVars.begin();
           theGroupVarsEnd = gc->theGroupVars.end();
@@ -315,7 +315,7 @@
     flwor_clause* c = NULL;
     window_clause* wc = NULL;
     orderby_clause* oc = NULL;
-    group_clause* gc = NULL;
+    groupby_clause* gc = NULL;
     flwor_wincond* wincond = NULL;
 
     EXPR_ITER_BEGIN();
@@ -362,9 +362,9 @@
         }
       }
 
-      else if (c->get_kind() == flwor_clause::group_clause)
+      else if (c->get_kind() == flwor_clause::groupby_clause)
       {
-        gc = static_cast<group_clause *>(c);
+        gc = static_cast<groupby_clause *>(c);
 
         theGroupVarsIter = gc->theGroupVars.begin();
         theGroupVarsEnd = gc->theGroupVars.end();
@@ -917,6 +917,27 @@
     return;
   }
 
+  case expr_match_expr_kind:
+  {
+    expr_match_expr* matchExpr = static_cast<expr_match_expr*>(theExpr);
+
+    EXPR_ITER_BEGIN();
+
+    EXPR_ITER_NEXT(matchExpr->theExpr);
+    EXPR_ITER_NEXT(matchExpr->theViewExpr);
+
+    theArgsIter = matchExpr->theArgs.begin();
+    theArgsEnd = matchExpr->theArgs.end();
+    for (; theArgsIter != theArgsEnd; ++theArgsIter)
+    {
+      EXPR_ITER_NEXT(*theArgsIter);
+    }
+
+    EXPR_ITER_END();
+    return;
+  }
+
+
 #ifdef ZORBA_WITH_DEBUGGER
   case debugger_expr_kind:
   {

=== modified file 'src/compiler/expression/expr_manager.cpp'
--- src/compiler/expression/expr_manager.cpp	2012-10-26 07:13:42 +0000
+++ src/compiler/expression/expr_manager.cpp	2012-12-21 04:09:22 +0000
@@ -421,7 +421,7 @@
     static_context* sctx,
     user_function* udf,
     const QueryLoc& loc,
-    store::Item_t val)
+    const store::Item_t& val)
 {
   CREATE_AND_RETURN_EXPR(const_expr, sctx, udf, loc, val);
 }
@@ -516,6 +516,21 @@
   CREATE_AND_RETURN_EXPR(eval_expr, sctx, udf, loc, e, scriptingKind, nsCtx);
 }
 
+
+expr_match_expr* ExprManager::create_expr_match_expr(
+      static_context* sctx,
+      user_function* udf,
+      const QueryLoc& loc,
+      expr* query,
+      expr* view,
+      expr_script_kind_t scriptingKind,
+      namespace_context* nsCtx)
+{
+  CREATE_AND_RETURN_EXPR(expr_match_expr, sctx, udf, loc,
+                         query, view, scriptingKind, nsCtx);
+}
+
+
 #ifdef ZORBA_WITH_DEBUGGER
 
 debugger_expr* ExprManager::create_debugger_expr(
@@ -945,14 +960,14 @@
 }
 
 
-group_clause* ExprManager::create_group_clause(
+groupby_clause* ExprManager::create_groupby_clause(
     static_context* sctx,
     const QueryLoc& loc,
     const flwor_clause::rebind_list_t& gvars,
     const flwor_clause::rebind_list_t& ngvars,
     const std::vector<std::string>& collations)
 {
-  CREATE_AND_RETURN(group_clause, sctx, theCCB,  loc, gvars, ngvars, collations);
+  CREATE_AND_RETURN(groupby_clause, sctx, theCCB,  loc, gvars, ngvars, collations);
 }
 
 

=== modified file 'src/compiler/expression/expr_manager.h'
--- src/compiler/expression/expr_manager.h	2012-10-26 07:13:42 +0000
+++ src/compiler/expression/expr_manager.h	2012-12-21 04:09:22 +0000
@@ -43,7 +43,7 @@
 class flwor_wincond;
 class copy_clause;
 class window_clause;
-class group_clause;
+class groupby_clause;
 class where_clause;
 class count_clause;
 class orderby_clause;
@@ -262,7 +262,7 @@
       static_context* sctx,
       user_function* udf,
       const QueryLoc&,
-      store::Item_t);
+      const store::Item_t&);
 
   const_expr* create_const_expr(
       static_context* sctx,
@@ -317,6 +317,15 @@
       expr_script_kind_t scriptingKind,
       namespace_context* nsCtx);
 
+  expr_match_expr* create_expr_match_expr(
+      static_context* sctx,
+      user_function* udf,
+      const QueryLoc& loc,
+      expr* query,
+      expr* view,
+      expr_script_kind_t scriptingKind,
+      namespace_context* nsCtx);
+
 #ifdef ZORBA_WITH_DEBUGGER
   debugger_expr* create_debugger_expr(
       static_context* sctx,
@@ -574,7 +583,7 @@
       const flwor_wincond_vars& out_vars,
       expr* cond);
 
-  group_clause* create_group_clause(
+  groupby_clause* create_groupby_clause(
       static_context* sctx,
       const QueryLoc& loc,
       const var_rebind_list_t& gvars,

=== modified file 'src/compiler/expression/expr_put.cpp'
--- src/compiler/expression/expr_put.cpp	2012-12-06 22:49:35 +0000
+++ src/compiler/expression/expr_put.cpp	2012-12-21 04:09:22 +0000
@@ -262,7 +262,7 @@
 }
 
 
-ostream& group_clause::put(ostream& os) const
+ostream& groupby_clause::put(ostream& os) const
 {
   BEGIN_PUT_NL(GROUPBY);
 
@@ -352,9 +352,9 @@
       static_cast<const window_clause *>(&c)->put(os);
       break;
     }
-    case flwor_clause::group_clause:
+    case flwor_clause::groupby_clause:
     {
-      static_cast<const group_clause *>(&c)->put(os);
+      static_cast<const groupby_clause *>(&c)->put(os);
       break;
     }
     case flwor_clause::order_clause:
@@ -441,6 +441,29 @@
 }
 
 
+ostream& expr_match_expr::put(ostream& os) const
+{
+  BEGIN_PUT(expr_match_expr);
+
+  for (csize i = 0; i < theArgs.size(); i++)
+  {
+    os << indent << "using $"
+       << theOuterVarNames[i]->getStringValue()
+       << " := [" << endl << inc_indent;
+
+    if (theArgs[i])
+      theArgs[i]->put(os);
+
+    os << dec_indent << indent << "]" << endl;
+  }
+
+  theExpr->put(os);
+  theViewExpr->put(os);
+
+  END_PUT();
+}
+
+
 ostream& function_trace_expr::put(ostream& os) const
 {
   BEGIN_PUT(function_trace_expr);

=== modified file 'src/compiler/expression/expr_type.cpp'
--- src/compiler/expression/expr_type.cpp	2012-12-06 22:49:35 +0000
+++ src/compiler/expression/expr_type.cpp	2012-12-21 04:09:22 +0000
@@ -719,6 +719,12 @@
     return;
   }
 
+  case expr_match_expr_kind:
+  {
+    theType = rtm.BOOLEAN_TYPE_ONE; // TODO
+    return;
+  }
+
   case debugger_expr_kind:
   {
     theType = rtm.ITEM_TYPE_STAR; // TODO

=== modified file 'src/compiler/expression/expr_visitor.h'
--- src/compiler/expression/expr_visitor.h	2012-09-19 21:16:15 +0000
+++ src/compiler/expression/expr_visitor.h	2012-12-21 04:09:22 +0000
@@ -95,6 +95,7 @@
   DECL_EXPR_VISITOR_VISIT_MEM_FNS(flowctl_expr);
 
   DECL_EXPR_VISITOR_VISIT_MEM_FNS(eval_expr);
+  DECL_EXPR_VISITOR_VISIT_MEM_FNS(expr_match_expr);
 #ifdef ZORBA_WITH_DEBUGGER
   DECL_EXPR_VISITOR_VISIT_MEM_FNS(debugger_expr);
 #endif

=== modified file 'src/compiler/expression/flwor_expr.cpp'
--- src/compiler/expression/flwor_expr.cpp	2012-10-26 07:13:42 +0000
+++ src/compiler/expression/flwor_expr.cpp	2012-12-21 04:09:22 +0000
@@ -526,7 +526,7 @@
 /*******************************************************************************
 
 ********************************************************************************/
-group_clause::group_clause(
+groupby_clause::groupby_clause(
      static_context* sctx,
      CompilerCB* ccb,
      const QueryLoc& loc,
@@ -534,7 +534,7 @@
      const rebind_list_t& ngvars,
      const std::vector<std::string>& collations)
   :
-  flwor_clause(sctx, ccb, loc, flwor_clause::group_clause),
+  flwor_clause(sctx, ccb, loc, flwor_clause::groupby_clause),
   theGroupVars(gvars),
   theNonGroupVars(ngvars),
   theCollations(collations)
@@ -543,14 +543,22 @@
   csize numNGVars = theNonGroupVars.size();
 
   for (csize i = 0; i < numGVars; ++i)
+  {
+    expr::checkSimpleExpr(theGroupVars[i].first);
+
     theGroupVars[i].second->set_flwor_clause(this);
+  }
 
   for (csize i = 0; i < numNGVars; ++i)
+  {
+    expr::checkSimpleExpr(theNonGroupVars[i].first);
+
     theNonGroupVars[i].second->set_flwor_clause(this);
+  }
 }
 
 
-group_clause::~group_clause()
+groupby_clause::~groupby_clause()
 {
   csize numGVars = theGroupVars.size();
   csize numNGVars = theNonGroupVars.size();
@@ -563,7 +571,7 @@
 }
 
 
-expr* group_clause::get_input_for_group_var(const var_expr* var)
+expr* groupby_clause::get_input_for_group_var(const var_expr* var)
 {
   csize numVars = theGroupVars.size();
   for (csize i = 0; i < numVars; ++i)
@@ -576,7 +584,7 @@
 }
 
 
-expr* group_clause::get_input_for_nongroup_var(const var_expr* var)
+expr* groupby_clause::get_input_for_nongroup_var(const var_expr* var)
 {
   csize numVars = theNonGroupVars.size();
   for (csize i = 0; i < numVars; ++i)
@@ -589,7 +597,7 @@
 }
 
 
-flwor_clause* group_clause::clone(
+flwor_clause* groupby_clause::clone(
     user_function* udf,
     expr::substitution_t& subst) const
 {
@@ -626,7 +634,7 @@
     subst[theNonGroupVars[i].second] = cloneNonGroupVars[i].second;
   }
 
-  return theCCB->theEM->create_group_clause(theContext,
+  return theCCB->theEM->create_groupby_clause(theContext,
                                             get_loc(),
                                             cloneGroupVars,
                                             cloneNonGroupVars,
@@ -788,7 +796,6 @@
     bool general)
   :
   expr(ccb, sctx, udf, loc, (general ? gflwor_expr_kind : flwor_expr_kind)),
-  theIsGeneral(general),
   theHasSequentialClauses(false),
   theReturnExpr(NULL)
 {
@@ -934,13 +941,13 @@
 /*******************************************************************************
   For simple flwor only.
 ********************************************************************************/
-group_clause* flwor_expr::get_group_clause() const
+groupby_clause* flwor_expr::get_group_clause() const
 {
   csize numClauses = num_clauses();
   for (csize i = 0; i < numClauses; ++i)
   {
-    if (theClauses[i]->get_kind() == flwor_clause::group_clause)
-      return reinterpret_cast<group_clause*>(theClauses[i]);
+    if (theClauses[i]->get_kind() == flwor_clause::groupby_clause)
+      return static_cast<groupby_clause*>(theClauses[i]);
   }
 
   return NULL;
@@ -1011,7 +1018,7 @@
   Returns a set containing all the variables defined by the clauses of this
   flwor expr.
 ******************************************************************************/
-void flwor_expr::get_vars(expr::FreeVars& vars) const
+void flwor_expr::get_vars(std::vector<var_expr*>& vars) const
 {
   csize numClauses = num_clauses();
 
@@ -1025,34 +1032,34 @@
     {
       const for_clause* fc = static_cast<const for_clause *>(&c);
 
-      vars.insert(fc->get_var());
+      vars.push_back(fc->get_var());
 
       if (fc->get_pos_var() != NULL)
-        vars.insert(fc->get_pos_var());
+        vars.push_back(fc->get_pos_var());
 
       break;
     }
     case flwor_clause::let_clause:
     {
       const let_clause* lc = static_cast<const let_clause *>(&c);
-      vars.insert(lc->get_var());
+      vars.push_back(lc->get_var());
       break;
     }
     case flwor_clause::window_clause:
     {
       const window_clause* wc = static_cast<const window_clause *>(&c);
 
-      vars.insert(wc->get_var());
+      vars.push_back(wc->get_var());
 
       if (wc->get_win_start() != NULL)
       {
         const flwor_wincond* cond = wc->get_win_start();
         const flwor_wincond::vars& condvars = cond->get_out_vars();
 
-        if (condvars.posvar != NULL) vars.insert(condvars.posvar);
-        if (condvars.curr != NULL) vars.insert(condvars.curr);
-        if (condvars.prev != NULL) vars.insert(condvars.prev);
-        if (condvars.next != NULL) vars.insert(condvars.next);
+        if (condvars.posvar != NULL) vars.push_back(condvars.posvar);
+        if (condvars.curr != NULL) vars.push_back(condvars.curr);
+        if (condvars.prev != NULL) vars.push_back(condvars.prev);
+        if (condvars.next != NULL) vars.push_back(condvars.next);
       }
 
       if (wc->get_win_stop() != NULL)
@@ -1060,24 +1067,24 @@
         const flwor_wincond* cond = wc->get_win_stop();
         const flwor_wincond::vars& condvars = cond->get_out_vars();
 
-        if (condvars.posvar != NULL) vars.insert(condvars.posvar);
-        if (condvars.curr != NULL) vars.insert(condvars.curr);
-        if (condvars.prev != NULL) vars.insert(condvars.prev);
-        if (condvars.next != NULL) vars.insert(condvars.next);
+        if (condvars.posvar != NULL) vars.push_back(condvars.posvar);
+        if (condvars.curr != NULL) vars.push_back(condvars.curr);
+        if (condvars.prev != NULL) vars.push_back(condvars.prev);
+        if (condvars.next != NULL) vars.push_back(condvars.next);
       }
 
       break;
     }
-    case flwor_clause::group_clause:
+    case flwor_clause::groupby_clause:
     {
-      const group_clause* gc = static_cast<const group_clause *>(&c);
+      const groupby_clause* gc = static_cast<const groupby_clause *>(&c);
 
       flwor_clause::rebind_list_t::const_iterator ite = gc->beginGroupVars();
       flwor_clause::rebind_list_t::const_iterator end = gc->endGroupVars();
 
       for (; ite != end; ++ite)
       {
-        vars.insert((*ite).second);
+        vars.push_back((*ite).second);
       }
 
       ite = gc->beginNonGroupVars();
@@ -1085,7 +1092,7 @@
 
       for (; ite != end; ++ite)
       {
-        vars.insert((*ite).second);
+        vars.push_back((*ite).second);
       }
 
       break;
@@ -1093,7 +1100,7 @@
     case flwor_clause::count_clause:
     {
       const count_clause* cc = static_cast<const count_clause *>(&c);
-      vars.insert(cc->get_var());
+      vars.push_back(cc->get_var());
       break;
     }
     default:

=== modified file 'src/compiler/expression/flwor_expr.h'
--- src/compiler/expression/flwor_expr.h	2012-10-29 11:41:36 +0000
+++ src/compiler/expression/flwor_expr.h	2012-12-21 04:09:22 +0000
@@ -55,7 +55,7 @@
     for_clause,
     let_clause,
     window_clause,
-    group_clause,
+    groupby_clause,
     order_clause,
     count_clause,
     where_clause,
@@ -242,15 +242,15 @@
 
 protected:
   window_clause(
-        static_context* sctx,
-        CompilerCB* ccb,
-        const QueryLoc& loc,
-        WindowKind winKind,
-        var_expr* varExpr,
-        expr* domainExpr,
-        flwor_wincond* winStart,
-        flwor_wincond* winStop,
-        bool lazy = false);
+      static_context* sctx,
+      CompilerCB* ccb,
+      const QueryLoc& loc,
+      WindowKind winKind,
+      var_expr* varExpr,
+      expr* domainExpr,
+      flwor_wincond* winStart,
+      flwor_wincond* winStop,
+      bool lazy = false);
 
 public:
   ~window_clause();
@@ -405,7 +405,7 @@
                     the Y values in the input tuples that were grouped into T.
   theCollations   : The collations to use when comparing values for grouping.
 ********************************************************************************/
-class group_clause : public flwor_clause
+class groupby_clause : public flwor_clause
 {
   friend class expr;
   friend class flwor_expr;
@@ -417,7 +417,7 @@
   rebind_list_t            theNonGroupVars;
   std::vector<std::string> theCollations;
 
-  group_clause(
+  groupby_clause(
       static_context* sctx,
       CompilerCB* ccb,
       const QueryLoc& loc,
@@ -426,7 +426,7 @@
       const std::vector<std::string>& collations);
 
 public:
-  ~group_clause();
+  ~groupby_clause();
 
   const std::vector<std::string>& get_collations() const { return theCollations; }
 
@@ -648,7 +648,6 @@
   typedef std::vector<flwor_clause*> clause_list_t;
 
 protected:
-  bool            theIsGeneral;
   bool            theHasSequentialClauses;
   clause_list_t   theClauses;
   expr          * theReturnExpr;
@@ -662,9 +661,9 @@
       bool general);
 
 public:
-  bool is_general() const { return theIsGeneral; }
+  bool is_general() const { return get_expr_kind() == gflwor_expr_kind; }
 
-  void set_general(bool v) { theIsGeneral = true; }
+  void set_general(bool v) { theKind = (v ? gflwor_expr_kind : flwor_expr_kind); }
 
   expr* get_return_expr() const { return theReturnExpr; }
 
@@ -698,14 +697,14 @@
 
   long defines_variable(const var_expr* v) const;
 
-  void get_vars(expr::FreeVars& vars) const;
+  void get_vars(std::vector<var_expr*>& vars) const;
 
   // The following 5 methods are for the simple flwor only. They should be
   // removed eventually.
   expr* get_where() const;
   void set_where(expr* e);
   void remove_where_clause();
-  group_clause* get_group_clause() const;
+  groupby_clause* get_group_clause() const;
   orderby_clause* get_order_clause() const;
   csize num_forlet_clauses();
 

=== modified file 'src/compiler/expression/path_expr.cpp'
--- src/compiler/expression/path_expr.cpp	2012-10-09 14:06:08 +0000
+++ src/compiler/expression/path_expr.cpp	2012-12-21 04:09:22 +0000
@@ -208,6 +208,99 @@
 }
 
 
+bool match_expr::matches(const match_expr* other) const
+{
+  if (theTestKind != other->theTestKind)
+    return false;
+
+  switch (theTestKind)
+  {
+  case match_name_test:
+  {
+    if (getWildKind() != other->getWildKind())
+      return false;
+
+    if (getWildName() != other->getWildName())
+      return false;
+
+    if (getWildKind() == match_no_wild || getWildKind() == match_name_wild)
+    {
+      return getQName()->equals(other->getQName());
+    }
+
+    return true;
+  }
+  case match_anykind_test:
+  case match_text_test:
+  case match_comment_test:
+  {
+    return true;
+  }
+  case match_pi_test:
+  {
+    if (theQName == NULL && other->theQName == NULL)
+      return true;
+
+    if (theQName == NULL || other->theQName == NULL)
+      return false;
+
+    return theQName->equals(other->theQName);
+  }
+  case match_doc_test:
+  {
+    if (theDocTestKind != other->theDocTestKind)
+      return false;
+
+    if (theDocTestKind == match_xs_elem_test)
+      goto schema_test;
+
+    // else fall through
+  }
+  case match_elem_test:
+  case match_attr_test:
+  {
+    if (theQName == NULL || other->theQName == NULL)
+    {
+      if (theQName != NULL || other->theQName != NULL)
+        return false;
+    }
+    else if (!theQName->equals(other->theQName))
+    {
+      return false;
+    }
+
+    if (theTypeName == NULL || other->theTypeName == NULL)
+    {
+      if (theTypeName != NULL || other->theTypeName != NULL)
+        return false;
+    }
+    else if (!theTypeName->equals(other->theTypeName))
+    {
+      return false;
+    }
+
+    if (theNilledAllowed != other->theNilledAllowed)
+      return false;
+
+    return true;
+  }
+  case match_xs_elem_test:
+  case match_xs_attr_test:
+  {
+schema_test:
+    return (theQName->equals(other->theQName) &&
+            theTypeName->equals(other->theTypeName));
+  }
+  default:
+  {
+    ZORBA_ASSERT(false);
+  }
+  }
+
+  return false;
+}
+
+
 }
 
 /* vim:set et sw=2 ts=2: */

=== modified file 'src/compiler/expression/path_expr.h'
--- src/compiler/expression/path_expr.h	2012-10-09 14:06:08 +0000
+++ src/compiler/expression/path_expr.h	2012-12-21 04:09:22 +0000
@@ -159,9 +159,25 @@
                      PITest | CommentTest | TextTest | AnyKindTest
 
   If a match_expr represents a KindTest, then theWildKind and theWildName data
-  members are not used. If a match_expr represents a NameTest, then theTypeName
-  and theNilledAllowed data members are not used.
-
+  members are not used. 
+
+  If a match_expr represents a NameTest, then theTypeName and theNilledAllowed
+  data members are not used. In this case, theWildKind is used to distinguish
+  among 4 subcases:
+
+  1. no wildcard: 
+     theQName holds the expanded qname to match against an element or attribute
+     node. theWildName is not used.
+
+  2. full wildcard (*):
+     Neither theQName nor theWildName are used.
+
+  3. localname wildcard (pre:*):
+     theQName holds an artificial qname: "ns:wildcard", where ns is the URI
+     associated with pre. theWildName holds the pre.
+
+  4. prefix wildcard (*:name):
+     theQName is not used and theWildName holds the local name.
 ********************************************************************************/
 class match_expr : public expr
 {
@@ -177,6 +193,7 @@
   zstring           theWildName;
 
   store::Item_t     theQName;
+
   store::Item_t     theTypeName;
   bool              theNilledAllowed;
 
@@ -202,8 +219,7 @@
 
   const zstring& getWildName() const { return theWildName; }
 
-  template<class StringType>
-  void setWildName(const StringType& v) { theWildName = v; }
+  void setWildName(const zstring& v) { theWildName = v; }
 
   store::Item* getQName() const { return theQName.getp(); }
 
@@ -221,6 +237,8 @@
 
   void compute_scripting_kind();
 
+  bool matches(const match_expr* other) const;
+
   void accept(expr_visitor&);
 
   std::ostream& put(std::ostream&) const;

=== modified file 'src/compiler/expression/var_expr.cpp'
--- src/compiler/expression/var_expr.cpp	2012-12-06 22:49:35 +0000
+++ src/compiler/expression/var_expr.cpp	2012-12-21 04:09:22 +0000
@@ -255,12 +255,12 @@
     }
     else if (theVarKind == groupby_var)
     {
-      return reinterpret_cast<group_clause*>(theFlworClause)->
+      return reinterpret_cast<groupby_clause*>(theFlworClause)->
              get_input_for_group_var(this);
     }
     else if (theVarKind == non_groupby_var)
     {
-      return reinterpret_cast<group_clause*>(theFlworClause)->
+      return reinterpret_cast<groupby_clause*>(theFlworClause)->
              get_input_for_nongroup_var(this);
     }
   }

=== modified file 'src/compiler/expression/var_expr.h'
--- src/compiler/expression/var_expr.h	2012-12-06 22:49:35 +0000
+++ src/compiler/expression/var_expr.h	2012-12-21 04:09:22 +0000
@@ -88,8 +88,8 @@
 
   theParamPos:
   ------------
-  For arg vars, it is the position, within the param list, of parameter that is
-  bound to this arg var.
+  For arg vars, it is the position, within the param list, of the parameter that
+  is bound to this arg var.
 
   theSetExprs:
   ------------
@@ -129,8 +129,8 @@
     for_var,
     let_var,
     pos_var,
+    score_var,
     win_var,
-    score_var,
     wincond_out_var,
     wincond_out_pos_var,
     wincond_in_var,

=== modified file 'src/compiler/rewriter/rewriters/default_optimizer.cpp'
--- src/compiler/rewriter/rewriters/default_optimizer.cpp	2012-10-26 18:24:00 +0000
+++ src/compiler/rewriter/rewriters/default_optimizer.cpp	2012-12-21 04:09:22 +0000
@@ -17,9 +17,12 @@
 
 #include "compiler/rewriter/framework/rule_driver.h"
 #include "compiler/rewriter/rules/ruleset.h"
+#include "compiler/rewriter/rules/fold_rules.h"
+#include "compiler/rewriter/rules/index_matching_rule.h"
 #include "compiler/rewriter/rewriters/common_rewriter.h"
 #include "compiler/rewriter/rewriters/default_optimizer.h"
 #include "compiler/rewriter/tools/expr_tools.h"
+#include "compiler/xqddf/value_index.h"
 //#include "compiler/rewriter/tools/udf_graph.h"
 #include "compiler/api/compilercb.h"
 
@@ -27,25 +30,14 @@
 
 #include "system/properties.h"
 
+#include "context/static_context.h"
+
+//#include "store/api/store.h"
+
 
 namespace zorba
 {
 
-class FoldRules : public RuleMajorDriver
-{
-public:
-  FoldRules()
-  {
-    ADD_RULE(MarkExprs);
-    ADD_RULE(MarkFreeVars);
-    ADD_RULE(FoldConst);
-    ADD_RULE(PartialEval);
-    ADD_RULE(RefactorPredFLWOR);
-    ADD_RULE(EliminateUnusedLetVars);
-    ADD_RULE(MergeFLWOR);
-  }
-};
-
 
 DefaultOptimizer::DefaultOptimizer()
 {
@@ -183,6 +175,53 @@
     }
   }
 
+  // index matching
+  if (Properties::instance()->useIndexes())
+  {
+    static_context* sctx = rCtx.theRoot->get_sctx();
+
+    std::vector<IndexDecl*> indexDecls;
+    sctx->get_index_decls(indexDecls);
+
+    if (!indexDecls.empty())
+    {
+      MarkFreeVars freeVarsRule;
+      bool modified;
+      freeVarsRule.apply(rCtx, rCtx.theRoot, modified);
+    }
+
+    std::vector<IndexDecl*>::const_iterator ite = indexDecls.begin();
+    std::vector<IndexDecl*>::const_iterator end = indexDecls.end();
+    for (; ite != end; ++ite)
+    {
+      bool local_modified = false;
+
+      //store::Index* idx = GENV_STORE.getIndex((*ite)->getName());
+
+      //if (idx != NULL)
+      if (!(*ite)->isTemp())
+      {
+        IndexMatchingRule rule(*ite);
+
+        expr* e = rule.apply(rCtx, rCtx.getRoot(), local_modified);
+
+        if (e != rCtx.getRoot())
+          rCtx.setRoot(e);
+      }
+
+      if (local_modified)
+      {
+        if (Properties::instance()->printIntermediateOpt())
+        {
+          std::cout << "After index matching : " << std::endl;
+          rCtx.getRoot()->put(std::cout) << std::endl;
+        }
+
+        modified = true;
+      }
+    }
+  }
+
   // Index Joins
   if (Properties::instance()->inferJoins())
   {

=== modified file 'src/compiler/rewriter/rules/CMakeLists.txt'
--- src/compiler/rewriter/rules/CMakeLists.txt	2012-09-19 21:16:15 +0000
+++ src/compiler/rewriter/rules/CMakeLists.txt	2012-12-21 04:09:22 +0000
@@ -21,4 +21,5 @@
     path_rules.cpp
     hoist_rules.cpp
     index_join_rule.cpp
+    index_matching_rule.cpp
 )

=== modified file 'src/compiler/rewriter/rules/flwor_rules.cpp'
--- src/compiler/rewriter/rules/flwor_rules.cpp	2012-12-18 15:09:02 +0000
+++ src/compiler/rewriter/rules/flwor_rules.cpp	2012-12-21 04:09:22 +0000
@@ -229,9 +229,9 @@
 
     switch (c->get_kind())
     {
-    case flwor_clause::group_clause:
+    case flwor_clause::groupby_clause:
     {
-      group_clause* gc = static_cast<group_clause *>(c);
+      groupby_clause* gc = static_cast<groupby_clause *>(c);
 
       flwor_clause::rebind_list_t::iterator ite = gc->beginNonGroupVars();
       flwor_clause::rebind_list_t::iterator end = gc->endNonGroupVars();
@@ -370,9 +370,9 @@
     {
       break;
     }
-    else if (clause->get_kind() == flwor_clause::group_clause)
+    else if (clause->get_kind() == flwor_clause::groupby_clause)
     {
-      group_clause* gc = static_cast<group_clause*>(clause);
+      groupby_clause* gc = static_cast<groupby_clause*>(clause);
 
       const flwor_clause::rebind_list_t& gVars = gc->get_grouping_vars();
 
@@ -697,9 +697,9 @@
 
         break;
       }
-      case flwor_clause::group_clause:
+      case flwor_clause::groupby_clause:
       {
-        group_clause* cl = static_cast<group_clause*>(clause);
+        groupby_clause* cl = static_cast<groupby_clause*>(clause);
 
         csize numExprs = cl->numGroupingVars();
 
@@ -1491,7 +1491,7 @@
     {
       checkClause = flworExpr->get_clause(checkClausePos);
 
-      if (checkClause->get_kind() == flwor_clause::group_clause ||
+      if (checkClause->get_kind() == flwor_clause::groupby_clause ||
           (checkClause->get_kind() == flwor_clause::count_clause && eq))
         return false;
 
@@ -1587,7 +1587,7 @@
           const flwor_clause* c = flwor->get_clause(i);
           
           if (c->get_kind() == flwor_clause::where_clause ||
-              c->get_kind() == flwor_clause::group_clause ||
+              c->get_kind() == flwor_clause::groupby_clause ||
               c->get_kind() == flwor_clause::order_clause)
           {
             goto next1;
@@ -1601,7 +1601,7 @@
       {
         const flwor_clause* c = returnFlwor->get_clause(i);
         
-        if (c->get_kind() == flwor_clause::group_clause ||
+        if (c->get_kind() == flwor_clause::groupby_clause ||
             c->get_kind() == flwor_clause::order_clause)
         {
           goto next1;
@@ -1651,7 +1651,7 @@
             if (nestedClauseKind == flwor_clause::for_clause)
             {
               xqtref_t nestedDomainType =
-                static_cast<for_clause*>(nestedClause)->get_expr()->get_return_type();
+              static_cast<for_clause*>(nestedClause)->get_expr()->get_return_type();
               
               if (nestedDomainType->get_quantifier() != TypeConstants::QUANT_ONE)
               {
@@ -1685,36 +1685,29 @@
             flwor_clause::ClauseKind nestedClauseKind = nestedClause->get_kind();
             
             if (nestedClauseKind != flwor_clause::let_clause &&
-                nestedClauseKind != flwor_clause::for_clause)
+                nestedClauseKind != flwor_clause::for_clause &&
+                nestedClauseKind != flwor_clause::where_clause)
             {
-#if 1
-              // temp hack until we have an optimized general flwor
-              if (nestedClauseKind == flwor_clause::where_clause &&
-                  i == numClauses-1 &&
-                  flwor->get_where() == NULL &&
-                  nestedFlwor->get_return_expr()->get_var() != NULL)
-              {
-                continue;
-              }
-#endif
               merge = false;
               break;
             }
           }
         }
-    }
+      }
       
       if (merge)
       {
         for (csize j = 0; j < numNestedClauses; ++j)
         {
           flwor_clause* nestedClause = nestedFlwor->get_clause(j);
-#if 1
-          if (nestedClause->get_kind() == flwor_clause::where_clause)
-            flwor->add_clause(i+j+1, nestedClause);
-          else
-#endif
-            flwor->add_clause(i+j, nestedClause);
+          flwor->add_clause(i+j, nestedClause);
+
+          if (!flwor->is_general() &&
+              nestedClause->get_kind() == flwor_clause::where_clause &&
+              i != numClauses - 1)
+          {
+            flwor->set_general(true);
+          }
         }
         
         c->set_expr(nestedFlwor->get_return_expr());

=== added file 'src/compiler/rewriter/rules/fold_rules.h'
--- src/compiler/rewriter/rules/fold_rules.h	1970-01-01 00:00:00 +0000
+++ src/compiler/rewriter/rules/fold_rules.h	2012-12-21 04:09:22 +0000
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2006-2008 The FLWOR Foundation.
+ *
+ * Licensed 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.
+ */
+#pragma once
+#ifndef ZORBA_COMPILER_REWRITER_FOLD_RULES
+#define ZORBA_COMPILER_REWRITER_FOLD_RULES
+
+#include "stdafx.h"
+
+#include "compiler/rewriter/framework/rule_driver.h"
+#include "compiler/rewriter/rewriters/common_rewriter.h"
+#include "compiler/rewriter/rules/ruleset.h"
+
+
+namespace zorba
+{
+
+class FoldRules : public RuleMajorDriver
+{
+public:
+  FoldRules()
+  {
+    ADD_RULE(MarkExprs);
+    ADD_RULE(MarkFreeVars);
+    ADD_RULE(FoldConst);
+    ADD_RULE(PartialEval);
+    ADD_RULE(RefactorPredFLWOR);
+    ADD_RULE(EliminateUnusedLetVars);
+    ADD_RULE(MergeFLWOR);
+  }
+};
+
+
+}
+
+#endif
+/* vim:set et sw=2 ts=2: */

=== modified file 'src/compiler/rewriter/rules/hoist_rules.cpp'
--- src/compiler/rewriter/rules/hoist_rules.cpp	2012-12-06 22:49:35 +0000
+++ src/compiler/rewriter/rules/hoist_rules.cpp	2012-12-21 04:09:22 +0000
@@ -408,7 +408,7 @@
       assert(step->theExpr->get_expr_kind() == flwor_expr_kind);
 
       flwor_expr* flwor = static_cast<flwor_expr*>(step->theExpr);
-      group_clause* gc = flwor->get_group_clause();
+      groupby_clause* gc = flwor->get_group_clause();
 
       // If any free variable is a group-by variable, give up.
       if (gc != NULL)

=== modified file 'src/compiler/rewriter/rules/index_join_rule.cpp'
--- src/compiler/rewriter/rules/index_join_rule.cpp	2012-12-06 22:49:35 +0000
+++ src/compiler/rewriter/rules/index_join_rule.cpp	2012-12-21 04:09:22 +0000
@@ -702,7 +702,7 @@
 
   sctx->bind_index(idx, loc);
 
-  buildExpr = idx->getBuildExpr(rCtx.getCompilerCB(), loc);
+  buildExpr = idx->getBuildExpr(loc);
 
   createExpr->set_arg(1, buildExpr);
 

=== added file 'src/compiler/rewriter/rules/index_matching_rule.cpp'
--- src/compiler/rewriter/rules/index_matching_rule.cpp	1970-01-01 00:00:00 +0000
+++ src/compiler/rewriter/rules/index_matching_rule.cpp	2012-12-21 04:09:22 +0000
@@ -0,0 +1,789 @@
+
+
+/*
+ * Copyright 2006-2008 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "stdafx.h"
+
+
+#include "compiler/expression/expr.h"
+#include "compiler/expression/expr_iter.h"
+
+#include "compiler/xqddf/value_index.h"
+
+#include "compiler/rewriter/rules/index_matching_rule.h"
+#include "compiler/rewriter/rules/fold_rules.h"
+#include "compiler/rewriter/tools/expr_tools.h"
+
+#include "compiler/api/compilercb.h"
+
+#include "functions/function.h"
+#include "functions/library.h"
+
+#include "types/typeops.h"
+
+#include "util/dynamic_bitset.h"
+
+#include "diagnostics/assert.h"
+
+#include "system/properties.h"
+
+
+namespace zorba
+{
+
+
+/*******************************************************************************
+
+********************************************************************************/
+IndexMatchingRule::PredInfo::PredInfo(
+    where_clause* wc,
+    csize wcPos,
+    fo_expr* andExpr,
+    csize argPos)
+  :
+  theClause(wc),
+  theClausePos(wcPos),
+  theAndExpr(andExpr),
+  theArgPos(argPos)
+{
+  if (theAndExpr)
+  {
+    assert(theAndExpr->get_func()->getKind() == FunctionConsts::OP_AND_N);
+
+    theExpr = theAndExpr->get_arg(theArgPos);
+  }
+  else
+  {
+    theExpr = theClause->get_expr();
+  }
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+IndexMatchingRule::IndexMatchingRule(IndexDecl* decl)
+  :
+  RewriteRule(RewriteRule::IndexJoin, "IndexJoin"),
+  theIndexDecl(decl),
+  theViewExpr(NULL),
+  theDoTrace(true)
+{
+  theViewExpr = decl->getViewExpr();
+
+  csize numVClauses = theViewExpr->num_clauses();
+
+  theKeyClauses.reserve(numVClauses);
+
+  for (csize i = 1; i < numVClauses; ++i)
+  {
+    assert(theViewExpr->get_clause(i)->get_kind() == flwor_clause::let_clause);
+    let_clause* lc = static_cast<let_clause*>(theViewExpr->get_clause(i));
+    theKeyClauses.push_back(lc);
+  }
+
+  std::ostringstream msg;
+  msg << "normalization of candidate index: " << decl->getName()->getStringValue();
+
+  RewriterContext rCtx(theViewExpr->get_ccb(),
+                       theViewExpr,
+                       theViewExpr->get_udf(),
+                       msg.str(),
+                       true);
+  FoldRules foldRules;
+  foldRules.rewrite(rCtx);
+
+  if (Properties::instance()->printIntermediateOpt() && theDoTrace)
+  {
+    std::cout << "Canonical view expr for candidate index : " 
+              << decl->getName()->getStringValue() << std::endl;
+    rCtx.getRoot()->put(std::cout) << std::endl;
+  }
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+expr* IndexMatchingRule::apply(RewriterContext& rCtx, expr* node, bool& modified)
+{
+  modified = false;
+
+  // TODO remove this
+  if (theIndexDecl->isGeneral() || theIndexDecl->isOrdered())
+    return node;
+
+  if (node->get_expr_kind() == flwor_expr_kind ||
+      node->get_expr_kind() == gflwor_expr_kind)
+  {
+    theQueryExpr = static_cast<flwor_expr*>(node);
+
+    bool matched = matchIndex();
+
+    if (matched)
+      modified = true;
+  }
+
+  ExprIterator iter(node);
+  while (!iter.done())
+  {
+    expr* currChild = **iter;
+
+    bool childModified = false;
+
+    expr* newChild = apply(rCtx, currChild, childModified);
+
+    ZORBA_ASSERT(currChild == newChild);
+
+    if (childModified)
+      modified = true;
+
+    iter.next();
+  }
+
+  return node;
+}
+
+
+/*******************************************************************************
+  Match a flwor expr with an index
+********************************************************************************/
+bool IndexMatchingRule::matchIndex()
+{
+  CompilerCB* ccb = theQueryExpr->get_ccb();
+  static_context* sctx = theQueryExpr->get_sctx();
+  user_function* udf = theQueryExpr->get_udf();
+
+  csize numVClauses = theViewExpr->num_clauses();
+  csize numQClauses = theQueryExpr->num_clauses();
+  csize nextQueryClause = 0;
+
+  expr::substitution_t subst;
+
+  for_clause* firstMatchedFOR = NULL;
+  csize firstMatchedFORpos = 0;
+  csize lastMatchedFORpos = 0;
+  csize lastMatchedWHEREpos = 0;
+  DynamicBitset matchedClauses(numQClauses);
+  matchedClauses.reset();
+
+  std::vector<PredInfo> vpreds;
+  std::vector<PredInfo> unmatchedQPreds;
+  std::vector<PredInfo> matchedQPreds;
+
+  // Match the FOR and WHERE clauses of the view FLWOR. For now, we can match
+  // only indexes whose domain and key expressions consist of FOR, LET, and
+  // WHERE clauses only.
+  for (csize vi = 0; vi < numVClauses; ++vi)
+  {
+    flwor_clause* vc = theViewExpr->get_clause(vi);
+
+    switch (vc->get_kind())
+    {
+    case flwor_clause::for_clause:
+    {
+      for_clause* vfc = static_cast<for_clause*>(vc);
+      expr* vdomExpr = vfc->get_expr();
+      var_expr* vvarExpr = vfc->get_var();
+
+      bool matched = false;
+
+      for (csize qi = nextQueryClause; qi < numQClauses && !matched; ++qi)
+      {
+        flwor_clause* qc = theQueryExpr->get_clause(qi);
+
+        switch (qc->get_kind())
+        {
+        case flwor_clause::for_clause:
+        {
+          for_clause* qfc = static_cast<for_clause*>(qc);
+          expr* qdomExpr = qfc->get_expr();
+          var_expr* qvarExpr = qfc->get_var();
+
+          if (!qfc->is_allowing_empty() &&
+              expr_tools::match_exact(qdomExpr, vdomExpr, subst))
+          {
+            nextQueryClause = qi+1;
+            subst[vvarExpr] = qvarExpr;
+            matchedClauses.set(qi, true);
+
+            if (firstMatchedFOR == NULL)
+            {
+              firstMatchedFOR = qfc;
+              firstMatchedFORpos = qi;
+            }
+
+            lastMatchedFORpos = qi;
+            matched = true;
+            break;
+          }
+          else if (firstMatchedFOR != NULL)
+          {
+            // TODO allow for FOR clause reordering, if conditions allow it
+            return false;
+          }
+
+          break;
+        }
+        case flwor_clause::let_clause:
+        {
+          if (firstMatchedFOR != NULL)
+          {
+            let_clause* qlc = static_cast<let_clause*>(qc);
+            expr* qdomExpr = qlc->get_expr();
+
+            if (qdomExpr->is_sequential())
+              return false;
+          }
+          break;
+        }
+        case flwor_clause::window_clause:
+        {
+          if (firstMatchedFOR != NULL)
+          {
+            // TODO allow for FOR clause reordering, if conditions allow it
+            return false; // todo
+          }
+
+          break;
+        }
+        case flwor_clause::where_clause:
+        {
+          getWherePreds(qi, static_cast<where_clause*>(qc), unmatchedQPreds);
+          break;
+        }
+        case flwor_clause::order_clause:
+        {
+          break;
+        }
+        case flwor_clause::count_clause:
+        case flwor_clause::groupby_clause:
+        case flwor_clause::materialize_clause:
+        {
+          if (firstMatchedFOR != NULL)
+            return false;
+
+          break;
+        }
+        default:
+          ZORBA_ASSERT(false);
+        }
+      }
+
+      if (!matched)
+        return false;
+
+      break;
+    }
+    case flwor_clause::let_clause:
+    {
+      break;
+    }
+    case flwor_clause::where_clause:
+    {
+      where_clause* vwc = static_cast<where_clause*>(vc);
+      getWherePreds(vi, vwc, vpreds);
+
+      break;
+    }
+    default:
+    {
+      assert(false);
+      return false;
+    }
+    }
+  }
+
+  // Collect the rest of the query preds, if any
+  for (csize qi = nextQueryClause; qi < numQClauses; ++qi)
+  {
+    flwor_clause* qc = theQueryExpr->get_clause(qi);
+
+    if (qc->get_kind() != flwor_clause::where_clause)
+      continue;
+
+    getWherePreds(qi, static_cast<where_clause*>(qc), unmatchedQPreds);
+  }
+
+  // Find a match for each index predicate
+  std::vector<PredInfo>::iterator vpredIte = vpreds.begin();
+  std::vector<PredInfo>::iterator vpredEnd = vpreds.end();
+
+  for (; vpredIte != vpredEnd; ++vpredIte)
+  {
+    expr* vpredExpr = vpredIte->theExpr;
+    bool matched = false;
+
+    std::vector<PredInfo>::iterator qpredIte = unmatchedQPreds.begin();
+    std::vector<PredInfo>::iterator qpredEnd = unmatchedQPreds.end();
+
+    for (; qpredIte != qpredEnd; ++qpredIte)
+    {
+      PredInfo& qpred = *qpredIte;
+      expr* qpredExpr = qpred.theExpr;
+
+      if (expr_tools::match_exact(qpredExpr, vpredExpr, subst))
+      {
+        matched = true;
+        matchedQPreds.push_back(qpred);
+        unmatchedQPreds.erase(qpredIte);
+
+        if (qpred.theClausePos > lastMatchedWHEREpos)
+          lastMatchedWHEREpos = qpred.theClausePos;
+
+        break;
+      }
+    }
+
+    if (!matched)
+      return false;
+  }
+
+  // Create the vector to store the args of the probe function
+  std::vector<expr*> probeArgs;
+  probeArgs.reserve(theKeyClauses.size() + 1);
+
+  // Create the index-name expr and make it the 1st arg of the probe function
+  store::Item_t indexName = theIndexDecl->getName();
+
+  expr* qnameExpr = ccb->theEM->
+  create_const_expr(sctx, udf, firstMatchedFOR->get_loc(), indexName);
+
+  probeArgs.push_back(qnameExpr);
+
+  // Match the key exprs
+  std::vector<let_clause*>::const_iterator keyIte = theKeyClauses.begin();
+  std::vector<let_clause*>::const_iterator keyEnd = theKeyClauses.end();
+
+  for (; keyIte != keyEnd; ++keyIte)
+  {
+    int matched = -1;
+    expr* keyExpr = (*keyIte)->get_expr();
+
+    std::vector<PredInfo>::iterator qpredIte = unmatchedQPreds.begin();
+    std::vector<PredInfo>::iterator qpredEnd = unmatchedQPreds.end();
+
+    for (; qpredIte != qpredEnd; ++qpredIte)
+    {
+      PredInfo& qpred = *qpredIte;
+
+      if (qpred.theExpr->get_expr_kind() != fo_expr_kind)
+        continue;
+
+      fo_expr* qpredExpr = static_cast<fo_expr*>(qpred.theExpr);
+      function* qpredFunc = qpredExpr->get_func();
+
+      if (qpredFunc->getKind() == FunctionConsts::FN_BOOLEAN_1)
+      {
+        if (qpredExpr->get_arg(0)->get_expr_kind() != fo_expr_kind)
+          continue;
+
+        qpredExpr = static_cast<fo_expr*>(qpredExpr->get_arg(0));
+        qpredFunc = qpredExpr->get_func();
+      }
+
+      if (qpredFunc->comparisonKind() != CompareConsts::VALUE_EQUAL)
+        continue;
+
+      if (matchKeyExpr(qpredExpr->get_arg(0), keyExpr, subst))
+        matched = 0;
+      else if (matchKeyExpr(qpredExpr->get_arg(1), keyExpr, subst))
+        matched = 1;
+
+      if (matched >= 0)
+      {
+        matchedQPreds.push_back(qpred);
+        unmatchedQPreds.erase(qpredIte);
+
+        if (qpred.theClausePos > lastMatchedWHEREpos)
+          lastMatchedWHEREpos = qpred.theClausePos;
+
+        probeArgs.push_back(qpredExpr->get_arg(1 - matched));
+        break;
+      }
+    }
+
+    if (matched < 0)
+      return false;
+  }
+
+  // Make sure thare are no "ilegal" query clauses between the last matched FOR
+  // clause and the last WHERE clause containing a matched pred.
+  for (csize i = lastMatchedFORpos + 1; i < lastMatchedWHEREpos; ++i)
+  {
+    flwor_clause* qc = theQueryExpr->get_clause(i);
+
+    switch (qc->get_kind())
+    {
+    case flwor_clause::for_clause:
+    case flwor_clause::let_clause:
+    case flwor_clause::window_clause:
+    {
+      forletwin_clause* qflwc = static_cast<forletwin_clause*>(qc);
+      expr* qdomExpr = qflwc->get_expr();
+
+      if (qdomExpr->is_sequential())
+        return false;
+      
+      break;
+    }
+    case flwor_clause::count_clause:
+    case flwor_clause::groupby_clause:
+    case flwor_clause::materialize_clause:
+    {
+      return false;
+    }
+    case flwor_clause::where_clause:
+    case flwor_clause::order_clause:
+    {
+      break;
+    }
+    default:
+      ZORBA_ASSERT(false);
+    }
+  }
+
+  // Mark the flwor vars of the query flwor expr as "not used" initially
+  std::vector<var_expr*> queryVars;
+  theQueryExpr->get_vars(queryVars);
+
+  for (csize i = 0; i < queryVars.size(); ++i)
+  {
+    queryVars[i]->setVisitId(0);
+  }
+
+  // Check for dependencies on query vars that will be eliminated by the rewrite
+  const var_expr* domVar = theViewExpr->get_return_expr()->get_var();
+  assert(domVar);
+  assert(subst[domVar]->get_expr_kind() == var_expr_kind);
+  domVar = static_cast<const var_expr*>(subst[domVar]);
+ 
+  for (csize i = 0; i < unmatchedQPreds.size(); ++i)
+  {
+    expr* pred = unmatchedQPreds[i].theExpr;
+    if (!checkFreeVars(pred, domVar, matchedClauses))
+      return false;
+  }
+
+  if (!checkFreeVars(theQueryExpr->get_return_expr(), domVar, matchedClauses))
+      return false;
+
+  for (csize i = numQClauses-1; i > 0; --i)
+  {
+    if (matchedClauses.get(i))
+      continue;
+
+    flwor_clause* c = theQueryExpr->get_clause(i);
+
+    switch (c->get_kind())
+    {
+    case flwor_clause::for_clause:
+    case flwor_clause::let_clause:
+    {
+      forlet_clause* flc = static_cast<forlet_clause*>(c);
+      var_expr* var = flc->get_var();
+      var_expr* posVar = flc->get_pos_var();
+
+      if (!var->isVisited(1) && (posVar == NULL || !posVar->isVisited(1)))
+        continue;
+
+      if (!checkFreeVars(flc->get_expr(), domVar, matchedClauses))
+        return false;
+
+      break;
+    }
+    case flwor_clause::window_clause:
+    {
+      window_clause* wc = static_cast<window_clause*>(c);
+      var_expr* var = wc->get_var();
+      flwor_wincond* startCond = wc->get_win_start();
+      flwor_wincond* stopCond = wc->get_win_stop();
+
+      bool used = var->isVisited(1);
+
+      if (! used && startCond)
+      {
+        const flwor_wincond_vars& vars = startCond->get_out_vars();
+
+        if ((vars.posvar && vars.posvar->isVisited(1)) ||
+            (vars.curr && vars.curr->isVisited(1)) ||
+            (vars.prev && vars.prev->isVisited(1)) ||
+            (vars.next && vars.next->isVisited(1)))
+          used = true;
+      }
+
+      if (! used && stopCond)
+      {
+        const flwor_wincond_vars& vars = stopCond->get_out_vars();
+
+        if ((vars.posvar && vars.posvar->isVisited(1)) ||
+            (vars.curr && vars.curr->isVisited(1)) ||
+            (vars.prev && vars.prev->isVisited(1)) ||
+            (vars.next && vars.next->isVisited(1)))
+          used = true;
+      }
+
+      if (used)
+      {
+        if (!checkFreeVars(wc->get_expr(), domVar, matchedClauses))
+          return false;
+
+        if (startCond &&
+            !checkFreeVars(startCond->get_expr(), domVar, matchedClauses))
+          return false;
+
+        if (stopCond &&
+            !checkFreeVars(stopCond->get_expr(), domVar, matchedClauses))
+          return false;
+      }
+
+      break;
+    }
+    case flwor_clause::order_clause:
+    {
+      orderby_clause* oc = static_cast<orderby_clause*>(c);
+
+      std::vector<expr*>::const_iterator ite = oc->begin();
+      std::vector<expr*>::const_iterator end = oc->end();
+      for (; ite != end; ++ite)
+      {
+        if (!checkFreeVars(*ite, domVar, matchedClauses))
+          return false;
+      }
+
+      break;
+    }
+    case flwor_clause::groupby_clause:
+    {
+      groupby_clause* gc = static_cast<groupby_clause*>(c);
+
+      flwor_clause::rebind_list_t::const_iterator ite = gc->beginGroupVars();
+      flwor_clause::rebind_list_t::const_iterator end = gc->endGroupVars();
+      for (; ite != end; ++ite)
+      {
+        if (!checkFreeVars(ite->first, domVar, matchedClauses))
+          return false;
+      }
+
+      ite = gc->beginNonGroupVars();
+      end = gc->endNonGroupVars();
+      for (; ite != end; ++ite)
+      {
+        if (!checkFreeVars(ite->first, domVar, matchedClauses))
+          return false;
+      }
+
+      break;
+    }
+    case flwor_clause::count_clause:
+    case flwor_clause::where_clause:
+    case flwor_clause::materialize_clause:
+    {
+      break;
+    }
+    default:
+    {
+      ZORBA_ASSERT(false);
+    }
+    }
+  }
+
+  // Do the rewrite
+  for (csize i = 0; i < matchedQPreds.size(); ++i)
+  {
+    PredInfo& pred = matchedQPreds[i];
+
+    if (pred.theAndExpr != NULL)
+    {
+      fo_expr* andExpr = pred.theAndExpr;
+      csize numRemoved = 0;
+
+      while (matchedQPreds[i].theAndExpr == andExpr)
+      {
+        matchedQPreds[i].theAndExpr->remove_arg(pred.theArgPos - numRemoved);
+        ++i;
+      }
+
+      --i;
+
+      if (andExpr->num_args() == 1)
+      {
+        pred.theClause->set_expr(pred.theAndExpr->get_arg(0));
+      }
+      else if (andExpr->num_args() == 0)
+      {
+        matchedClauses.set(pred.theClausePos, true);
+      }
+    }
+    else
+    {
+      matchedClauses.set(pred.theClausePos, true);
+    }
+  }
+
+  fo_expr* probeExpr = ccb->theEM->
+  create_fo_expr(sctx,
+                 udf,
+                 firstMatchedFOR->get_loc(),
+                 BUILTIN_FUNC(FN_ZORBA_XQDDF_PROBE_INDEX_POINT_VALUE_N),
+                 probeArgs);
+
+  firstMatchedFOR->set_expr(probeExpr);
+
+  csize numRemoved = 0;
+  for (csize i = firstMatchedFORpos + 1; i < matchedClauses.size(); ++i)
+  {
+    if (matchedClauses.get(i))
+    {
+      theQueryExpr->remove_clause(i - numRemoved);
+      ++numRemoved;
+    }
+  }
+
+  return true;
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+void IndexMatchingRule::getWherePreds(
+    csize clausePos,
+    where_clause* wc,
+    std::vector<PredInfo>& preds)
+{
+  expr* whereExpr = wc->get_expr();
+
+  if (whereExpr->get_function_kind() == FunctionConsts::OP_AND_N)
+  {
+    fo_expr* andExpr = static_cast<fo_expr*>(whereExpr);
+    csize numArgs = andExpr->num_args();
+
+    for (csize i = 0; i < numArgs; ++i)
+    {
+      preds.push_back(PredInfo(wc, clausePos, andExpr, i));
+    }
+  }
+  else
+  {
+    preds.push_back(PredInfo(wc, clausePos, NULL, 0));
+  }
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+bool IndexMatchingRule::matchKeyExpr(
+    expr* qexpr,
+    expr* vexpr,
+    expr::substitution_t& subst)
+{
+  if (qexpr->get_expr_kind() == promote_expr_kind &&
+      vexpr->get_expr_kind() == promote_expr_kind)
+  {
+    promote_expr* qe = static_cast<promote_expr*>(qexpr);
+    promote_expr* ve = static_cast<promote_expr*>(vexpr);
+    xqtref_t qtype = qe->get_return_type();
+    xqtref_t vtype = ve->get_target_type();
+
+    TypeManager* tm = qe->get_type_manager();
+    RootTypeManager& rtm = GENV_TYPESYSTEM;
+
+    if (TypeOps::is_subtype(tm, *qtype, *vtype) ||
+        (TypeOps::is_subtype(tm, *qtype, *rtm.UNTYPED_ATOMIC_TYPE_STAR) &&
+         TypeOps::is_subtype(tm, *vtype, *rtm.STRING_TYPE_STAR)))
+    {
+      return expr_tools::match_exact(qe->get_input(), ve->get_input(), subst);
+    }
+
+    return false;
+  }
+  else if (vexpr->get_expr_kind() == promote_expr_kind &&
+           qexpr->get_expr_kind() != promote_expr_kind)
+  {
+    promote_expr* ve = static_cast<promote_expr*>(vexpr);
+    xqtref_t qtype = qexpr->get_return_type();
+    xqtref_t vtype = ve->get_target_type();
+
+    TypeManager* tm = qexpr->get_type_manager();
+    RootTypeManager& rtm = GENV_TYPESYSTEM;
+
+    if (TypeOps::is_subtype(tm, *qtype, *vtype) ||
+        (TypeOps::is_subtype(tm, *qtype, *rtm.UNTYPED_ATOMIC_TYPE_STAR) &&
+         TypeOps::is_subtype(tm, *vtype, *rtm.STRING_TYPE_STAR)))
+    {
+      return expr_tools::match_exact(qexpr, ve->get_input(), subst);
+    }
+
+    return false;
+  }
+  else if (vexpr->get_expr_kind() == treat_expr_kind &&
+           qexpr->get_expr_kind() != treat_expr_kind)
+  {
+    treat_expr* ve = static_cast<treat_expr*>(vexpr);
+
+    return expr_tools::match_exact(qexpr, ve->get_input(), subst);
+  }
+
+  return expr_tools::match_exact(qexpr, vexpr, subst);
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+bool IndexMatchingRule::checkFreeVars(
+    const expr* qexpr,
+    const var_expr* domVar,
+    const DynamicBitset& matchedClauses)
+{
+  const expr::FreeVars& freeVars = qexpr->getFreeVars();
+
+  expr::FreeVars::const_iterator ite = freeVars.begin();
+  expr::FreeVars::const_iterator end = freeVars.end();
+  for (; ite != end; ++ite)
+  {
+    var_expr* freeVar = *ite;
+
+    if (freeVar == domVar)
+      continue;
+
+    if (freeVar->get_flwor_clause()->get_flwor_expr() == theQueryExpr)
+    {
+      freeVar->setVisitId(1);
+    }
+
+    if (freeVar->get_kind() != var_expr::for_var)
+      continue;
+
+    for (csize i = 0; i < matchedClauses.size(); ++i)
+    {
+      if (matchedClauses.get(i) &&
+          freeVar->get_flwor_clause() == theQueryExpr->get_clause(i))
+      {
+        return false;
+      }
+    }
+  }
+
+  return true;
+}
+
+
+}
+
+/* vim:set et sw=2 ts=2: */

=== modified file 'src/compiler/rewriter/rules/nodeid_rules.cpp'
--- src/compiler/rewriter/rules/nodeid_rules.cpp	2012-12-06 22:49:35 +0000
+++ src/compiler/rewriter/rules/nodeid_rules.cpp	2012-12-21 04:09:22 +0000
@@ -462,6 +462,7 @@
   case exit_expr_kind :       // TODO
 
   case eval_expr_kind :       // TODO
+  case expr_match_expr_kind : // TODO
   case debugger_expr_kind :   // TODO
   case dynamic_function_invocation_expr_kind : // TODO
   case function_item_expr_kind : // TODO
@@ -969,6 +970,7 @@
   }
 
   case eval_expr_kind:
+  case expr_match_expr_kind:
   {
     eval_expr* e = static_cast<eval_expr*>(node);
 
@@ -1367,6 +1369,7 @@
 
 
   case eval_expr_kind:
+  case expr_match_expr_kind:
   {
     break;
   }

=== modified file 'src/compiler/rewriter/rules/ruleset.h'
--- src/compiler/rewriter/rules/ruleset.h	2012-10-30 13:33:05 +0000
+++ src/compiler/rewriter/rules/ruleset.h	2012-12-21 04:09:22 +0000
@@ -144,7 +144,7 @@
   expr* apply(RewriterContext& rCtx, expr* node, bool& modified);
 };
 
-#if 1
+
 /*******************************************************************************
 
 ********************************************************************************/
@@ -159,7 +159,7 @@
 
   expr* apply(RewriterContext& rCtx, expr* node, bool& modified);
 };
-#endif
+
 
 /*******************************************************************************
 

=== modified file 'src/compiler/rewriter/tools/dataflow_annotations.cpp'
--- src/compiler/rewriter/tools/dataflow_annotations.cpp	2012-12-06 22:49:35 +0000
+++ src/compiler/rewriter/tools/dataflow_annotations.cpp	2012-12-21 04:09:22 +0000
@@ -242,6 +242,7 @@
   case ft_expr_kind:            // TODO
 #endif
   case eval_expr_kind:          // TODO
+  case expr_match_expr_kind:    // TODO
   case debugger_expr_kind:      // TODO
     break;
 
@@ -397,7 +398,7 @@
         break;
       }
       case flwor_clause::order_clause:
-      case flwor_clause::group_clause:
+      case flwor_clause::groupby_clause:
       {
         return;
       }
@@ -1152,6 +1153,7 @@
   }
 
   case eval_expr_kind:
+  case expr_match_expr_kind:
   {
     eval_expr* e = static_cast<eval_expr*>(node);
     // Make sure that the eval iterator will produce standalone trees.

=== modified file 'src/compiler/rewriter/tools/expr_tools.cpp'
--- src/compiler/rewriter/tools/expr_tools.cpp	2012-10-29 11:41:36 +0000
+++ src/compiler/rewriter/tools/expr_tools.cpp	2012-12-21 04:09:22 +0000
@@ -20,9 +20,11 @@
 #include "compiler/expression/flwor_expr.h"
 #include "compiler/expression/expr.h"
 #include "compiler/expression/path_expr.h"
+#include "compiler/expression/script_exprs.h"
 #include "compiler/expression/ft_expr.h"
 #include "compiler/expression/ftnode.h"
 #include "compiler/expression/expr_iter.h"
+#include "compiler/api/compilercb.h"
 
 #include "functions/func_errors_and_diagnostics.h"
 
@@ -48,6 +50,482 @@
 /*******************************************************************************
 
 ********************************************************************************/
+static void normalize_comp(
+    CompareConsts::CompareType& comp,
+    expr*& arg0,
+    expr*& arg1)
+{
+  switch (comp)
+  {
+  case CompareConsts::VALUE_GREATER:
+  case CompareConsts::GENERAL_GREATER:
+  case CompareConsts::VALUE_GREATER_EQUAL:
+  case CompareConsts::GENERAL_GREATER_EQUAL:
+  {
+    comp = static_cast<CompareConsts::CompareType>(static_cast<int>(comp) - 4);
+     
+    expr* tmp = arg0;
+    arg0 = arg1;
+    arg1 = tmp;
+     
+    break;
+  }
+  default:
+    break;
+  }
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+bool match_exact(expr* query, expr* view, expr::substitution_t& subst)
+{
+  if (query == view)
+    return true;
+
+  if (query->get_expr_kind() != view->get_expr_kind())
+  {
+    if (query->get_expr_kind() == var_expr_kind)
+    {
+      var_expr* qe = static_cast<var_expr*>(query);
+
+      if (qe->get_kind() != var_expr::let_var)
+        return false;
+
+      return match_exact(qe->get_domain_expr(), view, subst);
+    }
+    else if (view->get_expr_kind() == var_expr_kind)
+    {
+      var_expr* ve = static_cast<var_expr*>(view);
+
+      switch (ve->get_kind())
+      {
+      case var_expr::for_var:
+      {
+        expr::substitution_t::iterator ite = subst.find(view);
+
+        if (ite != subst.end())
+        {
+          return match_exact(query, ite->second, subst);
+        }
+        else
+        {
+          assert(false);
+          subst[view] = query;
+          return true;
+        }
+      }
+      case var_expr::let_var:
+      {
+        return match_exact(query, ve->get_domain_expr(), subst);
+      }
+      case var_expr::pos_var:
+      {
+        return false;
+      }
+      case var_expr::win_var:
+      case var_expr::wincond_out_var:
+      case var_expr::wincond_out_pos_var:
+      case var_expr::wincond_in_var:
+      case var_expr::wincond_in_pos_var:
+      case var_expr::groupby_var:
+      case var_expr::non_groupby_var:
+      case var_expr::count_var:
+      {
+        ZORBA_ASSERT(false); // TODO
+      }
+      case var_expr::score_var:
+      case var_expr::prolog_var:
+      case var_expr::local_var:
+      case var_expr::copy_var:
+      case var_expr::catch_var:
+      case var_expr::arg_var:
+      case var_expr::eval_var:
+      {
+        ZORBA_ASSERT(false);
+      }
+      default:
+      {
+        ZORBA_ASSERT(false);
+      }
+      }
+    }
+    else if (view->get_function_kind() == FunctionConsts::OP_UNHOIST_1)
+    {
+      fo_expr* vfo = static_cast<fo_expr*>(view);
+      return match_exact(query, vfo->get_arg(0), subst);
+    }
+    else if (query->get_function_kind() == FunctionConsts::OP_UNHOIST_1)
+    {
+      fo_expr* qfo = static_cast<fo_expr*>(query);
+      return match_exact(qfo->get_arg(0), view, subst);
+    }
+    else if (view->get_function_kind() == FunctionConsts::OP_HOIST_1)
+    {
+      fo_expr* vfo = static_cast<fo_expr*>(view);
+      return match_exact(query, vfo->get_arg(0), subst);
+    }
+    else if (query->get_function_kind() == FunctionConsts::OP_HOIST_1)
+    {
+      fo_expr* qfo = static_cast<fo_expr*>(query);
+      return match_exact(qfo->get_arg(0), view, subst);
+    }
+    else if (view->get_expr_kind() == wrapper_expr_kind)
+    {
+      wrapper_expr* vwe = static_cast<wrapper_expr*>(view);
+      return match_exact(query, vwe->get_input(), subst);
+    }
+    else if (query->get_expr_kind() == wrapper_expr_kind)
+    {
+      wrapper_expr* qwe = static_cast<wrapper_expr*>(query);
+      return match_exact(qwe->get_input(), view, subst);
+    }
+    else
+    {
+      return false;
+    }
+  }
+
+  switch (query->get_expr_kind())
+  {
+  case var_expr_kind:
+  {
+    var_expr* qe = static_cast<var_expr*>(query);
+    var_expr* ve = static_cast<var_expr*>(view);
+
+    var_expr::var_kind qkind = qe->get_kind();
+    var_expr::var_kind vkind = ve->get_kind();
+
+    if (qkind != vkind)
+    {
+      if (qkind == var_expr::let_var)
+      {
+        return match_exact(qe->get_domain_expr(), view, subst);
+      }
+
+      return false;
+    }
+
+    switch (qkind)
+    {
+    case var_expr::for_var:
+    case var_expr::pos_var:
+    {
+      expr::substitution_t::iterator ite = subst.find(view);
+
+      if (ite != subst.end())
+      {
+        return (qe == ite->second);
+      }
+      else
+      {
+        assert(false);
+        subst[view] = query;
+        return true;
+      }
+    }
+    case var_expr::let_var:
+    {
+      return match_exact(qe->get_domain_expr(), ve->get_domain_expr(), subst);
+    }
+    case var_expr::win_var:
+    case var_expr::wincond_out_var:
+    case var_expr::wincond_out_pos_var:
+    case var_expr::wincond_in_var:
+    case var_expr::wincond_in_pos_var:
+    case var_expr::groupby_var:
+    case var_expr::non_groupby_var:
+    case var_expr::count_var:
+    {
+      ZORBA_ASSERT(false); // TODO
+    }
+    case var_expr::score_var:
+    case var_expr::prolog_var:
+    case var_expr::local_var:
+    case var_expr::copy_var:
+    case var_expr::catch_var:
+    case var_expr::arg_var:
+    case var_expr::eval_var:
+    {
+      ZORBA_ASSERT(false);
+    }
+    default:
+    {
+      ZORBA_ASSERT(false);
+    }
+    }
+
+    break;
+  }
+
+  case fo_expr_kind:
+  {
+    fo_expr* qe = static_cast<fo_expr*>(query);
+    fo_expr* ve = static_cast<fo_expr*>(view);
+
+    if (qe->get_func() != ve->get_func())
+    {
+      function* vfunc = ve->get_func();
+      function* qfunc = qe->get_func();
+
+      if (qfunc->isComparisonFunction() && vfunc->isComparisonFunction())
+      {
+        CompareConsts::CompareType qcomp = qe->get_func()->comparisonKind();
+        CompareConsts::CompareType vcomp = ve->get_func()->comparisonKind();
+
+        expr* qarg0 = qe->get_arg(0);
+        expr* qarg1 = qe->get_arg(1);
+        expr* varg0 = ve->get_arg(0);
+        expr* varg1 = ve->get_arg(1);
+
+        normalize_comp(qcomp, qarg0, qarg1);
+        normalize_comp(vcomp, varg0, varg1);
+
+        if (qcomp == vcomp &&
+            match_exact(qarg0, varg0, subst) &&
+            match_exact(qarg1, varg1, subst))
+          return true;
+      }
+      else if (vfunc->getKind() == FunctionConsts::OP_UNHOIST_1)
+      {
+        return match_exact(query, ve->get_arg(0), subst);
+      }
+      else if (qfunc->getKind() == FunctionConsts::OP_UNHOIST_1)
+      {
+        return match_exact(qe->get_arg(0), view, subst);
+      }
+      else if (vfunc->getKind() == FunctionConsts::OP_HOIST_1)
+      {
+        return match_exact(query, ve->get_arg(0), subst);
+      }
+      else if (qfunc->getKind() == FunctionConsts::OP_HOIST_1)
+      {
+        return match_exact(qe->get_arg(0), view, subst);
+      }
+
+      return false;
+    }
+
+    function* func = qe->get_func();
+
+    csize numArgs = qe->num_args();
+
+    if (numArgs != ve->num_args())
+      return false;
+
+    csize i = 0;
+    for (; i < numArgs; i++)
+    {
+      if (!match_exact(qe->get_arg(i), ve->get_arg(i), subst))
+        break;
+    }
+
+    if (i < numArgs)
+    {
+      if (func->getKind() == FunctionConsts::STATIC_COLLECTIONS_DML_COLLECTION_1)
+      {
+        const store::Item* collName1 = ve->get_arg(0)->getQName();
+        const store::Item* collName2 = qe->get_arg(0)->getQName();
+
+        if (collName1 != NULL && collName2 != NULL && collName1->equals(collName2))
+          return true;
+#if 0
+        if (collName != NULL && qe->get_arg(0)->get_var() != NULL)
+        {
+          const var_expr* var = qe->get_arg(0)->get_var();
+
+          if (var->get_kind() == var_expr::prolog_var &&
+              var->num_set_exprs() == 1 &&
+              var->get_set_expr(0)->get_expr_kind() == var_decl_expr_kind)
+          {
+            const var_decl_expr* decl = 
+            static_cast<const var_decl_expr*>(var->get_set_expr(0));
+
+            const store::Item* collName2 = decl->get_init_expr()->getQName();
+
+            if (collName2 != NULL && collName->equals(collName2))
+              return true;
+          }
+        }
+#endif
+      }
+      else if (func->isComparisonFunction())
+      {
+        CompareConsts::CompareType compKind = func->comparisonKind();
+
+        if (CompareConsts::VALUE_EQUAL <= compKind && 
+            compKind <= CompareConsts::NODE_NOT_EQUAL)
+        {
+          if (match_exact(qe->get_arg(0), ve->get_arg(1), subst) &&
+              match_exact(qe->get_arg(1), ve->get_arg(0), subst))
+            return true;
+        }
+      }
+
+      return false;
+    }
+
+    return true;
+  }
+
+  case relpath_expr_kind:
+  {
+    relpath_expr* qe = static_cast<relpath_expr*>(query);
+    relpath_expr* ve = static_cast<relpath_expr*>(view);
+
+    csize vnumSteps = ve->size();
+    csize qnumSteps = qe->size();
+    csize numSteps = (vnumSteps < qnumSteps ? vnumSteps : qnumSteps);
+
+    for (csize i = numSteps-1; i > 0; --i)
+    {
+      axis_step_expr* qstep = static_cast<axis_step_expr*>((*qe)[i]);
+      axis_step_expr* vstep = static_cast<axis_step_expr*>((*ve)[i]);
+
+      if (qstep->getAxis() != vstep->getAxis())
+        return false;
+
+      match_expr* qtest = qstep->getTest();
+      match_expr* vtest = vstep->getTest();
+
+      if (!qtest->matches(vtest))
+        return false;
+    }
+
+    // <vsource>/b/c  vs  <qsource>/a/b/c
+    if (vnumSteps < qnumSteps)
+    {
+      expr* vsource = (*ve)[0];
+
+      if (vsource->get_expr_kind() != var_expr_kind)
+        return false;
+
+      relpath_expr* qpath = query->get_ccb()->getExprManager()->
+      create_relpath_expr(qe->get_sctx(), qe->get_udf(), qe->get_loc());
+
+      for (csize i = 0; i < qnumSteps - vnumSteps; ++i)
+        qpath->add_back((*qe)[i]);
+
+      return match_exact(qpath, vsource, subst);
+    }
+    // <vsource>/a/b/c  vs  <qsource>/b/c
+    else if (qnumSteps < vnumSteps)
+    {
+      expr* qsource = (*qe)[0];
+
+      if (qsource->get_expr_kind() != var_expr_kind)
+        return false;
+
+      relpath_expr* vpath = query->get_ccb()->getExprManager()->
+      create_relpath_expr(ve->get_sctx(), ve->get_udf(), ve->get_loc());
+
+      for (csize i = 0; i < vnumSteps - qnumSteps; ++i)
+        vpath->add_back((*ve)[i]);
+
+      return match_exact(qsource, vpath, subst);
+    }
+    else
+    {
+      return match_exact((*qe)[0], (*ve)[0], subst);
+    }
+  }
+
+  case cast_expr_kind:
+  case castable_expr_kind:
+  case instanceof_expr_kind:
+  {
+    cast_or_castable_base_expr* qe = static_cast<cast_or_castable_base_expr*>(query);
+    cast_or_castable_base_expr* ve = static_cast<cast_or_castable_base_expr*>(view);
+
+    TypeManager* tm = qe->get_type_manager();
+
+    if (!TypeOps::is_equal(tm, *qe->get_target_type(), *ve->get_target_type()))
+      return false;
+
+    return match_exact(qe->get_input(), ve->get_input(), subst);
+  }
+
+  case promote_expr_kind:
+  {
+    promote_expr* qe = static_cast<promote_expr*>(query);
+    promote_expr* ve = static_cast<promote_expr*>(view);
+
+    TypeManager* tm = qe->get_type_manager();
+
+    if (!TypeOps::is_subtype(tm, *qe->get_return_type(), *ve->get_target_type()))
+      return false;
+
+    return match_exact(qe->get_input(), ve->get_input(), subst);
+  }
+
+  case treat_expr_kind:
+  {
+    treat_expr* qe = static_cast<treat_expr*>(query);
+    treat_expr* ve = static_cast<treat_expr*>(view);
+
+    TypeManager* tm = qe->get_type_manager();
+
+    if (qe->get_check_prime() != ve->get_check_prime())
+      return false;
+
+    if (!qe->get_check_prime())
+    {
+      if (qe->get_target_type()->get_quantifier() !=
+          ve->get_target_type()->get_quantifier())
+        return false;
+    }
+    else if (!TypeOps::is_equal(tm, *qe->get_target_type(), *ve->get_target_type()))
+    {
+      return false;
+    }
+
+    return match_exact(qe->get_input(), ve->get_input(), subst);
+  }
+
+  case wrapper_expr_kind:
+  {
+    wrapper_expr* qe = static_cast<wrapper_expr*>(query);
+    wrapper_expr* ve = static_cast<wrapper_expr*>(view);
+
+    return match_exact(qe->get_input(), ve->get_input(), subst);
+  }
+
+  case const_expr_kind:
+  {
+    const_expr* qe = static_cast<const_expr*>(query);
+    const_expr* ve = static_cast<const_expr*>(view);
+
+    try
+    {
+      // TODO: collation, timezone ???? Implement the full eq spec ????
+      return qe->get_val()->equals(ve->get_val());
+    }
+    catch (ZorbaException&)
+    {
+      return false;
+    }
+    break;
+  }
+
+  case delete_expr_kind:
+  case insert_expr_kind:
+  case rename_expr_kind:
+  case replace_expr_kind:
+  case transform_expr_kind:
+  default:
+  {
+    ZORBA_ASSERT(false);
+  }
+  }
+
+  return false;
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
 bool count_var_uses_rec(
     expr* e,
     var_expr* var,
@@ -241,10 +719,10 @@
 
 /*******************************************************************************
   Let FLWOR(e) be the set of flwor exprs within the expr tree rooted at expr e.
-  Let FV(e) be the set of variables defined in any of the flwor exprs in FLWOR(e).
-  This method assigns a prefix id to each variable in FV(e) and stores the mapping
-  between var_expr and prefix id in "varmap". It also returns the number of vars
-  in FV(e).
+  Let FV(e) be the set of variables defined in any of the flwor exprs in 
+  FLWOR(e). This method assigns a prefix id to each variable in FV(e) and
+  stores the mapping between var_expr and prefix id in "varidmap" and the
+  reverse mapping in "idvapmap". It also returns the number of vars in FV(e).
 
   Given 2 vars v1 and v2 in FV(e), their prefix ids allows to check if v1 is
   defined before v2: v1 is defined before v2 iff id(v1) < id(v2).
@@ -302,9 +780,9 @@
         if (stopCond != NULL)
           add_wincond_vars(stopCond, numVars, varidmap, idvarmap);
       }
-      else if (c->get_kind() == flwor_clause::group_clause)
+      else if (c->get_kind() == flwor_clause::groupby_clause)
       {
-        const group_clause* gc = static_cast<const group_clause *>(c);
+        const groupby_clause* gc = static_cast<const groupby_clause *>(c);
 
         const flwor_clause::rebind_list_t& gvars = gc->get_grouping_vars();
         csize numGroupVars = gvars.size();
@@ -513,9 +991,9 @@
         if (stopCond != NULL)
           remove_wincond_vars(stopCond, varmap, freeset);
       }
-      else if (c->get_kind() == flwor_clause::group_clause)
+      else if (c->get_kind() == flwor_clause::groupby_clause)
       {
-        const group_clause* gc = static_cast<const group_clause *>(c);
+        const groupby_clause* gc = static_cast<const groupby_clause *>(c);
 
         const flwor_clause::rebind_list_t& gvars = gc->get_grouping_vars();
         csize numGroupVars = gvars.size();
@@ -891,9 +1369,9 @@
         computeMustCopyProperty(cc->get_expr());
         break;
       }
-      case flwor_clause::group_clause:
+      case flwor_clause::groupby_clause:
       {
-        group_clause* gc = static_cast<group_clause*>(clause);
+        groupby_clause* gc = static_cast<groupby_clause*>(clause);
 
         flwor_clause::rebind_list_t::iterator ite = gc->beginGroupVars();
         flwor_clause::rebind_list_t::iterator end = gc->endGroupVars();

=== modified file 'src/compiler/rewriter/tools/expr_tools.h'
--- src/compiler/rewriter/tools/expr_tools.h	2012-10-29 11:41:36 +0000
+++ src/compiler/rewriter/tools/expr_tools.h	2012-12-21 04:09:22 +0000
@@ -46,6 +46,9 @@
 namespace expr_tools
 {
 
+bool match_exact(expr* query, expr* ast, expr::substitution_t& subst);
+
+
 int count_variable_uses(
     expr* root,
     var_expr* var,

=== modified file 'src/compiler/translator/translator.cpp'
--- src/compiler/translator/translator.cpp	2012-12-12 08:11:40 +0000
+++ src/compiler/translator/translator.cpp	2012-12-21 04:09:22 +0000
@@ -1368,20 +1368,20 @@
   csize n = foExpr->num_args();
 
   const function* func = foExpr->get_func();
+  FunctionConsts::FunctionKind fkind = func->getKind();
 
-  if (func->getKind() == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_N ||
-      func->getKind() == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_SKIP_N)
+  if (fkind == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_N ||
+      fkind == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_SKIP_N)
   {
     csize nStarterParams =
-      (func->getKind() == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_N 
-       ? 1 : 2);
+    (fkind == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_N  ? 1 : 2);
 
     if  (n < (6 + nStarterParams) || (n - nStarterParams) % 6 != 0)
     {
       const store::Item* qname = NULL;
 
       if (n > 0)
-        qname = foExpr->get_arg(0)->getQName(theSctx);
+        qname = foExpr->get_arg(0)->getQName();
 
       zstring lMsgPart;
       ztd::to_string(nStarterParams, &lMsgPart);
@@ -1405,21 +1405,21 @@
 
     xqtref_t paramType;
 
-    if (func->getKind() == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_POINT_VALUE_N)
+    if (fkind == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_POINT_VALUE_N)
     {
       if (i == 0)
         paramType = sign[i];
       else
         paramType = theRTM.ANY_ATOMIC_TYPE_QUESTION;
     }
-    else if (func->getKind() == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_POINT_VALUE_SKIP_N)
+    else if (fkind == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_POINT_VALUE_SKIP_N)
     {
       if (i <= 1)
         paramType = sign[i];
       else
         paramType = theRTM.ANY_ATOMIC_TYPE_QUESTION;
     }
-    else if (func->getKind() == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_N)
+    else if (fkind == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_N)
     {
       if (i == 0)
         paramType = sign[i];
@@ -1428,7 +1428,7 @@
       else
         paramType = theRTM.BOOLEAN_TYPE_ONE;
     }
-    else if (func->getKind() == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_SKIP_N)
+    else if (fkind == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_SKIP_N)
     {
       if (i <= 1)
         paramType = sign[i];
@@ -1437,10 +1437,10 @@
       else
         paramType = theRTM.BOOLEAN_TYPE_ONE;
     }
-    else if (func->getKind() == FunctionConsts::FN_ZORBA_INVOKE_N ||
-             func->getKind() == FunctionConsts::FN_ZORBA_INVOKE_N_N ||
-             func->getKind() == FunctionConsts::FN_ZORBA_INVOKE_U_N ||
-             func->getKind() == FunctionConsts::FN_ZORBA_INVOKE_S_N)
+    else if (fkind == FunctionConsts::FN_ZORBA_INVOKE_N ||
+             fkind == FunctionConsts::FN_ZORBA_INVOKE_N_N ||
+             fkind == FunctionConsts::FN_ZORBA_INVOKE_U_N ||
+             fkind == FunctionConsts::FN_ZORBA_INVOKE_S_N)
     {
       if (i == 0)
         paramType = sign[i];
@@ -1456,10 +1456,7 @@
     // or match should be added. This is used by the reflection:invoke() function,
     if (paramType != NULL)
     {
-      if (TypeOps::is_subtype(tm,
-                              *paramType,
-                              *theRTM.ANY_ATOMIC_TYPE_STAR,
-                              loc))
+      if (TypeOps::is_subtype(tm, *paramType, *theRTM.ANY_ATOMIC_TYPE_STAR, loc))
       {
         argExpr = wrap_in_type_promotion(argExpr,
                                          paramType,
@@ -1486,11 +1483,11 @@
 ********************************************************************************/
 expr* wrap_in_atomization(expr* e)
 {
-  return theExprManager->create_fo_expr(theRootSctx,
-                                        theUDF,
-                                        e->get_loc(),
-                                        BUILTIN_FUNC(FN_DATA_1),
-                                        e);
+  return CREATE(fo)(theRootSctx,
+                    theUDF,
+                    e->get_loc(),
+                    BUILTIN_FUNC(FN_DATA_1),
+                    e);
 }
 
 
@@ -1505,13 +1502,13 @@
 {
   e = wrap_in_atomization(e);
 
-  return theExprManager->create_promote_expr(theRootSctx,
-                                             theUDF,
-                                             e->get_loc(),
-                                             e,
-                                             type,
-                                             errorKind,
-                                             qname);
+  return CREATE(promote)(theRootSctx,
+                         theUDF,
+                         e->get_loc(),
+                         e,
+                         type,
+                         errorKind,
+                         qname);
 }
 
 
@@ -4315,8 +4312,8 @@
   TypeConstants::quantifier_t quant;
   if (v.getType() == 0)
   {
-    lNodeType = theRTM.DOCUMENT_UNTYPED_TYPE_ONE;
-    lCollectionType = theRTM.DOCUMENT_UNTYPED_TYPE_STAR;
+    lNodeType = theRTM.ANY_NODE_UNTYPED_TYPE_ONE;
+    lCollectionType = theRTM.ANY_NODE_UNTYPED_TYPE_STAR;
     quant = TypeConstants::QUANT_STAR;
   }
   else
@@ -4525,7 +4522,7 @@
   IndexDecl_t index = theIndexDecl;
   theIndexDecl = NULL;
 
-  index->analyze(theCCB);
+  index->analyze();
 
   // Register the index in the sctx of the current module. Raise error if such
   // a binding exists already in the sctx.
@@ -4643,6 +4640,7 @@
   return no_state;
 }
 
+
 void end_visit(const IndexKeyList& v, void* /*visit_state*/)
 {
   TRACE_VISIT_OUT();
@@ -4672,8 +4670,6 @@
       ERROR_PARAMS(index->getName()->getStringValue()));
     }
 
-    keyExpr = wrap_in_atomization(keyExpr);
-
     xqtref_t type;
     xqtref_t ptype;
 
@@ -4685,6 +4681,8 @@
         ERROR_PARAMS(index->getName()->getStringValue(),
                      ZED(ZDST0027_NO_KEY_TYPE_DECL)));
       }
+
+      keyExpr = wrap_in_atomization(keyExpr);
     }
     else
     {
@@ -4735,11 +4733,26 @@
                      ptype->toSchemaString()));
       }
 
-      keyExpr = wrap_in_type_match(keyExpr,
-                                   type,
-                                   loc,
-                                   TREAT_INDEX_KEY,
-                                   index->getName());
+      if (!index->isGeneral() &&
+          (TypeOps::is_subtype(tm, *ptype, *theRTM.STRING_TYPE_ONE, kloc) ||
+           TypeOps::is_subtype(tm, *ptype, *theRTM.DOUBLE_TYPE_ONE, kloc) ||
+           TypeOps::is_subtype(tm, *ptype, *theRTM.FLOAT_TYPE_ONE, kloc)))
+      {
+        keyExpr = wrap_in_type_promotion(keyExpr,
+                                         type,
+                                         PROMOTE_INDEX_KEY,
+                                         index->getName());
+      }
+      else
+      {
+        keyExpr = wrap_in_atomization(keyExpr);
+
+        keyExpr = wrap_in_type_match(keyExpr,
+                                     type,
+                                     loc,
+                                     TREAT_INDEX_KEY,
+                                     index->getName());
+      }
 
       keyTypes[i] = ptype->getBaseBuiltinType();
     }
@@ -4748,12 +4761,11 @@
     {
       // Eliminate duplicate key values, as they don't play any role in a
       // general comparison predicate.
-      keyExpr = theExprManager->
-      create_fo_expr(theRootSctx,
-                     theUDF,
-                     keyExpr->get_loc(),
-                     BUILTIN_FUNC(FN_DISTINCT_VALUES_1),
-                     keyExpr);
+      keyExpr = CREATE(fo)(theRootSctx,
+                           theUDF,
+                           keyExpr->get_loc(),
+                           BUILTIN_FUNC(FN_DISTINCT_VALUES_1),
+                           keyExpr);
     }
 
     std::string collationUri;
@@ -4763,8 +4775,7 @@
       collationUri = collationSpec->get_uri().str();
 
       if (! theSctx->is_known_collation(collationUri))
-        RAISE_ERROR(err::XQST0076, kloc,
-        ERROR_PARAMS(collationUri));
+        RAISE_ERROR(err::XQST0076, kloc, ERROR_PARAMS(collationUri));
     }
     else if (ptype != NULL &&
              TypeOps::is_subtype(tm, *ptype, *theRTM.STRING_TYPE_ONE, loc))
@@ -6274,9 +6285,9 @@
       pop_scope();
       break;
     }
-    case flwor_clause::group_clause:
+    case flwor_clause::groupby_clause:
     {
-      group_clause* gc = static_cast<group_clause*>(curClause);
+      groupby_clause* gc = static_cast<groupby_clause*>(curClause);
 
       csize numGVars = gc->numGroupingVars();
 
@@ -6904,8 +6915,8 @@
   csize numGroupSpecs = groupSpecs.size();
 
   std::vector<std::string> collations;
-  group_clause::rebind_list_t grouping_rebind;
-  group_clause::rebind_list_t nongrouping_rebind;
+  groupby_clause::rebind_list_t grouping_rebind;
+  groupby_clause::rebind_list_t nongrouping_rebind;
 
   static_context* sctx = theSctx;
 
@@ -7013,12 +7024,12 @@
     nongrouping_rebind.push_back(std::pair<expr*, var_expr*>(inputExpr, ngVar));
   }
 
-  group_clause* clause = theExprManager->
-  create_group_clause(theRootSctx,
-                      loc,
-                      grouping_rebind,
-                      nongrouping_rebind,
-                      collations);
+  groupby_clause* clause = theExprManager->
+  create_groupby_clause(theRootSctx,
+                        loc,
+                        grouping_rebind,
+                        nongrouping_rebind,
+                        collations);
 
   theFlworClausesStack.push_back(clause);
 }
@@ -9696,7 +9707,7 @@
         matchExpr->setWildKind(match_all_wild);
         break;
       }
-      case ParseConstants::wild_elem:
+      case ParseConstants::wild_elem: // pre:*
       {
         matchExpr->setWildKind(match_name_wild);
         matchExpr->setWildName(wildcard->getNsOrPrefix());
@@ -9717,16 +9728,16 @@
         }
 
         theSctx->expand_qname(qnItem,
-            ns,
-            prefix,
-            localname,
-            wildcard->get_location());
+                              ns,
+                              prefix,
+                              localname,
+                              wildcard->get_location());
 
         matchExpr->setQName(qnItem);
 
         break;
       }
-      case ParseConstants::wild_prefix:
+      case ParseConstants::wild_prefix: // *:name
       {
         matchExpr->setWildKind(match_prefix_wild);
         matchExpr->setWildName(wildcard->getLocalName());
@@ -10903,7 +10914,7 @@
     // Create and normalize the fo expr
     std::reverse(arguments.begin(), arguments.end());
 
-    fo_expr* foExpr = theExprManager->create_fo_expr(theRootSctx, theUDF, loc, f, arguments);
+    fo_expr* foExpr = CREATE(fo)(theRootSctx, theUDF, loc, f, arguments);
 
     normalize_fo(foExpr);
 
@@ -10921,36 +10932,59 @@
     }
 
     // Some further normalization is required for certain builtin functions
-    FunctionConsts::FunctionKind lKind = f->getKind();
-    switch (lKind)
+    FunctionConsts::FunctionKind fkind = f->getKind();
+    switch (fkind)
     {
       case FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_POINT_GENERAL_N:
       case FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_GENERAL_N:
       {
         FunctionConsts::FunctionKind fkind = FunctionConsts::OP_SORT_DISTINCT_NODES_ASC_1;
 
-        resultExpr = theExprManager->create_fo_expr(theRootSctx, theUDF,
-                                 foExpr->get_loc(),
-                                 BuiltinFunctionLibrary::getFunction(fkind),
-                                 foExpr);
+        resultExpr = CREATE(fo)(theRootSctx,
+                                theUDF,
+                                foExpr->get_loc(),
+                                BuiltinFunctionLibrary::getFunction(fkind),
+                                foExpr);
 
         break;
       }
       case FunctionConsts::FN_ANALYZE_STRING_2:
       case FunctionConsts::FN_ANALYZE_STRING_3:
       {
-        resultExpr = wrap_in_validate_expr_strict(
-          foExpr,
-          "http://www.w3.org/2005/xpath-functions";);
+        resultExpr = 
+        wrap_in_validate_expr_strict(foExpr, "http://www.w3.org/2005/xpath-functions";);
 
         break;
       }
       case FunctionConsts::FN_SERIALIZE_2:
       {
-        import_schema_auto_prefix(
-          loc,
-          "http://www.w3.org/2010/xslt-xquery-serialization";,
-          NULL);
+        import_schema_auto_prefix(loc,
+                                  "http://www.w3.org/2010/xslt-xquery-serialization";,
+                                  NULL);
+        
+        break;
+      }
+      case FunctionConsts::FN_ZORBA_MATCH_2:
+      {
+        expr_match_expr* matchExpr = CREATE(expr_match)(theRootSctx,
+                                                        theUDF,
+                                                        loc,
+                                                        foExpr->get_arg(0),
+                                                        foExpr->get_arg(1),
+                                                        SIMPLE_EXPR,
+                                                        theNSCtx);
+
+        resultExpr = matchExpr;
+
+        std::vector<VarInfo*> inscopeVars;
+        theSctx->getVariables(inscopeVars);
+
+        csize numVars = inscopeVars.size();
+
+        for (csize i = 0; i < numVars; ++i)
+        {
+          matchExpr->add_var(inscopeVars[i]->getVar());
+        }
 
         break;
       }
@@ -10961,12 +10995,12 @@
       {
         expr_script_kind_t scriptingKind;
 
-        if (lKind == FunctionConsts::FN_ZORBA_EVAL_1 ||
-            lKind == FunctionConsts::FN_ZORBA_EVAL_N_1)
+        if (fkind == FunctionConsts::FN_ZORBA_EVAL_1 ||
+            fkind == FunctionConsts::FN_ZORBA_EVAL_N_1)
         {
           scriptingKind = SIMPLE_EXPR;
         }
-        else if (lKind == FunctionConsts::FN_ZORBA_EVAL_U_1)
+        else if (fkind == FunctionConsts::FN_ZORBA_EVAL_U_1)
         {
           scriptingKind = UPDATING_EXPR;
         }
@@ -10975,13 +11009,12 @@
           scriptingKind = SEQUENTIAL_FUNC_EXPR;
         }
 
-        eval_expr* evalExpr = theExprManager->
-        create_eval_expr(theRootSctx,
-                         theUDF,
-                         loc,
-                         foExpr->get_arg(0),
-                         scriptingKind,
-                         theNSCtx);
+        eval_expr* evalExpr = CREATE(eval)(theRootSctx,
+                                           theUDF,
+                                           loc,
+                                           foExpr->get_arg(0),
+                                           scriptingKind,
+                                           theNSCtx);
 
         resultExpr = evalExpr;
 
@@ -11023,16 +11056,16 @@
         zstring query_params;
         std::vector<var_expr*> temp_vars;
 
-        if (lKind == FunctionConsts::FN_ZORBA_INVOKE_N ||
-            lKind == FunctionConsts::FN_ZORBA_INVOKE_N_N)
+        if (fkind == FunctionConsts::FN_ZORBA_INVOKE_N ||
+            fkind == FunctionConsts::FN_ZORBA_INVOKE_N_N)
         {
           scriptingKind = SIMPLE_EXPR;
         }
-        else if (lKind == FunctionConsts::FN_ZORBA_INVOKE_U_N)
+        else if (fkind == FunctionConsts::FN_ZORBA_INVOKE_U_N)
         {
           scriptingKind = UPDATING_EXPR;
         }
-        else if (lKind == FunctionConsts::FN_ZORBA_INVOKE_S_N)
+        else if (fkind == FunctionConsts::FN_ZORBA_INVOKE_S_N)
         {
           scriptingKind = SEQUENTIAL_FUNC_EXPR;
         }
@@ -11044,8 +11077,7 @@
         }
 
         // create a flwor with LETs to hold the parameters
-        flwor_expr* flworExpr = theExprManager->
-        create_flwor_expr(theRootSctx, theUDF, loc, false);
+        flwor_expr* flworExpr = CREATE(flwor)(theRootSctx, theUDF, loc, false);
 
         // wrap function's QName
         expr* qnameExpr = wrap_in_type_promotion(arguments[0],
@@ -12934,8 +12966,8 @@
   TRACE_VISIT_OUT();
 
   // if the top of the stack is an axis step expr, add a node test expr to it.
-  axis_step_expr* axisExpr =
-    dynamic_cast<axis_step_expr*>(peek_nodestk_or_null());
+  axis_step_expr* axisExpr = dynamic_cast<axis_step_expr*>(peek_nodestk_or_null());
+
   if (axisExpr != NULL)
   {
     match_expr* me = theExprManager->create_match_expr(theRootSctx, theUDF, loc);
@@ -13039,8 +13071,7 @@
     expand_elem_qname(typeNameItem, typeName->get_name(), loc);
 
   // if the top of the stack is an axis step expr, add a node test expr to it.
-  axis_step_expr* axisExpr =
-    dynamic_cast<axis_step_expr*> (peek_nodestk_or_null ());
+  axis_step_expr* axisExpr = dynamic_cast<axis_step_expr*> (peek_nodestk_or_null ());
 
   xqtref_t contentType;
 
@@ -13083,19 +13114,16 @@
 
 
 /*******************************************************************************
-
   SchemaElementTest ::= "schema-element" "(" ElementDeclaration ")"
 
   ElementDeclaration ::= ElementName
-
 ********************************************************************************/
 void* begin_visit(const SchemaElementTest& v)
 {
   TRACE_VISIT();
 
 #ifndef ZORBA_NO_XMLSCHEMA
-  axis_step_expr* axisExpr =
-    dynamic_cast<axis_step_expr*> (peek_nodestk_or_null ());
+  axis_step_expr* axisExpr = dynamic_cast<axis_step_expr*> (peek_nodestk_or_null ());
   rchandle<QName> elemName = v.get_elem();
   ZORBA_ASSERT(elemName != NULL);
 
@@ -13122,8 +13150,7 @@
     theTypeStack.push(seqmatch);
   }
 #else /* ZORBA_NO_XMLSCHEMA */
-  RAISE_ERROR(zerr::ZXQP0005_NOT_ENABLED, loc,
-  ERROR_PARAMS(ZED(XMLSchema)));
+  RAISE_ERROR(zerr::ZXQP0005_NOT_ENABLED, loc, ERROR_PARAMS(ZED(XMLSchema)));
 #endif /* ZORBA_NO_XMLSCHEMA */
   return no_state;
 }
@@ -13135,6 +13162,11 @@
 }
 
 
+/*******************************************************************************
+  AttributeTest ::= "attribute" "(" (AttribNameOrWildcard ("," TypeName)?)? ")"
+
+  AttribNameOrWildcard ::= AttributeName | "*"
+********************************************************************************/
 void* begin_visit(const AttributeTest& v)
 {
   TRACE_VISIT();
@@ -13168,17 +13200,14 @@
 
     if (contentType == NULL)
     {
-      throw XQUERY_EXCEPTION(
-        err::XPST0008,
-        ERROR_PARAMS( typeNameItem->getStringValue(), ZED( AttributeName ) ),
-        ERROR_LOC( loc )
-      );
+      RAISE_ERROR(err::XPST0008, loc,
+      ERROR_PARAMS(typeNameItem->getStringValue(), ZED(AttributeName)));
     }
   }
 
   // if the top of the stack is an axis step expr, add a node test expr to it.
-  axis_step_expr* axisExpr =
-    dynamic_cast<axis_step_expr*> (peek_nodestk_or_null());
+  axis_step_expr* axisExpr = dynamic_cast<axis_step_expr*> (peek_nodestk_or_null());
+
   if (axisExpr != NULL)
   {
     match_expr* match = theExprManager->create_match_expr(theRootSctx, theUDF, loc);
@@ -13206,13 +13235,18 @@
 }
 
 
+/*******************************************************************************
+  SchemaAttributeTest ::= "schema-attribute" "(" AttributeDeclaration ")"
+
+  SchemaDeclaration ::= AttributeName
+********************************************************************************/
 void* begin_visit(const SchemaAttributeTest& v)
 {
   TRACE_VISIT();
 
 #ifndef ZORBA_NO_XMLSCHEMA
-  axis_step_expr* axisExpr =
-    dynamic_cast<axis_step_expr*> (peek_nodestk_or_null ());
+  axis_step_expr* axisExpr = dynamic_cast<axis_step_expr*>(peek_nodestk_or_null());
+
   rchandle<QName> attrName = v.get_attr();
   ZORBA_ASSERT(attrName != NULL);
 
@@ -13233,19 +13267,14 @@
   }
   else
   {
-    xqtref_t seqmatch = CTX_TM->create_schema_attribute_type(attrQNameItem,
-                                                             TypeConstants::QUANT_ONE,
-                                                             loc);
+    xqtref_t seqmatch = CTX_TM->
+    create_schema_attribute_type(attrQNameItem, TypeConstants::QUANT_ONE, loc);
 
     theTypeStack.push(seqmatch);
   }
 
 #else /* ZORBA_NO_XMLSCHEMA */
-  throw XQUERY_EXCEPTION(
-    zerr::ZXQP0005_NOT_ENABLED,
-    ERROR_PARAMS( ZED( XMLSchema ) ),
-    ERROR_LOC( loc )
-  );
+  RAISE_ERROR(zerr::ZXQP0005_NOT_ENABLED, loc, ERROR_PARAMS(ZED(XMLSchema)));
 #endif /* ZORBA_NO_XMLSCHEMA */
   return no_state;
 }
@@ -13322,8 +13351,8 @@
 {
   TRACE_VISIT_OUT();
 
-  axis_step_expr* axisExpr =
-    dynamic_cast<axis_step_expr*> (peek_nodestk_or_null ());
+  axis_step_expr* axisExpr = dynamic_cast<axis_step_expr*>(peek_nodestk_or_null());
+
   std::string target = v.get_target().str();
 
   store::Item_t qname = NULL;
@@ -13336,16 +13365,12 @@
     // is not in the lexical space of NCName, a type error is raised [err:XPTY0004]
 
     zstring lNormalizedTarget;
-    ascii::normalize_whitespace( target, &lNormalizedTarget );
+    ascii::normalize_whitespace(target, &lNormalizedTarget);
 
-    if (!GenericCast::instance()->castableToNCName(lNormalizedTarget))
+    if (!GenericCast::castableToNCName(lNormalizedTarget))
     {
-      throw XQUERY_EXCEPTION(err::XPTY0004,
-        ERROR_PARAMS(ZED(BadType_23o), lNormalizedTarget,
-          ZED( NoCastTo_45o ), "NCName"
-        ),
-        ERROR_LOC( loc )
-      );
+      RAISE_ERROR(err::XPTY0004, loc,
+      ERROR_PARAMS(ZED(BadType_23o), lNormalizedTarget, ZED(NoCastTo_45o), "NCName"));
     }
 
     // bugfix (see above); pass normalized string instead of original target
@@ -13358,6 +13383,7 @@
     match->setTestKind(match_pi_test);
     if (target != "")
       match->setQName(qname);
+
     axisExpr->setTest(match);
   }
   else
@@ -13374,7 +13400,7 @@
                                                     TypeConstants::QUANT_ONE,
                                                     false,
                                                     false);
-      theTypeStack.push (t);
+      theTypeStack.push(t);
     }
   }
 }

=== modified file 'src/compiler/xqddf/value_index.cpp'
--- src/compiler/xqddf/value_index.cpp	2012-10-24 11:32:56 +0000
+++ src/compiler/xqddf/value_index.cpp	2012-12-21 04:09:22 +0000
@@ -273,7 +273,7 @@
   XQDDF spec. This method is called from the translator, after the domain and
   key exprs have been translated and optimized.
 *******************************************************************************/
-void IndexDecl::analyze(CompilerCB* ccb)
+void IndexDecl::analyze()
 {
   store::Item_t dotQName;
   GENV_ITEMFACTORY->createQName(dotQName, "", "", static_context::DOT_VAR_NAME);
@@ -285,7 +285,7 @@
   if (var)
     dotVar = var->getVar();
 
-  expr::FreeVars varExprs;
+  std::vector<var_expr*> varExprs;
 
   // Check constraints on the domain expr
   analyzeExprInternal(getDomainExpr(),
@@ -341,12 +341,12 @@
   {
     // Have to do this here (rather than during runtime) so that we don't have to
     // serialize the index exprs.
-    (void)getDocIndexer(ccb, theLocation);
+    (void)getDocIndexer(theLocation);
   }
 
   // Have to do this here (rather than during runtime) so that we don't have to
   // serialize the index exprs.
-  (void)getBuildPlan(ccb, theLocation);
+  (void)getBuildPlan(theLocation);
 }
 
 
@@ -366,10 +366,12 @@
     expr* e,
     std::vector<store::Item*>& sourceNames,
     std::vector<expr*>& sourceExprs,
-    FreeVars& varExprs,
+    std::vector<var_expr*>& varExprs,
     expr* dotVar)
 {
-  if (e->get_expr_kind() == fo_expr_kind)
+  switch (e->get_expr_kind())
+  {
+  case fo_expr_kind:
   {
     fo_expr* foExpr = static_cast<fo_expr*>(e);
     const function* func = foExpr->get_func();
@@ -386,7 +388,7 @@
       {
         const expr* argExpr = foExpr->get_arg(0);
 
-        const store::Item* qname = argExpr->getQName(theSctx);
+        const store::Item* qname = argExpr->getQName();
 
         if (qname != NULL)
         {
@@ -405,21 +407,27 @@
         ERROR_PARAMS(theName->getStringValue()));
       }
     }
+
+    break;
   }
-  else if (e->get_expr_kind() == var_decl_expr_kind)
+  case var_decl_expr_kind:
   {
     var_expr* varExpr = static_cast<var_decl_expr*>(e)->get_var_expr();
 
     ZORBA_ASSERT(varExpr->get_kind() == var_expr::local_var);
 
-    varExprs.insert(varExpr);
+    varExprs.push_back(varExpr);
+
+    break;
   }
-  else if (e->get_expr_kind() == flwor_expr_kind ||
-           e->get_expr_kind() == gflwor_expr_kind)
+  case flwor_expr_kind:
+  case gflwor_expr_kind:
   {
     static_cast<const flwor_expr*>(e)->get_vars(varExprs);
+
+    break;
   }
-  else if (e->get_expr_kind() == var_expr_kind)
+  case var_expr_kind:
   {
     if (e == dotVar)
     {
@@ -427,12 +435,21 @@
       ERROR_PARAMS(theName->getStringValue()));
     }
 
+    var_expr* var = static_cast<var_expr*>(e);
+
     if (e != getDomainVariable() &&
-        varExprs.find(static_cast<var_expr*>(e)) == varExprs.end())
+        std::find(varExprs.begin(), varExprs.end(), var) == varExprs.end())
     {
       RAISE_ERROR(zerr::ZDST0031_INDEX_HAS_FREE_VARS,  e->get_loc(),
       ERROR_PARAMS(theName->getStringValue()));
     }
+
+    break;
+  }
+  default:
+  {
+    break;
+  }
   }
 
   ExprIterator iter(e);
@@ -445,6 +462,140 @@
 
 
 /******************************************************************************
+  Create the expression that represents the index as a view.
+ 
+  For now, this is done for value indexes only
+
+  for $newdot at $newpos in cloned_domain_expr
+  return value-index-entry-builder($$newdot, cloned_key1_expr, ..., cloned_keyN_expr)
+*******************************************************************************/
+flwor_expr* IndexDecl::getViewExpr()
+{
+  theDomainClause = NULL;
+
+  expr* domainExpr = getDomainExpr();
+  var_expr* dot = getDomainVariable();
+  var_expr* pos = getDomainPositionVariable();
+  static_context* sctx = domainExpr->get_sctx();
+  user_function* udf = domainExpr->get_udf();
+
+  assert(theIsTemp || udf == NULL);
+
+  const QueryLoc& domloc = domainExpr->get_loc();
+
+  // Clone the domain expr, the domain variable, and the domain pos variable.
+  // These 2 vars are referenced by the key exprs..
+  expr::substitution_t subst;
+  expr* newdom = domainExpr->clone(udf, subst);
+
+  var_expr* newdot = theCCB->theEM->
+  create_var_expr(sctx, udf, domloc, dot->get_kind(), dot->get_name());
+
+  var_expr* newpos = theCCB->theEM->
+  create_var_expr(sctx, udf, domloc, pos->get_kind(), pos->get_name());
+
+  //
+  // Create for clause (this has to be done here so that the cloned dot var gets
+  // associated with the cloned domain expr; this is needed before cloning the
+  // key expr) :
+  //
+  // for $newdot at $newpos in new_domain_expr
+  //
+  for_clause* fc = theCCB->theEM->
+  create_for_clause(sctx, domloc, newdot, newdom, newpos);
+
+  //
+  // Create flwor expr:
+  //
+  // for $newdot at $newpos in new_domain_expr
+  // return $newdot
+  //
+
+  expr* returnExpr = theCCB->theEM->create_wrapper_expr(sctx, udf, domloc, newdot);
+
+  flwor_expr* flworExpr = theCCB->theEM->create_flwor_expr(sctx, udf, domloc, false);
+  flworExpr->set_return_expr(returnExpr);
+  flworExpr->add_clause(fc);
+
+  //
+  // Handle the key exprs
+  //
+  // for $newdot at $newpos in new_domain_expr
+  // let $key_1 := new_key_expr_1
+  // .....
+  // let $key_N := new_key_expr_N
+  // where $key_1 eq $arg_1 and ... and $key_N eq $arg_N
+  // return $newdot
+  //
+  //function* compFunc = BUILTIN_FUNC(OP_EQUAL_2);
+  //std::vector<expr*> predExprs;
+  csize numKeys = theKeyExprs.size();
+
+  for (csize i = 0; i < numKeys; ++i)
+  {
+    // clone the key expr
+    subst.clear();
+    subst[dot] = newdot;
+    subst[pos] = newpos;
+
+    expr* keyClone = theKeyExprs[i]->clone(udf, subst);
+
+    const QueryLoc& keyloc = keyClone->get_loc();
+
+    // create the LET clause
+    std::string localName = "$$key_" + ztd::to_string(i);
+    store::Item_t keyVarName;
+    GENV_ITEMFACTORY->createQName(keyVarName, "", "", localName);
+
+    var_expr* keyVar = theCCB->theEM->
+    create_var_expr(sctx, udf, keyloc, var_expr::let_var, keyVarName);
+
+    let_clause* lc = theCCB->theEM->create_let_clause(sctx, keyloc, keyVar, keyClone);
+
+    flworExpr->add_clause(lc);
+
+#if 0
+    // create the predicate
+    expr* op1 = theCCB->theEM->create_wrapper_expr(sctx, udf, keyloc, keyVar);
+
+    localName = "$$arg_" + ztd::to_string(i);
+    store::Item_t argVarName;
+    GENV_ITEMFACTORY->createQName(argVarName, "", "", localName);
+
+    expr* op2 = theCCB->theEM->
+    create_var_expr(sctx, udf, keyloc, var_expr::arg_var, keyVarName);
+
+    expr* pred = theCCB->theEM->
+    create_fo_expr(sctx, udf, keyloc, compFunc, op1, op2);
+
+    predExprs.push_back(pred);
+#endif
+  }
+
+#if 0
+  expr* whereExpr;
+
+  if (predExprs.size() > 1)
+  {
+    whereExpr = theCCB->theEM->
+    create_fo_expr(sctx, udf, domloc, BUILTIN_FUNC(OP_AND_N), predExprs);
+  }
+  else
+  {
+    whereExpr = predExprs[0];
+  }
+
+  where_clause* wc = theCCB->theEM->
+  create_where_clause(sctx, whereExpr->get_loc(), whereExpr);
+
+  flworExpr->add_clause(wc);
+#endif
+
+  return flworExpr;
+}
+
+
+/******************************************************************************
   Create the expression that "builds" the index, if not done already. The expr
   to build is the following, for value and general indexes, respectively:
 
@@ -458,7 +609,7 @@
   then populates the index by creating entries out of the items returned by
   this expr.
 *******************************************************************************/
-expr* IndexDecl::getBuildExpr(CompilerCB* ccb, const QueryLoc& loc)
+expr* IndexDecl::getBuildExpr(const QueryLoc& loc)
 {
   if (theBuildExpr != NULL)
     return theBuildExpr;
@@ -545,11 +696,11 @@
 
   theBuildExpr = flworExpr;
 
-  if (ccb->theConfig.optimize_cb != NULL)
+  if (theCCB->theConfig.optimize_cb != NULL)
   {
     std::string msg = "build expr for index " + theName->getStringValue().str();
 
-    ccb->theConfig.optimize_cb(theBuildExpr, msg);
+    theCCB->theConfig.optimize_cb(theBuildExpr, msg);
   }
 
   return theBuildExpr;
@@ -559,15 +710,15 @@
 /*******************************************************************************
 
 ********************************************************************************/
-PlanIterator* IndexDecl::getBuildPlan(CompilerCB* ccb, const QueryLoc& loc)
+PlanIterator* IndexDecl::getBuildPlan(const QueryLoc& loc)
 {
   if (theBuildPlan != NULL)
     return theBuildPlan.getp();
 
-  expr* buildExpr = getBuildExpr(ccb, loc);
+  expr* buildExpr = getBuildExpr(loc);
 
   ulong nextVarId = 1;
-  theBuildPlan = codegen("index", buildExpr, ccb, nextVarId);
+  theBuildPlan = codegen("index", buildExpr, theCCB, nextVarId);
 
   return theBuildPlan.getp();
 }
@@ -577,9 +728,7 @@
   Called from ApplyIterator::nextImpl before it actually starts applying the
   updates.
 ********************************************************************************/
-DocIndexer* IndexDecl::getDocIndexer(
-    CompilerCB* ccb,
-    const QueryLoc& loc)
+DocIndexer* IndexDecl::getDocIndexer(const QueryLoc& loc)
 {
   if (theDocIndexer != NULL)
     return theDocIndexer.getp();
@@ -587,9 +736,7 @@
   if (theMaintenanceMode != DOC_MAP)
     return NULL;
 
-  std::stringstream ss;
-  ss << "$$idx_doc_var_" << this;
-  std::string varname = ss.str();
+  std::string varname = "$$idx_doc_var";
   store::Item_t docVarName;
   GENV_ITEMFACTORY->createQName(docVarName, "", "", varname.c_str());
 
@@ -697,11 +844,11 @@
   flworExpr->set_return_expr(returnExpr);
   flworExpr->add_clause(fc);
 
-  if (ccb->theConfig.optimize_cb != NULL)
+  if (theCCB->theConfig.optimize_cb != NULL)
   {
     std::string msg = "entry-creator expr for index " + theName->getStringValue().str();
 
-    ccb->theConfig.optimize_cb(flworExpr, msg);
+    theCCB->theConfig.optimize_cb(flworExpr, msg);
   }
 
   theDocIndexerExpr = flworExpr;
@@ -709,7 +856,7 @@
   //
   // Generate the runtime plan for theDocIndexerExpr
   //
-  theDocIndexerPlan = codegen("doc indexer", flworExpr, ccb, nextVarId);
+  theDocIndexerPlan = codegen("doc indexer", flworExpr, theCCB, nextVarId);
 
   //
   // Create theDocIndexer obj

=== modified file 'src/compiler/xqddf/value_index.h'
--- src/compiler/xqddf/value_index.h	2012-10-22 15:10:23 +0000
+++ src/compiler/xqddf/value_index.h	2012-12-21 04:09:22 +0000
@@ -31,6 +31,8 @@
 class ExprManager;
 class dynamic_context;
 class DocIndexer;
+class flwor_expr;
+
 typedef rchandle<DocIndexer> DocIndexer_t;
 
 
@@ -359,23 +361,25 @@
 
   const expr* getDomainSourceExpr(csize i) const { return theDomainSourceExprs[i]; }
 
-  void analyze(CompilerCB* ccb);
-
-  expr* getBuildExpr(CompilerCB* ccb, const QueryLoc& loc);
-
-  PlanIterator* getBuildPlan(CompilerCB* ccb, const QueryLoc& loc);
-
-  DocIndexer* getDocIndexer(CompilerCB* ccb, const QueryLoc& loc);
+  void analyze();
+
+  flwor_expr* getViewExpr();
+
+  expr* getBuildExpr(const QueryLoc& loc);
+
+  PlanIterator* getBuildPlan(const QueryLoc& loc);
+
+  DocIndexer* getDocIndexer(const QueryLoc& loc);
 
   std::string toString();
 
 private:
   void analyzeExprInternal(
-        expr* e,
-        std::vector<store::Item*>& sourceNames,
-        std::vector<expr*>& sourceExprs,
-        FreeVars& varExprs,
-        expr* dotVar);
+      expr* e,
+      std::vector<store::Item*>& sourceNames,
+      std::vector<expr*>& sourceExprs,
+      std::vector<var_expr*>& varExprs,
+      expr* dotVar);
 };
 
 

=== modified file 'src/context/sctx_map_iterator.h'
--- src/context/sctx_map_iterator.h	2012-09-19 21:16:15 +0000
+++ src/context/sctx_map_iterator.h	2012-12-21 04:09:22 +0000
@@ -45,8 +45,8 @@
   
 public:
   SctxMapIterator(
-        const static_context* aSctx,
-        ItemsMap* (static_context::*aMapGetter)() const);
+      const static_context* aSctx,
+      ItemsMap* (static_context::*aMapGetter)() const);
   
   virtual ~SctxMapIterator();
   

=== modified file 'src/context/static_context.cpp'
--- src/context/static_context.cpp	2012-12-11 20:27:40 +0000
+++ src/context/static_context.cpp	2012-12-21 04:09:22 +0000
@@ -539,6 +539,7 @@
             ns == ZORBA_JSON_FN_NS ||
             ns == ZORBA_FETCH_FN_NS ||
             ns == ZORBA_NODE_FN_NS ||
+            ns == ZORBA_UTIL_FN_NS ||
 #ifndef ZORBA_NO_FULL_TEXT
             ns == ZORBA_FULL_TEXT_FN_NS ||
 #endif /* ZORBA_NO_FULL_TEXT */
@@ -3112,7 +3113,7 @@
 }
 
 
-/***************************************************************************//**
+/*******************************************************************************
 
 ********************************************************************************/
 store::Iterator_t static_context::index_names() const
@@ -3121,6 +3122,32 @@
 }
 
 
+/*******************************************************************************
+
+********************************************************************************/
+void static_context::get_index_decls(std::vector<IndexDecl*>& decls) const
+{
+  const static_context* sctx = this;
+
+  while (sctx != NULL)
+  {
+    if (sctx->theIndexMap)
+    {
+      IndexMap::iterator ite = sctx->theIndexMap->begin();
+      IndexMap::iterator end = sctx->theIndexMap->end();
+      
+      for (; ite != end; ++ite)
+      {
+        IndexDecl* decl = ite.getValue().getp();
+        decls.push_back(decl);
+      }
+    }
+
+    sctx = sctx->theParent;
+  }
+}
+
+
 /////////////////////////////////////////////////////////////////////////////////
 //                                                                             //
 //  XQDDF Integrity Constraints                                                //

=== modified file 'src/context/static_context.h'
--- src/context/static_context.h	2012-12-06 01:17:18 +0000
+++ src/context/static_context.h	2012-12-21 04:09:22 +0000
@@ -956,6 +956,8 @@
 
   IndexDecl* lookup_index(const store::Item* qname) const;
 
+  void get_index_decls(std::vector<IndexDecl*>& decls) const;
+
   store::Iterator_t index_names() const;
 
 

=== modified file 'src/functions/func_booleans_impl.cpp'
--- src/functions/func_booleans_impl.cpp	2012-10-24 11:32:56 +0000
+++ src/functions/func_booleans_impl.cpp	2012-12-21 04:09:22 +0000
@@ -130,8 +130,8 @@
   xqtref_t getReturnType(const fo_expr* caller) const;
 
   function* specialize(
-        static_context* sctx,
-        const std::vector<xqtref_t>& argTypes) const;
+      static_context* sctx,
+      const std::vector<xqtref_t>& argTypes) const;
 };
 
 

=== modified file 'src/functions/func_collections_impl.cpp'
--- src/functions/func_collections_impl.cpp	2012-12-11 13:33:18 +0000
+++ src/functions/func_collections_impl.cpp	2012-12-21 04:09:22 +0000
@@ -78,7 +78,7 @@
 
   static_context* sctx = caller->get_sctx();
 
-  const store::Item* qname = caller->get_arg(0)->getQName(sctx);
+  const store::Item* qname = caller->get_arg(0)->getQName();
 
   if (qname != NULL)
   {

=== modified file 'src/functions/func_eval.cpp'
--- src/functions/func_eval.cpp	2012-09-19 21:16:15 +0000
+++ src/functions/func_eval.cpp	2012-12-21 04:09:22 +0000
@@ -91,6 +91,39 @@
   CODEGEN_DECL();
 };
 
+
+
+/***************************************************************************//**
+  1st arg is a string specifying the "query" expression, and 2nd arg is a string
+  specifying the "view" ast.
+********************************************************************************/
+class fn_zorba_match : public function
+{
+public:
+  fn_zorba_match(const signature& sig)
+    :
+    function(sig, FunctionConsts::FN_ZORBA_MATCH_2)
+  {
+  }
+
+  bool accessesDynCtx() const { return true; }
+
+  CODEGEN_DECL();
+};
+
+
+PlanIter_t fn_zorba_match::codegen(
+  CompilerCB*,
+  static_context* sctx,
+  const QueryLoc& loc,
+  std::vector<PlanIter_t>& argv,
+  expr& ann) const
+{
+  ZORBA_ASSERT(false);
+  return NULL;
+}
+
+
 PlanIter_t fn_zorba_eval::codegen(
   CompilerCB*,
   static_context* sctx,
@@ -102,6 +135,7 @@
   return NULL;
 }
 
+
 PlanIter_t fn_zorba_eval_n::codegen(
   CompilerCB*,
   static_context* sctx,
@@ -159,6 +193,13 @@
        (createQName(static_context::ZORBA_REFLECTION_FN_NS, "", "eval-s"),
         GENV_TYPESYSTEM.STRING_TYPE_ONE,
         GENV_TYPESYSTEM.ITEM_TYPE_STAR));
+
+  DECL(sctx, fn_zorba_match,
+       (createQName(static_context::ZORBA_UTIL_FN_NS, "", "match"),
+        GENV_TYPESYSTEM.STRING_TYPE_ONE,
+        GENV_TYPESYSTEM.STRING_TYPE_ONE,
+        GENV_TYPESYSTEM.BOOLEAN_TYPE_ONE));
+
 }
 
 

=== modified file 'src/functions/function_consts.h'
--- src/functions/function_consts.h	2012-10-24 11:32:56 +0000
+++ src/functions/function_consts.h	2012-12-21 04:09:22 +0000
@@ -41,6 +41,7 @@
   FN_HEAD_1,
   FN_TAIL_1,
 
+  FN_ZORBA_MATCH_2,
   FN_ZORBA_EVAL_1,
   FN_ZORBA_EVAL_N_1,
   FN_ZORBA_EVAL_U_1,

=== modified file 'src/runtime/core/apply_updates.cpp'
--- src/runtime/core/apply_updates.cpp	2012-12-01 00:06:15 +0000
+++ src/runtime/core/apply_updates.cpp	2012-12-21 04:09:22 +0000
@@ -174,7 +174,7 @@
 
     if (indexDecl->getMaintenanceMode() == IndexDecl::DOC_MAP)
     {
-      DocIndexer* docIndexer = indexDecl->getDocIndexer(ccb, loc);
+      DocIndexer* docIndexer = indexDecl->getDocIndexer(loc);
       assert(docIndexer != NULL);
 
       docIndexer->setup(ccb);
@@ -215,7 +215,7 @@
 
         if (zorbaIndex->getMaintenanceMode() == IndexDecl::REBUILD)
         {
-          PlanIter_t buildPlan = zorbaIndex->getBuildPlan(ccb, loc);
+          PlanIter_t buildPlan = zorbaIndex->getBuildPlan(loc);
 
           PlanWrapper_t planWrapper = new PlanWrapper(buildPlan,
                                                       ccb,

=== modified file 'src/runtime/core/sequencetypes.cpp'
--- src/runtime/core/sequencetypes.cpp	2012-11-26 20:49:01 +0000
+++ src/runtime/core/sequencetypes.cpp	2012-12-21 04:09:22 +0000
@@ -507,6 +507,12 @@
     break;
   }
 #endif
+  case PROMOTE_INDEX_KEY:
+  {
+    RAISE_ERROR(zerr::ZDTY0011_INDEX_KEY_TYPE_ERROR, loc,
+    ERROR_PARAMS(valueType, targetType, theQName->getStringValue()));
+    break;
+  }
   default:
   {
     ZORBA_ASSERT(false);

=== modified file 'src/runtime/eval/eval.cpp'
--- src/runtime/eval/eval.cpp	2012-10-24 11:32:56 +0000
+++ src/runtime/eval/eval.cpp	2012-12-21 04:09:22 +0000
@@ -18,6 +18,7 @@
 #include <sstream>
 
 #include "store/api/temp_seq.h"
+#include "store/api/item_factory.h"
 
 #include "runtime/eval/eval.h"
 
@@ -31,6 +32,7 @@
 #include "compiler/api/compiler_api.h"
 #include "compiler/expression/var_expr.h"
 #include "compiler/expression/expr_manager.h"
+#include "compiler/rewriter/tools/expr_tools.h"
 
 #include "context/dynamic_context.h"
 #include "context/static_context.h"
@@ -464,5 +466,207 @@
 NARY_ACCEPT(EvalIterator);
 
 
+/////////////////////////////////////////////////////////////////////////////////
+//                                                                             //
+//                                                                             //
+//                                                                             //
+/////////////////////////////////////////////////////////////////////////////////
+
+
+/********************************************************************************
+
+********************************************************************************/
+MatchIterator::MatchIterator(
+      static_context* sctx,
+      const QueryLoc& loc,
+      std::vector<PlanIter_t>& children,
+      const std::vector<store::Item_t>& varNames,
+      const std::vector<xqtref_t>& varTypes,
+      const std::vector<int>& isGlobalVar,
+      expr_script_kind_t scriptingKind,
+      const store::NsBindings& localBindings,
+      bool doNodeCopy)
+  :
+  NaryBaseIterator<MatchIterator, EvalIteratorState>(sctx, loc, children),
+  theOuterVarNames(varNames),
+  theOuterVarTypes(varTypes),
+  theIsGlobalVar(isGlobalVar),
+  theScriptingKind(scriptingKind),
+  theLocalBindings(localBindings),
+  theDoNodeCopy(doNodeCopy)
+{
+}
+
+
+/********************************************************************************
+
+********************************************************************************/
+MatchIterator::~MatchIterator()
+{
+}
+
+
+/********************************************************************************
+
+********************************************************************************/
+bool MatchIterator::nextImpl(store::Item_t& result, PlanState& planState) const
+{
+  bool res = false;
+  store::Item_t queryItem;
+  store::Item_t viewItem;
+  expr* queryExpr;
+  expr* viewExpr;
+  expr::substitution_t subst;
+  CompilerCB* queryCCB = NULL;
+  CompilerCB* viewCCB = NULL;
+
+  EvalIteratorState* state;
+  DEFAULT_STACK_INIT(EvalIteratorState, state, planState);
+
+  CONSUME(queryItem, 0);
+  CONSUME(viewItem, 1);
+
+  try
+  {
+    static_context* importSctx = theSctx->create_child_context();
+    static_context* querySctx = importSctx->create_child_context();
+    static_context* viewSctx = importSctx->create_child_context();
+
+    queryCCB = new CompilerCB(*planState.theCompilerCB);
+    queryCCB->theRootSctx = querySctx;
+    queryCCB->theConfig.for_serialization_only = !theDoNodeCopy;
+    (queryCCB->theSctxMap)[1] = querySctx;
+
+    viewCCB = new CompilerCB(*planState.theCompilerCB);
+    viewCCB->theRootSctx = viewSctx;
+    viewCCB->theConfig.for_serialization_only = !theDoNodeCopy;
+    (viewCCB->theSctxMap)[1] = viewSctx;
+
+    queryExpr = compile(queryCCB, queryItem->getStringValue());
+    viewExpr = compile(viewCCB, viewItem->getStringValue());
+
+    res = expr_tools::match_exact(queryExpr, viewExpr, subst);
+
+    GENV_ITEMFACTORY->createBoolean(result, res);
+
+    delete queryCCB;
+    delete viewCCB;
+  }
+  catch (...)
+  {
+    delete queryCCB;
+    delete viewCCB;
+
+    throw;
+  }
+
+  STACK_PUSH(true, state);
+
+  STACK_END(state);
+}
+
+
+/********************************************************************************
+  This method imports a static environment from the quter query into
+  the eval query.
+********************************************************************************/
+void MatchIterator::importOuterEnv(
+    PlanState& planState,
+    CompilerCB* evalCCB,
+    static_context* importSctx) const
+{
+  // Import the outer vars: for each outer var, create a declaration inside
+  // the importSctx.
+
+  csize numOuterVars = theOuterVarNames.size();
+
+  for (csize i = 0; i < numOuterVars; ++i)
+  {
+    var_expr* ve = evalCCB->theEM->create_var_expr(importSctx,
+                                                   NULL,
+                                                   loc,
+                                                   var_expr::prolog_var,
+                                                   theOuterVarNames[i].getp());
+
+    ve->set_type(theOuterVarTypes[i]);
+
+    importSctx->bind_var(ve, loc, err::XQST0049);
+  }
+
+  // Import the outer-query ns bindings
+
+  store::NsBindings::const_iterator ite = theLocalBindings.begin();
+  store::NsBindings::const_iterator end = theLocalBindings.end();
+
+  for (; ite != end; ++ite)
+  {
+    importSctx->bind_ns(ite->first, ite->second, loc);
+  }
+}
+
+
+
+/********************************************************************************
+
+********************************************************************************/
+expr* MatchIterator::compile(CompilerCB* ccb, const zstring& query) const
+{
+  std::stringstream os;
+  os.write(query.data(), (std::streamsize)query.size());
+
+  XQueryCompiler compiler(ccb);
+
+  std::stringstream evalname;
+  evalname << "eval@" << loc.getFilename()
+           << "-" << loc.getLineBegin()
+           << "-" << loc.getColumnBegin();
+
+  std::string lName = evalname.str();
+
+  parsenode_t ast = compiler.parse(os, lName);
+
+  rchandle<MainModule> mm = ast.dyn_cast<MainModule>();
+  if (mm == NULL)
+  {
+    RAISE_ERROR(err::XPST0003, loc,
+    ERROR_PARAMS(ZED(XPST0003_ModuleDeclNotInMain)));
+  }
+
+  expr* rootExpr = compiler.normalize(ast);
+  rootExpr = compiler.optimize(rootExpr);
+
+  if (theScriptingKind == SIMPLE_EXPR)
+  {
+    if (ccb->isSequential())
+    {
+      RAISE_ERROR(zerr::XSST0004, loc, ERROR_PARAMS("eval"));
+    }
+    else if (ccb->isUpdating())
+    {
+      RAISE_ERROR(err::XUST0001, loc, ERROR_PARAMS(ZED(XUST0001_UDF_2), "eval"));
+    }
+  }
+  else if (theScriptingKind == UPDATING_EXPR)
+  {
+    if (ccb->isSequential())
+    {
+      RAISE_ERROR(zerr::XSST0003, loc, ERROR_PARAMS("eval_u"));
+    }
+  }
+  else // sequential
+  {
+    if (ccb->isUpdating())
+    {
+      RAISE_ERROR(zerr::XSST0002, loc, ERROR_PARAMS("eval_s"));
+    }
+  }
+
+  return rootExpr;
+}
+
+
+NARY_ACCEPT(MatchIterator);
+
+
 }
 /* vim:set et sw=2 ts=2: */

=== modified file 'src/runtime/eval/eval.h'
--- src/runtime/eval/eval.h	2012-09-19 21:16:15 +0000
+++ src/runtime/eval/eval.h	2012-12-21 04:09:22 +0000
@@ -143,6 +143,54 @@
 };
 
 
+/****************************************************************************//**
+  The 1st child iterator computes the ast string, the 2nd child iterator computes
+  the query string, and the next N child iterators compute the value of each of 
+  the non-global outer variables
+********************************************************************************/
+class MatchIterator : public NaryBaseIterator<MatchIterator, EvalIteratorState>
+{ 
+protected:
+  std::vector<store::Item_t>  theOuterVarNames;
+
+  std::vector<xqtref_t>       theOuterVarTypes;
+
+  std::vector<int>            theIsGlobalVar;
+
+  expr_script_kind_t          theScriptingKind;
+
+  store::NsBindings           theLocalBindings;
+
+  bool                        theDoNodeCopy;
+
+public:
+  MatchIterator(
+      static_context* sctx,
+      const QueryLoc& loc,
+      std::vector<PlanIter_t>& children,
+      const std::vector<store::Item_t>& varNames,
+      const std::vector<xqtref_t>& varTypes,
+      const std::vector<int>& isGlobalVar,
+      expr_script_kind_t scriptingKind,
+      const store::NsBindings& localBindings,
+      bool doNodeCopy);
+
+  ~MatchIterator();
+
+  void accept(PlanIterVisitor& v) const;
+
+  bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
+
+private:
+  void importOuterEnv(
+      PlanState& planState,
+      CompilerCB* evalCCB,
+      static_context* importSctx) const;
+
+  expr* compile(CompilerCB* ccb, const zstring& query) const;
+};
+
+
 }
 #endif
 /*

=== modified file 'src/runtime/indexing/index_ddl.cpp'
--- src/runtime/indexing/index_ddl.cpp	2012-09-19 21:16:15 +0000
+++ src/runtime/indexing/index_ddl.cpp	2012-12-21 04:09:22 +0000
@@ -82,16 +82,7 @@
   xqtref_t searchKeyType = tm->create_value_type(searchKey);
   xqtref_t indexKeyType = (indexDecl->getKeyTypes())[keyNo];
 
-  if (indexKeyType != NULL &&
-      !TypeOps::is_subtype(tm, *searchKeyType, *indexKeyType))
-  {
-    RAISE_ERROR(err::XPTY0004, loc,
-    ERROR_PARAMS(ZED(SearchKeyTypeMismatch_234),
-                 *searchKeyType,
-                 indexDecl->getName()->getStringValue(),
-                 *indexKeyType));
-  }
-  else if (indexKeyType == NULL)
+  if (indexKeyType == NULL)
   {
     ZORBA_ASSERT(indexDecl->isGeneral());
 
@@ -113,6 +104,47 @@
                    indexDecl->getName()->getStringValue()));
     }
   }
+  else if (!TypeOps::is_subtype(tm, *searchKeyType, *indexKeyType))
+  {
+    store::SchemaTypeCode searchKeyTypeCode = searchKey->getTypeCode();
+
+    if (TypeOps::is_subtype(tm, *indexKeyType, *rtm.STRING_TYPE_ONE) &&
+        (searchKeyTypeCode == store::XS_UNTYPED_ATOMIC ||
+         searchKeyTypeCode == store::XS_ANY_URI))
+    {
+      return;
+    }
+
+    if (TypeOps::is_subtype(tm, *indexKeyType, *rtm.DOUBLE_TYPE_ONE))
+    {
+      if (TypeOps::is_subtype(searchKeyTypeCode, store::XS_DECIMAL))
+      {
+        GENV_STORE.getItemFactory()->
+        createDouble(searchKey, xs_double(searchKey->getDecimalValue()));
+      }
+      else if (TypeOps::is_subtype(searchKeyTypeCode, store::XS_FLOAT))
+      {
+        GENV_STORE.getItemFactory()->
+        createDouble(searchKey, xs_double(searchKey->getFloatValue()));
+      }
+
+      return;
+    }
+
+    if (TypeOps::is_subtype(tm, *indexKeyType, *rtm.FLOAT_TYPE_ONE) &&
+        TypeOps::is_subtype(searchKeyTypeCode, store::XS_DECIMAL))
+    {
+      GENV_STORE.getItemFactory()->
+      createDouble(searchKey, xs_float(searchKey->getDecimalValue()));
+      return;
+    }
+
+    RAISE_ERROR(err::XPTY0004, loc,
+    ERROR_PARAMS(ZED(SearchKeyTypeMismatch_234),
+                 *searchKeyType,
+                 indexDecl->getName()->getStringValue(),
+                 *indexKeyType));
+  }
 }
 
 
@@ -242,23 +274,17 @@
 
   if ((indexDecl = theSctx->lookup_index(qname)) == NULL)
   {
-    throw XQUERY_EXCEPTION(
-      zerr::ZDDY0021_INDEX_NOT_DECLARED,
-      ERROR_PARAMS( qname->getStringValue() ),
-      ERROR_LOC( loc )
-    );
+    RAISE_ERROR(zerr::ZDDY0021_INDEX_NOT_DECLARED, loc,
+    ERROR_PARAMS(qname->getStringValue()));
   }
 
   if (GENV_STORE.getIndex(qname) != NULL)
   {
-    throw XQUERY_EXCEPTION(
-      zerr::ZDDY0022_INDEX_ALREADY_EXISTS,
-      ERROR_PARAMS( qname->getStringValue() ),
-      ERROR_LOC( loc )
-    );
+    RAISE_ERROR(zerr::ZDDY0022_INDEX_ALREADY_EXISTS, loc,
+    ERROR_PARAMS(qname->getStringValue()));
   }
 
-  buildPlan = indexDecl->getBuildPlan(ccb, loc); 
+  buildPlan = indexDecl->getBuildPlan(loc); 
   
   planWrapper = new PlanWrapper(buildPlan, ccb, NULL, NULL, 0, false, 0); 
 
@@ -266,7 +292,8 @@
 
   result = GENV_ITEMFACTORY->createPendingUpdateList();
 
-  reinterpret_cast<store::PUL*>(result.getp())->addCreateIndex(&loc, qname, spec, planWrapper);
+  reinterpret_cast<store::PUL*>(result.getp())->
+  addCreateIndex(&loc, qname, spec, planWrapper);
 
   STACK_PUSH(true, state);
 
@@ -387,7 +414,7 @@
     );
   }
 
-  buildPlan = indexDecl->getBuildPlan(ccb, loc); 
+  buildPlan = indexDecl->getBuildPlan(loc); 
   
   planWrapper = new PlanWrapper(buildPlan, ccb, dctx, NULL, 0, false, 0); 
 
@@ -607,7 +634,7 @@
   TypeManager* tm = theSctx->get_typemanager();
   RootTypeManager& rtm = GENV_TYPESYSTEM;
   xs_integer lSkip = xs_integer::zero();
-  ulong lAmountNonKeyParams = (theSkip ? 2 : 1);
+  ulong numNonKeyParams = (theSkip ? 2 : 1);
 
   try
   {
@@ -627,16 +654,13 @@
         ERROR_PARAMS(qnameItem->getStringValue()));
       }
 
-      if ( state->theIndexDecl->getNumKeyExprs() 
-        != numChildren - lAmountNonKeyParams )
+      if (state->theIndexDecl->getNumKeyExprs() != numChildren - numNonKeyParams)
       {
         RAISE_ERROR(zerr::ZDDY0025_INDEX_WRONG_NUMBER_OF_PROBE_ARGS, loc,
-        ERROR_PARAMS(
-          qnameItem->getStringValue(),
-          "index",
-          numChildren - lAmountNonKeyParams,
-          state->theIndexDecl->getNumKeyExprs())
-        );
+        ERROR_PARAMS(qnameItem->getStringValue(),
+                     "index",
+                     numChildren - numNonKeyParams,
+                     state->theIndexDecl->getNumKeyExprs()));
       }
 
       state->theIndex = (state->theIndexDecl->isTemp() ?
@@ -666,7 +690,7 @@
         lSkip = xs_integer::zero();
     }
 
-    for (i = lAmountNonKeyParams; i < numChildren; ++i) 
+    for (i = numNonKeyParams; i < numChildren; ++i) 
     {
       if (!consumeNext(keyItem, theChildren[i], planState)) 
       {
@@ -676,12 +700,11 @@
 
       if (theCheckKeyType)
       {
-        checkKeyType(loc, tm, state->theIndexDecl, 
-                     i - lAmountNonKeyParams, keyItem);
+        checkKeyType(loc, tm, state->theIndexDecl, i - numNonKeyParams, keyItem);
       }
 
       if (state->theIndexDecl->isGeneral() &&
-          (state->theIndexDecl->getKeyTypes())[i - lAmountNonKeyParams] == NULL)
+          (state->theIndexDecl->getKeyTypes())[i - numNonKeyParams] == NULL)
       {
         xqtref_t searchKeyType = tm->create_value_type(keyItem);
         

=== modified file 'src/runtime/visitors/planiter_visitor_impl_code.h'
--- src/runtime/visitors/planiter_visitor_impl_code.h	2012-09-19 21:16:15 +0000
+++ src/runtime/visitors/planiter_visitor_impl_code.h	2012-12-21 04:09:22 +0000
@@ -353,6 +353,7 @@
   PLAN_ITER_VISITOR(DynamicFnCallIterator);
 
   PLAN_ITER_VISITOR(EvalIterator);
+  PLAN_ITER_VISITOR(MatchIterator);
 
   PLAN_ITER_VISITOR(MaterializeIterator);
 

=== modified file 'src/runtime/visitors/planiter_visitor_impl_include.h'
--- src/runtime/visitors/planiter_visitor_impl_include.h	2012-09-19 21:16:15 +0000
+++ src/runtime/visitors/planiter_visitor_impl_include.h	2012-12-21 04:09:22 +0000
@@ -175,6 +175,7 @@
 class DynamicFnCallIterator;
 
 class EvalIterator;
+class MatchIterator;
 
 class MaterializeIterator;
 

=== modified file 'src/runtime/visitors/printer_visitor_impl.cpp'
--- src/runtime/visitors/printer_visitor_impl.cpp	2012-10-08 12:09:36 +0000
+++ src/runtime/visitors/printer_visitor_impl.cpp	2012-12-21 04:09:22 +0000
@@ -1514,6 +1514,7 @@
   PRINTER_VISITOR_DEFINITION(DynamicFnCallIterator);
 
   PRINTER_VISITOR_DEFINITION(EvalIterator);
+  PRINTER_VISITOR_DEFINITION(MatchIterator);
 
   PRINTER_VISITOR_DEFINITION(MaterializeIterator);
 

=== modified file 'src/runtime/visitors/printer_visitor_impl.h'
--- src/runtime/visitors/printer_visitor_impl.h	2012-09-19 21:16:15 +0000
+++ src/runtime/visitors/printer_visitor_impl.h	2012-12-21 04:09:22 +0000
@@ -308,6 +308,7 @@
   DECLARE_VISITOR(DynamicFnCallIterator);
 
   DECLARE_VISITOR(EvalIterator);
+  DECLARE_VISITOR(MatchIterator);
 
   DECLARE_VISITOR(MaterializeIterator);
 

=== modified file 'src/system/zorba_properties.h'
--- src/system/zorba_properties.h	2012-09-19 21:16:15 +0000
+++ src/system/zorba_properties.h	2012-12-21 04:09:22 +0000
@@ -79,6 +79,7 @@
   bool theInlineUdf;
   bool theLoopHoisting;
   bool theInferJoins;
+  bool theUseIndexes;
   bool theNoCopyOptim;
   int theSerializeOnlyQuery;
   bool theTraceTranslator;
@@ -123,6 +124,7 @@
     theInlineUdf = true;
     theLoopHoisting = true;
     theInferJoins = true;
+    theUseIndexes = true;
     theNoCopyOptim = true;
     theSerializeOnlyQuery = -1;
     theTraceTranslator = false;
@@ -161,11 +163,12 @@
   const bool &forceGflwor () const { return theForceGflwor; }
   const bool &reorderGlobals () const { return theReorderGlobals; }
   const bool &specializeNum () const { return theSpecializeNum; }
-  const bool &specializeCmp () const { return theSpecializeCmp; }
-  const bool &inlineUdf () const { return theInlineUdf; }
-  const bool &loopHoisting () const { return theLoopHoisting; }
-  const bool &inferJoins () const { return theInferJoins; }
-  const bool &noCopyOptim() const { return theNoCopyOptim; }
+  const bool& specializeCmp () const { return theSpecializeCmp; }
+  const bool& inlineUdf () const { return theInlineUdf; }
+  const bool& loopHoisting () const { return theLoopHoisting; }
+  const bool& inferJoins () const { return theInferJoins; }
+  const bool& useIndexes() const { return theUseIndexes; }
+  const bool& noCopyOptim() const { return theNoCopyOptim; }
   const int& serializeOnlyQuery() const { return theSerializeOnlyQuery; }
   const bool &traceTranslator () const { return theTraceTranslator; }
   const bool &traceCodegen () const { return theTraceCodegen; }
@@ -301,33 +304,47 @@
 
         init_val (*argv, theSpecializeCmp, d);
       }
-      else if (strcmp (*argv, "--inline-udf") == 0) {
+      else if (strcmp (*argv, "--inline-udf") == 0)
+      {
         int d = 2;
         if ((*argv) [1] == '-' || (*argv) [2] == '\0') { d = 0; ++argv; }
         if (*argv == NULL) { result = "No value given for --inline-udf option"; break; }
 
         init_val (*argv, theInlineUdf, d);
       }
-      else if (strcmp (*argv, "--loop-hoisting") == 0) {
+      else if (strcmp (*argv, "--loop-hoisting") == 0)
+      {
         int d = 2;
         if ((*argv) [1] == '-' || (*argv) [2] == '\0') { d = 0; ++argv; }
         if (*argv == NULL) { result = "No value given for --loop-hoisting option"; break; }
 
         init_val (*argv, theLoopHoisting, d);
       }
-      else if (strcmp (*argv, "--infer-joins") == 0) {
+      else if (strcmp (*argv, "--infer-joins") == 0)
+      {
         int d = 2;
-        if ((*argv) [1] == '-' || (*argv) [2] == '\0') { d = 0; ++argv; }
+        if ((*argv)[1] == '-' || (*argv)[2] == '\0') { d = 0; ++argv; }
         if (*argv == NULL) { result = "No value given for --infer-joins option"; break; }
 
-        init_val (*argv, theInferJoins, d);
-      }
-      else if (strcmp (*argv, "--no-copy-optim") == 0)
-      {
-        int d = 2;
-        if ((*argv) [1] == '-' || (*argv) [2] == '\0') { d = 0; ++argv; }
-        if (*argv == NULL) { result = "No value given for --no-copy-optim option"; break; }
-        init_val (*argv, theNoCopyOptim, d);
+        init_val(*argv, theInferJoins, d);
+      }
+      else if (strcmp(*argv, "--use-indexes") == 0)
+      {
+        int d = 2;
+        if ((*argv)[1] == '-' || (*argv)[2] == '\0') { d = 0; ++argv; }
+        if (*argv == NULL) { result = "No value given for --use-indexes option"; break; }
+
+        init_val(*argv, theUseIndexes, d);
+      }
+      else if (strcmp(*argv, "--no-copy-optim") == 0)
+      {
+        int d = 2;
+        if ((*argv)[1] == '-' || (*argv)[2] == '\0') { d = 0; ++argv; }
+        if (*argv == NULL)
+        {
+          result = "No value given for --no-copy-optim option"; break; 
+        }
+        init_val(*argv, theNoCopyOptim, d);
       }
       else if (strcmp (*argv, "--serialize-only-query") == 0)
       {
@@ -338,10 +355,14 @@
         init_val(*argv, theSerializeOnlyQuery, d);
       }
 #ifndef NDEBUG
-      else if (strcmp (*argv, "--trace-translator") == 0 || strncmp (*argv, "-l", 2) == 0) {
+      else if (strcmp (*argv, "--trace-translator") == 0 ||
+               strncmp (*argv, "-l", 2) == 0)
+      {
         theTraceTranslator = true;
       }
-      else if (strcmp (*argv, "--trace-codegen") == 0 || strncmp (*argv, "-c", 2) == 0) {
+      else if (strcmp (*argv, "--trace-codegen") == 0 ||
+               strncmp (*argv, "-c", 2) == 0)
+      {
         theTraceCodegen = true;
       }
       else if (strcmp (*argv, "--trace-fulltext") == 0) {

=== modified file 'src/types/typeops.cpp'
--- src/types/typeops.cpp	2012-10-16 13:08:12 +0000
+++ src/types/typeops.cpp	2012-12-21 04:09:22 +0000
@@ -763,7 +763,7 @@
 {
   CHECK_IN_SCOPE(tm, supertype, loc);
 
-  switch(supertype.type_kind()) 
+  switch (supertype.type_kind()) 
   {
   case XQType::EMPTY_KIND:
   case XQType::NONE_KIND:
@@ -905,30 +905,7 @@
     if (!subitem->isAtomic())
       return false;
 
-    xqtref_t subtype = tm->create_named_atomic_type(subitem->getType(),
-                                                    TypeConstants::QUANT_ONE,
-                                                    loc,
-                                                    err::XPTY0004);
-    switch (subtype->type_kind())
-    {
-    case XQType::ATOMIC_TYPE_KIND:
-    case XQType::ANY_SIMPLE_TYPE_KIND:
-    case XQType::EMPTY_KIND:
-      return true;
-
-    case XQType::USER_DEFINED_KIND:
-    {
-      const UserDefinedXQType& udSubType = 
-      static_cast<const UserDefinedXQType&>(*subtype);
-
-      return (udSubType.isAtomic() || udSubType.isList() || udSubType.isUnion());
-    }
-
-    default:
-      // ANY, UNTYPED, ITEM, NODE
-      return false;
-    }
-    break;
+    return true;
   }
 
   case XQType::UNTYPED_KIND:

=== modified file 'src/util/dynamic_bitset.cpp'
--- src/util/dynamic_bitset.cpp	2012-09-19 21:16:15 +0000
+++ src/util/dynamic_bitset.cpp	2012-12-21 04:09:22 +0000
@@ -25,9 +25,10 @@
 std::ostream& operator <<(std::ostream& s, const DynamicBitset& set)
 {
   s << "BitSet[" << set.size() << "] = {";
-  for(ulong i = 0; i < set.size(); ++i) 
+  for(std::size_t i = 0; i < set.size(); ++i) 
   {
-    if (set.get(i)) {
+    if (set.get(i)) 
+    {
       s << i << ", ";
     }
   }

=== modified file 'src/util/dynamic_bitset.h'
--- src/util/dynamic_bitset.h	2012-09-19 21:16:15 +0000
+++ src/util/dynamic_bitset.h	2012-12-21 04:09:22 +0000
@@ -31,7 +31,7 @@
 
 private:
   ulong    m_num_bits;
-  bits_t m_bits;
+  bits_t   m_bits;
 
 public:
   DynamicBitset() { }
@@ -100,7 +100,7 @@
   void reset()
   {
     bits_t::iterator end = m_bits.end();
-    for(bits_t::iterator i = m_bits.begin(); i != end; ++i) 
+    for (bits_t::iterator i = m_bits.begin(); i != end; ++i) 
     {
       *i = 0;
     }

=== modified file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/gary1.iter'
--- test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/gary1.iter	2012-12-18 15:09:02 +0000
+++ test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/gary1.iter	2012-12-21 04:09:22 +0000
@@ -26,200 +26,178 @@
     <flwor::FLWORIterator>
       <LetVariable name="y" materialize="true">
         <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,data)" typename="*" nill allowed="0">
-          <flwor::FLWORIterator>
-            <ForVariable name="$$context-item">
-              <FnDocIterator>
-                <SingletonIterator value="xs:string(min_ic1980.xml)"/>
-              </FnDocIterator>
-            </ForVariable>
-            <ForVariable name="$$context-item">
+          <flwor::TupleStreamIterator>
+            <flwor::WhereIterator>
+              <flwor::WhereIterator>
+                <flwor::ForIterator>
+                  <ForVariable name="$$context-item"/>
+                  <flwor::ForIterator>
+                    <ForVariable name="$$context-item"/>
+                    <flwor::TupleSourceIterator/>
+                    <FnDocIterator>
+                      <SingletonIterator value="xs:string(min_ic1980.xml)"/>
+                    </FnDocIterator>
+                  </flwor::ForIterator>
+                  <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,ipeds)" typename="*" nill allowed="0">
+                    <ForVarIterator varname="$$context-item"/>
+                  </ChildAxisIterator>
+                </flwor::ForIterator>
+                <CompareIterator>
+                  <FnDataIterator>
+                    <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,year)" typename="*" nill allowed="0">
+                      <ForVarIterator varname="$$context-item"/>
+                    </AttributeAxisIterator>
+                  </FnDataIterator>
+                  <SingletonIterator value="xs:integer(1980)"/>
+                </CompareIterator>
+              </flwor::WhereIterator>
+              <CompareIterator>
+                <FnDataIterator>
+                  <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,file)" typename="*" nill allowed="0">
+                    <ForVarIterator varname="$$context-item"/>
+                  </AttributeAxisIterator>
+                </FnDataIterator>
+                <SingletonIterator value="xs:string(ic1980)"/>
+              </CompareIterator>
+            </flwor::WhereIterator>
+            <ForVarIterator varname="$$context-item"/>
+          </flwor::TupleStreamIterator>
+        </ChildAxisIterator>
+      </LetVariable>
+      <ForVariable name="i">
+        <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,inst)" typename="*" nill allowed="0">
+          <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,institutions)" typename="*" nill allowed="0">
+            <FnDocIterator>
+              <SingletonIterator value="xs:string(base.xml)"/>
+            </FnDocIterator>
+          </ChildAxisIterator>
+        </ChildAxisIterator>
+      </ForVariable>
+      <LetVariable name="unitid" materialize="true">
+        <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,unitid)" typename="*" nill allowed="0">
+          <ForVarIterator varname="i"/>
+        </AttributeAxisIterator>
+      </LetVariable>
+      <LetVariable name="$$opt_temp_1" materialize="true">
+        <HoistIterator>
+          <NodeSortIterator distinct="true" ascending="true">
+            <AttributeAxisIterator test kind="match_name_test" qname="*" typename="*" nill allowed="0">
               <flwor::FLWORIterator>
                 <ForVariable name="$$context-item">
-                  <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,ipeds)" typename="*" nill allowed="0">
-                    <ForVarIterator varname="$$context-item"/>
-                  </ChildAxisIterator>
+                  <LetVarIterator varname="y"/>
                 </ForVariable>
                 <WhereClause>
                   <CompareIterator>
                     <FnDataIterator>
-                      <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,year)" typename="*" nill allowed="0">
+                      <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,unitid)" typename="*" nill allowed="0">
                         <ForVarIterator varname="$$context-item"/>
                       </AttributeAxisIterator>
                     </FnDataIterator>
-                    <SingletonIterator value="xs:integer(1980)"/>
+                    <FnDataIterator>
+                      <LetVarIterator varname="unitid"/>
+                    </FnDataIterator>
                   </CompareIterator>
                 </WhereClause>
                 <ReturnClause>
                   <ForVarIterator varname="$$context-item"/>
                 </ReturnClause>
               </flwor::FLWORIterator>
-            </ForVariable>
-            <WhereClause>
-              <CompareIterator>
-                <FnDataIterator>
-                  <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,file)" typename="*" nill allowed="0">
-                    <ForVarIterator varname="$$context-item"/>
-                  </AttributeAxisIterator>
-                </FnDataIterator>
-                <SingletonIterator value="xs:string(ic1980)"/>
-              </CompareIterator>
-            </WhereClause>
-            <ReturnClause>
-              <ForVarIterator varname="$$context-item"/>
-            </ReturnClause>
-          </flwor::FLWORIterator>
-        </ChildAxisIterator>
+            </AttributeAxisIterator>
+          </NodeSortIterator>
+        </HoistIterator>
       </LetVariable>
       <ReturnClause>
-        <SequentialIterator>
-          <CreateInternalIndexIterator name="xs:QName(,,tempIndex0)">
+        <ElementIterator>
+          <SingletonIterator value="xs:QName(,,inst)"/>
+          <AttributeIterator qname="xs:QName(,,unitid)">
+            <EnclosedIterator attr_cont="true">
+              <FnDataIterator>
+                <LetVarIterator varname="unitid"/>
+              </FnDataIterator>
+            </EnclosedIterator>
+          </AttributeIterator>
+          <EnclosedIterator attr_cont="false">
             <flwor::FLWORIterator>
-              <ForVariable name="$$opt_temp_2">
-                <LetVarIterator varname="y"/>
+              <ForVariable name="j">
+                <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,year)" typename="*" nill allowed="0">
+                  <ForVarIterator varname="i"/>
+                </ChildAxisIterator>
+              </ForVariable>
+              <LetVariable name="year" materialize="true">
+                <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,name)" typename="*" nill allowed="0">
+                  <ForVarIterator varname="j"/>
+                </AttributeAxisIterator>
+              </LetVariable>
+              <ForVariable name="$$opt_temp_0">
+                <HoistIterator>
+                  <CompareIterator>
+                    <FnDataIterator>
+                      <LetVarIterator varname="year"/>
+                    </FnDataIterator>
+                    <SingletonIterator value="xs:integer(1980)"/>
+                  </CompareIterator>
+                </HoistIterator>
               </ForVariable>
               <ReturnClause>
-                <GeneralIndexEntryBuilderIterator>
-                  <ForVarIterator varname="$$opt_temp_2"/>
-                  <FnDataIterator>
-                    <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,unitid)" typename="*" nill allowed="0">
-                      <ForVarIterator varname="$$opt_temp_2"/>
-                    </AttributeAxisIterator>
-                  </FnDataIterator>
-                </GeneralIndexEntryBuilderIterator>
+                <ElementIterator>
+                  <SingletonIterator value="xs:QName(,,year)"/>
+                  <AttributeIterator qname="xs:QName(,,name)">
+                    <EnclosedIterator attr_cont="true">
+                      <FnDataIterator>
+                        <LetVarIterator varname="year"/>
+                      </FnDataIterator>
+                    </EnclosedIterator>
+                  </AttributeIterator>
+                  <EnclosedIterator attr_cont="false">
+                    <flwor::FLWORIterator>
+                      <ForVariable name="k">
+                        <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,file)" typename="*" nill allowed="0">
+                          <ForVarIterator varname="j"/>
+                        </ChildAxisIterator>
+                      </ForVariable>
+                      <LetVariable name="file" materialize="true">
+                        <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,name)" typename="*" nill allowed="0">
+                          <ForVarIterator varname="k"/>
+                        </AttributeAxisIterator>
+                      </LetVariable>
+                      <ReturnClause>
+                        <ElementIterator>
+                          <SingletonIterator value="xs:QName(,,file)"/>
+                          <AttributeIterator qname="xs:QName(,,name)">
+                            <EnclosedIterator attr_cont="true">
+                              <FnDataIterator>
+                                <LetVarIterator varname="file"/>
+                              </FnDataIterator>
+                            </EnclosedIterator>
+                          </AttributeIterator>
+                          <EnclosedIterator attr_cont="false">
+                            <IfThenElseIterator>
+                              <AndIterator>
+                                <UnhoistIterator>
+                                  <ForVarIterator varname="$$opt_temp_0"/>
+                                </UnhoistIterator>
+                                <CompareIterator>
+                                  <FnDataIterator>
+                                    <LetVarIterator varname="file"/>
+                                  </FnDataIterator>
+                                  <SingletonIterator value="xs:string(ic1980)"/>
+                                </CompareIterator>
+                              </AndIterator>
+                              <UnhoistIterator>
+                                <LetVarIterator varname="$$opt_temp_1"/>
+                              </UnhoistIterator>
+                              <FnConcatIterator/>
+                            </IfThenElseIterator>
+                          </EnclosedIterator>
+                        </ElementIterator>
+                      </ReturnClause>
+                    </flwor::FLWORIterator>
+                  </EnclosedIterator>
+                </ElementIterator>
               </ReturnClause>
             </flwor::FLWORIterator>
-          </CreateInternalIndexIterator>
-          <flwor::FLWORIterator>
-            <ForVariable name="i">
-              <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,inst)" typename="*" nill allowed="0">
-                <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,institutions)" typename="*" nill allowed="0">
-                  <FnDocIterator>
-                    <SingletonIterator value="xs:string(base.xml)"/>
-                  </FnDocIterator>
-                </ChildAxisIterator>
-              </ChildAxisIterator>
-            </ForVariable>
-            <LetVariable name="unitid" materialize="true">
-              <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,unitid)" typename="*" nill allowed="0">
-                <ForVarIterator varname="i"/>
-              </AttributeAxisIterator>
-            </LetVariable>
-            <LetVariable name="$$opt_temp_1" materialize="true">
-              <HoistIterator>
-                <AttributeAxisIterator test kind="match_name_test" qname="*" typename="*" nill allowed="0">
-                  <flwor::FLWORIterator>
-                    <ForVariable name="$$context-item">
-                      <NodeSortIterator distinct="true" ascending="true">
-                        <ProbeIndexPointGeneralIterator>
-                          <SingletonIterator value="xs:QName(,,tempIndex0)"/>
-                          <FnDataIterator>
-                            <LetVarIterator varname="unitid"/>
-                          </FnDataIterator>
-                        </ProbeIndexPointGeneralIterator>
-                      </NodeSortIterator>
-                    </ForVariable>
-                    <ReturnClause>
-                      <ForVarIterator varname="$$context-item"/>
-                    </ReturnClause>
-                  </flwor::FLWORIterator>
-                </AttributeAxisIterator>
-              </HoistIterator>
-            </LetVariable>
-            <ReturnClause>
-              <ElementIterator>
-                <SingletonIterator value="xs:QName(,,inst)"/>
-                <AttributeIterator qname="xs:QName(,,unitid)">
-                  <EnclosedIterator attr_cont="true">
-                    <FnDataIterator>
-                      <LetVarIterator varname="unitid"/>
-                    </FnDataIterator>
-                  </EnclosedIterator>
-                </AttributeIterator>
-                <EnclosedIterator attr_cont="false">
-                  <flwor::FLWORIterator>
-                    <ForVariable name="j">
-                      <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,year)" typename="*" nill allowed="0">
-                        <ForVarIterator varname="i"/>
-                      </ChildAxisIterator>
-                    </ForVariable>
-                    <LetVariable name="year" materialize="true">
-                      <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,name)" typename="*" nill allowed="0">
-                        <ForVarIterator varname="j"/>
-                      </AttributeAxisIterator>
-                    </LetVariable>
-                    <ForVariable name="$$opt_temp_0">
-                      <HoistIterator>
-                        <CompareIterator>
-                          <FnDataIterator>
-                            <LetVarIterator varname="year"/>
-                          </FnDataIterator>
-                          <SingletonIterator value="xs:integer(1980)"/>
-                        </CompareIterator>
-                      </HoistIterator>
-                    </ForVariable>
-                    <ReturnClause>
-                      <ElementIterator>
-                        <SingletonIterator value="xs:QName(,,year)"/>
-                        <AttributeIterator qname="xs:QName(,,name)">
-                          <EnclosedIterator attr_cont="true">
-                            <FnDataIterator>
-                              <LetVarIterator varname="year"/>
-                            </FnDataIterator>
-                          </EnclosedIterator>
-                        </AttributeIterator>
-                        <EnclosedIterator attr_cont="false">
-                          <flwor::FLWORIterator>
-                            <ForVariable name="k">
-                              <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,file)" typename="*" nill allowed="0">
-                                <ForVarIterator varname="j"/>
-                              </ChildAxisIterator>
-                            </ForVariable>
-                            <LetVariable name="file" materialize="true">
-                              <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,name)" typename="*" nill allowed="0">
-                                <ForVarIterator varname="k"/>
-                              </AttributeAxisIterator>
-                            </LetVariable>
-                            <ReturnClause>
-                              <ElementIterator>
-                                <SingletonIterator value="xs:QName(,,file)"/>
-                                <AttributeIterator qname="xs:QName(,,name)">
-                                  <EnclosedIterator attr_cont="true">
-                                    <FnDataIterator>
-                                      <LetVarIterator varname="file"/>
-                                    </FnDataIterator>
-                                  </EnclosedIterator>
-                                </AttributeIterator>
-                                <EnclosedIterator attr_cont="false">
-                                  <IfThenElseIterator>
-                                    <AndIterator>
-                                      <UnhoistIterator>
-                                        <ForVarIterator varname="$$opt_temp_0"/>
-                                      </UnhoistIterator>
-                                      <CompareIterator>
-                                        <FnDataIterator>
-                                          <LetVarIterator varname="file"/>
-                                        </FnDataIterator>
-                                        <SingletonIterator value="xs:string(ic1980)"/>
-                                      </CompareIterator>
-                                    </AndIterator>
-                                    <UnhoistIterator>
-                                      <LetVarIterator varname="$$opt_temp_1"/>
-                                    </UnhoistIterator>
-                                    <FnConcatIterator/>
-                                  </IfThenElseIterator>
-                                </EnclosedIterator>
-                              </ElementIterator>
-                            </ReturnClause>
-                          </flwor::FLWORIterator>
-                        </EnclosedIterator>
-                      </ElementIterator>
-                    </ReturnClause>
-                  </flwor::FLWORIterator>
-                </EnclosedIterator>
-              </ElementIterator>
-            </ReturnClause>
-          </flwor::FLWORIterator>
-        </SequentialIterator>
+          </EnclosedIterator>
+        </ElementIterator>
       </ReturnClause>
     </flwor::FLWORIterator>
   </EnclosedIterator>

=== added directory 'test/rbkt/ExpCompilerResults/IterPlan/zorba/index'
=== added file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_01.iter'
--- test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_01.iter	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_01.iter	2012-12-21 04:09:22 +0000
@@ -0,0 +1,125 @@
+Iterator tree for doc indexer:
+<flwor::FLWORIterator>
+  <ForVariable name="$$context-item">
+    <CtxVarIterator varid="1" varname="$$idx_doc_var" varkind="global"/>
+  </ForVariable>
+  <ReturnClause>
+    <ValueIndexEntryBuilderIterator>
+      <ForVarIterator varname="$$context-item"/>
+      <CastIterator type="xs:string">
+        <FnDataIterator>
+          <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,email)" typename="*" nill allowed="0">
+            <ForVarIterator varname="$$context-item"/>
+          </AttributeAxisIterator>
+        </FnDataIterator>
+      </CastIterator>
+    </ValueIndexEntryBuilderIterator>
+  </ReturnClause>
+</flwor::FLWORIterator>
+
+Iterator tree for index:
+<flwor::FLWORIterator>
+  <ForVariable name="$$context-item">
+    <ZorbaCollectionIterator>
+      <SingletonIterator value="xs:QName(www.accounts.com,accounts,accounts)"/>
+    </ZorbaCollectionIterator>
+  </ForVariable>
+  <ReturnClause>
+    <ValueIndexEntryBuilderIterator>
+      <ForVarIterator varname="$$context-item"/>
+      <CastIterator type="xs:string">
+        <FnDataIterator>
+          <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,email)" typename="*" nill allowed="0">
+            <ForVarIterator varname="$$context-item"/>
+          </AttributeAxisIterator>
+        </FnDataIterator>
+      </CastIterator>
+    </ValueIndexEntryBuilderIterator>
+  </ReturnClause>
+</flwor::FLWORIterator>
+
+Iterator tree for const-folded expr:
+<OrIterator>
+  <SingletonIterator value="xs:boolean(false)"/>
+  <SingletonIterator value="xs:boolean(false)"/>
+  <SingletonIterator value="xs:boolean(false)"/>
+</OrIterator>
+
+Iterator tree for const-folded expr:
+<LowerCaseIterator>
+  <SingletonIterator value="xs:string(George@xxxxxxxxx)"/>
+</LowerCaseIterator>
+
+Iterator tree for main query:
+<SequentialIterator>
+  <CtxVarDeclareIterator varid="4" varname="doc">
+    <ElementIterator>
+      <SingletonIterator value="xs:QName(,,accounts)"/>
+      <FnConcatIterator>
+        <ElementIterator>
+          <SingletonIterator value="xs:QName(,,account)"/>
+          <FnConcatIterator>
+            <AttributeIterator qname="xs:QName(,,name)">
+              <SingletonIterator value="xs:string(John)"/>
+            </AttributeIterator>
+            <AttributeIterator qname="xs:QName(,,email)">
+              <SingletonIterator value="xs:string(john@xxxxxxxxx)"/>
+            </AttributeIterator>
+          </FnConcatIterator>
+        </ElementIterator>
+        <ElementIterator>
+          <SingletonIterator value="xs:QName(,,account)"/>
+          <FnConcatIterator>
+            <AttributeIterator qname="xs:QName(,,name)">
+              <SingletonIterator value="xs:string(George)"/>
+            </AttributeIterator>
+            <AttributeIterator qname="xs:QName(,,email)">
+              <SingletonIterator value="xs:string(george@xxxxxxxxx)"/>
+            </AttributeIterator>
+          </FnConcatIterator>
+        </ElementIterator>
+      </FnConcatIterator>
+    </ElementIterator>
+  </CtxVarDeclareIterator>
+  <SequentialIterator>
+    <ApplyIterator>
+      <ZorbaCreateCollectionIterator>
+        <SingletonIterator value="xs:QName(www.accounts.com,accounts,accounts)"/>
+      </ZorbaCreateCollectionIterator>
+    </ApplyIterator>
+    <ApplyIterator>
+      <CreateIndexIterator>
+        <SingletonIterator value="xs:QName(www.accounts.com,accounts,accounts-index)"/>
+      </CreateIndexIterator>
+    </ApplyIterator>
+    <flwor::FLWORIterator>
+      <ForVariable name="acc">
+        <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,account)" typename="*" nill allowed="0">
+          <CtxVarIterator varid="4" varname="doc" varkind="global"/>
+        </ChildAxisIterator>
+      </ForVariable>
+      <MaterializeClause>
+        <MaterializeForVariable inputVar="acc : "/>
+      </MaterializeClause>
+      <ReturnClause>
+        <ApplyIterator>
+          <ZorbaInsertNodesIterator need-to-copy="true">
+            <SingletonIterator value="xs:QName(www.accounts.com,accounts,accounts)"/>
+            <ForVarIterator varname="acc"/>
+          </ZorbaInsertNodesIterator>
+        </ApplyIterator>
+      </ReturnClause>
+    </flwor::FLWORIterator>
+    <FnConcatIterator>
+      <FunctionTraceIterator>
+        <ProbeIndexPointValueIterator>
+          <SingletonIterator value="xs:QName(www.accounts.com,accounts,accounts-index)"/>
+          <SingletonIterator value="xs:string(george@xxxxxxxxx)"/>
+        </ProbeIndexPointValueIterator>
+      </FunctionTraceIterator>
+      <SingletonIterator value="xs:string(
+)"/>
+    </FnConcatIterator>
+  </SequentialIterator>
+</SequentialIterator>
+

=== added file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_02.iter'
--- test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_02.iter	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_02.iter	2012-12-21 04:09:22 +0000
@@ -0,0 +1,163 @@
+Iterator tree for doc indexer:
+<flwor::FLWORIterator>
+  <ForVariable name="$$context-item">
+    <CtxVarIterator varid="1" varname="$$idx_doc_var" varkind="global"/>
+  </ForVariable>
+  <ReturnClause>
+    <ValueIndexEntryBuilderIterator>
+      <ForVarIterator varname="$$context-item"/>
+      <CastIterator type="xs:string">
+        <FnDataIterator>
+          <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,id)" typename="*" nill allowed="0">
+            <ForVarIterator varname="$$context-item"/>
+          </AttributeAxisIterator>
+        </FnDataIterator>
+      </CastIterator>
+    </ValueIndexEntryBuilderIterator>
+  </ReturnClause>
+</flwor::FLWORIterator>
+
+Iterator tree for index:
+<flwor::FLWORIterator>
+  <ForVariable name="$$context-item">
+    <ZorbaCollectionIterator>
+      <SingletonIterator value="xs:QName(www.sessions.com,sessions,sessions)"/>
+    </ZorbaCollectionIterator>
+  </ForVariable>
+  <ReturnClause>
+    <ValueIndexEntryBuilderIterator>
+      <ForVarIterator varname="$$context-item"/>
+      <CastIterator type="xs:string">
+        <FnDataIterator>
+          <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,id)" typename="*" nill allowed="0">
+            <ForVarIterator varname="$$context-item"/>
+          </AttributeAxisIterator>
+        </FnDataIterator>
+      </CastIterator>
+    </ValueIndexEntryBuilderIterator>
+  </ReturnClause>
+</flwor::FLWORIterator>
+
+Iterator tree for main query:
+<SequentialIterator>
+  <CtxVarDeclareIterator varid="4" varname="sessions:sessions">
+    <SingletonIterator value="xs:QName(www.sessions.com,sessions,sessions)"/>
+  </CtxVarDeclareIterator>
+  <CtxVarDeclareIterator varid="5" varname="external_id">
+    <SingletonIterator value="xs:string(50)"/>
+  </CtxVarDeclareIterator>
+  <CtxVarDeclareIterator varid="6" varname="doc">
+    <ElementIterator>
+      <SingletonIterator value="xs:QName(,,sessions)"/>
+      <FnConcatIterator>
+        <ElementIterator>
+          <SingletonIterator value="xs:QName(,,session)"/>
+          <AttributeIterator qname="xs:QName(,,id)">
+            <SingletonIterator value="xs:string(50)"/>
+          </AttributeIterator>
+          <ElementIterator>
+            <SingletonIterator value="xs:QName(,,data)"/>
+            <TextIterator>
+              <SingletonIterator value="xs:string(1111111111)"/>
+            </TextIterator>
+          </ElementIterator>
+        </ElementIterator>
+        <ElementIterator>
+          <SingletonIterator value="xs:QName(,,session)"/>
+          <AttributeIterator qname="xs:QName(,,id)">
+            <SingletonIterator value="xs:string(12)"/>
+          </AttributeIterator>
+          <ElementIterator>
+            <SingletonIterator value="xs:QName(,,data)"/>
+            <TextIterator>
+              <SingletonIterator value="xs:string(2222222222)"/>
+            </TextIterator>
+          </ElementIterator>
+        </ElementIterator>
+        <ElementIterator>
+          <SingletonIterator value="xs:QName(,,session)"/>
+          <AttributeIterator qname="xs:QName(,,id)">
+            <SingletonIterator value="xs:string(50)"/>
+          </AttributeIterator>
+          <ElementIterator>
+            <SingletonIterator value="xs:QName(,,data)"/>
+            <TextIterator>
+              <SingletonIterator value="xs:string(3333333333)"/>
+            </TextIterator>
+          </ElementIterator>
+        </ElementIterator>
+      </FnConcatIterator>
+    </ElementIterator>
+  </CtxVarDeclareIterator>
+  <SequentialIterator>
+    <ApplyIterator>
+      <ZorbaCreateCollectionIterator>
+        <CtxVarIterator varid="4" varname="sessions:sessions" varkind="global"/>
+      </ZorbaCreateCollectionIterator>
+    </ApplyIterator>
+    <ApplyIterator>
+      <CreateIndexIterator>
+        <SingletonIterator value="xs:QName(www.sessions.com,s,session-index)"/>
+      </CreateIndexIterator>
+    </ApplyIterator>
+    <flwor::FLWORIterator>
+      <ForVariable name="s">
+        <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,session)" typename="*" nill allowed="0">
+          <CtxVarIterator varid="6" varname="doc" varkind="global"/>
+        </ChildAxisIterator>
+      </ForVariable>
+      <MaterializeClause>
+        <MaterializeForVariable inputVar="s : "/>
+      </MaterializeClause>
+      <ReturnClause>
+        <ApplyIterator>
+          <ZorbaInsertNodesIterator need-to-copy="true">
+            <CtxVarIterator varid="4" varname="sessions:sessions" varkind="global"/>
+            <ForVarIterator varname="s"/>
+          </ZorbaInsertNodesIterator>
+        </ApplyIterator>
+      </ReturnClause>
+    </flwor::FLWORIterator>
+    <FnConcatIterator>
+      <flwor::FLWORIterator>
+        <LetVariable name="id" materialize="true">
+          <CtxVarIterator varid="5" varname="external_id" varkind="global"/>
+        </LetVariable>
+        <LetVariable name="session" materialize="true">
+          <flwor::FLWORIterator>
+            <ForVariable name="session">
+              <ProbeIndexPointValueIterator>
+                <SingletonIterator value="xs:QName(www.sessions.com,sessions,session-index)"/>
+                <PromoteIterator type="xs:anyAtomicType">
+                  <FnDataIterator>
+                    <LetVarIterator varname="id"/>
+                  </FnDataIterator>
+                </PromoteIterator>
+              </ProbeIndexPointValueIterator>
+            </ForVariable>
+            <ReturnClause>
+              <ForVarIterator varname="session"/>
+            </ReturnClause>
+          </flwor::FLWORIterator>
+        </LetVariable>
+        <ReturnClause>
+          <IfThenElseIterator>
+            <FnEmptyIterator>
+              <LetVarIterator varname="session"/>
+            </FnEmptyIterator>
+            <TraceIterator>
+              <LetVarIterator varname="id"/>
+              <SingletonIterator value="xs:string(no session with the given uuid)"/>
+            </TraceIterator>
+            <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,data)" typename="*" nill allowed="0">
+              <LetVarIterator varname="session"/>
+            </ChildAxisIterator>
+          </IfThenElseIterator>
+        </ReturnClause>
+      </flwor::FLWORIterator>
+      <SingletonIterator value="xs:string(
+)"/>
+    </FnConcatIterator>
+  </SequentialIterator>
+</SequentialIterator>
+

=== added file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_03.iter'
--- test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_03.iter	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_03.iter	2012-12-21 04:09:22 +0000
@@ -0,0 +1,163 @@
+Iterator tree for doc indexer:
+<flwor::FLWORIterator>
+  <ForVariable name="$$context-item">
+    <CtxVarIterator varid="1" varname="$$idx_doc_var" varkind="global"/>
+  </ForVariable>
+  <ReturnClause>
+    <ValueIndexEntryBuilderIterator>
+      <ForVarIterator varname="$$context-item"/>
+      <CastIterator type="xs:string">
+        <FnDataIterator>
+          <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,id)" typename="*" nill allowed="0">
+            <ForVarIterator varname="$$context-item"/>
+          </AttributeAxisIterator>
+        </FnDataIterator>
+      </CastIterator>
+    </ValueIndexEntryBuilderIterator>
+  </ReturnClause>
+</flwor::FLWORIterator>
+
+Iterator tree for index:
+<flwor::FLWORIterator>
+  <ForVariable name="$$context-item">
+    <ZorbaCollectionIterator>
+      <SingletonIterator value="xs:QName(www.sessions.com,sessions,sessions)"/>
+    </ZorbaCollectionIterator>
+  </ForVariable>
+  <ReturnClause>
+    <ValueIndexEntryBuilderIterator>
+      <ForVarIterator varname="$$context-item"/>
+      <CastIterator type="xs:string">
+        <FnDataIterator>
+          <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,id)" typename="*" nill allowed="0">
+            <ForVarIterator varname="$$context-item"/>
+          </AttributeAxisIterator>
+        </FnDataIterator>
+      </CastIterator>
+    </ValueIndexEntryBuilderIterator>
+  </ReturnClause>
+</flwor::FLWORIterator>
+
+Iterator tree for main query:
+<SequentialIterator>
+  <CtxVarDeclareIterator varid="4" varname="sessions:sessions">
+    <SingletonIterator value="xs:QName(www.sessions.com,sessions,sessions)"/>
+  </CtxVarDeclareIterator>
+  <CtxVarDeclareIterator varid="5" varname="external_id">
+    <SingletonIterator value="xs:string(50)"/>
+  </CtxVarDeclareIterator>
+  <CtxVarDeclareIterator varid="6" varname="doc">
+    <ElementIterator>
+      <SingletonIterator value="xs:QName(,,sessions)"/>
+      <FnConcatIterator>
+        <ElementIterator>
+          <SingletonIterator value="xs:QName(,,session)"/>
+          <AttributeIterator qname="xs:QName(,,id)">
+            <SingletonIterator value="xs:string(50)"/>
+          </AttributeIterator>
+          <ElementIterator>
+            <SingletonIterator value="xs:QName(,,data)"/>
+            <TextIterator>
+              <SingletonIterator value="xs:string(1111111111)"/>
+            </TextIterator>
+          </ElementIterator>
+        </ElementIterator>
+        <ElementIterator>
+          <SingletonIterator value="xs:QName(,,session)"/>
+          <AttributeIterator qname="xs:QName(,,id)">
+            <SingletonIterator value="xs:string(12)"/>
+          </AttributeIterator>
+          <ElementIterator>
+            <SingletonIterator value="xs:QName(,,data)"/>
+            <TextIterator>
+              <SingletonIterator value="xs:string(2222222222)"/>
+            </TextIterator>
+          </ElementIterator>
+        </ElementIterator>
+        <ElementIterator>
+          <SingletonIterator value="xs:QName(,,session)"/>
+          <AttributeIterator qname="xs:QName(,,id)">
+            <SingletonIterator value="xs:string(50)"/>
+          </AttributeIterator>
+          <ElementIterator>
+            <SingletonIterator value="xs:QName(,,data)"/>
+            <TextIterator>
+              <SingletonIterator value="xs:string(3333333333)"/>
+            </TextIterator>
+          </ElementIterator>
+        </ElementIterator>
+      </FnConcatIterator>
+    </ElementIterator>
+  </CtxVarDeclareIterator>
+  <SequentialIterator>
+    <ApplyIterator>
+      <ZorbaCreateCollectionIterator>
+        <CtxVarIterator varid="4" varname="sessions:sessions" varkind="global"/>
+      </ZorbaCreateCollectionIterator>
+    </ApplyIterator>
+    <ApplyIterator>
+      <CreateIndexIterator>
+        <SingletonIterator value="xs:QName(www.sessions.com,s,session-index)"/>
+      </CreateIndexIterator>
+    </ApplyIterator>
+    <flwor::FLWORIterator>
+      <ForVariable name="s">
+        <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,session)" typename="*" nill allowed="0">
+          <CtxVarIterator varid="6" varname="doc" varkind="global"/>
+        </ChildAxisIterator>
+      </ForVariable>
+      <MaterializeClause>
+        <MaterializeForVariable inputVar="s : "/>
+      </MaterializeClause>
+      <ReturnClause>
+        <ApplyIterator>
+          <ZorbaInsertNodesIterator need-to-copy="true">
+            <CtxVarIterator varid="4" varname="sessions:sessions" varkind="global"/>
+            <ForVarIterator varname="s"/>
+          </ZorbaInsertNodesIterator>
+        </ApplyIterator>
+      </ReturnClause>
+    </flwor::FLWORIterator>
+    <FnConcatIterator>
+      <flwor::FLWORIterator>
+        <LetVariable name="id" materialize="true">
+          <CtxVarIterator varid="5" varname="external_id" varkind="global"/>
+        </LetVariable>
+        <LetVariable name="session" materialize="true">
+          <flwor::FLWORIterator>
+            <ForVariable name="session">
+              <ProbeIndexPointValueIterator>
+                <SingletonIterator value="xs:QName(www.sessions.com,sessions,session-index)"/>
+                <PromoteIterator type="xs:anyAtomicType">
+                  <FnDataIterator>
+                    <LetVarIterator varname="id"/>
+                  </FnDataIterator>
+                </PromoteIterator>
+              </ProbeIndexPointValueIterator>
+            </ForVariable>
+            <ReturnClause>
+              <ForVarIterator varname="session"/>
+            </ReturnClause>
+          </flwor::FLWORIterator>
+        </LetVariable>
+        <ReturnClause>
+          <IfThenElseIterator>
+            <FnEmptyIterator>
+              <LetVarIterator varname="session"/>
+            </FnEmptyIterator>
+            <TraceIterator>
+              <LetVarIterator varname="id"/>
+              <SingletonIterator value="xs:string(no session with the given uuid)"/>
+            </TraceIterator>
+            <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,data)" typename="*" nill allowed="0">
+              <LetVarIterator varname="session"/>
+            </ChildAxisIterator>
+          </IfThenElseIterator>
+        </ReturnClause>
+      </flwor::FLWORIterator>
+      <SingletonIterator value="xs:string(
+)"/>
+    </FnConcatIterator>
+  </SequentialIterator>
+</SequentialIterator>
+

=== added file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_04.iter'
--- test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_04.iter	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_04.iter	2012-12-21 04:09:22 +0000
@@ -0,0 +1,228 @@
+Iterator tree for const-folded expr:
+<OrIterator>
+  <SingletonIterator value="xs:boolean(false)"/>
+  <SingletonIterator value="xs:boolean(false)"/>
+  <SingletonIterator value="xs:boolean(false)"/>
+</OrIterator>
+
+Iterator tree for doc indexer:
+<flwor::FLWORIterator>
+  <ForVariable name="$$context-item">
+    <flwor::FLWORIterator>
+      <ForVariable name="$$context-item">
+        <CtxVarIterator varid="1" varname="$$idx_doc_var" varkind="global"/>
+      </ForVariable>
+      <WhereClause>
+        <CompareIterator>
+          <FnDataIterator>
+            <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,duration)" typename="*" nill allowed="0">
+              <ForVarIterator varname="$$context-item"/>
+            </AttributeAxisIterator>
+          </FnDataIterator>
+          <SingletonIterator value="xs:integer(120)"/>
+        </CompareIterator>
+      </WhereClause>
+      <ReturnClause>
+        <ForVarIterator varname="$$context-item"/>
+      </ReturnClause>
+    </flwor::FLWORIterator>
+  </ForVariable>
+  <ReturnClause>
+    <ValueIndexEntryBuilderIterator>
+      <ForVarIterator varname="$$context-item"/>
+      <CastIterator type="xs:string">
+        <FnDataIterator>
+          <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,id)" typename="*" nill allowed="0">
+            <ForVarIterator varname="$$context-item"/>
+          </AttributeAxisIterator>
+        </FnDataIterator>
+      </CastIterator>
+    </ValueIndexEntryBuilderIterator>
+  </ReturnClause>
+</flwor::FLWORIterator>
+
+Iterator tree for index:
+<flwor::FLWORIterator>
+  <ForVariable name="$$context-item">
+    <flwor::FLWORIterator>
+      <ForVariable name="$$context-item">
+        <ZorbaCollectionIterator>
+          <SingletonIterator value="xs:QName(www.sessions.com,sessions,sessions)"/>
+        </ZorbaCollectionIterator>
+      </ForVariable>
+      <WhereClause>
+        <CompareIterator>
+          <FnDataIterator>
+            <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,duration)" typename="*" nill allowed="0">
+              <ForVarIterator varname="$$context-item"/>
+            </AttributeAxisIterator>
+          </FnDataIterator>
+          <SingletonIterator value="xs:integer(120)"/>
+        </CompareIterator>
+      </WhereClause>
+      <ReturnClause>
+        <ForVarIterator varname="$$context-item"/>
+      </ReturnClause>
+    </flwor::FLWORIterator>
+  </ForVariable>
+  <ReturnClause>
+    <ValueIndexEntryBuilderIterator>
+      <ForVarIterator varname="$$context-item"/>
+      <CastIterator type="xs:string">
+        <FnDataIterator>
+          <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,id)" typename="*" nill allowed="0">
+            <ForVarIterator varname="$$context-item"/>
+          </AttributeAxisIterator>
+        </FnDataIterator>
+      </CastIterator>
+    </ValueIndexEntryBuilderIterator>
+  </ReturnClause>
+</flwor::FLWORIterator>
+
+Iterator tree for const-folded expr:
+<OrIterator>
+  <SingletonIterator value="xs:boolean(false)"/>
+  <SingletonIterator value="xs:boolean(false)"/>
+  <SingletonIterator value="xs:boolean(false)"/>
+</OrIterator>
+
+Iterator tree for main query:
+<SequentialIterator>
+  <CtxVarDeclareIterator varid="4" varname="sessions:sessions">
+    <SingletonIterator value="xs:QName(www.sessions.com,sessions,sessions)"/>
+  </CtxVarDeclareIterator>
+  <CtxVarDeclareIterator varid="5" varname="external_id">
+    <SingletonIterator value="xs:string(50)"/>
+  </CtxVarDeclareIterator>
+  <CtxVarDeclareIterator varid="6" varname="doc">
+    <ElementIterator>
+      <SingletonIterator value="xs:QName(,,sessions)"/>
+      <FnConcatIterator>
+        <ElementIterator>
+          <SingletonIterator value="xs:QName(,,session)"/>
+          <FnConcatIterator>
+            <AttributeIterator qname="xs:QName(,,id)">
+              <SingletonIterator value="xs:string(50)"/>
+            </AttributeIterator>
+            <AttributeIterator qname="xs:QName(,,duration)">
+              <SingletonIterator value="xs:string(130)"/>
+            </AttributeIterator>
+          </FnConcatIterator>
+          <ElementIterator>
+            <SingletonIterator value="xs:QName(,,data)"/>
+            <TextIterator>
+              <SingletonIterator value="xs:string(1111111111)"/>
+            </TextIterator>
+          </ElementIterator>
+        </ElementIterator>
+        <ElementIterator>
+          <SingletonIterator value="xs:QName(,,session)"/>
+          <FnConcatIterator>
+            <AttributeIterator qname="xs:QName(,,id)">
+              <SingletonIterator value="xs:string(12)"/>
+            </AttributeIterator>
+            <AttributeIterator qname="xs:QName(,,duration)">
+              <SingletonIterator value="xs:string(30)"/>
+            </AttributeIterator>
+          </FnConcatIterator>
+          <ElementIterator>
+            <SingletonIterator value="xs:QName(,,data)"/>
+            <TextIterator>
+              <SingletonIterator value="xs:string(2222222222)"/>
+            </TextIterator>
+          </ElementIterator>
+        </ElementIterator>
+        <ElementIterator>
+          <SingletonIterator value="xs:QName(,,session)"/>
+          <FnConcatIterator>
+            <AttributeIterator qname="xs:QName(,,id)">
+              <SingletonIterator value="xs:string(50)"/>
+            </AttributeIterator>
+            <AttributeIterator qname="xs:QName(,,duration)">
+              <SingletonIterator value="xs:string(150)"/>
+            </AttributeIterator>
+          </FnConcatIterator>
+          <ElementIterator>
+            <SingletonIterator value="xs:QName(,,data)"/>
+            <TextIterator>
+              <SingletonIterator value="xs:string(3333333333)"/>
+            </TextIterator>
+          </ElementIterator>
+        </ElementIterator>
+      </FnConcatIterator>
+    </ElementIterator>
+  </CtxVarDeclareIterator>
+  <SequentialIterator>
+    <ApplyIterator>
+      <ZorbaCreateCollectionIterator>
+        <CtxVarIterator varid="4" varname="sessions:sessions" varkind="global"/>
+      </ZorbaCreateCollectionIterator>
+    </ApplyIterator>
+    <ApplyIterator>
+      <CreateIndexIterator>
+        <SingletonIterator value="xs:QName(www.sessions.com,s,session-index)"/>
+      </CreateIndexIterator>
+    </ApplyIterator>
+    <flwor::FLWORIterator>
+      <ForVariable name="s">
+        <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,session)" typename="*" nill allowed="0">
+          <CtxVarIterator varid="6" varname="doc" varkind="global"/>
+        </ChildAxisIterator>
+      </ForVariable>
+      <MaterializeClause>
+        <MaterializeForVariable inputVar="s : "/>
+      </MaterializeClause>
+      <ReturnClause>
+        <ApplyIterator>
+          <ZorbaInsertNodesIterator need-to-copy="true">
+            <CtxVarIterator varid="4" varname="sessions:sessions" varkind="global"/>
+            <ForVarIterator varname="s"/>
+          </ZorbaInsertNodesIterator>
+        </ApplyIterator>
+      </ReturnClause>
+    </flwor::FLWORIterator>
+    <FnConcatIterator>
+      <flwor::FLWORIterator>
+        <LetVariable name="id" materialize="true">
+          <CtxVarIterator varid="5" varname="external_id" varkind="global"/>
+        </LetVariable>
+        <LetVariable name="session" materialize="true">
+          <flwor::TupleStreamIterator>
+            <flwor::ForIterator>
+              <ForVariable name="$$context-item"/>
+              <flwor::TupleSourceIterator/>
+              <ProbeIndexPointValueIterator>
+                <SingletonIterator value="xs:QName(www.sessions.com,sessions,session-index)"/>
+                <PromoteIterator type="xs:anyAtomicType">
+                  <FnDataIterator>
+                    <LetVarIterator varname="id"/>
+                  </FnDataIterator>
+                </PromoteIterator>
+              </ProbeIndexPointValueIterator>
+            </flwor::ForIterator>
+            <ForVarIterator varname="$$context-item"/>
+          </flwor::TupleStreamIterator>
+        </LetVariable>
+        <ReturnClause>
+          <IfThenElseIterator>
+            <FnEmptyIterator>
+              <LetVarIterator varname="session"/>
+            </FnEmptyIterator>
+            <TraceIterator>
+              <LetVarIterator varname="id"/>
+              <SingletonIterator value="xs:string(no session with the given uuid)"/>
+            </TraceIterator>
+            <NodeSortIterator distinct="true" ascending="true">
+              <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,data)" typename="*" nill allowed="0">
+                <LetVarIterator varname="session"/>
+              </ChildAxisIterator>
+            </NodeSortIterator>
+          </IfThenElseIterator>
+        </ReturnClause>
+      </flwor::FLWORIterator>
+      <SingletonIterator value="xs:string(
+)"/>
+    </FnConcatIterator>
+  </SequentialIterator>
+</SequentialIterator>
+

=== added file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_05.iter'
--- test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_05.iter	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_05.iter	2012-12-21 04:09:22 +0000
@@ -0,0 +1,315 @@
+Iterator tree for const-folded expr:
+<OrIterator>
+  <SingletonIterator value="xs:boolean(false)"/>
+  <SingletonIterator value="xs:boolean(false)"/>
+  <SingletonIterator value="xs:boolean(false)"/>
+</OrIterator>
+
+Iterator tree for doc indexer:
+<flwor::FLWORIterator>
+  <ForVariable name="$$context-item">
+    <flwor::FLWORIterator>
+      <ForVariable name="$$context-item">
+        <CtxVarIterator varid="1" varname="$$idx_doc_var" varkind="global"/>
+      </ForVariable>
+      <WhereClause>
+        <CompareIterator>
+          <FnDataIterator>
+            <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,duration)" typename="*" nill allowed="0">
+              <ForVarIterator varname="$$context-item"/>
+            </AttributeAxisIterator>
+          </FnDataIterator>
+          <SingletonIterator value="xs:integer(120)"/>
+        </CompareIterator>
+      </WhereClause>
+      <ReturnClause>
+        <ForVarIterator varname="$$context-item"/>
+      </ReturnClause>
+    </flwor::FLWORIterator>
+  </ForVariable>
+  <ReturnClause>
+    <ValueIndexEntryBuilderIterator>
+      <ForVarIterator varname="$$context-item"/>
+      <PromoteIterator type="xs:string">
+        <FnDataIterator>
+          <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,id)" typename="*" nill allowed="0">
+            <ForVarIterator varname="$$context-item"/>
+          </AttributeAxisIterator>
+        </FnDataIterator>
+      </PromoteIterator>
+    </ValueIndexEntryBuilderIterator>
+  </ReturnClause>
+</flwor::FLWORIterator>
+
+Iterator tree for index:
+<flwor::FLWORIterator>
+  <ForVariable name="$$context-item">
+    <flwor::FLWORIterator>
+      <ForVariable name="$$context-item">
+        <ZorbaCollectionIterator>
+          <SingletonIterator value="xs:QName(www.sessions.com,sessions,sessions)"/>
+        </ZorbaCollectionIterator>
+      </ForVariable>
+      <WhereClause>
+        <CompareIterator>
+          <FnDataIterator>
+            <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,duration)" typename="*" nill allowed="0">
+              <ForVarIterator varname="$$context-item"/>
+            </AttributeAxisIterator>
+          </FnDataIterator>
+          <SingletonIterator value="xs:integer(120)"/>
+        </CompareIterator>
+      </WhereClause>
+      <ReturnClause>
+        <ForVarIterator varname="$$context-item"/>
+      </ReturnClause>
+    </flwor::FLWORIterator>
+  </ForVariable>
+  <ReturnClause>
+    <ValueIndexEntryBuilderIterator>
+      <ForVarIterator varname="$$context-item"/>
+      <PromoteIterator type="xs:string">
+        <FnDataIterator>
+          <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,id)" typename="*" nill allowed="0">
+            <ForVarIterator varname="$$context-item"/>
+          </AttributeAxisIterator>
+        </FnDataIterator>
+      </PromoteIterator>
+    </ValueIndexEntryBuilderIterator>
+  </ReturnClause>
+</flwor::FLWORIterator>
+
+Iterator tree for const-folded expr:
+<OrIterator>
+  <SingletonIterator value="xs:boolean(false)"/>
+  <SingletonIterator value="xs:boolean(false)"/>
+  <SingletonIterator value="xs:boolean(false)"/>
+</OrIterator>
+
+Iterator tree for main query:
+<SequentialIterator>
+  <CtxVarDeclareIterator varid="4" varname="sessions:sessions">
+    <SingletonIterator value="xs:QName(www.sessions.com,sessions,sessions)"/>
+  </CtxVarDeclareIterator>
+  <CtxVarDeclareIterator varid="5" varname="external_id">
+    <SingletonIterator value="xs:string(50)"/>
+  </CtxVarDeclareIterator>
+  <CtxVarDeclareIterator varid="6" varname="doc">
+    <ElementIterator>
+      <SingletonIterator value="xs:QName(,,sessions)"/>
+      <FnConcatIterator>
+        <ElementIterator>
+          <SingletonIterator value="xs:QName(,,session)"/>
+          <FnConcatIterator>
+            <AttributeIterator qname="xs:QName(,,id)">
+              <SingletonIterator value="xs:string(50)"/>
+            </AttributeIterator>
+            <AttributeIterator qname="xs:QName(,,duration)">
+              <SingletonIterator value="xs:string(130)"/>
+            </AttributeIterator>
+          </FnConcatIterator>
+          <ElementIterator>
+            <SingletonIterator value="xs:QName(,,data)"/>
+            <TextIterator>
+              <SingletonIterator value="xs:string(1111111111)"/>
+            </TextIterator>
+          </ElementIterator>
+        </ElementIterator>
+        <ElementIterator>
+          <SingletonIterator value="xs:QName(,,session)"/>
+          <FnConcatIterator>
+            <AttributeIterator qname="xs:QName(,,id)">
+              <SingletonIterator value="xs:string(12)"/>
+            </AttributeIterator>
+            <AttributeIterator qname="xs:QName(,,duration)">
+              <SingletonIterator value="xs:string(30)"/>
+            </AttributeIterator>
+          </FnConcatIterator>
+          <ElementIterator>
+            <SingletonIterator value="xs:QName(,,data)"/>
+            <TextIterator>
+              <SingletonIterator value="xs:string(2222222222)"/>
+            </TextIterator>
+          </ElementIterator>
+        </ElementIterator>
+        <ElementIterator>
+          <SingletonIterator value="xs:QName(,,session)"/>
+          <FnConcatIterator>
+            <AttributeIterator qname="xs:QName(,,id)">
+              <SingletonIterator value="xs:string(50)"/>
+            </AttributeIterator>
+            <AttributeIterator qname="xs:QName(,,duration)">
+              <SingletonIterator value="xs:string(150)"/>
+            </AttributeIterator>
+          </FnConcatIterator>
+          <ElementIterator>
+            <SingletonIterator value="xs:QName(,,data)"/>
+            <TextIterator>
+              <SingletonIterator value="xs:string(3333333333)"/>
+            </TextIterator>
+          </ElementIterator>
+        </ElementIterator>
+      </FnConcatIterator>
+    </ElementIterator>
+  </CtxVarDeclareIterator>
+  <CtxVarDeclareIterator varid="7" varname="doc2">
+    <ElementIterator>
+      <SingletonIterator value="xs:QName(,,sessions)"/>
+      <FnConcatIterator>
+        <ElementIterator>
+          <SingletonIterator value="xs:QName(,,session)"/>
+          <FnConcatIterator>
+            <AttributeIterator qname="xs:QName(,,id)">
+              <SingletonIterator value="xs:string(50)"/>
+            </AttributeIterator>
+            <AttributeIterator qname="xs:QName(,,duration)">
+              <SingletonIterator value="xs:string(130)"/>
+            </AttributeIterator>
+          </FnConcatIterator>
+          <ElementIterator>
+            <SingletonIterator value="xs:QName(,,data)"/>
+            <TextIterator>
+              <SingletonIterator value="xs:string(6666666)"/>
+            </TextIterator>
+          </ElementIterator>
+        </ElementIterator>
+        <ElementIterator>
+          <SingletonIterator value="xs:QName(,,session)"/>
+          <FnConcatIterator>
+            <AttributeIterator qname="xs:QName(,,id)">
+              <SingletonIterator value="xs:string(70)"/>
+            </AttributeIterator>
+            <AttributeIterator qname="xs:QName(,,duration)">
+              <SingletonIterator value="xs:string(150)"/>
+            </AttributeIterator>
+          </FnConcatIterator>
+          <ElementIterator>
+            <SingletonIterator value="xs:QName(,,data)"/>
+            <TextIterator>
+              <SingletonIterator value="xs:string(7777777)"/>
+            </TextIterator>
+          </ElementIterator>
+        </ElementIterator>
+      </FnConcatIterator>
+    </ElementIterator>
+  </CtxVarDeclareIterator>
+  <SequentialIterator>
+    <ApplyIterator>
+      <ZorbaCreateCollectionIterator>
+        <CtxVarIterator varid="4" varname="sessions:sessions" varkind="global"/>
+      </ZorbaCreateCollectionIterator>
+    </ApplyIterator>
+    <ApplyIterator>
+      <CreateIndexIterator>
+        <SingletonIterator value="xs:QName(www.sessions.com,s,session-index)"/>
+      </CreateIndexIterator>
+    </ApplyIterator>
+    <flwor::FLWORIterator>
+      <ForVariable name="s">
+        <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,session)" typename="*" nill allowed="0">
+          <CtxVarIterator varid="6" varname="doc" varkind="global"/>
+        </ChildAxisIterator>
+      </ForVariable>
+      <MaterializeClause>
+        <MaterializeForVariable inputVar="s : "/>
+      </MaterializeClause>
+      <ReturnClause>
+        <ApplyIterator>
+          <ZorbaInsertNodesIterator need-to-copy="true">
+            <CtxVarIterator varid="4" varname="sessions:sessions" varkind="global"/>
+            <ForVarIterator varname="s"/>
+          </ZorbaInsertNodesIterator>
+        </ApplyIterator>
+      </ReturnClause>
+    </flwor::FLWORIterator>
+    <flwor::FLWORIterator>
+      <ForVariable name="s">
+        <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,session)" typename="*" nill allowed="0">
+          <CtxVarIterator varid="7" varname="doc2" varkind="global"/>
+        </ChildAxisIterator>
+      </ForVariable>
+      <MaterializeClause>
+        <MaterializeForVariable inputVar="s : "/>
+      </MaterializeClause>
+      <ReturnClause>
+        <ApplyIterator>
+          <ZorbaInsertNodesFirstIterator need-to-copy="true">
+            <CtxVarIterator varid="4" varname="sessions:sessions" varkind="global"/>
+            <ForVarIterator varname="s"/>
+          </ZorbaInsertNodesFirstIterator>
+        </ApplyIterator>
+      </ReturnClause>
+    </flwor::FLWORIterator>
+    <flwor::FLWORIterator>
+      <ForVariable name="s">
+        <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,session)" typename="*" nill allowed="0">
+          <CtxVarIterator varid="7" varname="doc2" varkind="global"/>
+        </ChildAxisIterator>
+      </ForVariable>
+      <MaterializeClause>
+        <MaterializeForVariable inputVar="s : "/>
+      </MaterializeClause>
+      <ReturnClause>
+        <ApplyIterator>
+          <ZorbaInsertNodesLastIterator need-to-copy="true">
+            <CtxVarIterator varid="4" varname="sessions:sessions" varkind="global"/>
+            <ForVarIterator varname="s"/>
+          </ZorbaInsertNodesLastIterator>
+        </ApplyIterator>
+      </ReturnClause>
+    </flwor::FLWORIterator>
+    <FnConcatIterator>
+      <flwor::FLWORIterator>
+        <LetVariable name="id" materialize="true">
+          <CtxVarIterator varid="5" varname="external_id" varkind="global"/>
+        </LetVariable>
+        <LetVariable name="session" materialize="true">
+          <flwor::TupleStreamIterator>
+            <flwor::WhereIterator>
+              <flwor::ForIterator>
+                <ForVariable name="$$context-item"/>
+                <flwor::TupleSourceIterator/>
+                <ProbeIndexPointValueIterator>
+                  <SingletonIterator value="xs:QName(www.sessions.com,sessions,session-index)"/>
+                  <PromoteIterator type="xs:anyAtomicType">
+                    <FnDataIterator>
+                      <LetVarIterator varname="id"/>
+                    </FnDataIterator>
+                  </PromoteIterator>
+                </ProbeIndexPointValueIterator>
+              </flwor::ForIterator>
+              <CompareIterator>
+                <FnDataIterator>
+                  <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,duration)" typename="*" nill allowed="0">
+                    <ForVarIterator varname="$$context-item"/>
+                  </AttributeAxisIterator>
+                </FnDataIterator>
+                <SingletonIterator value="xs:integer(150)"/>
+              </CompareIterator>
+            </flwor::WhereIterator>
+            <ForVarIterator varname="$$context-item"/>
+          </flwor::TupleStreamIterator>
+        </LetVariable>
+        <ReturnClause>
+          <IfThenElseIterator>
+            <FnEmptyIterator>
+              <LetVarIterator varname="session"/>
+            </FnEmptyIterator>
+            <TraceIterator>
+              <LetVarIterator varname="id"/>
+              <SingletonIterator value="xs:string(no session with the given uuid)"/>
+            </TraceIterator>
+            <NodeSortIterator distinct="true" ascending="true">
+              <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,data)" typename="*" nill allowed="0">
+                <LetVarIterator varname="session"/>
+              </ChildAxisIterator>
+            </NodeSortIterator>
+          </IfThenElseIterator>
+        </ReturnClause>
+      </flwor::FLWORIterator>
+      <SingletonIterator value="xs:string(
+)"/>
+    </FnConcatIterator>
+  </SequentialIterator>
+</SequentialIterator>
+

=== added file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_06.iter'
--- test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_06.iter	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_06.iter	2012-12-21 04:09:22 +0000
@@ -0,0 +1,334 @@
+Iterator tree for doc indexer:
+<flwor::FLWORIterator>
+  <ForVariable name="$$context-item">
+    <CtxVarIterator varid="1" varname="$$idx_doc_var" varkind="global"/>
+  </ForVariable>
+  <ReturnClause>
+    <ValueIndexEntryBuilderIterator>
+      <ForVarIterator varname="$$context-item"/>
+      <PromoteIterator type="xs:string">
+        <FnDataIterator>
+          <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,uri)" typename="*" nill allowed="0">
+            <ForVarIterator varname="$$context-item"/>
+          </AttributeAxisIterator>
+        </FnDataIterator>
+      </PromoteIterator>
+      <PromoteIterator type="xs:string">
+        <FnDataIterator>
+          <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,child)" typename="*" nill allowed="0">
+            <ForVarIterator varname="$$context-item"/>
+          </AttributeAxisIterator>
+        </FnDataIterator>
+      </PromoteIterator>
+    </ValueIndexEntryBuilderIterator>
+  </ReturnClause>
+</flwor::FLWORIterator>
+
+Iterator tree for index:
+<flwor::FLWORIterator>
+  <ForVariable name="$$context-item">
+    <ZorbaCollectionIterator>
+      <SingletonIterator value="xs:QName(www.data.com,data,parents)"/>
+    </ZorbaCollectionIterator>
+  </ForVariable>
+  <ReturnClause>
+    <ValueIndexEntryBuilderIterator>
+      <ForVarIterator varname="$$context-item"/>
+      <PromoteIterator type="xs:string">
+        <FnDataIterator>
+          <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,uri)" typename="*" nill allowed="0">
+            <ForVarIterator varname="$$context-item"/>
+          </AttributeAxisIterator>
+        </FnDataIterator>
+      </PromoteIterator>
+      <PromoteIterator type="xs:string">
+        <FnDataIterator>
+          <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,child)" typename="*" nill allowed="0">
+            <ForVarIterator varname="$$context-item"/>
+          </AttributeAxisIterator>
+        </FnDataIterator>
+      </PromoteIterator>
+    </ValueIndexEntryBuilderIterator>
+  </ReturnClause>
+</flwor::FLWORIterator>
+
+Iterator tree for const-folded expr:
+<SingletonIterator value="xs:boolean(true)"/>
+
+Iterator tree for const-folded expr:
+<SingletonIterator value="xs:boolean(false)"/>
+
+Iterator tree for const-folded expr:
+<CastIterator type="xs:anyURI">
+  <SingletonIterator value="xs:string(http://www.xmlteam.com/zorba/repo/index)"/>
+</CastIterator>
+
+Iterator tree for const-folded expr:
+<SingletonIterator value="xs:boolean(true)"/>
+
+Iterator tree for main query:
+<SequentialIterator>
+  <CtxVarDeclareIterator varid="4" varname="data:parents">
+    <SingletonIterator value="xs:QName(www.data.com,data,parents)"/>
+  </CtxVarDeclareIterator>
+  <CtxVarDeclareIterator varid="5" varname="data:idx">
+    <SingletonIterator value="xs:QName(www.data.com,data,idx)"/>
+  </CtxVarDeclareIterator>
+  <SequentialIterator>
+    <ApplyIterator>
+      <ZorbaCreateCollectionIterator>
+        <CtxVarIterator varid="4" varname="data:parents" varkind="global"/>
+      </ZorbaCreateCollectionIterator>
+    </ApplyIterator>
+    <ApplyIterator>
+      <CreateIndexIterator>
+        <CtxVarIterator varid="5" varname="data:idx" varkind="global"/>
+      </CreateIndexIterator>
+    </ApplyIterator>
+    <ApplyIterator>
+      <UDFunctionCallIterator>
+        <SingletonIterator value="xs:anyURI(http://www.xmlteam.com/zorba/repo/index)"/>
+        <SingletonIterator value="xs:boolean(true)"/>
+      </UDFunctionCallIterator>
+    </ApplyIterator>
+    <FnConcatIterator>
+      <ZorbaCollectionIterator>
+        <CtxVarIterator varid="4" varname="data:parents" varkind="global"/>
+      </ZorbaCollectionIterator>
+      <SingletonIterator value="xs:string(
+)"/>
+    </FnConcatIterator>
+  </SequentialIterator>
+</SequentialIterator>
+
+Iterator tree for data:add-document:
+<flwor::FLWORIterator>
+  <ForVariable name="docURI">
+    <LetVarIterator varname="docURI"/>
+  </ForVariable>
+  <ForVariable name="overwrite">
+    <LetVarIterator varname="overwrite"/>
+  </ForVariable>
+  <MaterializeClause>
+    <MaterializeForVariable inputVar="docURI : "/>
+    <MaterializeForVariable inputVar="overwrite : "/>
+  </MaterializeClause>
+  <ReturnClause>
+    <SequentialIterator>
+      <CtxVarDeclareIterator varid="1" varname="doc-uri">
+        <SubstringAfterIterator>
+          <PromoteIterator type="xs:string">
+            <ForVarIterator varname="docURI"/>
+          </PromoteIterator>
+          <SingletonIterator value="xs:string(http://www.xmlteam.com)"/>
+        </SubstringAfterIterator>
+      </CtxVarDeclareIterator>
+      <CtxVarDeclareIterator varid="2" varname="segments">
+        <FnTokenizeIterator>
+          <PromoteIterator type="xs:string">
+            <FnDataIterator>
+              <CtxVarIterator varid="1" varname="doc-uri" varkind="local"/>
+            </FnDataIterator>
+          </PromoteIterator>
+          <SingletonIterator value="xs:string(/)"/>
+        </FnTokenizeIterator>
+      </CtxVarDeclareIterator>
+      <flwor::FLWORIterator>
+        <LetVariable name="$$opt_temp_0" materialize="true">
+          <HoistIterator>
+            <ZorbaCollectionIterator>
+              <CtxVarIterator varid="4" varname="data:parents" varkind="global"/>
+            </ZorbaCollectionIterator>
+          </HoistIterator>
+        </LetVariable>
+        <ForVariable name="segment">
+          <CtxVarIterator varid="2" varname="segments" varkind="local"/>
+        </ForVariable>
+        <ForVariable name="parent">
+          <StringJoinIterator>
+            <PromoteIterator type="xs:string">
+              <FnDataIterator>
+                <CtxVarIterator varid="2" varname="segments" varkind="local">
+                  <SingletonIterator value="xs:integer(1)"/>
+                  <SpecificNumArithIterator_SubtractOperation_INTEGER>
+                    <ForVarIterator varname="i"/>
+                    <SingletonIterator value="xs:integer(1)"/>
+                  </SpecificNumArithIterator_SubtractOperation_INTEGER>
+                </CtxVarIterator>
+              </FnDataIterator>
+            </PromoteIterator>
+            <SingletonIterator value="xs:string(/)"/>
+          </StringJoinIterator>
+        </ForVariable>
+        <ForVariable name="child">
+          <StringJoinIterator>
+            <PromoteIterator type="xs:string">
+              <FnDataIterator>
+                <CtxVarIterator varid="2" varname="segments" varkind="local">
+                  <SingletonIterator value="xs:integer(1)"/>
+                  <ForVarIterator varname="i"/>
+                </CtxVarIterator>
+              </FnDataIterator>
+            </PromoteIterator>
+            <SingletonIterator value="xs:string(/)"/>
+          </StringJoinIterator>
+        </ForVariable>
+        <WhereClause>
+          <AndIterator>
+            <TypedValueCompareIterator_INTEGER>
+              <ForVarIterator varname="i"/>
+              <SingletonIterator value="xs:integer(1)"/>
+            </TypedValueCompareIterator_INTEGER>
+            <FnEmptyIterator>
+              <flwor::FLWORIterator>
+                <ForVariable name="p">
+                  <ProbeIndexPointValueIterator>
+                    <SingletonIterator value="xs:QName(www.data.com,data,idx)"/>
+                    <ForVarIterator varname="parent"/>
+                    <ForVarIterator varname="child"/>
+                  </ProbeIndexPointValueIterator>
+                </ForVariable>
+                <ReturnClause>
+                  <SingletonIterator value="xs:boolean(true)"/>
+                </ReturnClause>
+              </flwor::FLWORIterator>
+            </FnEmptyIterator>
+          </AndIterator>
+        </WhereClause>
+        <MaterializeClause>
+          <MaterializeForVariable inputVar="parent : "/>
+          <MaterializeForVariable inputVar="child : "/>
+        </MaterializeClause>
+        <ReturnClause>
+          <ApplyIterator>
+            <ZorbaInsertNodesIterator need-to-copy="true">
+              <CtxVarIterator varid="4" varname="data:parents" varkind="global"/>
+              <ElementIterator>
+                <SingletonIterator value="xs:QName(,,parent)"/>
+                <FnConcatIterator>
+                  <AttributeIterator qname="xs:QName(,,uri)">
+                    <EnclosedIterator attr_cont="true">
+                      <ForVarIterator varname="parent"/>
+                    </EnclosedIterator>
+                  </AttributeIterator>
+                  <AttributeIterator qname="xs:QName(,,child)">
+                    <EnclosedIterator attr_cont="true">
+                      <ForVarIterator varname="child"/>
+                    </EnclosedIterator>
+                  </AttributeIterator>
+                </FnConcatIterator>
+              </ElementIterator>
+            </ZorbaInsertNodesIterator>
+          </ApplyIterator>
+        </ReturnClause>
+      </flwor::FLWORIterator>
+      <IfThenElseIterator>
+        <AndIterator>
+          <ForVarIterator varname="overwrite"/>
+          <FunctionTraceIterator>
+            <flwor::FLWORIterator>
+              <ForVariable name="docURI">
+                <PromoteIterator type="xs:string">
+                  <FnDataIterator>
+                    <CtxVarIterator varid="1" varname="doc-uri" varkind="local"/>
+                  </FnDataIterator>
+                </PromoteIterator>
+              </ForVariable>
+              <ReturnClause>
+                <IfThenElseIterator>
+                  <FnBooleanIterator>
+                    <TryCatchIterator>
+                      <RetrieveDocumentIterator>
+                        <ForVarIterator varname="docURI"/>
+                      </RetrieveDocumentIterator>
+                      <FnConcatIterator/>
+                    </TryCatchIterator>
+                  </FnBooleanIterator>
+                  <SingletonIterator value="xs:boolean(true)"/>
+                  <SingletonIterator value="xs:boolean(false)"/>
+                </IfThenElseIterator>
+              </ReturnClause>
+            </flwor::FLWORIterator>
+          </FunctionTraceIterator>
+        </AndIterator>
+        <ApplyIterator>
+          <FunctionTraceIterator>
+            <flwor::FLWORIterator>
+              <LetVariable name="tokens" materialize="true">
+                <FnTokenizeIterator>
+                  <SubstringAfterIterator>
+                    <PromoteIterator type="xs:string">
+                      <TraceIterator>
+                        <ForVarIterator varname="docURI"/>
+                        <SingletonIterator value="xs:string(uri)"/>
+                      </TraceIterator>
+                    </PromoteIterator>
+                    <SingletonIterator value="xs:string(http://www.xmlteam.com)"/>
+                  </SubstringAfterIterator>
+                  <SingletonIterator value="xs:string(/)"/>
+                </FnTokenizeIterator>
+              </LetVariable>
+              <ForVariable name="parent-uri">
+                <StringJoinIterator>
+                  <LetVarIterator varname="tokens">
+                    <SingletonIterator value="xs:integer(1)"/>
+                    <SpecificNumArithIterator_SubtractOperation_INTEGER>
+                      <FnCountIterator>
+                        <LetVarIterator varname="tokens"/>
+                      </FnCountIterator>
+                      <SingletonIterator value="xs:integer(1)"/>
+                    </SpecificNumArithIterator_SubtractOperation_INTEGER>
+                  </LetVarIterator>
+                  <SingletonIterator value="xs:string(/)"/>
+                </StringJoinIterator>
+              </ForVariable>
+              <ForVariable name="child-uri">
+                <StringJoinIterator>
+                  <LetVarIterator varname="tokens"/>
+                  <SingletonIterator value="xs:string(/)"/>
+                </StringJoinIterator>
+              </ForVariable>
+              <LetVariable name="parent" materialize="true">
+                <ProbeIndexPointValueIterator>
+                  <SingletonIterator value="xs:QName(www.data.com,data,idx)"/>
+                  <ForVarIterator varname="parent-uri"/>
+                  <ForVarIterator varname="child-uri"/>
+                </ProbeIndexPointValueIterator>
+              </LetVariable>
+              <MaterializeClause>
+                <MaterializeForVariable inputVar="parent-uri : "/>
+                <MaterializeForVariable inputVar="child-uri : "/>
+                <MaterializeLetVariable inputVar="parent : "/>
+              </MaterializeClause>
+              <ReturnClause>
+                <SequentialIterator>
+                  <ApplyIterator>
+                    <TraceIterator>
+                      <ForVarIterator varname="parent-uri"/>
+                      <SingletonIterator value="xs:string(parent)"/>
+                    </TraceIterator>
+                  </ApplyIterator>
+                  <ApplyIterator>
+                    <TraceIterator>
+                      <ForVarIterator varname="child-uri"/>
+                      <SingletonIterator value="xs:string(child)"/>
+                    </TraceIterator>
+                  </ApplyIterator>
+                  <ApplyIterator>
+                    <ZorbaDeleteNodesIterator>
+                      <LetVarIterator varname="parent"/>
+                    </ZorbaDeleteNodesIterator>
+                  </ApplyIterator>
+                </SequentialIterator>
+              </ReturnClause>
+            </flwor::FLWORIterator>
+          </FunctionTraceIterator>
+        </ApplyIterator>
+        <ApplyIterator>
+          <FnConcatIterator/>
+        </ApplyIterator>
+      </IfThenElseIterator>
+    </SequentialIterator>
+  </ReturnClause>
+</flwor::FLWORIterator>
+

=== added file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_07.iter'
--- test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_07.iter	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_07.iter	2012-12-21 04:09:22 +0000
@@ -0,0 +1,155 @@
+Iterator tree for doc indexer:
+<flwor::FLWORIterator>
+  <ForVariable name="$$context-item">
+    <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,closed_auction)" typename="*" nill allowed="0">
+      <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,closed_auctions)" typename="*" nill allowed="0">
+        <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,site)" typename="*" nill allowed="0">
+          <CtxVarIterator varid="1" varname="$$idx_doc_var" varkind="global"/>
+        </ChildAxisIterator>
+      </ChildAxisIterator>
+    </ChildAxisIterator>
+  </ForVariable>
+  <ReturnClause>
+    <ValueIndexEntryBuilderIterator>
+      <ForVarIterator varname="$$context-item"/>
+      <PromoteIterator type="xs:string">
+        <FnDataIterator>
+          <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,person)" typename="*" nill allowed="0">
+            <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,buyer)" typename="*" nill allowed="0">
+              <ForVarIterator varname="$$context-item"/>
+            </ChildAxisIterator>
+          </AttributeAxisIterator>
+        </FnDataIterator>
+      </PromoteIterator>
+    </ValueIndexEntryBuilderIterator>
+  </ReturnClause>
+</flwor::FLWORIterator>
+
+Iterator tree for index:
+<flwor::FLWORIterator>
+  <ForVariable name="$$context-item">
+    <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,closed_auction)" typename="*" nill allowed="0">
+      <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,closed_auctions)" typename="*" nill allowed="0">
+        <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,site)" typename="*" nill allowed="0">
+          <ZorbaCollectionIterator>
+            <SingletonIterator value="xs:QName(www.xmark.com,x,auctions)"/>
+          </ZorbaCollectionIterator>
+        </ChildAxisIterator>
+      </ChildAxisIterator>
+    </ChildAxisIterator>
+  </ForVariable>
+  <ReturnClause>
+    <ValueIndexEntryBuilderIterator>
+      <ForVarIterator varname="$$context-item"/>
+      <PromoteIterator type="xs:string">
+        <FnDataIterator>
+          <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,person)" typename="*" nill allowed="0">
+            <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,buyer)" typename="*" nill allowed="0">
+              <ForVarIterator varname="$$context-item"/>
+            </ChildAxisIterator>
+          </AttributeAxisIterator>
+        </FnDataIterator>
+      </PromoteIterator>
+    </ValueIndexEntryBuilderIterator>
+  </ReturnClause>
+</flwor::FLWORIterator>
+
+Iterator tree for main query:
+<SequentialIterator>
+  <CtxVarDeclareIterator varid="4" varname="x:auctions">
+    <SingletonIterator value="xs:QName(www.xmark.com,x,auctions)"/>
+  </CtxVarDeclareIterator>
+  <CtxVarDeclareIterator varid="5" varname="x:idx">
+    <SingletonIterator value="xs:QName(www.xmark.com,x,idx)"/>
+  </CtxVarDeclareIterator>
+  <SequentialIterator>
+    <ApplyIterator>
+      <ZorbaCreateCollectionIterator>
+        <CtxVarIterator varid="4" varname="x:auctions" varkind="global"/>
+      </ZorbaCreateCollectionIterator>
+    </ApplyIterator>
+    <ApplyIterator>
+      <CreateIndexIterator>
+        <CtxVarIterator varid="5" varname="x:idx" varkind="global"/>
+      </CreateIndexIterator>
+    </ApplyIterator>
+    <ApplyIterator>
+      <ZorbaInsertNodesIterator need-to-copy="true">
+        <CtxVarIterator varid="4" varname="x:auctions" varkind="global"/>
+        <FnDocIterator>
+          <SingletonIterator value="xs:string(auction.xml)"/>
+        </FnDocIterator>
+      </ZorbaInsertNodesIterator>
+    </ApplyIterator>
+    <flwor::FLWORIterator>
+      <LetVariable name="auctions" materialize="true">
+        <ZorbaCollectionIterator>
+          <CtxVarIterator varid="4" varname="x:auctions" varkind="global"/>
+        </ZorbaCollectionIterator>
+      </LetVariable>
+      <LetVariable name="$$opt_temp_0" materialize="true">
+        <HoistIterator>
+          <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,closed_auction)" typename="*" nill allowed="0">
+            <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,closed_auctions)" typename="*" nill allowed="0">
+              <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,site)" typename="*" nill allowed="0">
+                <LetVarIterator varname="auctions"/>
+              </ChildAxisIterator>
+            </ChildAxisIterator>
+          </ChildAxisIterator>
+        </HoistIterator>
+      </LetVariable>
+      <ForVariable name="p">
+        <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,person)" typename="*" nill allowed="0">
+          <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,people)" typename="*" nill allowed="0">
+            <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,site)" typename="*" nill allowed="0">
+              <LetVarIterator varname="auctions"/>
+            </ChildAxisIterator>
+          </ChildAxisIterator>
+        </ChildAxisIterator>
+      </ForVariable>
+      <LetVariable name="$$opt_temp_1" materialize="true">
+        <HoistIterator>
+          <FnDataIterator>
+            <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,id)" typename="*" nill allowed="0">
+              <ForVarIterator varname="p"/>
+            </AttributeAxisIterator>
+          </FnDataIterator>
+        </HoistIterator>
+      </LetVariable>
+      <ReturnClause>
+        <ElementIterator>
+          <SingletonIterator value="xs:QName(,,item)"/>
+          <AttributeIterator qname="xs:QName(,,person)">
+            <EnclosedIterator attr_cont="true">
+              <FnDataIterator>
+                <ChildAxisIterator test kind="match_text_test" qname="*" typename="*" nill allowed="0">
+                  <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,name)" typename="*" nill allowed="0">
+                    <ForVarIterator varname="p"/>
+                  </ChildAxisIterator>
+                </ChildAxisIterator>
+              </FnDataIterator>
+            </EnclosedIterator>
+          </AttributeIterator>
+          <EnclosedIterator attr_cont="false">
+            <FnCountIterator>
+              <flwor::FLWORIterator>
+                <ForVariable name="t">
+                  <ProbeIndexPointValueIterator>
+                    <SingletonIterator value="xs:QName(www.xmark.com,x,idx)"/>
+                    <UnhoistIterator>
+                      <LetVarIterator varname="$$opt_temp_1"/>
+                    </UnhoistIterator>
+                  </ProbeIndexPointValueIterator>
+                </ForVariable>
+                <ReturnClause>
+                  <ForVarIterator varname="t"/>
+                </ReturnClause>
+              </flwor::FLWORIterator>
+            </FnCountIterator>
+          </EnclosedIterator>
+        </ElementIterator>
+      </ReturnClause>
+    </flwor::FLWORIterator>
+  </SequentialIterator>
+</SequentialIterator>
+

=== modified file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/no-copy/hashjoin-gary1.iter'
--- test/rbkt/ExpCompilerResults/IterPlan/zorba/no-copy/hashjoin-gary1.iter	2012-12-18 15:09:02 +0000
+++ test/rbkt/ExpCompilerResults/IterPlan/zorba/no-copy/hashjoin-gary1.iter	2012-12-21 04:09:22 +0000
@@ -26,200 +26,178 @@
     <flwor::FLWORIterator>
       <LetVariable name="y" materialize="true">
         <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,data)" typename="*" nill allowed="0">
-          <flwor::FLWORIterator>
-            <ForVariable name="$$context-item">
-              <FnDocIterator>
-                <SingletonIterator value="xs:string(../hashjoins/min_ic1980.xml)"/>
-              </FnDocIterator>
-            </ForVariable>
-            <ForVariable name="$$context-item">
+          <flwor::TupleStreamIterator>
+            <flwor::WhereIterator>
+              <flwor::WhereIterator>
+                <flwor::ForIterator>
+                  <ForVariable name="$$context-item"/>
+                  <flwor::ForIterator>
+                    <ForVariable name="$$context-item"/>
+                    <flwor::TupleSourceIterator/>
+                    <FnDocIterator>
+                      <SingletonIterator value="xs:string(../hashjoins/min_ic1980.xml)"/>
+                    </FnDocIterator>
+                  </flwor::ForIterator>
+                  <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,ipeds)" typename="*" nill allowed="0">
+                    <ForVarIterator varname="$$context-item"/>
+                  </ChildAxisIterator>
+                </flwor::ForIterator>
+                <CompareIterator>
+                  <FnDataIterator>
+                    <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,year)" typename="*" nill allowed="0">
+                      <ForVarIterator varname="$$context-item"/>
+                    </AttributeAxisIterator>
+                  </FnDataIterator>
+                  <SingletonIterator value="xs:integer(1980)"/>
+                </CompareIterator>
+              </flwor::WhereIterator>
+              <CompareIterator>
+                <FnDataIterator>
+                  <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,file)" typename="*" nill allowed="0">
+                    <ForVarIterator varname="$$context-item"/>
+                  </AttributeAxisIterator>
+                </FnDataIterator>
+                <SingletonIterator value="xs:string(ic1980)"/>
+              </CompareIterator>
+            </flwor::WhereIterator>
+            <ForVarIterator varname="$$context-item"/>
+          </flwor::TupleStreamIterator>
+        </ChildAxisIterator>
+      </LetVariable>
+      <ForVariable name="i">
+        <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,inst)" typename="*" nill allowed="0">
+          <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,institutions)" typename="*" nill allowed="0">
+            <FnDocIterator>
+              <SingletonIterator value="xs:string(../hashjoins/base.xml)"/>
+            </FnDocIterator>
+          </ChildAxisIterator>
+        </ChildAxisIterator>
+      </ForVariable>
+      <LetVariable name="unitid" materialize="true">
+        <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,unitid)" typename="*" nill allowed="0">
+          <ForVarIterator varname="i"/>
+        </AttributeAxisIterator>
+      </LetVariable>
+      <LetVariable name="$$opt_temp_1" materialize="true">
+        <HoistIterator>
+          <NodeSortIterator distinct="true" ascending="true">
+            <AttributeAxisIterator test kind="match_name_test" qname="*" typename="*" nill allowed="0">
               <flwor::FLWORIterator>
                 <ForVariable name="$$context-item">
-                  <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,ipeds)" typename="*" nill allowed="0">
-                    <ForVarIterator varname="$$context-item"/>
-                  </ChildAxisIterator>
+                  <LetVarIterator varname="y"/>
                 </ForVariable>
                 <WhereClause>
                   <CompareIterator>
                     <FnDataIterator>
-                      <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,year)" typename="*" nill allowed="0">
+                      <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,unitid)" typename="*" nill allowed="0">
                         <ForVarIterator varname="$$context-item"/>
                       </AttributeAxisIterator>
                     </FnDataIterator>
-                    <SingletonIterator value="xs:integer(1980)"/>
+                    <FnDataIterator>
+                      <LetVarIterator varname="unitid"/>
+                    </FnDataIterator>
                   </CompareIterator>
                 </WhereClause>
                 <ReturnClause>
                   <ForVarIterator varname="$$context-item"/>
                 </ReturnClause>
               </flwor::FLWORIterator>
-            </ForVariable>
-            <WhereClause>
-              <CompareIterator>
-                <FnDataIterator>
-                  <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,file)" typename="*" nill allowed="0">
-                    <ForVarIterator varname="$$context-item"/>
-                  </AttributeAxisIterator>
-                </FnDataIterator>
-                <SingletonIterator value="xs:string(ic1980)"/>
-              </CompareIterator>
-            </WhereClause>
-            <ReturnClause>
-              <ForVarIterator varname="$$context-item"/>
-            </ReturnClause>
-          </flwor::FLWORIterator>
-        </ChildAxisIterator>
+            </AttributeAxisIterator>
+          </NodeSortIterator>
+        </HoistIterator>
       </LetVariable>
       <ReturnClause>
-        <SequentialIterator>
-          <CreateInternalIndexIterator name="xs:QName(,,tempIndex0)">
+        <ElementIterator copyInputNodes="false">
+          <SingletonIterator value="xs:QName(,,inst)"/>
+          <AttributeIterator qname="xs:QName(,,unitid)">
+            <EnclosedIterator attr_cont="true">
+              <FnDataIterator>
+                <LetVarIterator varname="unitid"/>
+              </FnDataIterator>
+            </EnclosedIterator>
+          </AttributeIterator>
+          <EnclosedIterator attr_cont="false">
             <flwor::FLWORIterator>
-              <ForVariable name="$$opt_temp_2">
-                <LetVarIterator varname="y"/>
+              <ForVariable name="j">
+                <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,year)" typename="*" nill allowed="0">
+                  <ForVarIterator varname="i"/>
+                </ChildAxisIterator>
+              </ForVariable>
+              <LetVariable name="year" materialize="true">
+                <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,name)" typename="*" nill allowed="0">
+                  <ForVarIterator varname="j"/>
+                </AttributeAxisIterator>
+              </LetVariable>
+              <ForVariable name="$$opt_temp_0">
+                <HoistIterator>
+                  <CompareIterator>
+                    <FnDataIterator>
+                      <LetVarIterator varname="year"/>
+                    </FnDataIterator>
+                    <SingletonIterator value="xs:integer(1980)"/>
+                  </CompareIterator>
+                </HoistIterator>
               </ForVariable>
               <ReturnClause>
-                <GeneralIndexEntryBuilderIterator>
-                  <ForVarIterator varname="$$opt_temp_2"/>
-                  <FnDataIterator>
-                    <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,unitid)" typename="*" nill allowed="0">
-                      <ForVarIterator varname="$$opt_temp_2"/>
-                    </AttributeAxisIterator>
-                  </FnDataIterator>
-                </GeneralIndexEntryBuilderIterator>
+                <ElementIterator copyInputNodes="false">
+                  <SingletonIterator value="xs:QName(,,year)"/>
+                  <AttributeIterator qname="xs:QName(,,name)">
+                    <EnclosedIterator attr_cont="true">
+                      <FnDataIterator>
+                        <LetVarIterator varname="year"/>
+                      </FnDataIterator>
+                    </EnclosedIterator>
+                  </AttributeIterator>
+                  <EnclosedIterator attr_cont="false">
+                    <flwor::FLWORIterator>
+                      <ForVariable name="k">
+                        <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,file)" typename="*" nill allowed="0">
+                          <ForVarIterator varname="j"/>
+                        </ChildAxisIterator>
+                      </ForVariable>
+                      <LetVariable name="file" materialize="true">
+                        <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,name)" typename="*" nill allowed="0">
+                          <ForVarIterator varname="k"/>
+                        </AttributeAxisIterator>
+                      </LetVariable>
+                      <ReturnClause>
+                        <ElementIterator copyInputNodes="false">
+                          <SingletonIterator value="xs:QName(,,file)"/>
+                          <AttributeIterator qname="xs:QName(,,name)">
+                            <EnclosedIterator attr_cont="true">
+                              <FnDataIterator>
+                                <LetVarIterator varname="file"/>
+                              </FnDataIterator>
+                            </EnclosedIterator>
+                          </AttributeIterator>
+                          <EnclosedIterator attr_cont="false">
+                            <IfThenElseIterator>
+                              <AndIterator>
+                                <UnhoistIterator>
+                                  <ForVarIterator varname="$$opt_temp_0"/>
+                                </UnhoistIterator>
+                                <CompareIterator>
+                                  <FnDataIterator>
+                                    <LetVarIterator varname="file"/>
+                                  </FnDataIterator>
+                                  <SingletonIterator value="xs:string(ic1980)"/>
+                                </CompareIterator>
+                              </AndIterator>
+                              <UnhoistIterator>
+                                <LetVarIterator varname="$$opt_temp_1"/>
+                              </UnhoistIterator>
+                              <FnConcatIterator/>
+                            </IfThenElseIterator>
+                          </EnclosedIterator>
+                        </ElementIterator>
+                      </ReturnClause>
+                    </flwor::FLWORIterator>
+                  </EnclosedIterator>
+                </ElementIterator>
               </ReturnClause>
             </flwor::FLWORIterator>
-          </CreateInternalIndexIterator>
-          <flwor::FLWORIterator>
-            <ForVariable name="i">
-              <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,inst)" typename="*" nill allowed="0">
-                <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,institutions)" typename="*" nill allowed="0">
-                  <FnDocIterator>
-                    <SingletonIterator value="xs:string(../hashjoins/base.xml)"/>
-                  </FnDocIterator>
-                </ChildAxisIterator>
-              </ChildAxisIterator>
-            </ForVariable>
-            <LetVariable name="unitid" materialize="true">
-              <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,unitid)" typename="*" nill allowed="0">
-                <ForVarIterator varname="i"/>
-              </AttributeAxisIterator>
-            </LetVariable>
-            <LetVariable name="$$opt_temp_1" materialize="true">
-              <HoistIterator>
-                <AttributeAxisIterator test kind="match_name_test" qname="*" typename="*" nill allowed="0">
-                  <flwor::FLWORIterator>
-                    <ForVariable name="$$context-item">
-                      <NodeSortIterator distinct="true" ascending="true">
-                        <ProbeIndexPointGeneralIterator>
-                          <SingletonIterator value="xs:QName(,,tempIndex0)"/>
-                          <FnDataIterator>
-                            <LetVarIterator varname="unitid"/>
-                          </FnDataIterator>
-                        </ProbeIndexPointGeneralIterator>
-                      </NodeSortIterator>
-                    </ForVariable>
-                    <ReturnClause>
-                      <ForVarIterator varname="$$context-item"/>
-                    </ReturnClause>
-                  </flwor::FLWORIterator>
-                </AttributeAxisIterator>
-              </HoistIterator>
-            </LetVariable>
-            <ReturnClause>
-              <ElementIterator copyInputNodes="false">
-                <SingletonIterator value="xs:QName(,,inst)"/>
-                <AttributeIterator qname="xs:QName(,,unitid)">
-                  <EnclosedIterator attr_cont="true">
-                    <FnDataIterator>
-                      <LetVarIterator varname="unitid"/>
-                    </FnDataIterator>
-                  </EnclosedIterator>
-                </AttributeIterator>
-                <EnclosedIterator attr_cont="false">
-                  <flwor::FLWORIterator>
-                    <ForVariable name="j">
-                      <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,year)" typename="*" nill allowed="0">
-                        <ForVarIterator varname="i"/>
-                      </ChildAxisIterator>
-                    </ForVariable>
-                    <LetVariable name="year" materialize="true">
-                      <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,name)" typename="*" nill allowed="0">
-                        <ForVarIterator varname="j"/>
-                      </AttributeAxisIterator>
-                    </LetVariable>
-                    <ForVariable name="$$opt_temp_0">
-                      <HoistIterator>
-                        <CompareIterator>
-                          <FnDataIterator>
-                            <LetVarIterator varname="year"/>
-                          </FnDataIterator>
-                          <SingletonIterator value="xs:integer(1980)"/>
-                        </CompareIterator>
-                      </HoistIterator>
-                    </ForVariable>
-                    <ReturnClause>
-                      <ElementIterator copyInputNodes="false">
-                        <SingletonIterator value="xs:QName(,,year)"/>
-                        <AttributeIterator qname="xs:QName(,,name)">
-                          <EnclosedIterator attr_cont="true">
-                            <FnDataIterator>
-                              <LetVarIterator varname="year"/>
-                            </FnDataIterator>
-                          </EnclosedIterator>
-                        </AttributeIterator>
-                        <EnclosedIterator attr_cont="false">
-                          <flwor::FLWORIterator>
-                            <ForVariable name="k">
-                              <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,file)" typename="*" nill allowed="0">
-                                <ForVarIterator varname="j"/>
-                              </ChildAxisIterator>
-                            </ForVariable>
-                            <LetVariable name="file" materialize="true">
-                              <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,name)" typename="*" nill allowed="0">
-                                <ForVarIterator varname="k"/>
-                              </AttributeAxisIterator>
-                            </LetVariable>
-                            <ReturnClause>
-                              <ElementIterator copyInputNodes="false">
-                                <SingletonIterator value="xs:QName(,,file)"/>
-                                <AttributeIterator qname="xs:QName(,,name)">
-                                  <EnclosedIterator attr_cont="true">
-                                    <FnDataIterator>
-                                      <LetVarIterator varname="file"/>
-                                    </FnDataIterator>
-                                  </EnclosedIterator>
-                                </AttributeIterator>
-                                <EnclosedIterator attr_cont="false">
-                                  <IfThenElseIterator>
-                                    <AndIterator>
-                                      <UnhoistIterator>
-                                        <ForVarIterator varname="$$opt_temp_0"/>
-                                      </UnhoistIterator>
-                                      <CompareIterator>
-                                        <FnDataIterator>
-                                          <LetVarIterator varname="file"/>
-                                        </FnDataIterator>
-                                        <SingletonIterator value="xs:string(ic1980)"/>
-                                      </CompareIterator>
-                                    </AndIterator>
-                                    <UnhoistIterator>
-                                      <LetVarIterator varname="$$opt_temp_1"/>
-                                    </UnhoistIterator>
-                                    <FnConcatIterator/>
-                                  </IfThenElseIterator>
-                                </EnclosedIterator>
-                              </ElementIterator>
-                            </ReturnClause>
-                          </flwor::FLWORIterator>
-                        </EnclosedIterator>
-                      </ElementIterator>
-                    </ReturnClause>
-                  </flwor::FLWORIterator>
-                </EnclosedIterator>
-              </ElementIterator>
-            </ReturnClause>
-          </flwor::FLWORIterator>
-        </SequentialIterator>
+          </EnclosedIterator>
+        </ElementIterator>
       </ReturnClause>
     </flwor::FLWORIterator>
   </EnclosedIterator>

=== modified file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/no-copy/q4.iter'
--- test/rbkt/ExpCompilerResults/IterPlan/zorba/no-copy/q4.iter	2012-10-08 12:09:36 +0000
+++ test/rbkt/ExpCompilerResults/IterPlan/zorba/no-copy/q4.iter	2012-12-21 04:09:22 +0000
@@ -31,82 +31,64 @@
         </ChildAxisIterator>
       </ChildAxisIterator>
     </ForVariable>
-    <LetVariable name="$$opt_temp_0" materialize="true">
-      <HoistIterator>
-        <flwor::FLWORIterator>
-          <ForVariable name="$$context-item">
-            <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,bidder)" typename="*" nill allowed="0">
-              <ForVarIterator varname="b"/>
-            </ChildAxisIterator>
-          </ForVariable>
-          <ForVariable name="$$context-item">
-            <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,personref)" typename="*" nill allowed="0">
-              <ForVarIterator varname="$$context-item"/>
-            </ChildAxisIterator>
-          </ForVariable>
-          <WhereClause>
-            <CompareIterator>
-              <FnDataIterator>
-                <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,person)" typename="*" nill allowed="0">
-                  <ForVarIterator varname="$$context-item"/>
-                </AttributeAxisIterator>
-              </FnDataIterator>
-              <SingletonIterator value="xs:string(person51)"/>
-            </CompareIterator>
-          </WhereClause>
-          <ReturnClause>
-            <ForVarIterator varname="$$context-item"/>
-          </ReturnClause>
-        </flwor::FLWORIterator>
-      </HoistIterator>
-    </LetVariable>
     <WhereClause>
       <FnExistsIterator>
-        <flwor::FLWORIterator>
-          <ForVariable name="pr1">
-            <flwor::FLWORIterator>
-              <ForVariable name="$$context-item">
-                <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,bidder)" typename="*" nill allowed="0">
-                  <ForVarIterator varname="b"/>
-                </ChildAxisIterator>
-              </ForVariable>
-              <ForVariable name="$$context-item">
+        <flwor::TupleStreamIterator>
+          <flwor::WhereIterator>
+            <flwor::WhereIterator>
+              <flwor::ForIterator>
+                <ForVariable name="$$context-item"/>
+                <flwor::ForIterator>
+                  <ForVariable name="$$context-item"/>
+                  <flwor::WhereIterator>
+                    <flwor::ForIterator>
+                      <ForVariable name="$$context-item"/>
+                      <flwor::ForIterator>
+                        <ForVariable name="$$context-item"/>
+                        <flwor::TupleSourceIterator/>
+                        <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,bidder)" typename="*" nill allowed="0">
+                          <ForVarIterator varname="b"/>
+                        </ChildAxisIterator>
+                      </flwor::ForIterator>
+                      <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,personref)" typename="*" nill allowed="0">
+                        <ForVarIterator varname="$$context-item"/>
+                      </ChildAxisIterator>
+                    </flwor::ForIterator>
+                    <CompareIterator>
+                      <FnDataIterator>
+                        <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,person)" typename="*" nill allowed="0">
+                          <ForVarIterator varname="$$context-item"/>
+                        </AttributeAxisIterator>
+                      </FnDataIterator>
+                      <SingletonIterator value="xs:string(person20)"/>
+                    </CompareIterator>
+                  </flwor::WhereIterator>
+                  <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,bidder)" typename="*" nill allowed="0">
+                    <ForVarIterator varname="b"/>
+                  </ChildAxisIterator>
+                </flwor::ForIterator>
                 <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,personref)" typename="*" nill allowed="0">
                   <ForVarIterator varname="$$context-item"/>
                 </ChildAxisIterator>
-              </ForVariable>
-              <WhereClause>
-                <CompareIterator>
-                  <FnDataIterator>
-                    <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,person)" typename="*" nill allowed="0">
-                      <ForVarIterator varname="$$context-item"/>
-                    </AttributeAxisIterator>
-                  </FnDataIterator>
-                  <SingletonIterator value="xs:string(person20)"/>
-                </CompareIterator>
-              </WhereClause>
-              <ReturnClause>
-                <ForVarIterator varname="$$context-item"/>
-              </ReturnClause>
-            </flwor::FLWORIterator>
-          </ForVariable>
-          <ForVariable name="pr2">
-            <UnhoistIterator>
-              <LetVarIterator varname="$$opt_temp_0"/>
-            </UnhoistIterator>
-          </ForVariable>
-          <WhereClause>
+              </flwor::ForIterator>
+              <CompareIterator>
+                <FnDataIterator>
+                  <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,person)" typename="*" nill allowed="0">
+                    <ForVarIterator varname="$$context-item"/>
+                  </AttributeAxisIterator>
+                </FnDataIterator>
+                <SingletonIterator value="xs:string(person51)"/>
+              </CompareIterator>
+            </flwor::WhereIterator>
             <FnBooleanIterator>
               <NodeBeforeIterator>
-                <ForVarIterator varname="pr1"/>
-                <ForVarIterator varname="pr2"/>
+                <ForVarIterator varname="$$context-item"/>
+                <ForVarIterator varname="$$context-item"/>
               </NodeBeforeIterator>
             </FnBooleanIterator>
-          </WhereClause>
-          <ReturnClause>
-            <SingletonIterator value="xs:boolean(true)"/>
-          </ReturnClause>
-        </flwor::FLWORIterator>
+          </flwor::WhereIterator>
+          <SingletonIterator value="xs:boolean(true)"/>
+        </flwor::TupleStreamIterator>
       </FnExistsIterator>
     </WhereClause>
     <ReturnClause>

=== modified file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/xmark/q4.iter'
--- test/rbkt/ExpCompilerResults/IterPlan/zorba/xmark/q4.iter	2012-10-08 12:09:36 +0000
+++ test/rbkt/ExpCompilerResults/IterPlan/zorba/xmark/q4.iter	2012-12-21 04:09:22 +0000
@@ -31,82 +31,64 @@
         </ChildAxisIterator>
       </ChildAxisIterator>
     </ForVariable>
-    <LetVariable name="$$opt_temp_0" materialize="true">
-      <HoistIterator>
-        <flwor::FLWORIterator>
-          <ForVariable name="$$context-item">
-            <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,bidder)" typename="*" nill allowed="0">
-              <ForVarIterator varname="b"/>
-            </ChildAxisIterator>
-          </ForVariable>
-          <ForVariable name="$$context-item">
-            <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,personref)" typename="*" nill allowed="0">
-              <ForVarIterator varname="$$context-item"/>
-            </ChildAxisIterator>
-          </ForVariable>
-          <WhereClause>
-            <CompareIterator>
-              <FnDataIterator>
-                <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,person)" typename="*" nill allowed="0">
-                  <ForVarIterator varname="$$context-item"/>
-                </AttributeAxisIterator>
-              </FnDataIterator>
-              <SingletonIterator value="xs:string(person51)"/>
-            </CompareIterator>
-          </WhereClause>
-          <ReturnClause>
-            <ForVarIterator varname="$$context-item"/>
-          </ReturnClause>
-        </flwor::FLWORIterator>
-      </HoistIterator>
-    </LetVariable>
     <WhereClause>
       <FnExistsIterator>
-        <flwor::FLWORIterator>
-          <ForVariable name="pr1">
-            <flwor::FLWORIterator>
-              <ForVariable name="$$context-item">
-                <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,bidder)" typename="*" nill allowed="0">
-                  <ForVarIterator varname="b"/>
-                </ChildAxisIterator>
-              </ForVariable>
-              <ForVariable name="$$context-item">
+        <flwor::TupleStreamIterator>
+          <flwor::WhereIterator>
+            <flwor::WhereIterator>
+              <flwor::ForIterator>
+                <ForVariable name="$$context-item"/>
+                <flwor::ForIterator>
+                  <ForVariable name="$$context-item"/>
+                  <flwor::WhereIterator>
+                    <flwor::ForIterator>
+                      <ForVariable name="$$context-item"/>
+                      <flwor::ForIterator>
+                        <ForVariable name="$$context-item"/>
+                        <flwor::TupleSourceIterator/>
+                        <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,bidder)" typename="*" nill allowed="0">
+                          <ForVarIterator varname="b"/>
+                        </ChildAxisIterator>
+                      </flwor::ForIterator>
+                      <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,personref)" typename="*" nill allowed="0">
+                        <ForVarIterator varname="$$context-item"/>
+                      </ChildAxisIterator>
+                    </flwor::ForIterator>
+                    <CompareIterator>
+                      <FnDataIterator>
+                        <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,person)" typename="*" nill allowed="0">
+                          <ForVarIterator varname="$$context-item"/>
+                        </AttributeAxisIterator>
+                      </FnDataIterator>
+                      <SingletonIterator value="xs:string(person20)"/>
+                    </CompareIterator>
+                  </flwor::WhereIterator>
+                  <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,bidder)" typename="*" nill allowed="0">
+                    <ForVarIterator varname="b"/>
+                  </ChildAxisIterator>
+                </flwor::ForIterator>
                 <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,personref)" typename="*" nill allowed="0">
                   <ForVarIterator varname="$$context-item"/>
                 </ChildAxisIterator>
-              </ForVariable>
-              <WhereClause>
-                <CompareIterator>
-                  <FnDataIterator>
-                    <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,person)" typename="*" nill allowed="0">
-                      <ForVarIterator varname="$$context-item"/>
-                    </AttributeAxisIterator>
-                  </FnDataIterator>
-                  <SingletonIterator value="xs:string(person20)"/>
-                </CompareIterator>
-              </WhereClause>
-              <ReturnClause>
-                <ForVarIterator varname="$$context-item"/>
-              </ReturnClause>
-            </flwor::FLWORIterator>
-          </ForVariable>
-          <ForVariable name="pr2">
-            <UnhoistIterator>
-              <LetVarIterator varname="$$opt_temp_0"/>
-            </UnhoistIterator>
-          </ForVariable>
-          <WhereClause>
+              </flwor::ForIterator>
+              <CompareIterator>
+                <FnDataIterator>
+                  <AttributeAxisIterator test kind="match_name_test" qname="xs:QName(,,person)" typename="*" nill allowed="0">
+                    <ForVarIterator varname="$$context-item"/>
+                  </AttributeAxisIterator>
+                </FnDataIterator>
+                <SingletonIterator value="xs:string(person51)"/>
+              </CompareIterator>
+            </flwor::WhereIterator>
             <FnBooleanIterator>
               <NodeBeforeIterator>
-                <ForVarIterator varname="pr1"/>
-                <ForVarIterator varname="pr2"/>
+                <ForVarIterator varname="$$context-item"/>
+                <ForVarIterator varname="$$context-item"/>
               </NodeBeforeIterator>
             </FnBooleanIterator>
-          </WhereClause>
-          <ReturnClause>
-            <SingletonIterator value="xs:boolean(true)"/>
-          </ReturnClause>
-        </flwor::FLWORIterator>
+          </flwor::WhereIterator>
+          <SingletonIterator value="xs:boolean(true)"/>
+        </flwor::TupleStreamIterator>
       </FnExistsIterator>
     </WhereClause>
     <ReturnClause>

=== modified file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/xray/ppm_10.iter'
--- test/rbkt/ExpCompilerResults/IterPlan/zorba/xray/ppm_10.iter	2012-12-18 15:09:02 +0000
+++ test/rbkt/ExpCompilerResults/IterPlan/zorba/xray/ppm_10.iter	2012-12-21 04:09:22 +0000
@@ -935,86 +935,85 @@
   <ReturnClause>
     <SubsequenceIntIterator>
       <FnConcatIterator>
-        <flwor::FLWORIterator>
-          <ForVariable name="shape">
-            <flwor::FLWORIterator>
-              <ForVariable name="$$context-item">
-                <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,shapes)" typename="*" nill allowed="0">
-                  <ForVarIterator varname="scene"/>
-                </ChildAxisIterator>
-              </ForVariable>
-              <ForVariable name="$$context-item">
-                <ChildAxisIterator test kind="match_name_test" qname="*" typename="*" nill allowed="0">
+        <flwor::TupleStreamIterator>
+          <flwor::OrderByIterator>
+            <OrderByForVariable inputVar="$$context-item : "/>
+            <OrderByLetVariable inputVar="distance : "/>
+            <OrderBySpec>
+              <LetVarIterator varname="distance"/>
+            </OrderBySpec>
+            <flwor::WhereIterator>
+              <flwor::LetIterator>
+                <LetVariable name="distance" materialize="true"/>
+                <flwor::WhereIterator>
+                  <flwor::ForIterator>
+                    <ForVariable name="$$context-item"/>
+                    <flwor::ForIterator>
+                      <ForVariable name="$$context-item"/>
+                      <flwor::TupleSourceIterator/>
+                      <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,shapes)" typename="*" nill allowed="0">
+                        <ForVarIterator varname="scene"/>
+                      </ChildAxisIterator>
+                    </flwor::ForIterator>
+                    <ChildAxisIterator test kind="match_name_test" qname="*" typename="*" nill allowed="0">
+                      <ForVarIterator varname="$$context-item"/>
+                    </ChildAxisIterator>
+                  </flwor::ForIterator>
+                  <FnBooleanIterator>
+                    <IsSameNodeIterator>
+                      <ForVarIterator varname="$$context-item"/>
+                      <LetVarIterator varname="ignore"/>
+                    </IsSameNodeIterator>
+                  </FnBooleanIterator>
+                </flwor::WhereIterator>
+                <UDFunctionCallIterator>
+                  <LetVarIterator varname="source"/>
+                  <LetVarIterator varname="direction"/>
                   <ForVarIterator varname="$$context-item"/>
-                </ChildAxisIterator>
-              </ForVariable>
-              <WhereClause>
-                <FnBooleanIterator>
-                  <IsSameNodeIterator>
-                    <ForVarIterator varname="$$context-item"/>
-                    <LetVarIterator varname="ignore"/>
-                  </IsSameNodeIterator>
-                </FnBooleanIterator>
-              </WhereClause>
-              <ReturnClause>
-                <ForVarIterator varname="$$context-item"/>
-              </ReturnClause>
-            </flwor::FLWORIterator>
-          </ForVariable>
-          <LetVariable name="distance" materialize="true">
-            <UDFunctionCallIterator>
-              <LetVarIterator varname="source"/>
-              <LetVarIterator varname="direction"/>
-              <ForVarIterator varname="shape"/>
-            </UDFunctionCallIterator>
-          </LetVariable>
-          <WhereClause>
-            <FnExistsIterator>
-              <LetVarIterator varname="distance"/>
-            </FnExistsIterator>
-          </WhereClause>
-          <OrderBySpec>
-            <LetVarIterator varname="distance"/>
-          </OrderBySpec>
-          <ReturnClause>
-            <UDFunctionCallIterator>
-              <FunctionTraceIterator>
-                <flwor::FLWORIterator>
-                  <LetVariable name="v2" materialize="true">
-                    <FunctionTraceIterator>
-                      <flwor::FLWORIterator>
-                        <ForVariable name="y">
-                          <LetVarIterator varname="direction"/>
-                        </ForVariable>
-                        <ReturnClause>
-                          <SpecificNumArithIterator_MultiplyOperation_DOUBLE>
-                            <LetVarIterator varname="distance"/>
-                            <ForVarIterator varname="y"/>
-                          </SpecificNumArithIterator_MultiplyOperation_DOUBLE>
-                        </ReturnClause>
-                      </flwor::FLWORIterator>
-                    </FunctionTraceIterator>
-                  </LetVariable>
-                  <ForVariable name="x">
-                    <LetVarIterator varname="source"/>
-                  </ForVariable>
-                  <ReturnClause>
-                    <SpecificNumArithIterator_AddOperation_DOUBLE>
-                      <ForVarIterator varname="x"/>
-                      <LetVarIterator varname="v2">
-                        <ForVarIterator varname="p"/>
-                      </LetVarIterator>
-                    </SpecificNumArithIterator_AddOperation_DOUBLE>
-                  </ReturnClause>
-                </flwor::FLWORIterator>
-              </FunctionTraceIterator>
-              <LetVarIterator varname="direction"/>
-              <ForVarIterator varname="shape"/>
-              <ForVarIterator varname="scene"/>
-              <ForVarIterator varname="contribution"/>
-            </UDFunctionCallIterator>
-          </ReturnClause>
-        </flwor::FLWORIterator>
+                </UDFunctionCallIterator>
+              </flwor::LetIterator>
+              <FnExistsIterator>
+                <LetVarIterator varname="distance"/>
+              </FnExistsIterator>
+            </flwor::WhereIterator>
+          </flwor::OrderByIterator>
+          <UDFunctionCallIterator>
+            <FunctionTraceIterator>
+              <flwor::FLWORIterator>
+                <LetVariable name="v2" materialize="true">
+                  <FunctionTraceIterator>
+                    <flwor::FLWORIterator>
+                      <ForVariable name="y">
+                        <LetVarIterator varname="direction"/>
+                      </ForVariable>
+                      <ReturnClause>
+                        <SpecificNumArithIterator_MultiplyOperation_DOUBLE>
+                          <LetVarIterator varname="distance"/>
+                          <ForVarIterator varname="y"/>
+                        </SpecificNumArithIterator_MultiplyOperation_DOUBLE>
+                      </ReturnClause>
+                    </flwor::FLWORIterator>
+                  </FunctionTraceIterator>
+                </LetVariable>
+                <ForVariable name="x">
+                  <LetVarIterator varname="source"/>
+                </ForVariable>
+                <ReturnClause>
+                  <SpecificNumArithIterator_AddOperation_DOUBLE>
+                    <ForVarIterator varname="x"/>
+                    <LetVarIterator varname="v2">
+                      <ForVarIterator varname="p"/>
+                    </LetVarIterator>
+                  </SpecificNumArithIterator_AddOperation_DOUBLE>
+                </ReturnClause>
+              </flwor::FLWORIterator>
+            </FunctionTraceIterator>
+            <LetVarIterator varname="direction"/>
+            <ForVarIterator varname="$$context-item"/>
+            <ForVarIterator varname="scene"/>
+            <ForVarIterator varname="contribution"/>
+          </UDFunctionCallIterator>
+        </flwor::TupleStreamIterator>
         <FunctionTraceIterator>
           <flwor::FLWORIterator>
             <ForVariable name="a">

=== added file 'test/rbkt/ExpQueryResults/zorba/index/match_veq_01.xml.res'
--- test/rbkt/ExpQueryResults/zorba/index/match_veq_01.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/index/match_veq_01.xml.res	2012-12-21 04:09:22 +0000
@@ -0,0 +1,1 @@
+<account name="George" email="george@xxxxxxxxx"/>

=== added file 'test/rbkt/ExpQueryResults/zorba/index/match_veq_02.xml.res'
--- test/rbkt/ExpQueryResults/zorba/index/match_veq_02.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/index/match_veq_02.xml.res	2012-12-21 04:09:22 +0000
@@ -0,0 +1,1 @@
+<data>1111111111</data><data>3333333333</data>

=== added file 'test/rbkt/ExpQueryResults/zorba/index/match_veq_03.xml.res'
--- test/rbkt/ExpQueryResults/zorba/index/match_veq_03.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/index/match_veq_03.xml.res	2012-12-21 04:09:22 +0000
@@ -0,0 +1,1 @@
+<data>1111111111</data><data>3333333333</data>

=== added file 'test/rbkt/ExpQueryResults/zorba/index/match_veq_04.xml.res'
--- test/rbkt/ExpQueryResults/zorba/index/match_veq_04.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/index/match_veq_04.xml.res	2012-12-21 04:09:22 +0000
@@ -0,0 +1,1 @@
+<data>1111111111</data><data>3333333333</data>

=== added file 'test/rbkt/ExpQueryResults/zorba/index/match_veq_05.xml.res'
--- test/rbkt/ExpQueryResults/zorba/index/match_veq_05.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/index/match_veq_05.xml.res	2012-12-21 04:09:22 +0000
@@ -0,0 +1,1 @@
+<data>6666666</data><data>1111111111</data><data>6666666</data>

=== added file 'test/rbkt/ExpQueryResults/zorba/index/match_veq_06.xml.res'
--- test/rbkt/ExpQueryResults/zorba/index/match_veq_06.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/index/match_veq_06.xml.res	2012-12-21 04:09:22 +0000
@@ -0,0 +1,3 @@
+<parent uri="" child="/zorba"/>
+<parent uri="/zorba" child="/zorba/repo"/>
+<parent uri="/zorba/repo" child="/zorba/repo/index"/>

=== added file 'test/rbkt/ExpQueryResults/zorba/index/match_veq_07.xml.res'
--- test/rbkt/ExpQueryResults/zorba/index/match_veq_07.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/index/match_veq_07.xml.res	2012-12-21 04:09:22 +0000
@@ -0,0 +1,1 @@
+<item person="Huei Demke">0</item><item person="Daishiro Juric">0</item><item person="Kawon Unni">0</item><item person="Ewing Andrade">0</item><item person="Jamaludin Kleiser">0</item><item person="Eliana Ruemmler">0</item><item person="Bassem Nagasaki">0</item><item person="Mehrdad McCay">0</item><item person="Bassem Manderick">1</item><item person="Jarkko Nozawa">0</item><item person="Masanao Marsiglia">1</item><item person="Saul Schaap">2</item><item person="Kishor Monkewich">2</item><item person="Martti Halgason">0</item><item person="Laurian Grass">3</item><item person="Shooichi Oerlemans">0</item><item person="Uzi Atrawala">0</item><item person="Aloys Singleton">1</item><item person="Maha DuBourdieux">0</item><item person="Masaski Carrere">0</item><item person="Nestoras Gausemeier">0</item><item person="Yechezkel Calmet">0</item><item person="Slavian Usery">0</item><item person="Piere Schiex">0</item><item person="Shaoyun Morreau">0</item>

=== modified file 'test/rbkt/Queries/zorba/collections/collection_001.xqdata'
--- test/rbkt/Queries/zorba/collections/collection_001.xqdata	2012-12-11 14:47:49 +0000
+++ test/rbkt/Queries/zorba/collections/collection_001.xqdata	2012-12-21 04:09:22 +0000
@@ -8,7 +8,7 @@
 
 declare collection ns:collection-objects as object()*;
 
-declare %ann:ordered collection ns:collection2;
+declare %ann:ordered collection ns:collection2 as document-node();
 
 declare %ann:const collection ns:collection_const as node()*;
 

=== added file 'test/rbkt/Queries/zorba/index/match_veq_01.xq'
--- test/rbkt/Queries/zorba/index/match_veq_01.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/index/match_veq_01.xq	2012-12-21 04:09:22 +0000
@@ -0,0 +1,39 @@
+
+import module namespace accounts="www.accounts.com" at "match_veq_01.xqlib";
+
+import module namespace ddl = 
+"http://www.zorba-xquery.com/modules/store/static/collections/ddl";;
+
+import module namespace dml = 
+"http://www.zorba-xquery.com/modules/store/static/collections/dml";;
+
+import module namespace iddl = 
+"http://www.zorba-xquery.com/modules/store/static/indexes/ddl";;
+
+
+declare variable $doc := 
+<accounts>
+<account name="John" email="john@xxxxxxxxx"/>
+<account name="George" email="george@xxxxxxxxx"/>
+</accounts>;
+
+
+declare function local:account($email as xs:string?) as element(account)?
+{
+  dml:collection(xs:QName('accounts:accounts'))[xs:string(@email) eq lower-case($email)]
+};
+
+
+ddl:create(xs:QName("accounts:accounts"));
+
+iddl:create(xs:QName("accounts:accounts-index"));
+
+for $acc in $doc/account
+return dml:insert(xs:QName('accounts:accounts'), $acc);
+
+local:account("George@xxxxxxxxx")
+,
+"
+"
+
+

=== added file 'test/rbkt/Queries/zorba/index/match_veq_01.xqlib'
--- test/rbkt/Queries/zorba/index/match_veq_01.xqlib	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/index/match_veq_01.xqlib	2012-12-21 04:09:22 +0000
@@ -0,0 +1,23 @@
+
+
+module namespace accounts = "www.accounts.com";
+
+import module namespace ddl = 
+"http://www.zorba-xquery.com/modules/store/static/collections/ddl";;
+
+import module namespace dml = 
+"http://www.zorba-xquery.com/modules/store/static/collections/dml";;
+
+import module namespace iddl = 
+"http://www.zorba-xquery.com/modules/store/static/indexes/ddl";;
+
+declare namespace an = "http://www.zorba-xquery.com/annotations";;
+
+
+declare collection accounts:accounts as element(account);
+
+
+declare %an:automatic %an:unique %an:value-equality index accounts:accounts-index
+on nodes dml:collection(xs:QName('accounts:accounts'))
+by xs:string(@email) as xs:string?;
+

=== added file 'test/rbkt/Queries/zorba/index/match_veq_02.xq'
--- test/rbkt/Queries/zorba/index/match_veq_02.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/index/match_veq_02.xq	2012-12-21 04:09:22 +0000
@@ -0,0 +1,50 @@
+
+import module namespace s="www.sessions.com" at "match_veq_02.xqlib";
+
+import module namespace ddl = 
+"http://www.zorba-xquery.com/modules/store/static/collections/ddl";;
+
+import module namespace dml = 
+"http://www.zorba-xquery.com/modules/store/static/collections/dml";;
+
+import module namespace iddl = 
+"http://www.zorba-xquery.com/modules/store/static/indexes/ddl";;
+
+
+declare variable $external_id external := "50";
+
+declare variable $doc := 
+<sessions>
+<session id="50"><data>1111111111</data></session>
+<session id="12"><data>2222222222</data></session>
+<session id="50"><data>3333333333</data></session>
+</sessions>;
+
+
+ddl:create($s:sessions);
+
+iddl:create(xs:QName("s:session-index"));
+
+for $s in $doc/session
+return dml:insert($s:sessions, $s);
+
+
+let $id := $external_id
+
+let $session := 
+  for $session in dml:collection($s:sessions)
+  where xs:string($session/@id) eq $id
+  return $session
+
+return
+if (empty($session)) then 
+{
+  fn:trace($id, "no session with the given uuid")
+}
+else
+{
+  $session/data
+}
+,
+"
+"

=== added file 'test/rbkt/Queries/zorba/index/match_veq_02.xqlib'
--- test/rbkt/Queries/zorba/index/match_veq_02.xqlib	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/index/match_veq_02.xqlib	2012-12-21 04:09:22 +0000
@@ -0,0 +1,24 @@
+
+
+module namespace sessions = "www.sessions.com";
+
+import module namespace ddl = 
+"http://www.zorba-xquery.com/modules/store/static/collections/ddl";;
+
+import module namespace dml = 
+"http://www.zorba-xquery.com/modules/store/static/collections/dml";;
+
+import module namespace iddl = 
+"http://www.zorba-xquery.com/modules/store/static/indexes/ddl";;
+
+declare namespace an = "http://www.zorba-xquery.com/annotations";;
+
+
+declare collection sessions:sessions as element();
+
+declare variable $sessions:sessions as xs:QName := xs:QName("sessions:sessions");
+
+declare %an:automatic %an:nonunique %an:value-equality index sessions:session-index
+on nodes dml:collection(xs:QName("sessions:sessions"))
+by xs:string(@id) as xs:string?;
+

=== added file 'test/rbkt/Queries/zorba/index/match_veq_03.xq'
--- test/rbkt/Queries/zorba/index/match_veq_03.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/index/match_veq_03.xq	2012-12-21 04:09:22 +0000
@@ -0,0 +1,50 @@
+
+import module namespace s="www.sessions.com" at "match_veq_03.xqlib";
+
+import module namespace ddl = 
+"http://www.zorba-xquery.com/modules/store/static/collections/ddl";;
+
+import module namespace dml = 
+"http://www.zorba-xquery.com/modules/store/static/collections/dml";;
+
+import module namespace iddl = 
+"http://www.zorba-xquery.com/modules/store/static/indexes/ddl";;
+
+
+declare variable $external_id external := "50";
+
+declare variable $doc := 
+<sessions>
+<session id="50"><data>1111111111</data></session>
+<session id="12"><data>2222222222</data></session>
+<session id="50"><data>3333333333</data></session>
+</sessions>;
+
+
+ddl:create($s:sessions);
+
+iddl:create(xs:QName("s:session-index"));
+
+for $s in $doc/session
+return dml:insert($s:sessions, $s);
+
+
+let $id := $external_id
+
+let $session := 
+  for $session in dml:collection($s:sessions)
+  where xs:string($session/@id) eq $id
+  return $session
+
+return
+if (empty($session)) then 
+{
+  fn:trace($id, "no session with the given uuid")
+}
+else
+{
+  $session/data
+}
+,
+"
+"

=== added file 'test/rbkt/Queries/zorba/index/match_veq_03.xqlib'
--- test/rbkt/Queries/zorba/index/match_veq_03.xqlib	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/index/match_veq_03.xqlib	2012-12-21 04:09:22 +0000
@@ -0,0 +1,22 @@
+
+module namespace sessions = "www.sessions.com";
+
+import module namespace ddl = 
+"http://www.zorba-xquery.com/modules/store/static/collections/ddl";;
+
+import module namespace dml = 
+"http://www.zorba-xquery.com/modules/store/static/collections/dml";;
+
+import module namespace iddl = 
+"http://www.zorba-xquery.com/modules/store/static/indexes/ddl";;
+
+declare namespace an = "http://www.zorba-xquery.com/annotations";;
+
+
+declare collection sessions:sessions as element();
+
+declare variable $sessions:sessions := xs:QName("sessions:sessions");
+
+declare %an:automatic %an:nonunique %an:value-equality index sessions:session-index
+on nodes dml:collection(xs:QName("sessions:sessions"))
+by xs:string(@id) as xs:string?;

=== added file 'test/rbkt/Queries/zorba/index/match_veq_04.xq'
--- test/rbkt/Queries/zorba/index/match_veq_04.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/index/match_veq_04.xq	2012-12-21 04:09:22 +0000
@@ -0,0 +1,49 @@
+import module namespace s="www.sessions.com" at "match_veq_04.xqlib";
+
+import module namespace ddl = 
+"http://www.zorba-xquery.com/modules/store/static/collections/ddl";;
+
+import module namespace dml = 
+"http://www.zorba-xquery.com/modules/store/static/collections/dml";;
+
+import module namespace iddl = 
+"http://www.zorba-xquery.com/modules/store/static/indexes/ddl";;
+
+
+declare variable $external_id external := "50";
+
+declare variable $doc := 
+<sessions>
+<session id="50" duration="130"><data>1111111111</data></session>
+<session id="12" duration="30"><data>2222222222</data></session>
+<session id="50" duration="150"><data>3333333333</data></session>
+</sessions>;
+
+
+ddl:create($s:sessions);
+
+iddl:create(xs:QName("s:session-index"));
+
+for $s in $doc/session
+return dml:insert($s:sessions, $s);
+
+
+let $id := $external_id
+
+let $session := 
+  for $session in dml:collection($s:sessions)[@duration > 120]
+  where xs:string($session/@id) eq $id
+  return $session
+
+return
+if (empty($session)) then 
+{
+  fn:trace($id, "no session with the given uuid")
+}
+else
+{
+  $session/data
+}
+,
+"
+"

=== added file 'test/rbkt/Queries/zorba/index/match_veq_04.xqlib'
--- test/rbkt/Queries/zorba/index/match_veq_04.xqlib	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/index/match_veq_04.xqlib	2012-12-21 04:09:22 +0000
@@ -0,0 +1,21 @@
+module namespace sessions = "www.sessions.com";
+
+import module namespace ddl = 
+"http://www.zorba-xquery.com/modules/store/static/collections/ddl";;
+
+import module namespace dml = 
+"http://www.zorba-xquery.com/modules/store/static/collections/dml";;
+
+import module namespace iddl = 
+"http://www.zorba-xquery.com/modules/store/static/indexes/ddl";;
+
+declare namespace an = "http://www.zorba-xquery.com/annotations";;
+
+
+declare collection sessions:sessions;
+
+declare variable $sessions:sessions := xs:QName("sessions:sessions");
+
+declare %an:automatic %an:nonunique %an:value-equality index sessions:session-index
+on nodes dml:collection(xs:QName("sessions:sessions"))[@duration > 120]
+by xs:string(@id) as xs:string?;

=== added file 'test/rbkt/Queries/zorba/index/match_veq_05.xq'
--- test/rbkt/Queries/zorba/index/match_veq_05.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/index/match_veq_05.xq	2012-12-21 04:09:22 +0000
@@ -0,0 +1,61 @@
+import module namespace s="www.sessions.com" at "match_veq_05.xqlib";
+
+import module namespace ddl = 
+"http://www.zorba-xquery.com/modules/store/static/collections/ddl";;
+
+import module namespace dml = 
+"http://www.zorba-xquery.com/modules/store/static/collections/dml";;
+
+import module namespace iddl = 
+"http://www.zorba-xquery.com/modules/store/static/indexes/ddl";;
+
+
+declare variable $external_id external := "50";
+
+declare variable $doc := 
+<sessions>
+<session id="50" duration="130"><data>1111111111</data></session>
+<session id="12" duration="30"><data>2222222222</data></session>
+<session id="50" duration="150"><data>3333333333</data></session>
+</sessions>;
+
+declare variable $doc2 := 
+<sessions>
+<session id="50" duration="130"><data>6666666</data></session>
+<session id="70" duration="150"><data>7777777</data></session>
+</sessions>;
+
+
+ddl:create($s:sessions);
+
+iddl:create(xs:QName("s:session-index"));
+
+for $s in $doc/session
+return dml:insert($s:sessions, $s);
+
+for $s in $doc2/session
+return dml:insert-first($s:sessions, $s);
+
+for $s in $doc2/session
+return dml:insert-last($s:sessions, $s);
+
+
+let $id := $external_id
+
+let $session := 
+  for $session in dml:collection($s:sessions)[120 < @duration and @duration < 150]
+  where $id eq $session/@id
+  return $session
+
+return
+if (empty($session)) then 
+{
+  fn:trace($id, "no session with the given uuid")
+}
+else
+{
+  $session/data
+}
+,
+"
+"

=== added file 'test/rbkt/Queries/zorba/index/match_veq_05.xqlib'
--- test/rbkt/Queries/zorba/index/match_veq_05.xqlib	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/index/match_veq_05.xqlib	2012-12-21 04:09:22 +0000
@@ -0,0 +1,21 @@
+module namespace sessions = "www.sessions.com";
+
+import module namespace ddl = 
+"http://www.zorba-xquery.com/modules/store/static/collections/ddl";;
+
+import module namespace dml = 
+"http://www.zorba-xquery.com/modules/store/static/collections/dml";;
+
+import module namespace iddl = 
+"http://www.zorba-xquery.com/modules/store/static/indexes/ddl";;
+
+declare namespace an = "http://www.zorba-xquery.com/annotations";;
+
+
+declare %an:ordered collection sessions:sessions;
+
+declare variable $sessions:sessions := xs:QName("sessions:sessions");
+
+declare %an:automatic %an:nonunique %an:value-equality index sessions:session-index
+on nodes dml:collection(xs:QName("sessions:sessions"))[@duration > 120]
+by @id as xs:string?;

=== added file 'test/rbkt/Queries/zorba/index/match_veq_06.xq'
--- test/rbkt/Queries/zorba/index/match_veq_06.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/index/match_veq_06.xq	2012-12-21 04:09:22 +0000
@@ -0,0 +1,26 @@
+import module namespace d="www.data.com" at "match_veq_06.xqlib";
+
+import module namespace doc = 
+"http://www.zorba-xquery.com/modules/store/dynamic/documents";;
+
+import module namespace ddl = 
+"http://www.zorba-xquery.com/modules/store/static/collections/ddl";;
+
+import module namespace dml = 
+"http://www.zorba-xquery.com/modules/store/static/collections/dml";;
+
+import module namespace iddl = 
+"http://www.zorba-xquery.com/modules/store/static/indexes/ddl";;
+
+
+ddl:create($d:parents);
+
+iddl:create($d:idx);
+
+d:add-document(xs:anyURI("http://www.xmlteam.com/zorba/repo/index";), true());
+
+
+dml:collection($d:parents)
+,
+"
+"

=== added file 'test/rbkt/Queries/zorba/index/match_veq_06.xqlib'
--- test/rbkt/Queries/zorba/index/match_veq_06.xqlib	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/index/match_veq_06.xqlib	2012-12-21 04:09:22 +0000
@@ -0,0 +1,99 @@
+
+module namespace data = "www.data.com";
+
+import module namespace ddl = 
+"http://www.zorba-xquery.com/modules/store/static/collections/ddl";;
+
+import module namespace dml = 
+"http://www.zorba-xquery.com/modules/store/static/collections/dml";;
+
+import module namespace iddl = 
+"http://www.zorba-xquery.com/modules/store/static/indexes/ddl";;
+
+import module namespace idml = 
+"http://www.zorba-xquery.com/modules/store/static/indexes/dml";;
+
+import module namespace doc = 
+"http://www.zorba-xquery.com/modules/store/dynamic/documents";;
+
+declare namespace an = "http://www.zorba-xquery.com/annotations";;
+
+
+declare collection data:parents;
+
+declare variable $data:parents as xs:QName := xs:QName('data:parents');
+
+
+declare %private %an:automatic %an:value-equality %an:unique index data:idx
+  on nodes dml:collection(xs:QName('data:parents'))
+  by @uri as xs:string,
+     @child as xs:string;
+
+declare variable $data:idx as xs:QName := xs:QName('data:idx');
+
+
+declare %an:sequential function 
+data:add-document(
+    $docURI as xs:anyURI,
+    $overwrite as xs:boolean) as empty-sequence()
+{
+  variable $doc-uri := substring-after($docURI, "http://www.xmlteam.com";);
+  variable $segments := tokenize($doc-uri, "/");
+
+  for $segment at $i in $segments
+  let $parent := string-join(subsequence($segments, 1, $i - 1), "/")
+  let $child := string-join(subsequence($segments, 1, $i), "/")
+  where $i gt 1 and empty(for $p in dml:collection($data:parents)
+                          where $p/@uri eq $parent and $p/@child eq $child
+                          return $p)
+  return 
+  {
+    dml:insert-nodes($data:parents, <parent uri="{$parent}" child="{$child}"/>);
+  }
+
+  if ($overwrite and data:doc-exists($doc-uri)) then
+    data:remove-document($docURI);
+  else
+    ();
+};
+
+
+declare %an:sequential function 
+data:remove-document($docURI as xs:anyURI) as empty-sequence()
+{
+  let $uri := substring-after(trace($docURI, "uri"), "http://www.xmlteam.com";)
+
+  let $tokens := tokenize($uri, "/")
+
+  let $parent-uri := string-join(subsequence($tokens, 1, count($tokens) - 1), "/")
+
+  let $child-uri := string-join($tokens, "/")
+
+  let $parent := for $p in dml:collection($data:parents)
+                 where $p/@uri eq $parent-uri and $p/@child eq $child-uri
+                 return $p
+  return 
+  {
+    trace($parent-uri, "parent");
+    trace($child-uri, "child");
+    dml:delete-nodes($parent);
+  }
+};
+
+
+declare function 
+data:doc-exists($docURI as xs:string) as xs:boolean
+{
+  if (try
+      {
+        doc:document($docURI)
+      }
+      catch *
+      {
+        ()
+      })
+  then
+    true()
+  else
+    false()
+};

=== added file 'test/rbkt/Queries/zorba/index/match_veq_07.xq'
--- test/rbkt/Queries/zorba/index/match_veq_07.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/index/match_veq_07.xq	2012-12-21 04:09:22 +0000
@@ -0,0 +1,27 @@
+
+import module namespace x="www.xmark.com" at "match_veq_07.xqlib";
+
+import module namespace ddl = 
+"http://www.zorba-xquery.com/modules/store/static/collections/ddl";;
+
+import module namespace dml = 
+"http://www.zorba-xquery.com/modules/store/static/collections/dml";;
+
+import module namespace iddl = 
+"http://www.zorba-xquery.com/modules/store/static/indexes/ddl";;
+
+
+ddl:create($x:auctions);
+
+iddl:create($x:idx);
+
+dml:insert($x:auctions, doc("auction.xml"));
+
+let $auctions := dml:collection($x:auctions) 
+return
+  for $p in $auctions/site/people/person
+  let $a :=
+    for $t in $auctions/site/closed_auctions/closed_auction
+    where $t/buyer/@person eq $p/@id
+    return $t
+  return <item person="{$p/name/text()}">{count($a)}</item>

=== added file 'test/rbkt/Queries/zorba/index/match_veq_07.xqlib'
--- test/rbkt/Queries/zorba/index/match_veq_07.xqlib	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/index/match_veq_07.xqlib	2012-12-21 04:09:22 +0000
@@ -0,0 +1,30 @@
+module namespace x = "www.xmark.com";
+
+import module namespace ddl = 
+"http://www.zorba-xquery.com/modules/store/static/collections/ddl";;
+
+import module namespace dml = 
+"http://www.zorba-xquery.com/modules/store/static/collections/dml";;
+
+import module namespace iddl = 
+"http://www.zorba-xquery.com/modules/store/static/indexes/ddl";;
+
+import module namespace idml = 
+"http://www.zorba-xquery.com/modules/store/static/indexes/dml";;
+
+import module namespace doc = 
+"http://www.zorba-xquery.com/modules/store/dynamic/documents";;
+
+declare namespace an = "http://www.zorba-xquery.com/annotations";;
+
+
+declare collection x:auctions;
+
+declare variable $x:auctions as xs:QName := xs:QName('x:auctions');
+
+
+declare %private %an:automatic %an:value-equality index x:idx
+  on nodes dml:collection(xs:QName('x:auctions'))/site/closed_auctions/closed_auction
+  by buyer/@person as xs:string?;
+
+declare variable $x:idx as xs:QName := xs:QName('x:idx');


Follow ups