← Back to team overview

zorba-coders team mailing list archive

[Merge] lp:~zorba-coders/zorba/markos-scratch into lp:zorba

 

Markos Zaharioudakis has proposed merging lp:~zorba-coders/zorba/markos-scratch into lp:zorba.

Commit message:
made $objects() equivalent to jn:keys($objects) + optimized jsoniq navigation

Requested reviews:
  Markos Zaharioudakis (markos-za)

For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/markos-scratch/+merge/180553

made $objects() equivalent to jn:keys($objects) + optimized jsoniq navigation
-- 
https://code.launchpad.net/~zorba-coders/zorba/markos-scratch/+merge/180553
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'modules/org/jsoniq/www/function-library.xq'
--- modules/org/jsoniq/www/function-library.xq	2013-08-14 16:32:41 +0000
+++ modules/org/jsoniq/www/function-library.xq	2013-08-16 13:03:04 +0000
@@ -46,7 +46,7 @@
  :        accumulated into a single object.
  : @return The accumulated object.
  :)
-declare function libjn:accumulate($items as item()*) as object()
+declare function libjn:accumulate($items as item*) as object
 {
   {[ $items ]}
 };
@@ -58,7 +58,7 @@
  : @param $items A sequence of items.
  : @return The descendant arrays of the input sequence.
  :)
-declare function libjn:descendant-arrays($items as item()*) as array()*
+declare function libjn:descendant-arrays($items as item*) as array*
 {
   for $i in $items
   return libjn:descendant-arrays-priv($i)
@@ -71,20 +71,20 @@
  : @param $i An item
  : @return The descendant arrays of the item
  :)
-declare %private function libjn:descendant-arrays-priv($i as item()) as array()*
+declare %private function libjn:descendant-arrays-priv($i as item) as array*
 {
   typeswitch ($i)
 
-  case object() return
+  case object return
     for $v in libjn:values($i)
-    where $v instance of json-item()
+    where $v instance of json-item
     return libjn:descendant-arrays-priv($v)
 
-  case array() return
+  case array return
     (
     $i,
     for $v in $i[]
-    where $v instance of json-item()
+    where $v instance of json-item
     return libjn:descendant-arrays-priv($v)
     )
 
@@ -99,7 +99,7 @@
  : @param $items A sequence of items.
  : @return The descendant objects of the input sequence.
  :)
-declare function libjn:descendant-objects($items as item()*) as object()*
+declare function libjn:descendant-objects($items as item*) as object*
 {
   for $i in $items
   return libjn:descendant-objects-priv($i)
@@ -112,21 +112,21 @@
  : @param $i An item
  : @return The descendant objects of the item
  :)
-declare %private function libjn:descendant-objects-priv($i as item()) as object()*
+declare %private function libjn:descendant-objects-priv($i as item) as object*
 {
-  if ($i instance of object())
+  if ($i instance of object)
   then
     (
       $i,
       for $v in libjn:values($i)
-      where $v instance of json-item()
+      where $v instance of json-item
       return libjn:descendant-objects-priv($v)
     )
-  else if ($i instance of array())
+  else if ($i instance of array)
   then
     (
       for $v in $i[]
-      where $v instance of json-item()
+      where $v instance of json-item
       return libjn:descendant-objects-priv($v)
     )
   else
@@ -140,7 +140,7 @@
  : @param $o An object.
  : @return All direct and indirect descendant pairs.
  :)
-declare function libjn:descendant-pairs($items as item()*) as object()*
+declare function libjn:descendant-pairs($items as item*) as object*
 {
   for $i in $items
   return libjn:descendant-pairs-priv($i)
@@ -153,11 +153,11 @@
  : @param $i An item
  : @return The descendant pairs of the item
  :)
-declare function libjn:descendant-pairs-priv($i as item()) as object()*
+declare function libjn:descendant-pairs-priv($i as item) as object*
 {
   typeswitch ($i)
 
-  case $o as object() return
+  case $o as object return
     for $k in jn:keys($o)
     return
       (
@@ -165,9 +165,9 @@
       libjn:descendant-pairs-priv($o($k))
       )
 
-  case $a as array() return
+  case $a as array return
     for $i in $a[]
-    where $i instance of json-item()
+    where $i instance of json-item
     return libjn:descendant-pairs-priv($i)
 
   default return
@@ -183,10 +183,10 @@
  : @param $items A sequence of items.
  : @return The insersection of the objects contained in $items.
  :)
-declare function libjn:intersect($items as item()*) as object()
+declare function libjn:intersect($items as item*) as object
 {
   {|
-    let $objects := $items[$$ instance of object()]
+    let $objects := $items[$$ instance of object]
     for $key in keys(head($objects))
     where every $o in tail($objects)
           satisfies exists(index-of(keys($o), $key))
@@ -201,10 +201,10 @@
  : @param $items A sequence of items.
  : @return The values inside the objects of the sequence.
  :)
-declare function libjn:values($items as item()*) as item()*
+declare function libjn:values($items as item*) as item*
 {
   for $i in $items
   for $k in jn:keys($i)
-  return ($i treat as object())($k)
+  return ($i treat as object)($k)
 };
 

=== modified file 'modules/org/jsoniq/www/functions.xq'
--- modules/org/jsoniq/www/functions.xq	2013-08-14 15:16:42 +0000
+++ modules/org/jsoniq/www/functions.xq	2013-08-16 13:03:04 +0000
@@ -174,7 +174,7 @@
  :   if jsoniq-multiple-top-level-items is false and there is additional
  :   content after the first JSON Object or Array.
  : @error jerr:JNTY0020 if the value for the option
- :   jsoniq-multiple-top-level-items is not of type xs:boolean.
+ :   jsoniq-multiple-top-level-items is not of type boolean.
  :
  : @return a sequence of JSON Object or Array item.
  :)

=== modified file 'src/api/staticcontextimpl.cpp'
--- src/api/staticcontextimpl.cpp	2013-08-06 08:41:26 +0000
+++ src/api/staticcontextimpl.cpp	2013-08-16 13:03:04 +0000
@@ -452,12 +452,19 @@
 ********************************************************************************/
 xquery_version_t StaticContextImpl::getXQueryVersion() const
 {
-  try {
-    return theCtx->xquery_version()==StaticContextConsts::xquery_version_1_0?
-      xquery_version_1_0:xquery_version_3_0;
-  } catch (ZorbaException const& e) {
+  try
+  {
+    return
+    (theCtx->xquery_version() == StaticContextConsts::xquery_version_1_0 ?
+     xquery_version_1_0 :
+     xquery_version_3_0);
+  }
+  catch (ZorbaException const& e)
+  {
     ZorbaImpl::notifyError(theDiagnosticHandler, e);
-  } catch (std::exception const& e) {
+  }
+  catch (std::exception const& e)
+  {
     ZorbaImpl::notifyError(theDiagnosticHandler, e.what());
   }
   return xquery_version_1_0;
@@ -469,14 +476,19 @@
 ********************************************************************************/
 jsoniq_version_t StaticContextImpl::getJSONiqVersion() const
 {
-  try {
+  try 
+  {
     if (theCtx->language_kind() != StaticContextConsts::language_kind_jsoniq)
       return jsoniq_version_undefined;
     return theCtx->jsoniq_version()==StaticContextConsts::jsoniq_version_1_0?
       jsoniq_version_1_0:jsoniq_version_undefined;
-  } catch (ZorbaException const& e) {
+  }
+  catch (ZorbaException const& e)
+  {
     ZorbaImpl::notifyError(theDiagnosticHandler, e);
-  } catch (std::exception const& e) {
+  }
+  catch (std::exception const& e)
+  {
     ZorbaImpl::notifyError(theDiagnosticHandler, e.what());
   }
   return jsoniq_version_undefined;

=== modified file 'src/compiler/codegen/plan_visitor.cpp'
--- src/compiler/codegen/plan_visitor.cpp	2013-07-01 18:59:06 +0000
+++ src/compiler/codegen/plan_visitor.cpp	2013-08-16 13:03:04 +0000
@@ -516,13 +516,13 @@
 {
   CODEGEN_TRACE_OUT("");
 
-  csize numArgs = v.get_args().size() + 1;
+  csize numArgs = v.get_args().size();
 
   std::vector<PlanIter_t> argIters;
   
   bool isPartialApply = false;
   
-  for (csize i = 0; i < numArgs-1; ++i)
+  for (csize i = 0; i < numArgs; ++i)
   {
     if (v.get_args()[i]->get_expr_kind() == argument_placeholder_expr_kind)
       isPartialApply = true;
@@ -534,7 +534,10 @@
 
   std::reverse(argIters.begin(), argIters.end());
 
-  push_itstack(new DynamicFnCallIterator(sctx, qloc, argIters, isPartialApply));
+  if (numArgs > 0 || v.get_input()->get_return_type()->max_card() <= 1)
+    push_itstack(new SingleDynamicFnCallIterator(sctx, qloc, argIters, isPartialApply));
+  else
+    push_itstack(new MultiDynamicFnCallIterator(sctx, qloc, argIters[0]));
 }
 
 

=== modified file 'src/compiler/expression/expr_type.cpp'
--- src/compiler/expression/expr_type.cpp	2013-06-15 02:57:08 +0000
+++ src/compiler/expression/expr_type.cpp	2013-08-16 13:03:04 +0000
@@ -638,7 +638,12 @@
     static_cast<dynamic_function_invocation_expr*>(this);
 
     xqtref_t fiType = e->theExpr->get_return_type();
-    if (fiType->type_kind() == XQType::FUNCTION_TYPE_KIND)
+
+    if (fiType->max_card() == 0)
+    {
+      newType = rtm.EMPTY_TYPE;
+    }
+    else if (fiType->type_kind() == XQType::FUNCTION_TYPE_KIND)
     {
       const FunctionXQType* funcType = static_cast<const FunctionXQType*>(fiType.getp());
       newType = funcType->get_return_type();

=== modified file 'src/compiler/expression/function_item_expr.h'
--- src/compiler/expression/function_item_expr.h	2013-07-02 21:32:23 +0000
+++ src/compiler/expression/function_item_expr.h	2013-08-16 13:03:04 +0000
@@ -95,7 +95,7 @@
       const std::vector<expr*>& args);
 
 public:
-  expr* get_function() const { return theExpr; }
+  expr* get_input() const { return theExpr; }
 
   const std::vector<expr*>& get_args() const { return theArgs; }
   

=== modified file 'src/compiler/rewriter/rules/type_rules.cpp'
--- src/compiler/rewriter/rules/type_rules.cpp	2013-06-27 15:54:27 +0000
+++ src/compiler/rewriter/rules/type_rules.cpp	2013-08-16 13:03:04 +0000
@@ -108,7 +108,9 @@
   {
     fo_expr* fo = static_cast<fo_expr *>(node);
 
-    if (fo->get_func()->getKind() == FunctionConsts::FN_BOOLEAN_1)
+    switch (fo->get_func()->getKind())
+    {
+    case FunctionConsts::FN_BOOLEAN_1:
     {
       expr* arg = fo->get_arg(0);
       xqtref_t arg_type = arg->get_return_type();
@@ -118,7 +120,7 @@
         return NULL;
     }
 
-    if (fo->get_func()->getKind() == FunctionConsts::FN_DATA_1)
+    case FunctionConsts::FN_DATA_1:
     {
       expr* arg = fo->get_arg(0);
       xqtref_t arg_type = arg->get_return_type();
@@ -128,7 +130,7 @@
         return NULL;
     }
 
-    if (fo->get_func()->getKind() == FunctionConsts::OP_ZORBA_JSON_BOX_1)
+    case FunctionConsts::OP_ZORBA_JSON_BOX_1:
     {
       expr* arg = fo->get_arg(0);
       xqtref_t arg_type = arg->get_return_type();
@@ -147,6 +149,76 @@
       return NULL;
     }
 
+    case FunctionConsts::FN_JSONIQ_KEYS_1:
+    {
+      expr* arg = fo->get_arg(0);
+      xqtref_t arg_type = arg->get_return_type();
+
+      if (arg_type->max_card() <= 1)
+      {
+        return rCtx.theEM->
+               create_fo_expr(sctx, fo->get_udf(), fo->get_loc(),
+                              BUILTIN_FUNC(OP_ZORBA_KEYS_1),
+                              arg);
+      }
+
+      return NULL;
+    }
+
+    case FunctionConsts::OP_ZORBA_MULTI_OBJECT_LOOKUP_2:
+    {
+      expr* arg = fo->get_arg(0);
+      xqtref_t arg_type = arg->get_return_type();
+
+      if (arg_type->max_card() <= 1)
+      {
+        return rCtx.theEM->
+               create_fo_expr(sctx, fo->get_udf(), fo->get_loc(),
+                              BUILTIN_FUNC(OP_ZORBA_SINGLE_OBJECT_LOOKUP_2),
+                              arg, fo->get_arg(1));
+      }
+
+      return NULL;
+    }
+
+    case FunctionConsts::FN_JSONIQ_MEMBERS_1:
+    {
+      expr* arg = fo->get_arg(0);
+      xqtref_t arg_type = arg->get_return_type();
+
+      if (arg_type->max_card() <= 1)
+      {
+        return rCtx.theEM->
+               create_fo_expr(sctx, fo->get_udf(), fo->get_loc(),
+                              BUILTIN_FUNC(OP_ZORBA_MEMBERS_1),
+                              arg);
+      }
+
+      return NULL;
+    }
+
+    case FunctionConsts::OP_ZORBA_MULTI_ARRAY_LOOKUP_2:
+    {
+      expr* arg = fo->get_arg(0);
+      xqtref_t arg_type = arg->get_return_type();
+
+      if (arg_type->max_card() <= 1)
+      {
+        return rCtx.theEM->
+               create_fo_expr(sctx, fo->get_udf(), fo->get_loc(),
+                              BUILTIN_FUNC(OP_ZORBA_SINGLE_ARRAY_LOOKUP_2),
+                              arg, fo->get_arg(1));
+      }
+
+      return NULL;
+    }
+
+    default:
+    {
+      break;
+    }
+    }
+
     break;
   }
   case cast_expr_kind:

=== modified file 'src/compiler/rewriter/tools/expr_tools.cpp'
--- src/compiler/rewriter/tools/expr_tools.cpp	2013-05-24 16:34:11 +0000
+++ src/compiler/rewriter/tools/expr_tools.cpp	2013-08-16 13:03:04 +0000
@@ -394,7 +394,7 @@
     const dynamic_function_invocation_expr* ve =
     static_cast<const dynamic_function_invocation_expr*>(view);
 
-    if (!match_exact(qe->get_function(), ve->get_function(), subst))
+    if (!match_exact(qe->get_input(), ve->get_input(), subst))
       return false;
 
     if (qe->get_args().size() != ve->get_args().size())

=== modified file 'src/compiler/translator/translator.cpp'
--- src/compiler/translator/translator.cpp	2013-08-12 09:28:02 +0000
+++ src/compiler/translator/translator.cpp	2013-08-16 13:03:04 +0000
@@ -10835,38 +10835,29 @@
 
     expr* arrayExpr = sourceClause->get_expr();
     expr* selectorExpr = static_cast<json_array_expr*>(predExpr)->get_expr();
+    expr* accessorExpr;
 
     xqtref_t domainType = arrayExpr->get_return_type();
 
+    std::vector<expr*> args(2);
+    args[0] = arrayExpr;
+    args[1] = selectorExpr;
+
     if (domainType->max_card() > 1)
     {
-      expr* flworVarExpr = 
-      CREATE(wrapper)(theRootSctx, theUDF, loc, sourceClause->get_var());
-
-      std::vector<expr*> args(2);
-      args[0] = flworVarExpr;
-      args[1] = selectorExpr;
-
-      expr* accessorExpr =
-      generate_fn_body(BUILTIN_FUNC(OP_ZORBA_ARRAY_MEMBER_2), args, loc);
-
-      flworExpr->set_return_expr(accessorExpr);
-
-      push_nodestack(flworExpr);
+      accessorExpr =
+      generate_fn_body(BUILTIN_FUNC(OP_ZORBA_MULTI_ARRAY_LOOKUP_2), args, loc);
+
       pop_scope();
     }
     else
     {
-      std::vector<expr*> args(2);
-      args[0] = arrayExpr;
-      args[1] = selectorExpr;
-
-      expr* accessorExpr =
-      generate_fn_body(BUILTIN_FUNC(OP_ZORBA_ARRAY_MEMBER_2), args, loc);
-
-      push_nodestack(accessorExpr);
+      accessorExpr =
+      generate_fn_body(BUILTIN_FUNC(OP_ZORBA_SINGLE_ARRAY_LOOKUP_2), args, loc);
     }
 
+    push_nodestack(accessorExpr);
+
     return;
   }
 
@@ -10896,23 +10887,22 @@
       {
         expr* sourceExpr = sourceClause->get_expr();
         
-        if (sourceExpr->get_function_kind() == FunctionConsts::FN_JSONIQ_MEMBERS_1)
+        FunctionConsts::FunctionKind fkind = sourceExpr->get_function_kind();
+
+        if (fkind == FunctionConsts::OP_ZORBA_MEMBERS_1)
         {
           expr* arrayExpr = static_cast<fo_expr*>(sourceExpr)->get_arg(0);
           
-          if (arrayExpr->get_return_type()->max_card() <= 1)
-          {
-            fo_expr* pointExpr = 
-            CREATE(fo)(sourceExpr->get_sctx(), theUDF, sourceExpr->get_loc(),
-                       BUILTIN_FUNC(OP_ZORBA_ARRAY_MEMBER_2),
-                       arrayExpr,
-                       predExpr);
+          fo_expr* pointExpr = 
+          CREATE(fo)(sourceExpr->get_sctx(), theUDF, sourceExpr->get_loc(),
+                     BUILTIN_FUNC(OP_ZORBA_SINGLE_ARRAY_LOOKUP_2),
+                     arrayExpr,
+                     predExpr);
             
-            push_nodestack(pointExpr);
-            pop_scope();
+          push_nodestack(pointExpr);
+          pop_scope();
               
-            return;
-          }
+          return;
         }
           
         fo_expr* pointExpr = 
@@ -11084,45 +11074,20 @@
 
   expr* selectExpr = pop_nodestack();
   expr* objectExpr = pop_nodestack();
+  expr* accessorExpr;
 
   assert(selectExpr && objectExpr);
 
   xqtref_t domainType = objectExpr->get_return_type();
 
-  if (domainType->max_card() > 1)
-  {
-    flwor_expr* flworExpr = wrap_expr_in_flwor(objectExpr, false);
-
-    for_clause* fc = static_cast<for_clause*>(flworExpr->get_clause(0));
-
-    expr* flworVarExpr = CREATE(wrapper)(theRootSctx, theUDF, loc, fc->get_var());
-
-    std::vector<expr*> args(2);
-    args[0] = flworVarExpr;
-    args[1] = selectExpr;
-
-    expr* accessorExpr =
-    generate_fn_body(BUILTIN_FUNC(OP_ZORBA_OBJECT_VALUE_2), args, loc);
-
-    assert(accessorExpr->get_expr_kind() == fo_expr_kind);
-
-    flworExpr->set_return_expr(accessorExpr);
-
-    pop_scope();
-
-    push_nodestack(flworExpr);
-  }
-  else
-  {
-    std::vector<expr*> args(2);
-    args[0] = objectExpr;
-    args[1] = selectExpr;
-
-    expr* accessorExpr =
-    generate_fn_body(BUILTIN_FUNC(OP_ZORBA_OBJECT_VALUE_2), args, loc);
-
-    push_nodestack(accessorExpr);
-  }
+  std::vector<expr*> args(2);
+  args[0] = objectExpr;
+  args[1] = selectExpr;
+
+  accessorExpr =
+  generate_fn_body(BUILTIN_FUNC(OP_ZORBA_MULTI_OBJECT_LOOKUP_2), args, loc);
+
+  push_nodestack(accessorExpr);
 }
 
 
@@ -12221,26 +12186,34 @@
 
     break;
   }
-  case FunctionConsts::OP_ZORBA_OBJECT_VALUE_2:
+  case FunctionConsts::OP_ZORBA_MULTI_OBJECT_LOOKUP_2:
+  {
+    if (arguments[0]->get_return_type()->max_card() <= 1)
+      f = BUILTIN_FUNC(OP_ZORBA_SINGLE_OBJECT_LOOKUP_2);
+
+    // fall through
+  }
+  case FunctionConsts::OP_ZORBA_SINGLE_OBJECT_LOOKUP_2:
   {
     arguments[1] = 
     create_cast_expr(loc, arguments[1], theRTM.STRING_TYPE_ONE, true, true);
 
     break;
   }
-  case FunctionConsts::OP_ZORBA_ARRAY_MEMBER_2:
+  case FunctionConsts::OP_ZORBA_MULTI_ARRAY_LOOKUP_2:
+  {
+    if (arguments[0]->get_return_type()->max_card() <= 1)
+      f = BUILTIN_FUNC(OP_ZORBA_SINGLE_ARRAY_LOOKUP_2);
+
+    // fall through
+  }
+  case FunctionConsts::OP_ZORBA_SINGLE_ARRAY_LOOKUP_2:
   {
     arguments[1] =
     create_cast_expr(loc, arguments[1], theRTM.INTEGER_TYPE_ONE, true, true);
 
     break;
   }
-  case FunctionConsts::OP_ZORBA_JSON_ITEM_ACCESSOR_2:
-  {
-    arguments[1] = wrap_in_atomization(arguments[1]);
-
-    break;
-  }
   case FunctionConsts::FN_JSONIQ_KEYS_1:
   {
     if (arguments[0]->get_return_type()->max_card() <= 1)
@@ -12513,79 +12486,64 @@
     }
   }
 
-  bool isJSON = 
-  (TypeOps::is_subtype(tm, *srcType, *theRTM.JSON_ITEM_TYPE_STAR) && numArgs <= 1);
-
-  bool implicitIter =
-  (srcType->get_quantifier() != TypeConstants::QUANT_ONE &&
-   (srcType->max_card() > 1 || !isJSON));
-
-  flwor_expr* flworExpr;
-
-  // Implementing implicit iteration over the sequence returned by the source expr
-  if (implicitIter)
-  {
-    flworExpr = wrap_expr_in_flwor(sourceExpr, false);
-
-    for_clause* fc = static_cast<for_clause*>(flworExpr->get_clause(0));
-
-    sourceExpr = CREATE(wrapper)(theRootSctx, theUDF, loc, fc->get_var());
-  }
+  function* func;
+  expr* accessorExpr;
 
   // Note: if numArgs > 1 and the input contains a json item, DynamicFnCallIterator
   // will raise an error. However, no error will be raised if the input is empty.
-  if (isJSON)
-  {
-    function* func;
-    expr* accessorExpr;
-
-    if (numArgs == 1)
-    {
-      if (TypeOps::is_subtype(tm, *srcType, *theRTM.JSON_ARRAY_TYPE_STAR))
-      {
-        func = BUILTIN_FUNC(OP_ZORBA_ARRAY_MEMBER_2);
-      }
-      else if (TypeOps::is_subtype(tm, *srcType, *theRTM.JSON_OBJECT_TYPE_STAR))
-      {
-        func = BUILTIN_FUNC(OP_ZORBA_OBJECT_VALUE_2);
-      }
-      else
-      {
-        func = BUILTIN_FUNC(OP_ZORBA_JSON_ITEM_ACCESSOR_2);
-      }
-    }
-    else
-    {
-      if (TypeOps::is_subtype(tm, *srcType, *theRTM.JSON_ARRAY_TYPE_STAR))
-      {
-        func = BUILTIN_FUNC(OP_ZORBA_MEMBERS_1);
-      }
-      else if (TypeOps::is_subtype(tm, *srcType, *theRTM.JSON_OBJECT_TYPE_STAR))
-      {
-        func = BUILTIN_FUNC(OP_ZORBA_KEYS_1);
-      }
-      else
-      {
-          func = BUILTIN_FUNC(OP_ZORBA_JSON_ITEM_ACCESSOR_1);
-      }
-    }
-
-    arguments.insert(arguments.begin(), sourceExpr);
-    
-    accessorExpr = generate_fn_body(func, arguments, loc);
-    
-    if (implicitIter)
-    {
-      flworExpr->set_return_expr(accessorExpr);
-
-      pop_scope();
-    
-      push_nodestack(flworExpr);
-    }
-    else
-    {
-      push_nodestack(accessorExpr);
-    }
+
+  if (TypeOps::is_subtype(tm, *srcType, *theRTM.JSON_ARRAY_TYPE_STAR) &&
+      numArgs <= 1)
+  {
+    arguments.insert(arguments.begin(), sourceExpr);
+
+    if (numArgs == 1)
+    {
+      func = BUILTIN_FUNC(OP_ZORBA_MULTI_ARRAY_LOOKUP_2);
+    }
+    else // numArgs == 0
+    {
+      func = BUILTIN_FUNC(FN_JSONIQ_MEMBERS_1);
+    }
+
+    accessorExpr = generate_fn_body(func, arguments, loc);
+    
+    push_nodestack(accessorExpr);
+  }
+  else if (TypeOps::is_subtype(tm, *srcType, *theRTM.JSON_OBJECT_TYPE_STAR) &&
+           numArgs <= 1)
+  {
+    arguments.insert(arguments.begin(), sourceExpr);
+
+    if (numArgs == 1)
+    {
+      func = BUILTIN_FUNC(OP_ZORBA_MULTI_OBJECT_LOOKUP_2);
+    }
+    else
+    {
+      func = BUILTIN_FUNC(FN_JSONIQ_KEYS_1);
+    }
+    
+    accessorExpr = generate_fn_body(func, arguments, loc);
+
+    push_nodestack(accessorExpr);
+  }
+  else if (numArgs > 0)
+  {
+    flwor_expr* flworExpr = wrap_expr_in_flwor(sourceExpr, false);
+
+    for_clause* fc = static_cast<for_clause*>(flworExpr->get_clause(0));
+
+    sourceExpr = CREATE(wrapper)(theRootSctx, theUDF, loc, fc->get_var());
+
+    expr* dynFuncInvocation =
+    CREATE(dynamic_function_invocation)(theRootSctx, theUDF, loc,
+                                        sourceExpr,
+                                        arguments);
+
+    flworExpr->set_return_expr(dynFuncInvocation);
+    pop_scope();
+    push_nodestack(flworExpr);
   }
   else
   {
@@ -12593,16 +12551,7 @@
     CREATE(dynamic_function_invocation)(theRootSctx, theUDF, loc,
                                         sourceExpr,
                                         arguments);
-    if (implicitIter)
-    {
-      flworExpr->set_return_expr(dynFuncInvocation);
-      pop_scope();
-      push_nodestack(flworExpr);
-    }
-    else
-    {
-      push_nodestack(dynFuncInvocation);
-    }
+    push_nodestack(dynFuncInvocation);
   }
 }
 

=== modified file 'src/functions/func_jsoniq_functions_impl.cpp'
--- src/functions/func_jsoniq_functions_impl.cpp	2013-08-14 15:16:42 +0000
+++ src/functions/func_jsoniq_functions_impl.cpp	2013-08-16 13:03:04 +0000
@@ -58,36 +58,36 @@
 /*******************************************************************************
 
 ********************************************************************************/
-xqtref_t op_zorba_json_item_accessor::getReturnType(const fo_expr* caller) const
-{
-  if (caller->get_arg(0)->get_return_type()->max_card() == 0)
-    return GENV_TYPESYSTEM.EMPTY_TYPE;
-
-  return theSignature.returnType();
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
 PlanIter_t fn_jsoniq_keys::codegen(
-  CompilerCB*,
-  static_context* sctx,
-  const QueryLoc& loc,
-  std::vector<PlanIter_t>& argv,
-  expr& arg) const
+    CompilerCB*,
+    static_context* sctx,
+    const QueryLoc& loc,
+    std::vector<PlanIter_t>& argv,
+    expr& arg) const
 {
   if (arg.get_return_type()->max_card() <= 1)
-    return new SingleObjectNamesIterator(sctx, loc, argv[0]);
-
-  return new JSONObjectNamesIterator(sctx, loc, argv[0]);
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
-xqtref_t op_zorba_object_value::getReturnType(const fo_expr* caller) const
+    return new SingleObjectKeysIterator(sctx, loc, argv[0]);
+
+  return new MultiObjectKeysIterator(sctx, loc, argv[0]);
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+xqtref_t op_zorba_multi_object_lookup::getReturnType(const fo_expr* caller) const
+{
+  if (caller->get_arg(0)->get_return_type()->max_card() == 0)
+    return GENV_TYPESYSTEM.EMPTY_TYPE;
+
+  return theSignature.returnType();
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+xqtref_t op_zorba_single_object_lookup::getReturnType(const fo_expr* caller) const
 {
   if (caller->get_arg(0)->get_return_type()->max_card() == 0)
     return GENV_TYPESYSTEM.EMPTY_TYPE;
@@ -117,7 +117,36 @@
 /*******************************************************************************
 
 ********************************************************************************/
-xqtref_t op_zorba_array_member::getReturnType(const fo_expr* caller) const
+PlanIter_t fn_jsoniq_members::codegen(
+  CompilerCB*,
+  static_context* sctx,
+  const QueryLoc& loc,
+  std::vector<PlanIter_t>& argv,
+  expr& arg) const
+{
+  if (arg.get_return_type()->max_card() <= 1)
+    return new SingleArrayMembersIterator(sctx, loc, argv[0]);
+
+  return new MultiArrayMembersIterator(sctx, loc, argv[0]);
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+xqtref_t op_zorba_multi_array_lookup::getReturnType(const fo_expr* caller) const
+{
+  if (caller->get_arg(0)->get_return_type()->max_card() == 0)
+    return GENV_TYPESYSTEM.EMPTY_TYPE;
+
+  return theSignature.returnType();
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+xqtref_t op_zorba_single_array_lookup::getReturnType(const fo_expr* caller) const
 {
   if (caller->get_arg(0)->get_return_type()->max_card() == 0)
     return GENV_TYPESYSTEM.EMPTY_TYPE;
@@ -141,23 +170,6 @@
 /*******************************************************************************
 
 ********************************************************************************/
-PlanIter_t fn_jsoniq_members::codegen(
-  CompilerCB*,
-  static_context* sctx,
-  const QueryLoc& loc,
-  std::vector<PlanIter_t>& argv,
-  expr& arg) const
-{
-  if (arg.get_return_type()->max_card() <= 1)
-    return new SingleArrayMembersIterator(sctx, loc, argv[0]);
-
-  return new JSONArrayMembersIterator(sctx, loc, argv[0]);
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
 bool op_zorba_json_array_insert::mustCopyInputNodes(expr* fo, csize producer) const
 {
   static_context* sctx = fo->get_sctx();

=== modified file 'src/functions/pregenerated/func_jsoniq_functions.cpp'
--- src/functions/pregenerated/func_jsoniq_functions.cpp	2013-08-14 15:16:42 +0000
+++ src/functions/pregenerated/func_jsoniq_functions.cpp	2013-08-16 13:03:04 +0000
@@ -52,16 +52,6 @@
 }
 
 
-PlanIter_t op_zorba_json_item_accessor::codegen(
-  CompilerCB*,
-  static_context* sctx,
-  const QueryLoc& loc,
-  std::vector<PlanIter_t>& argv,
-  expr& ann) const
-{
-  return new JSONItemAccessorIterator(sctx, loc, argv);
-}
-
 
 PlanIter_t op_zorba_keys::codegen(
   CompilerCB*,
@@ -70,17 +60,27 @@
   std::vector<PlanIter_t>& argv,
   expr& ann) const
 {
-  return new SingleObjectNamesIterator(sctx, loc, argv[0]);
-}
-
-PlanIter_t op_zorba_object_value::codegen(
-  CompilerCB*,
-  static_context* sctx,
-  const QueryLoc& loc,
-  std::vector<PlanIter_t>& argv,
-  expr& ann) const
-{
-  return new JSONObjectValueIterator(sctx, loc, argv[0], argv[1]);
+  return new SingleObjectKeysIterator(sctx, loc, argv[0]);
+}
+
+PlanIter_t op_zorba_multi_object_lookup::codegen(
+  CompilerCB*,
+  static_context* sctx,
+  const QueryLoc& loc,
+  std::vector<PlanIter_t>& argv,
+  expr& ann) const
+{
+  return new MultiObjectLookupIterator(sctx, loc, argv[0], argv[1]);
+}
+
+PlanIter_t op_zorba_single_object_lookup::codegen(
+  CompilerCB*,
+  static_context* sctx,
+  const QueryLoc& loc,
+  std::vector<PlanIter_t>& argv,
+  expr& ann) const
+{
+  return new SingleObjectLookupIterator(sctx, loc, argv[0], argv[1]);
 }
 
 PlanIter_t fn_jsoniq_project::codegen(
@@ -103,16 +103,6 @@
   return new JSONObjectTrimIterator(sctx, loc, argv[0], argv[1]);
 }
 
-PlanIter_t op_zorba_array_member::codegen(
-  CompilerCB*,
-  static_context* sctx,
-  const QueryLoc& loc,
-  std::vector<PlanIter_t>& argv,
-  expr& ann) const
-{
-  return new JSONArrayMemberIterator(sctx, loc, argv[0], argv[1]);
-}
-
 
 PlanIter_t op_zorba_members::codegen(
   CompilerCB*,
@@ -124,6 +114,26 @@
   return new SingleArrayMembersIterator(sctx, loc, argv[0]);
 }
 
+PlanIter_t op_zorba_multi_array_lookup::codegen(
+  CompilerCB*,
+  static_context* sctx,
+  const QueryLoc& loc,
+  std::vector<PlanIter_t>& argv,
+  expr& ann) const
+{
+  return new MultiArrayLookupIterator(sctx, loc, argv[0], argv[1]);
+}
+
+PlanIter_t op_zorba_single_array_lookup::codegen(
+  CompilerCB*,
+  static_context* sctx,
+  const QueryLoc& loc,
+  std::vector<PlanIter_t>& argv,
+  expr& ann) const
+{
+  return new SingleArrayLookupIterator(sctx, loc, argv[0], argv[1]);
+}
+
 PlanIter_t fn_jsoniq_size::codegen(
   CompilerCB*,
   static_context* sctx,
@@ -295,31 +305,6 @@
 
 
       {
-    DECL_WITH_KIND(sctx, op_zorba_json_item_accessor,
-        (createQName("http://zorba.io/internal/zorba-ops","","json-item-accessor";), 
-        GENV_TYPESYSTEM.ITEM_TYPE_QUESTION, 
-        GENV_TYPESYSTEM.ITEM_TYPE_STAR),
-        FunctionConsts::OP_ZORBA_JSON_ITEM_ACCESSOR_1);
-
-  }
-
-
-
-
-      {
-    DECL_WITH_KIND(sctx, op_zorba_json_item_accessor,
-        (createQName("http://zorba.io/internal/zorba-ops","","json-item-accessor";), 
-        GENV_TYPESYSTEM.ITEM_TYPE_QUESTION, 
-        GENV_TYPESYSTEM.ITEM_TYPE_QUESTION, 
-        GENV_TYPESYSTEM.ITEM_TYPE_QUESTION),
-        FunctionConsts::OP_ZORBA_JSON_ITEM_ACCESSOR_2);
-
-  }
-
-
-
-
-      {
     DECL_WITH_KIND(sctx, fn_jsoniq_keys,
         (createQName("http://jsoniq.org/functions","","keys";), 
         GENV_TYPESYSTEM.ITEM_TYPE_STAR, 
@@ -344,12 +329,25 @@
 
 
       {
-    DECL_WITH_KIND(sctx, op_zorba_object_value,
-        (createQName("http://zorba.io/internal/zorba-ops","","object-value";), 
+    DECL_WITH_KIND(sctx, op_zorba_multi_object_lookup,
+        (createQName("http://zorba.io/internal/zorba-ops","","multi-object-lookup";), 
+        GENV_TYPESYSTEM.ITEM_TYPE_STAR, 
+        GENV_TYPESYSTEM.ITEM_TYPE_QUESTION, 
+        GENV_TYPESYSTEM.ITEM_TYPE_STAR),
+        FunctionConsts::OP_ZORBA_MULTI_OBJECT_LOOKUP_2);
+
+  }
+
+
+
+
+      {
+    DECL_WITH_KIND(sctx, op_zorba_single_object_lookup,
+        (createQName("http://zorba.io/internal/zorba-ops","","single-object-lookup";), 
         GENV_TYPESYSTEM.ITEM_TYPE_QUESTION, 
         GENV_TYPESYSTEM.ITEM_TYPE_QUESTION, 
         GENV_TYPESYSTEM.ITEM_TYPE_QUESTION),
-        FunctionConsts::OP_ZORBA_OBJECT_VALUE_2);
+        FunctionConsts::OP_ZORBA_SINGLE_OBJECT_LOOKUP_2);
 
   }
 
@@ -383,19 +381,6 @@
 
 
       {
-    DECL_WITH_KIND(sctx, op_zorba_array_member,
-        (createQName("http://zorba.io/internal/zorba-ops","","array-member";), 
-        GENV_TYPESYSTEM.ITEM_TYPE_QUESTION, 
-        GENV_TYPESYSTEM.ITEM_TYPE_QUESTION, 
-        GENV_TYPESYSTEM.ITEM_TYPE_QUESTION),
-        FunctionConsts::OP_ZORBA_ARRAY_MEMBER_2);
-
-  }
-
-
-
-
-      {
     DECL_WITH_KIND(sctx, fn_jsoniq_members,
         (createQName("http://jsoniq.org/functions","","members";), 
         GENV_TYPESYSTEM.ITEM_TYPE_STAR, 
@@ -420,6 +405,32 @@
 
 
       {
+    DECL_WITH_KIND(sctx, op_zorba_multi_array_lookup,
+        (createQName("http://zorba.io/internal/zorba-ops","","multi-array-lookup";), 
+        GENV_TYPESYSTEM.ITEM_TYPE_STAR, 
+        GENV_TYPESYSTEM.ITEM_TYPE_QUESTION, 
+        GENV_TYPESYSTEM.ITEM_TYPE_STAR),
+        FunctionConsts::OP_ZORBA_MULTI_ARRAY_LOOKUP_2);
+
+  }
+
+
+
+
+      {
+    DECL_WITH_KIND(sctx, op_zorba_single_array_lookup,
+        (createQName("http://zorba.io/internal/zorba-ops","","single-array-lookup";), 
+        GENV_TYPESYSTEM.ITEM_TYPE_QUESTION, 
+        GENV_TYPESYSTEM.ITEM_TYPE_QUESTION, 
+        GENV_TYPESYSTEM.ITEM_TYPE_QUESTION),
+        FunctionConsts::OP_ZORBA_SINGLE_ARRAY_LOOKUP_2);
+
+  }
+
+
+
+
+      {
     DECL_WITH_KIND(sctx, fn_jsoniq_size,
         (createQName("http://jsoniq.org/functions","","size";), 
         GENV_TYPESYSTEM.JSON_ARRAY_TYPE_QUESTION, 

=== modified file 'src/functions/pregenerated/func_jsoniq_functions.h'
--- src/functions/pregenerated/func_jsoniq_functions.h	2013-08-14 15:16:42 +0000
+++ src/functions/pregenerated/func_jsoniq_functions.h	2013-08-16 13:03:04 +0000
@@ -95,27 +95,6 @@
 };
 
 
-//op-zorba:json-item-accessor
-class op_zorba_json_item_accessor : public function
-{
-public:
-  op_zorba_json_item_accessor(const signature& sig, FunctionConsts::FunctionKind kind)
-    : 
-    function(sig, kind)
-  {
-
-  }
-
-  xqtref_t getReturnType(const fo_expr* caller) const;
-
-  bool propagatesInputNodes(expr* fo, csize producer) const { return producer == 0; }
-
-  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
-
-  CODEGEN_DECL();
-};
-
-
 //fn-jsoniq:keys
 class fn_jsoniq_keys : public function
 {
@@ -156,11 +135,32 @@
 };
 
 
-//op-zorba:object-value
-class op_zorba_object_value : public function
-{
-public:
-  op_zorba_object_value(const signature& sig, FunctionConsts::FunctionKind kind)
+//op-zorba:multi-object-lookup
+class op_zorba_multi_object_lookup : public function
+{
+public:
+  op_zorba_multi_object_lookup(const signature& sig, FunctionConsts::FunctionKind kind)
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  xqtref_t getReturnType(const fo_expr* caller) const;
+
+  bool propagatesInputNodes(expr* fo, csize producer) const { return producer == 0; }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
+
+  CODEGEN_DECL();
+};
+
+
+//op-zorba:single-object-lookup
+class op_zorba_single_object_lookup : public function
+{
+public:
+  op_zorba_single_object_lookup(const signature& sig, FunctionConsts::FunctionKind kind)
     : 
     function(sig, kind)
   {
@@ -223,27 +223,6 @@
 };
 
 
-//op-zorba:array-member
-class op_zorba_array_member : public function
-{
-public:
-  op_zorba_array_member(const signature& sig, FunctionConsts::FunctionKind kind)
-    : 
-    function(sig, kind)
-  {
-
-  }
-
-  xqtref_t getReturnType(const fo_expr* caller) const;
-
-  bool propagatesInputNodes(expr* fo, csize producer) const { return producer == 0; }
-
-  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
-
-  CODEGEN_DECL();
-};
-
-
 //fn-jsoniq:members
 class fn_jsoniq_members : public function
 {
@@ -284,6 +263,50 @@
 };
 
 
+//op-zorba:multi-array-lookup
+class op_zorba_multi_array_lookup : public function
+{
+public:
+  op_zorba_multi_array_lookup(const signature& sig, FunctionConsts::FunctionKind kind)
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  xqtref_t getReturnType(const fo_expr* caller) const;
+
+  bool propagatesInputNodes(expr* fo, csize producer) const { return producer == 0; }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
+
+  bool isMap(csize producer) const { return producer == 0; }
+
+  CODEGEN_DECL();
+};
+
+
+//op-zorba:single-array-lookup
+class op_zorba_single_array_lookup : public function
+{
+public:
+  op_zorba_single_array_lookup(const signature& sig, FunctionConsts::FunctionKind kind)
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  xqtref_t getReturnType(const fo_expr* caller) const;
+
+  bool propagatesInputNodes(expr* fo, csize producer) const { return producer == 0; }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
+
+  CODEGEN_DECL();
+};
+
+
 //fn-jsoniq:size
 class fn_jsoniq_size : public function
 {

=== modified file 'src/functions/pregenerated/function_enum.h'
--- src/functions/pregenerated/function_enum.h	2013-08-14 15:16:42 +0000
+++ src/functions/pregenerated/function_enum.h	2013-08-16 13:03:04 +0000
@@ -258,16 +258,16 @@
   FN_JSONIQ_ENCODE_FOR_ROUNDTRIP_2,
   FN_JSONIQ_PARSE_JSON_1,
   FN_JSONIQ_PARSE_JSON_2,
-  OP_ZORBA_JSON_ITEM_ACCESSOR_1,
-  OP_ZORBA_JSON_ITEM_ACCESSOR_2,
   FN_JSONIQ_KEYS_1,
   OP_ZORBA_KEYS_1,
-  OP_ZORBA_OBJECT_VALUE_2,
+  OP_ZORBA_MULTI_OBJECT_LOOKUP_2,
+  OP_ZORBA_SINGLE_OBJECT_LOOKUP_2,
   FN_JSONIQ_PROJECT_2,
   FN_JSONIQ_TRIM_2,
-  OP_ZORBA_ARRAY_MEMBER_2,
   FN_JSONIQ_MEMBERS_1,
   OP_ZORBA_MEMBERS_1,
+  OP_ZORBA_MULTI_ARRAY_LOOKUP_2,
+  OP_ZORBA_SINGLE_ARRAY_LOOKUP_2,
   FN_JSONIQ_SIZE_1,
   FN_JSONIQ_FLATTEN_1,
   FN_JSONIQ_NULL_0,

=== modified file 'src/runtime/base/plan_iterator.h'
--- src/runtime/base/plan_iterator.h	2013-07-15 10:32:25 +0000
+++ src/runtime/base/plan_iterator.h	2013-08-16 13:03:04 +0000
@@ -178,13 +178,16 @@
   {
   }
 
+  /*
+   * It is invoked by the closeImpl() method of each iterator.
+   */
   ~PlanIteratorState() {}
 
   void setDuffsLine(uint32_t v) { theDuffsLine = v; }
 
   uint32_t getDuffsLine() const { return theDuffsLine; }
 
-  /**
+  /*
    * Initialize the current state object.
    *
    * This method is invoked be the openImpl() method of the associated iterator
@@ -201,7 +204,7 @@
     theDuffsLine = DUFFS_ALLOCATE_RESOURCES;
   }
 
-  /**
+  /*
    * Reset the current state object.
    *
    * This method is invoked by the resetImpl() method of the associated iterator.

=== modified file 'src/runtime/hof/dynamic_fncall_iterator.cpp'
--- src/runtime/hof/dynamic_fncall_iterator.cpp	2013-06-05 07:00:21 +0000
+++ src/runtime/hof/dynamic_fncall_iterator.cpp	2013-08-16 13:03:04 +0000
@@ -47,13 +47,15 @@
 
 NOARY_ACCEPT(ArgumentPlaceholderIterator)
 
-SERIALIZABLE_CLASS_VERSIONS(DynamicFnCallIterator)
+SERIALIZABLE_CLASS_VERSIONS(SingleDynamicFnCallIterator)
+
+SERIALIZABLE_CLASS_VERSIONS(MultiDynamicFnCallIterator)
 
 
 /*******************************************************************************
 
 ********************************************************************************/
-DynamicFnCallIteratorState::DynamicFnCallIteratorState()
+SingleDynamicFnCallIteratorState::SingleDynamicFnCallIteratorState()
 {
 }
 
@@ -61,7 +63,7 @@
 /*******************************************************************************
 
 ********************************************************************************/
-DynamicFnCallIteratorState::~DynamicFnCallIteratorState()
+SingleDynamicFnCallIteratorState::~SingleDynamicFnCallIteratorState()
 {
   if (theIsOpen)
   {
@@ -73,7 +75,7 @@
 /*******************************************************************************
 
 ********************************************************************************/
-void DynamicFnCallIteratorState::init(PlanState& planState)
+void SingleDynamicFnCallIteratorState::init(PlanState& planState)
 {
   PlanIteratorState::init(planState);
   thePlanState = &planState;
@@ -85,12 +87,13 @@
 /*******************************************************************************
 
 ********************************************************************************/
-void DynamicFnCallIteratorState::reset(PlanState& planState)
+void SingleDynamicFnCallIteratorState::reset(PlanState& planState)
 {
   PlanIteratorState::reset(planState);
   if (theIsOpen)
   {
-    thePlan->reset(planState);
+    thePlan->close(planState);
+    theIsOpen = false;
   }
 }
 
@@ -98,10 +101,11 @@
 /*******************************************************************************
 
 ********************************************************************************/
-void DynamicFnCallIterator::serialize(::zorba::serialization::Archiver& ar)
+void SingleDynamicFnCallIterator::serialize(::zorba::serialization::Archiver& ar)
 {
   serialize_baseclass(ar,
-  (NaryBaseIterator<DynamicFnCallIterator, DynamicFnCallIteratorState>*)this);
+  (NaryBaseIterator<SingleDynamicFnCallIterator,
+                     SingleDynamicFnCallIteratorState>*)this);
 
   ar & theIsPartialApply;
 }
@@ -110,10 +114,11 @@
 /*******************************************************************************
 
 ********************************************************************************/
-uint32_t DynamicFnCallIterator::getStateSizeOfSubtree() const
+uint32_t SingleDynamicFnCallIterator::getStateSizeOfSubtree() const
 {
-  uint32_t size = NaryBaseIterator<DynamicFnCallIterator, DynamicFnCallIteratorState>::
-                  getStateSizeOfSubtree();
+  uint32_t size =
+  NaryBaseIterator<SingleDynamicFnCallIterator, SingleDynamicFnCallIteratorState>::
+  getStateSizeOfSubtree();
 
   return size + sizeof(UDFunctionCallIteratorState);
 }
@@ -122,16 +127,16 @@
 /*******************************************************************************
 
 ********************************************************************************/
-void DynamicFnCallIterator::openImpl(PlanState& planState, uint32_t& offset)
+void SingleDynamicFnCallIterator::openImpl(PlanState& planState, uint32_t& offset)
 {
-  StateTraitsImpl<DynamicFnCallIteratorState>::
+  StateTraitsImpl<SingleDynamicFnCallIteratorState>::
   createState(planState, theStateOffset, offset);
 
-  StateTraitsImpl<DynamicFnCallIteratorState>::
+  StateTraitsImpl<SingleDynamicFnCallIteratorState>::
   initState(planState, theStateOffset);
 
-  DynamicFnCallIteratorState* state = 
-  StateTraitsImpl<DynamicFnCallIteratorState>::
+  SingleDynamicFnCallIteratorState* state = 
+  StateTraitsImpl<SingleDynamicFnCallIteratorState>::
   getState(planState, theStateOffset);
 
   state->theUDFStateOffset = offset;
@@ -150,27 +155,7 @@
 /*******************************************************************************
 
 ********************************************************************************/
-void DynamicFnCallIterator::resetImpl(PlanState& planState) const
-{
-  DynamicFnCallIteratorState* state = 
-  StateTraitsImpl<DynamicFnCallIteratorState>::
-  getState(planState, theStateOffset);
-  
-  if (state->theIsOpen)
-  {
-    state->thePlan->close(planState);
-    state->theIsOpen = false;
-  }
-  
-  NaryBaseIterator<DynamicFnCallIterator, DynamicFnCallIteratorState>::
-  resetImpl(planState);
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
-bool DynamicFnCallIterator::nextImpl(
+bool SingleDynamicFnCallIterator::nextImpl(
     store::Item_t& result,
     PlanState& planState) const
 {
@@ -181,11 +166,9 @@
   store::Item_t selectorItem2;
   store::Item_t selectorItem3;
 
-  TypeManager* tm = theSctx->get_typemanager();
-
-  DynamicFnCallIteratorState* state;
-
-  DEFAULT_STACK_INIT(DynamicFnCallIteratorState, state, planState);
+  SingleDynamicFnCallIteratorState* state;
+
+  DEFAULT_STACK_INIT(SingleDynamicFnCallIteratorState, state, planState);
 
   // first child must return exactly one item which is a function item
   // otherwise XPTY0004 is raised
@@ -238,7 +221,9 @@
           fnItem->setArgumentValue(pos, value);
         }
         else
-          pos++;
+        {
+          ++pos;
+        }
       }
 
       result = fnItem;
@@ -371,24 +356,248 @@
       state->theIterator->close();
     }
   }
+#if 0
   else if (theSctx->language_kind() == StaticContextConsts::language_kind_xquery)
   {
-    xqtref_t type = tm->create_value_type(targetItem);
+    xqtref_t type = theSctx->get_typemanager()->create_value_type(targetItem);
 
     RAISE_ERROR(err::XPTY0004, loc, 
     ERROR_PARAMS(ZED(XPTY0004_NoTypePromote_23),
                  type->toSchemaString(),
                  GENV_TYPESYSTEM.ANY_FUNCTION_TYPE_ONE->toSchemaString()));
   }
-
-  STACK_END(state);
-};
-
-
-/*******************************************************************************
-
-********************************************************************************/
-NARY_ACCEPT(DynamicFnCallIterator)
+#endif
+
+  STACK_END(state);
+};
+
+
+/*******************************************************************************
+
+********************************************************************************/
+NARY_ACCEPT(SingleDynamicFnCallIterator)
+
+
+/*******************************************************************************
+
+********************************************************************************/
+MultiDynamicFnCallIteratorState::MultiDynamicFnCallIteratorState()
+{
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+MultiDynamicFnCallIteratorState::~MultiDynamicFnCallIteratorState()
+{
+  if (theIsOpen)
+  {
+    thePlan->close(*thePlanState);
+  }
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+void MultiDynamicFnCallIteratorState::init(PlanState& planState)
+{
+  PlanIteratorState::init(planState);
+  thePlanState = &planState;
+  thePlan = NULL;
+  theIsOpen = false;
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+void MultiDynamicFnCallIteratorState::reset(PlanState& planState)
+{
+  PlanIteratorState::reset(planState);
+
+  if (theIsOpen)
+  {
+    thePlan->reset(planState);
+  }
+
+  if (theKeysSet.get())
+  {
+    theKeysSet->clear();
+  }
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+void MultiDynamicFnCallIterator::serialize(::zorba::serialization::Archiver& ar)
+{
+  serialize_baseclass(ar,
+  (UnaryBaseIterator<MultiDynamicFnCallIterator, MultiDynamicFnCallIteratorState>*)this);
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+uint32_t MultiDynamicFnCallIterator::getStateSizeOfSubtree() const
+{
+  uint32_t size =
+  UnaryBaseIterator<MultiDynamicFnCallIterator, MultiDynamicFnCallIteratorState>::
+  getStateSizeOfSubtree();
+
+  return size + sizeof(UDFunctionCallIteratorState);
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+void MultiDynamicFnCallIterator::openImpl(PlanState& planState, uint32_t& offset)
+{
+  StateTraitsImpl<MultiDynamicFnCallIteratorState>::
+  createState(planState, theStateOffset, offset);
+
+  StateTraitsImpl<MultiDynamicFnCallIteratorState>::
+  initState(planState, theStateOffset);
+
+  MultiDynamicFnCallIteratorState* state = 
+  StateTraitsImpl<MultiDynamicFnCallIteratorState>::
+  getState(planState, theStateOffset);
+
+  state->theUDFStateOffset = offset;
+
+  offset += sizeof(UDFunctionCallIteratorState);
+
+  theChild->open(planState, offset);
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+void MultiDynamicFnCallIterator::resetImpl(PlanState& planState) const
+{
+  MultiDynamicFnCallIteratorState* state = 
+  StateTraitsImpl<MultiDynamicFnCallIteratorState>::
+  getState(planState, theStateOffset);
+  
+  if (state->theIsOpen)
+  {
+    state->thePlan->close(planState);
+    state->theIsOpen = false;
+  }
+  
+  UnaryBaseIterator<MultiDynamicFnCallIterator, MultiDynamicFnCallIteratorState>::
+  resetImpl(planState);
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+bool MultiDynamicFnCallIterator::nextImpl(
+    store::Item_t& result,
+    PlanState& planState) const
+{
+  store::Item_t item;
+  store::Item_t targetItem;
+  FunctionItem* fnItem;
+  zstring key;
+
+  MultiDynamicFnCallIteratorState* state;
+
+  DEFAULT_STACK_INIT(MultiDynamicFnCallIteratorState, state, planState);
+
+  while (consumeNext(targetItem, theChild, planState))
+  {
+    if (targetItem->isFunction())
+    {
+      fnItem = static_cast<FunctionItem*>(targetItem.getp());
+
+      if (fnItem->getArity() != 0)
+      {
+        RAISE_ERROR(err::XPTY0004, loc,
+        ERROR_PARAMS("dynamic function invoked with incorrect number of arguments"));
+      }
+
+      state->thePlan = fnItem->getImplementation(planState.theCompilerCB);
+      
+      // must be opened after vars and params are set
+      state->thePlan->open(planState, state->theUDFStateOffset);
+      state->theIsOpen = true;
+
+      while (consumeNext(result, state->thePlan, planState))
+      {
+        STACK_PUSH(true, state);
+      }
+
+      // Need to close here early in case the plan is completely consumed.
+      // Otherwise, the plan would still be opened if destroyed from the
+      // state's destructor.
+      state->thePlan->close(planState);
+      state->theIsOpen = false;
+    } // if (targetItem->isFunction())
+
+    else if (targetItem->isJSONItem())
+    {
+      if (targetItem->isObject())
+      {
+        if (!state->theKeysSet.get())
+          state->theKeysSet.reset(new HashSet<zstring, HashMapZStringCmp>(64, false));
+
+        state->theIterator = targetItem->getObjectKeys();
+
+        state->theIterator->open();
+
+        while (state->theIterator->next(result))
+        {
+          key = result->getStringValue();
+
+          if (!state->theKeysSet->exists(key))
+          {
+            state->theKeysSet->insert(key);
+            STACK_PUSH(true, state);
+          }
+        }
+      }
+      else
+      {
+        state->theIterator = targetItem->getArrayValues();
+
+        state->theIterator->open();
+
+        while (state->theIterator->next(result))
+        {
+          STACK_PUSH(true, state);
+        }
+      }
+
+      state->theIterator->close();
+    } // jsoniq item
+#if 0
+    else if (theSctx->language_kind() == StaticContextConsts::language_kind_xquery)
+    {
+      xqtref_t type = theSctx->get_typemanager()->create_value_type(targetItem);
+
+      RAISE_ERROR(err::XPTY0004, loc, 
+      ERROR_PARAMS(ZED(XPTY0004_NoTypePromote_23),
+                   type->toSchemaString(),
+                   GENV_TYPESYSTEM.ANY_FUNCTION_TYPE_ONE->toSchemaString()));
+    }
+#endif
+  }
+
+  STACK_END(state);
+};
+
+
+/*******************************************************************************
+
+********************************************************************************/
+UNARY_ACCEPT(MultiDynamicFnCallIterator)
 
 
 }//zorba namespace

=== modified file 'src/runtime/hof/dynamic_fncall_iterator.h'
--- src/runtime/hof/dynamic_fncall_iterator.h	2013-06-15 02:57:08 +0000
+++ src/runtime/hof/dynamic_fncall_iterator.h	2013-08-16 13:03:04 +0000
@@ -20,9 +20,12 @@
 #include "common/shared_types.h"
 
 #include "runtime/base/narybase.h"
-
+#include "runtime/base/unarybase.h"
 #include "runtime/base/noarybase.h"
 
+#include "zorbautils/hashset.h"
+#include "zorbautils/hashmap_zstring.h"
+
 
 namespace zorba
 {
@@ -60,7 +63,7 @@
 /*******************************************************************************
 
 ********************************************************************************/
-class DynamicFnCallIteratorState : public PlanIteratorState
+class SingleDynamicFnCallIteratorState : public PlanIteratorState
 {
 public:
   PlanState  * thePlanState;
@@ -71,9 +74,9 @@
 
   store::Iterator_t theIterator;
 
-  DynamicFnCallIteratorState();
+  SingleDynamicFnCallIteratorState();
 
-  ~DynamicFnCallIteratorState();
+  ~SingleDynamicFnCallIteratorState();
 
   void init(PlanState&);
   void reset(PlanState&);
@@ -84,29 +87,30 @@
   The 1st child iterator returns the functionItem obj to invoke. The rest of
   the child iterators compute the args to pass to the invocation.
 ********************************************************************************/
-class DynamicFnCallIterator : public NaryBaseIterator<DynamicFnCallIterator,
-                                                      DynamicFnCallIteratorState>
+class SingleDynamicFnCallIterator :
+public NaryBaseIterator<SingleDynamicFnCallIterator, SingleDynamicFnCallIteratorState>
 {
 protected:
-  bool   theIsPartialApply;
+  bool theIsPartialApply;
   
 public:
-  SERIALIZABLE_CLASS(DynamicFnCallIterator);
-
-  SERIALIZABLE_CLASS_CONSTRUCTOR2T(DynamicFnCallIterator,
-  NaryBaseIterator<DynamicFnCallIterator, DynamicFnCallIteratorState>);
-
-  void serialize( ::zorba::serialization::Archiver& ar);
+  SERIALIZABLE_CLASS(SingleDynamicFnCallIterator);
+
+  SERIALIZABLE_CLASS_CONSTRUCTOR2T(SingleDynamicFnCallIterator,
+  NaryBaseIterator<SingleDynamicFnCallIterator, SingleDynamicFnCallIteratorState>);
+
+  void serialize(::zorba::serialization::Archiver& ar);
 
 public:
-  DynamicFnCallIterator(
+  SingleDynamicFnCallIterator(
       static_context* sctx,
       const QueryLoc& loc,
       std::vector<PlanIter_t>& args,
       bool isPartialApply,
       xqtref_t coercionTargetType = NULL)
     :
-    NaryBaseIterator<DynamicFnCallIterator, DynamicFnCallIteratorState>(sctx, loc, args),
+    NaryBaseIterator<SingleDynamicFnCallIterator,
+                     SingleDynamicFnCallIteratorState>(sctx, loc, args),
     theIsPartialApply(isPartialApply)
   {
   }
@@ -118,6 +122,69 @@
   void openImpl(PlanState& planState, uint32_t& offset);
 
   bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
+};
+
+
+/*******************************************************************************
+
+********************************************************************************/
+class MultiDynamicFnCallIteratorState : public PlanIteratorState
+{
+public:
+  PlanState      * thePlanState;
+  PlanIter_t       thePlan;
+  bool             theIsOpen;
+
+  uint32_t          theUDFStateOffset;
+
+  store::Iterator_t theIterator;
+
+  std::unique_ptr<HashSet<zstring, HashMapZStringCmp> > theKeysSet;
+
+public:
+  MultiDynamicFnCallIteratorState();
+
+  ~MultiDynamicFnCallIteratorState();
+
+  void init(PlanState&);
+  void reset(PlanState&);
+};
+
+
+/*******************************************************************************
+  The 1st child iterator returns the functionItem obj to invoke. The rest of
+  the child iterators compute the args to pass to the invocation.
+********************************************************************************/
+class MultiDynamicFnCallIterator : 
+public UnaryBaseIterator<MultiDynamicFnCallIterator,
+                         MultiDynamicFnCallIteratorState>
+{
+public:
+  SERIALIZABLE_CLASS(MultiDynamicFnCallIterator);
+
+  SERIALIZABLE_CLASS_CONSTRUCTOR2T(MultiDynamicFnCallIterator,
+  UnaryBaseIterator<MultiDynamicFnCallIterator, MultiDynamicFnCallIteratorState>);
+
+  void serialize(::zorba::serialization::Archiver& ar);
+
+public:
+  MultiDynamicFnCallIterator(
+      static_context* sctx,
+      const QueryLoc& loc,
+      const PlanIter_t& arg)
+    :
+    UnaryBaseIterator<MultiDynamicFnCallIterator,
+                      MultiDynamicFnCallIteratorState>(sctx, loc, arg)
+  {
+  }
+
+  void accept(PlanIterVisitor& v) const;
+
+  uint32_t getStateSizeOfSubtree() const;
+
+  void openImpl(PlanState& planState, uint32_t& offset);
+
+  bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
 
   void resetImpl(PlanState& planState) const;
 };

=== modified file 'src/runtime/hof/function_item.cpp'
--- src/runtime/hof/function_item.cpp	2013-07-02 21:32:23 +0000
+++ src/runtime/hof/function_item.cpp	2013-08-16 13:03:04 +0000
@@ -362,6 +362,37 @@
 /*******************************************************************************
 
 ********************************************************************************/
+PlanIter_t FunctionItem::getImplementation(CompilerCB* ccb)
+{
+  std::vector<PlanIter_t> args;
+
+  expr* dummy = ccb->theEM->
+  create_function_item_expr(NULL,
+                            NULL,
+                            theFunctionItemInfo->theLoc,
+                            false,
+                            false);
+  
+  PlanIter_t udfCallIterator = theFunctionItemInfo->theFunction->
+  codegen(ccb,
+          theFunctionItemInfo->theClosureSctx,
+          theFunctionItemInfo->theLoc,
+          args,
+          *dummy);
+
+  UDFunctionCallIterator* udfIter =
+  static_cast<UDFunctionCallIterator*>(udfCallIterator.getp());
+
+  udfIter->setDynamic();
+  udfIter->setFunctionItem(this);
+
+  return udfCallIterator;
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
 zstring FunctionItem::show() const
 {
   std::ostringstream lRes;

=== modified file 'src/runtime/hof/function_item.h'
--- src/runtime/hof/function_item.h	2013-07-02 21:32:23 +0000
+++ src/runtime/hof/function_item.h	2013-08-16 13:03:04 +0000
@@ -230,6 +230,8 @@
       const std::vector<PlanIter_t>& argValues,
       CompilerCB* ccb);
   
+  PlanIter_t getImplementation(CompilerCB* ccb);
+
   zstring show() const;
 };
 

=== modified file 'src/runtime/json/jsoniq_functions_impl.cpp'
--- src/runtime/json/jsoniq_functions_impl.cpp	2013-08-14 15:16:42 +0000
+++ src/runtime/json/jsoniq_functions_impl.cpp	2013-08-16 13:03:04 +0000
@@ -866,7 +866,8 @@
       *state->theInputStream, true, lStripTopLevelArray
     );
 
-    if ( state->theInput == NULL && theRelativeLocation ) {
+    if ( state->theInput == NULL && theRelativeLocation )
+    {
       // pass the query location of the StringLiteral to the JSON
       // parser such that it can give better error locations.
       state->loader_->set_loc(
@@ -875,11 +876,14 @@
         theRelativeLocation.getColumnBegin()
       );
     }
+
     if ( stream_uri )
       state->loader_->set_loc( stream_uri, 1, 1 );
 
-    while ( state->loader_->next( &result ) ) {
-      if ( !state->theAllowMultiple && state->theGotOne ) {
+    while ( state->loader_->next( &result ) )
+    {
+      if ( !state->theAllowMultiple && state->theGotOne )
+      {
         throw XQUERY_EXCEPTION(
           jerr::JNDY0021,
           ERROR_PARAMS( ZED( JNDY0021_UnexpectedExtraContent ) ),
@@ -895,84 +899,121 @@
 
 
 /*******************************************************************************
-  op_zorba:json-item-accessor($i as item()?, $sel as item()?) as item()?
-
-  op_zorba:json-item-accessor($i as item()?) as item()*
-
-  These two are zorba internal functions that are introduced by the translator
-  when translating a dynamic function invocation (DFI) expr and we know statically
-  that the source of the DFI is a json item, but we don't know if it's going to
-  be an object or an array.
-
-  Note: the translator always wraps the $sel param to with fn:data(), so we can
-  assume here that the selector item is atomic.
+  jn:keys($o as item()*) as xs:string*
 ********************************************************************************/
-bool JSONItemAccessorIterator::nextImpl(
+void MultiObjectKeysIteratorState::init(PlanState& planState)
+{
+  theUniqueKeys.reset(new HashSet<zstring, HashMapZStringCmp>(64, false));
+}
+
+
+void MultiObjectKeysIteratorState::reset(PlanState& planState)
+{
+  PlanIteratorState::reset(planState);
+  theUniqueKeys->clear();
+}
+
+
+bool MultiObjectKeysIterator::nextImpl(
     store::Item_t& result,
     PlanState& planState) const
 {
-  store::Item_t input;
-  store::Item_t selector;
-  store::Item_t selector2;
-
-  JSONItemAccessorIteratorState* state;
-  DEFAULT_STACK_INIT(JSONItemAccessorIteratorState, state, planState);
-
-  if (consumeNext(input, theChildren[0].getp(), planState))
-  {
-    if (input->isArray())
-    {
-      if (theChildren.size() == 2 &&
-          consumeNext(selector, theChildren[1].getp(), planState))
-      {
-        GenericCast::castToBuiltinAtomic(selector2,
-                                         selector,
-                                         store::XS_INTEGER,
-                                         NULL,
-                                         loc);
-
-        result = input->getArrayValue(selector2->getIntegerValue());
-        
-        STACK_PUSH(result != 0, state);
-      }
-      else
-      {
-        state->theIterator = input->getArrayValues();
-        
-        state->theIterator->open();
-        while (state->theIterator->next(result))
-        {
-          STACK_PUSH(true, state);
-        }
-        state->theIterator->close();
-      }
-    }
-    else if (input->isObject())
-    {
-      if (theChildren.size() == 2 &&
-          consumeNext(selector, theChildren[1].getp(), planState))
-      {
-        GenericCast::castToBuiltinAtomic(selector2,
-                                         selector,
-                                         store::XS_STRING,
-                                         NULL,
-                                         loc);
-        
-        result = input->getObjectValue(selector2);
-        
-        STACK_PUSH(result != 0, state);
-      }
-      else
-      {
-        state->theIterator = input->getObjectKeys();
-        
-        state->theIterator->open();
-        while (state->theIterator->next(result))
-        {
-          STACK_PUSH(true, state);
-        }
-        state->theIterator->close();
-      }
+  store::Item_t item;
+  store::Item_t obj1;
+  store::Item_t obj2;
+  zstring key;
+
+  MultiObjectKeysIteratorState* state;
+  DEFAULT_STACK_INIT(MultiObjectKeysIteratorState, state, planState);
+
+  // skip non-objects
+  while (consumeNext(item, theChild.getp(), planState))
+  {
+    if (item->isObject())
+    {
+      obj1.transfer(item);
+      break;
+    }
+  }
+
+  if (obj1)
+  {
+    // skip non-objects
+    while (consumeNext(item, theChild.getp(), planState))
+    {
+      if (item->isObject())
+      {
+        obj2.transfer(item);
+        break;
+      }
+    }
+
+    if (obj2)
+    {
+      state->theSecondObj.transfer(obj2);
+
+      // Return and record the keys of the 1st obj
+      state->theObjKeysIte = obj1->getObjectKeys();
+      state->theObjKeysIte->open();
+          
+      while (state->theObjKeysIte->next(result))
+      {
+        key = result->getStringValue();
+        state->theUniqueKeys->insert(key);
+        STACK_PUSH(true, state);
+      }
+
+      // Conditionally return and record the keys of the 2nd obj
+      state->theObjKeysIte = state->theSecondObj->getObjectKeys();
+      state->theObjKeysIte->open();
+          
+      while (state->theObjKeysIte->next(result))
+      {
+        key = result->getStringValue();
+            
+        if (!state->theUniqueKeys->exists(key))
+        {
+          state->theUniqueKeys->insert(key);
+          STACK_PUSH(true, state);
+        }
+      }
+
+      state->theObjKeysIte = NULL;
+
+      // Conditionally return and record the keys of the subsequent objs, if any
+      while (consumeNext(item, theChild.getp(), planState))
+      {
+        if (item->isObject())
+        {
+          state->theObjKeysIte = item->getObjectKeys();
+          state->theObjKeysIte->open();
+          
+          while (state->theObjKeysIte->next(result))
+          {
+            key = result->getStringValue();
+            
+            if (!state->theUniqueKeys->exists(key))
+            {
+              state->theUniqueKeys->insert(key);
+              STACK_PUSH(true, state);
+            }
+          }
+          
+          state->theObjKeysIte = NULL;
+        }
+      }
+    }
+    else
+    {
+      state->theObjKeysIte = obj1->getObjectKeys();
+      state->theObjKeysIte->open();
+          
+      while (state->theObjKeysIte->next(result))
+      {
+        STACK_PUSH(true, state);
+      }
+      
+      state->theObjKeysIte = NULL;
     }
   }
 
@@ -981,29 +1022,29 @@
 
 
 /*******************************************************************************
-  op-zorba:keys($o as item()) as xs:string*
+  op-zorba:keys($o as item()?) as xs:string*
 ********************************************************************************/
-bool SingleObjectNamesIterator::nextImpl(
+bool SingleObjectKeysIterator::nextImpl(
     store::Item_t& result,
     PlanState& planState) const
 {
   store::Item_t input;
 
-  SingleObjectNamesIteratorState* state;
-  DEFAULT_STACK_INIT(SingleObjectNamesIteratorState, state, planState);
+  SingleObjectKeysIteratorState* state;
+  DEFAULT_STACK_INIT(SingleObjectKeysIteratorState, state, planState);
 
   if (consumeNext(input, theChild.getp(), planState))
   {
     if (input->isObject())
     {
-      state->theNames = input->getObjectKeys();
-      state->theNames->open();
+      state->theObjKeysIte = input->getObjectKeys();
+      state->theObjKeysIte->open();
 
-      while (state->theNames->next(result))
+      while (state->theObjKeysIte->next(result))
       {
         STACK_PUSH (true, state);
       }
-      state->theNames = NULL;
+      state->theObjKeysIte = NULL;
     }
   }
 
@@ -1011,15 +1052,15 @@
 }
 
 
-bool SingleObjectNamesIterator::count(
+bool SingleObjectKeysIterator::count(
   store::Item_t& result,
   PlanState& planState) const
 {
   store::Item_t obj;
   xs_integer count(0);
 
-  SingleObjectNamesIteratorState* state;
-  DEFAULT_STACK_INIT(SingleObjectNamesIteratorState, state, planState);
+  SingleObjectKeysIteratorState* state;
+  DEFAULT_STACK_INIT(SingleObjectKeysIteratorState, state, planState);
 
   if (consumeNext(obj, theChild.getp(), planState))
   {
@@ -1035,51 +1076,31 @@
 
 
 /*******************************************************************************
-  jn:keys($o as item()*) as xs:string*
+  op-zorba:multi-object-lookup($o as item()*, $name as item()?) as item()*
+
+  Note: the translator always wraps the $name param to a [cast as xs:string?]
+  expr, so we don's have to check the type of the selector item here.
 ********************************************************************************/
-
-void JSONObjectNamesIteratorState::init(PlanState& planState)
-{
-  theNamesSet.reset(new HashSet<zstring, HashMapZStringCmp>(64, false));
-}
-
-
-void JSONObjectNamesIteratorState::reset(PlanState& planState)
-{
-  PlanIteratorState::reset(planState);
-  theNamesSet->clear();
-}
-
-
-bool JSONObjectNamesIterator::nextImpl(
+bool MultiObjectLookupIterator::nextImpl(
     store::Item_t& result,
     PlanState& planState) const
 {
   store::Item_t input;
-  zstring name;
-
-  JSONObjectNamesIteratorState* state;
-  DEFAULT_STACK_INIT(JSONObjectNamesIteratorState, state, planState);
-
-  while (consumeNext(input, theChild.getp(), planState))
+
+  MultiObjectLookupIteratorState* state;
+  DEFAULT_STACK_INIT(MultiObjectLookupIteratorState, state, planState);
+
+  if (consumeNext(state->theKey, theChild1.getp(), planState))
   {
-    if (input->isObject())
+    while (consumeNext(input, theChild0.getp(), planState))
     {
-      state->theNames = input->getObjectKeys();
-      state->theNames->open();
-
-      while (state->theNames->next(result))
+      if (input->isObject())
       {
-        name = result->getStringValue();
-
-        if (!state->theNamesSet->exists(name))
-        {
-          state->theNamesSet->insert(name);
+        result = input->getObjectValue(state->theKey);
+        
+        if (result)
           STACK_PUSH(true, state);
-        }
       }
-
-      state->theNames = NULL;
     }
   }
 
@@ -1088,14 +1109,14 @@
 
 
 /*******************************************************************************
-  op-zorba:object-value($o as item()?, $name as item()?) as item()?
+  op-zorba:single-object-lookup($o as item()?, $name as item()?) as item()?
 
   Note: the translator always wraps the $name param to a [cast as xs:string?]
   expr, so we don's have to check the type of the selector item here.
 ********************************************************************************/
-bool JSONObjectValueIterator::nextImpl(
-  store::Item_t& result,
-  PlanState& planState) const
+bool SingleObjectLookupIterator::nextImpl(
+    store::Item_t& result,
+    PlanState& planState) const
 {
   store::Item_t input;
   store::Item_t name;
@@ -1258,35 +1279,57 @@
 }
 
 
+
 /*******************************************************************************
-  op-zorba:member($a as item()?, $pos as item()?) as item()?
-
-  Note: the translator always wraps the $pos param to a [cast as xs:integer?]
-  expr, so we don's have to check the type of the selector item here.
+  jn:members($a as item()*) as item()*
 ********************************************************************************/
-bool JSONArrayMemberIterator::nextImpl(
+bool MultiArrayMembersIterator::nextImpl(
     store::Item_t& result,
     PlanState& planState) const
 {
-  store::Item_t input;
-  store::Item_t position;
-
-  PlanIteratorState* state;
-  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
-
-  if (consumeNext(input, theChild0.getp(), planState))
+  store::Item_t array;
+
+  MultiArrayMembersIteratorState* state;
+  DEFAULT_STACK_INIT(MultiArrayMembersIteratorState, state, planState);
+
+  while (consumeNext(array, theChild.getp(), planState))
   {
-    if (input->isArray())
+    if (array->isArray())
     {
-      if (consumeNext(position, theChild1.getp(), planState))
+      state->theMembers = array->getArrayValues();
+
+      state->theMembers->open();
+      while (state->theMembers->next(result))
       {
-        result = input->getArrayValue(position->getIntegerValue());
-        
-        STACK_PUSH(result != 0, state);
+        STACK_PUSH(true, state);
       }
-    }
-  }
-
+      state->theMembers->close();
+    }
+  }
+
+  STACK_END(state);
+}
+
+
+bool MultiArrayMembersIterator::count(
+    store::Item_t& result,
+    PlanState& planState) const
+{
+  store::Item_t array;
+  xs_integer count(0);
+
+  MultiArrayMembersIteratorState* state;
+  DEFAULT_STACK_INIT(MultiArrayMembersIteratorState, state, planState);
+
+  while (consumeNext(array, theChild.getp(), planState))
+  {
+    if (array->isArray())
+    {
+      count += array->getArraySize();
+    }
+  }
+
+  STACK_PUSH(GENV_ITEMFACTORY->createInteger(result, count), state);
   STACK_END(state);
 }
 
@@ -1295,13 +1338,13 @@
   op-zorba:members($a as item()?) as item()*
 ********************************************************************************/
 bool SingleArrayMembersIterator::nextImpl(
-  store::Item_t& result,
-  PlanState& planState) const
+    store::Item_t& result,
+    PlanState& planState) const
 {
   store::Item_t array;
 
-  JSONArrayMembersIteratorState* state;
-  DEFAULT_STACK_INIT(JSONArrayMembersIteratorState, state, planState);
+  SingleArrayMembersIteratorState* state;
+  DEFAULT_STACK_INIT(SingleArrayMembersIteratorState, state, planState);
 
   if (consumeNext(array, theChild.getp(), planState))
   {
@@ -1323,14 +1366,14 @@
 
 
 bool SingleArrayMembersIterator::count(
-  store::Item_t& result,
-  PlanState& planState) const
+    store::Item_t& result,
+    PlanState& planState) const
 {
   store::Item_t array;
   xs_integer count(0);
 
-  JSONArrayMembersIteratorState* state;
-  DEFAULT_STACK_INIT(JSONArrayMembersIteratorState, state, planState);
+  SingleArrayMembersIteratorState* state;
+  DEFAULT_STACK_INIT(SingleArrayMembersIteratorState, state, planState);
 
   if (consumeNext(array, theChild.getp(), planState))
   {
@@ -1347,29 +1390,31 @@
 
 
 /*******************************************************************************
-  jn:members($a as item()*) as item()*
+  op-zorba:mutli-array-lookup($a as item()*, $pos as item()?) as item()*
+
+  Note: the translator always wraps the $pos param to a [cast as xs:integer?]
+  expr, so we don's have to check the type of the selector item here.
 ********************************************************************************/
-bool JSONArrayMembersIterator::nextImpl(
-  store::Item_t& result,
-  PlanState& planState) const
+bool MultiArrayLookupIterator::nextImpl(
+    store::Item_t& result,
+    PlanState& planState) const
 {
-  store::Item_t array;
-
-  JSONArrayMembersIteratorState* state;
-  DEFAULT_STACK_INIT(JSONArrayMembersIteratorState, state, planState);
-
-  while (consumeNext(array, theChild.getp(), planState))
+  store::Item_t input;
+
+  MultiArrayLookupIteratorState* state;
+  DEFAULT_STACK_INIT(MultiArrayLookupIteratorState, state, planState);
+
+  if (consumeNext(state->thePosition, theChild1.getp(), planState))
   {
-    if (array->isArray())
+    while (consumeNext(input, theChild0.getp(), planState))
     {
-      state->theMembers = array->getArrayValues();
-
-      state->theMembers->open();
-      while (state->theMembers->next(result))
+      if (input->isArray())
       {
-        STACK_PUSH(true, state);
+        result = input->getArrayValue(state->thePosition->getIntegerValue());
+
+        if (result)
+          STACK_PUSH(true, state);
       }
-      state->theMembers->close();
     }
   }
 
@@ -1377,25 +1422,35 @@
 }
 
 
-bool JSONArrayMembersIterator::count(
-  store::Item_t& result,
-  PlanState& planState) const
+/*******************************************************************************
+  op-zorba:single-array-lookup($a as item()?, $pos as item()?) as item()?
+
+  Note: the translator always wraps the $pos param to a [cast as xs:integer?]
+  expr, so we don's have to check the type of the selector item here.
+********************************************************************************/
+bool SingleArrayLookupIterator::nextImpl(
+    store::Item_t& result,
+    PlanState& planState) const
 {
-  store::Item_t array;
-  xs_integer count(0);
-
-  JSONArrayMembersIteratorState* state;
-  DEFAULT_STACK_INIT(JSONArrayMembersIteratorState, state, planState);
-
-  while (consumeNext(array, theChild.getp(), planState))
+  store::Item_t input;
+  store::Item_t position;
+
+  PlanIteratorState* state;
+  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
+
+  if (consumeNext(input, theChild0.getp(), planState))
   {
-    if (array->isArray())
+    if (input->isArray())
     {
-      count += array->getArraySize();
+      if (consumeNext(position, theChild1.getp(), planState))
+      {
+        result = input->getArrayValue(position->getIntegerValue());
+        
+        STACK_PUSH(result != 0, state);
+      }
     }
   }
 
-  STACK_PUSH(GENV_ITEMFACTORY->createInteger(result, count), state);
   STACK_END(state);
 }
 

=== modified file 'src/runtime/json/pregenerated/jsoniq_functions.cpp'
--- src/runtime/json/pregenerated/jsoniq_functions.cpp	2013-08-14 15:16:42 +0000
+++ src/runtime/json/pregenerated/jsoniq_functions.cpp	2013-08-16 13:03:04 +0000
@@ -144,133 +144,130 @@
 // </JSONParseIterator>
 
 
-// <JSONItemAccessorIterator>
-SERIALIZABLE_CLASS_VERSIONS(JSONItemAccessorIterator)
-
-void JSONItemAccessorIterator::serialize(::zorba::serialization::Archiver& ar)
-{
-  serialize_baseclass(ar,
-  (NaryBaseIterator<JSONItemAccessorIterator, JSONItemAccessorIteratorState>*)this);
-}
-
-
-void JSONItemAccessorIterator::accept(PlanIterVisitor& v) const
-{
-  v.beginVisit(*this);
-
-  std::vector<PlanIter_t>::const_iterator lIter = theChildren.begin();
-  std::vector<PlanIter_t>::const_iterator lEnd = theChildren.end();
-  for ( ; lIter != lEnd; ++lIter ){
-    (*lIter)->accept(v);
-  }
-
-  v.endVisit(*this);
-}
-
-JSONItemAccessorIterator::~JSONItemAccessorIterator() {}
-
-JSONItemAccessorIteratorState::JSONItemAccessorIteratorState() {}
-
-JSONItemAccessorIteratorState::~JSONItemAccessorIteratorState() {}
-
-
-void JSONItemAccessorIteratorState::init(PlanState& planState) {
-  PlanIteratorState::init(planState);
-}
-
-void JSONItemAccessorIteratorState::reset(PlanState& planState) {
-  PlanIteratorState::reset(planState);
-}
-// </JSONItemAccessorIterator>
-
-
-// <JSONObjectNamesIterator>
-SERIALIZABLE_CLASS_VERSIONS(JSONObjectNamesIterator)
-
-void JSONObjectNamesIterator::serialize(::zorba::serialization::Archiver& ar)
-{
-  serialize_baseclass(ar,
-  (UnaryBaseIterator<JSONObjectNamesIterator, JSONObjectNamesIteratorState>*)this);
-}
-
-
-void JSONObjectNamesIterator::accept(PlanIterVisitor& v) const
-{
-  v.beginVisit(*this);
-
-  theChild->accept(v);
-
-  v.endVisit(*this);
-}
-
-JSONObjectNamesIterator::~JSONObjectNamesIterator() {}
-
-JSONObjectNamesIteratorState::JSONObjectNamesIteratorState() {}
-
-JSONObjectNamesIteratorState::~JSONObjectNamesIteratorState() {}
-
-// </JSONObjectNamesIterator>
-
-
-// <SingleObjectNamesIterator>
-SERIALIZABLE_CLASS_VERSIONS(SingleObjectNamesIterator)
-
-void SingleObjectNamesIterator::serialize(::zorba::serialization::Archiver& ar)
-{
-  serialize_baseclass(ar,
-  (UnaryBaseIterator<SingleObjectNamesIterator, SingleObjectNamesIteratorState>*)this);
-}
-
-
-void SingleObjectNamesIterator::accept(PlanIterVisitor& v) const
-{
-  v.beginVisit(*this);
-
-  theChild->accept(v);
-
-  v.endVisit(*this);
-}
-
-SingleObjectNamesIterator::~SingleObjectNamesIterator() {}
-
-SingleObjectNamesIteratorState::SingleObjectNamesIteratorState() {}
-
-SingleObjectNamesIteratorState::~SingleObjectNamesIteratorState() {}
-
-
-void SingleObjectNamesIteratorState::init(PlanState& planState) {
-  PlanIteratorState::init(planState);
-}
-
-void SingleObjectNamesIteratorState::reset(PlanState& planState) {
-  PlanIteratorState::reset(planState);
-}
-// </SingleObjectNamesIterator>
-
-
-// <JSONObjectValueIterator>
-SERIALIZABLE_CLASS_VERSIONS(JSONObjectValueIterator)
-
-void JSONObjectValueIterator::serialize(::zorba::serialization::Archiver& ar)
-{
-  serialize_baseclass(ar,
-  (BinaryBaseIterator<JSONObjectValueIterator, PlanIteratorState>*)this);
-}
-
-
-void JSONObjectValueIterator::accept(PlanIterVisitor& v) const
-{
-  v.beginVisit(*this);
-
-  theChild0->accept(v);
-theChild1->accept(v);
-
-  v.endVisit(*this);
-}
-
-JSONObjectValueIterator::~JSONObjectValueIterator() {}
-
-// </JSONObjectValueIterator>
+// <MultiObjectKeysIterator>
+SERIALIZABLE_CLASS_VERSIONS(MultiObjectKeysIterator)
+
+void MultiObjectKeysIterator::serialize(::zorba::serialization::Archiver& ar)
+{
+  serialize_baseclass(ar,
+  (UnaryBaseIterator<MultiObjectKeysIterator, MultiObjectKeysIteratorState>*)this);
+}
+
+
+void MultiObjectKeysIterator::accept(PlanIterVisitor& v) const
+{
+  v.beginVisit(*this);
+
+  theChild->accept(v);
+
+  v.endVisit(*this);
+}
+
+MultiObjectKeysIterator::~MultiObjectKeysIterator() {}
+
+MultiObjectKeysIteratorState::MultiObjectKeysIteratorState() {}
+
+MultiObjectKeysIteratorState::~MultiObjectKeysIteratorState() {}
+
+// </MultiObjectKeysIterator>
+
+
+// <SingleObjectKeysIterator>
+SERIALIZABLE_CLASS_VERSIONS(SingleObjectKeysIterator)
+
+void SingleObjectKeysIterator::serialize(::zorba::serialization::Archiver& ar)
+{
+  serialize_baseclass(ar,
+  (UnaryBaseIterator<SingleObjectKeysIterator, SingleObjectKeysIteratorState>*)this);
+}
+
+
+void SingleObjectKeysIterator::accept(PlanIterVisitor& v) const
+{
+  v.beginVisit(*this);
+
+  theChild->accept(v);
+
+  v.endVisit(*this);
+}
+
+SingleObjectKeysIterator::~SingleObjectKeysIterator() {}
+
+SingleObjectKeysIteratorState::SingleObjectKeysIteratorState() {}
+
+SingleObjectKeysIteratorState::~SingleObjectKeysIteratorState() {}
+
+
+void SingleObjectKeysIteratorState::init(PlanState& planState) {
+  PlanIteratorState::init(planState);
+}
+
+void SingleObjectKeysIteratorState::reset(PlanState& planState) {
+  PlanIteratorState::reset(planState);
+}
+// </SingleObjectKeysIterator>
+
+
+// <MultiObjectLookupIterator>
+SERIALIZABLE_CLASS_VERSIONS(MultiObjectLookupIterator)
+
+void MultiObjectLookupIterator::serialize(::zorba::serialization::Archiver& ar)
+{
+  serialize_baseclass(ar,
+  (BinaryBaseIterator<MultiObjectLookupIterator, MultiObjectLookupIteratorState>*)this);
+}
+
+
+void MultiObjectLookupIterator::accept(PlanIterVisitor& v) const
+{
+  v.beginVisit(*this);
+
+  theChild0->accept(v);
+theChild1->accept(v);
+
+  v.endVisit(*this);
+}
+
+MultiObjectLookupIterator::~MultiObjectLookupIterator() {}
+
+MultiObjectLookupIteratorState::MultiObjectLookupIteratorState() {}
+
+MultiObjectLookupIteratorState::~MultiObjectLookupIteratorState() {}
+
+
+void MultiObjectLookupIteratorState::init(PlanState& planState) {
+  PlanIteratorState::init(planState);
+}
+
+void MultiObjectLookupIteratorState::reset(PlanState& planState) {
+  PlanIteratorState::reset(planState);
+}
+// </MultiObjectLookupIterator>
+
+
+// <SingleObjectLookupIterator>
+SERIALIZABLE_CLASS_VERSIONS(SingleObjectLookupIterator)
+
+void SingleObjectLookupIterator::serialize(::zorba::serialization::Archiver& ar)
+{
+  serialize_baseclass(ar,
+  (BinaryBaseIterator<SingleObjectLookupIterator, PlanIteratorState>*)this);
+}
+
+
+void SingleObjectLookupIterator::accept(PlanIterVisitor& v) const
+{
+  v.beginVisit(*this);
+
+  theChild0->accept(v);
+theChild1->accept(v);
+
+  v.endVisit(*this);
+}
+
+SingleObjectLookupIterator::~SingleObjectLookupIterator() {}
+
+// </SingleObjectLookupIterator>
 
 
 // <JSONObjectProjectIterator>
@@ -347,42 +344,17 @@
 // </JSONObjectTrimIterator>
 
 
-// <JSONArrayMemberIterator>
-SERIALIZABLE_CLASS_VERSIONS(JSONArrayMemberIterator)
-
-void JSONArrayMemberIterator::serialize(::zorba::serialization::Archiver& ar)
-{
-  serialize_baseclass(ar,
-  (BinaryBaseIterator<JSONArrayMemberIterator, PlanIteratorState>*)this);
-}
-
-
-void JSONArrayMemberIterator::accept(PlanIterVisitor& v) const
-{
-  v.beginVisit(*this);
-
-  theChild0->accept(v);
-theChild1->accept(v);
-
-  v.endVisit(*this);
-}
-
-JSONArrayMemberIterator::~JSONArrayMemberIterator() {}
-
-// </JSONArrayMemberIterator>
-
-
-// <JSONArrayMembersIterator>
-SERIALIZABLE_CLASS_VERSIONS(JSONArrayMembersIterator)
-
-void JSONArrayMembersIterator::serialize(::zorba::serialization::Archiver& ar)
-{
-  serialize_baseclass(ar,
-  (UnaryBaseIterator<JSONArrayMembersIterator, JSONArrayMembersIteratorState>*)this);
-}
-
-
-void JSONArrayMembersIterator::accept(PlanIterVisitor& v) const
+// <MultiArrayMembersIterator>
+SERIALIZABLE_CLASS_VERSIONS(MultiArrayMembersIterator)
+
+void MultiArrayMembersIterator::serialize(::zorba::serialization::Archiver& ar)
+{
+  serialize_baseclass(ar,
+  (UnaryBaseIterator<MultiArrayMembersIterator, MultiArrayMembersIteratorState>*)this);
+}
+
+
+void MultiArrayMembersIterator::accept(PlanIterVisitor& v) const
 {
   v.beginVisit(*this);
 
@@ -391,21 +363,21 @@
   v.endVisit(*this);
 }
 
-JSONArrayMembersIterator::~JSONArrayMembersIterator() {}
-
-JSONArrayMembersIteratorState::JSONArrayMembersIteratorState() {}
-
-JSONArrayMembersIteratorState::~JSONArrayMembersIteratorState() {}
-
-
-void JSONArrayMembersIteratorState::init(PlanState& planState) {
+MultiArrayMembersIterator::~MultiArrayMembersIterator() {}
+
+MultiArrayMembersIteratorState::MultiArrayMembersIteratorState() {}
+
+MultiArrayMembersIteratorState::~MultiArrayMembersIteratorState() {}
+
+
+void MultiArrayMembersIteratorState::init(PlanState& planState) {
   PlanIteratorState::init(planState);
 }
 
-void JSONArrayMembersIteratorState::reset(PlanState& planState) {
+void MultiArrayMembersIteratorState::reset(PlanState& planState) {
   PlanIteratorState::reset(planState);
 }
-// </JSONArrayMembersIterator>
+// </MultiArrayMembersIterator>
 
 
 // <SingleArrayMembersIterator>
@@ -444,6 +416,68 @@
 // </SingleArrayMembersIterator>
 
 
+// <MultiArrayLookupIterator>
+SERIALIZABLE_CLASS_VERSIONS(MultiArrayLookupIterator)
+
+void MultiArrayLookupIterator::serialize(::zorba::serialization::Archiver& ar)
+{
+  serialize_baseclass(ar,
+  (BinaryBaseIterator<MultiArrayLookupIterator, MultiArrayLookupIteratorState>*)this);
+}
+
+
+void MultiArrayLookupIterator::accept(PlanIterVisitor& v) const
+{
+  v.beginVisit(*this);
+
+  theChild0->accept(v);
+theChild1->accept(v);
+
+  v.endVisit(*this);
+}
+
+MultiArrayLookupIterator::~MultiArrayLookupIterator() {}
+
+MultiArrayLookupIteratorState::MultiArrayLookupIteratorState() {}
+
+MultiArrayLookupIteratorState::~MultiArrayLookupIteratorState() {}
+
+
+void MultiArrayLookupIteratorState::init(PlanState& planState) {
+  PlanIteratorState::init(planState);
+}
+
+void MultiArrayLookupIteratorState::reset(PlanState& planState) {
+  PlanIteratorState::reset(planState);
+}
+// </MultiArrayLookupIterator>
+
+
+// <SingleArrayLookupIterator>
+SERIALIZABLE_CLASS_VERSIONS(SingleArrayLookupIterator)
+
+void SingleArrayLookupIterator::serialize(::zorba::serialization::Archiver& ar)
+{
+  serialize_baseclass(ar,
+  (BinaryBaseIterator<SingleArrayLookupIterator, PlanIteratorState>*)this);
+}
+
+
+void SingleArrayLookupIterator::accept(PlanIterVisitor& v) const
+{
+  v.beginVisit(*this);
+
+  theChild0->accept(v);
+theChild1->accept(v);
+
+  v.endVisit(*this);
+}
+
+SingleArrayLookupIterator::~SingleArrayLookupIterator() {}
+
+// </SingleArrayLookupIterator>
+
+
 // <JSONArraySizeIterator>
 SERIALIZABLE_CLASS_VERSIONS(JSONArraySizeIterator)
 

=== modified file 'src/runtime/json/pregenerated/jsoniq_functions.h'
--- src/runtime/json/pregenerated/jsoniq_functions.h	2013-08-14 15:16:42 +0000
+++ src/runtime/json/pregenerated/jsoniq_functions.h	2013-08-16 13:03:04 +0000
@@ -195,125 +195,83 @@
  * 
  * Author: 
  */
-class JSONItemAccessorIteratorState : public PlanIteratorState
-{
-public:
-  store::Iterator_t theIterator; //
-
-  JSONItemAccessorIteratorState();
-
-  ~JSONItemAccessorIteratorState();
-
-  void init(PlanState&);
-  void reset(PlanState&);
-};
-
-class JSONItemAccessorIterator : public NaryBaseIterator<JSONItemAccessorIterator, JSONItemAccessorIteratorState>
-{ 
-public:
-  SERIALIZABLE_CLASS(JSONItemAccessorIterator);
-
-  SERIALIZABLE_CLASS_CONSTRUCTOR2T(JSONItemAccessorIterator,
-    NaryBaseIterator<JSONItemAccessorIterator, JSONItemAccessorIteratorState>);
-
-  void serialize( ::zorba::serialization::Archiver& ar);
-
-  JSONItemAccessorIterator(
-    static_context* sctx,
-    const QueryLoc& loc,
-    std::vector<PlanIter_t>& children)
-    : 
-    NaryBaseIterator<JSONItemAccessorIterator, JSONItemAccessorIteratorState>(sctx, loc, children)
-  {}
-
-  virtual ~JSONItemAccessorIterator();
-
-  void accept(PlanIterVisitor& v) const;
-
-  bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
-};
-
-
-/**
- * 
- * Author: 
- */
-class JSONObjectNamesIteratorState : public PlanIteratorState
-{
-public:
-  store::Iterator_t theNames; //
-  std::unique_ptr<HashSet<zstring, HashMapZStringCmp> > theNamesSet; //
-
-  JSONObjectNamesIteratorState();
-
-  ~JSONObjectNamesIteratorState();
-
-  void init(PlanState&);
-  void reset(PlanState&);
-};
-
-class JSONObjectNamesIterator : public UnaryBaseIterator<JSONObjectNamesIterator, JSONObjectNamesIteratorState>
-{ 
-public:
-  SERIALIZABLE_CLASS(JSONObjectNamesIterator);
-
-  SERIALIZABLE_CLASS_CONSTRUCTOR2T(JSONObjectNamesIterator,
-    UnaryBaseIterator<JSONObjectNamesIterator, JSONObjectNamesIteratorState>);
-
-  void serialize( ::zorba::serialization::Archiver& ar);
-
-  JSONObjectNamesIterator(
-    static_context* sctx,
-    const QueryLoc& loc,
-    PlanIter_t& child)
-    : 
-    UnaryBaseIterator<JSONObjectNamesIterator, JSONObjectNamesIteratorState>(sctx, loc, child)
-  {}
-
-  virtual ~JSONObjectNamesIterator();
-
-  void accept(PlanIterVisitor& v) const;
-
-  bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
-};
-
-
-/**
- * 
- * Author: 
- */
-class SingleObjectNamesIteratorState : public PlanIteratorState
-{
-public:
-  store::Iterator_t theNames; //
-
-  SingleObjectNamesIteratorState();
-
-  ~SingleObjectNamesIteratorState();
-
-  void init(PlanState&);
-  void reset(PlanState&);
-};
-
-class SingleObjectNamesIterator : public UnaryBaseIterator<SingleObjectNamesIterator, SingleObjectNamesIteratorState>
-{ 
-public:
-  SERIALIZABLE_CLASS(SingleObjectNamesIterator);
-
-  SERIALIZABLE_CLASS_CONSTRUCTOR2T(SingleObjectNamesIterator,
-    UnaryBaseIterator<SingleObjectNamesIterator, SingleObjectNamesIteratorState>);
-
-  void serialize( ::zorba::serialization::Archiver& ar);
-
-  SingleObjectNamesIterator(
-    static_context* sctx,
-    const QueryLoc& loc,
-    PlanIter_t& child)
-    : 
-    UnaryBaseIterator<SingleObjectNamesIterator, SingleObjectNamesIteratorState>(sctx, loc, child)
-  {}
-
-  virtual ~SingleObjectNamesIterator();
+class MultiObjectKeysIteratorState : public PlanIteratorState
+{
+public:
+  store::Iterator_t theObjKeysIte; //
+  store::Item_t theSecondObj; //
+  std::unique_ptr<HashSet<zstring, HashMapZStringCmp> > theUniqueKeys; //
+
+  MultiObjectKeysIteratorState();
+
+  ~MultiObjectKeysIteratorState();
+
+  void init(PlanState&);
+  void reset(PlanState&);
+};
+
+class MultiObjectKeysIterator : public UnaryBaseIterator<MultiObjectKeysIterator, MultiObjectKeysIteratorState>
+{ 
+public:
+  SERIALIZABLE_CLASS(MultiObjectKeysIterator);
+
+  SERIALIZABLE_CLASS_CONSTRUCTOR2T(MultiObjectKeysIterator,
+    UnaryBaseIterator<MultiObjectKeysIterator, MultiObjectKeysIteratorState>);
+
+  void serialize( ::zorba::serialization::Archiver& ar);
+
+  MultiObjectKeysIterator(
+    static_context* sctx,
+    const QueryLoc& loc,
+    PlanIter_t& child)
+    : 
+    UnaryBaseIterator<MultiObjectKeysIterator, MultiObjectKeysIteratorState>(sctx, loc, child)
+  {}
+
+  virtual ~MultiObjectKeysIterator();
+
+  void accept(PlanIterVisitor& v) const;
+
+  bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
+};
+
+
+/**
+ * 
+ * Author: 
+ */
+class SingleObjectKeysIteratorState : public PlanIteratorState
+{
+public:
+  store::Iterator_t theObjKeysIte; //
+
+  SingleObjectKeysIteratorState();
+
+  ~SingleObjectKeysIteratorState();
+
+  void init(PlanState&);
+  void reset(PlanState&);
+};
+
+class SingleObjectKeysIterator : public UnaryBaseIterator<SingleObjectKeysIterator, SingleObjectKeysIteratorState>
+{ 
+public:
+  SERIALIZABLE_CLASS(SingleObjectKeysIterator);
+
+  SERIALIZABLE_CLASS_CONSTRUCTOR2T(SingleObjectKeysIterator,
+    UnaryBaseIterator<SingleObjectKeysIterator, SingleObjectKeysIteratorState>);
+
+  void serialize( ::zorba::serialization::Archiver& ar);
+
+  SingleObjectKeysIterator(
+    static_context* sctx,
+    const QueryLoc& loc,
+    PlanIter_t& child)
+    : 
+    UnaryBaseIterator<SingleObjectKeysIterator, SingleObjectKeysIteratorState>(sctx, loc, child)
+  {}
+
+  virtual ~SingleObjectKeysIterator();
 
 public:
   bool count(store::Item_t& result, PlanState& planState) const;
@@ -327,25 +285,68 @@
  * 
  * Author: 
  */
-class JSONObjectValueIterator : public BinaryBaseIterator<JSONObjectValueIterator, PlanIteratorState>
-{ 
-public:
-  SERIALIZABLE_CLASS(JSONObjectValueIterator);
-
-  SERIALIZABLE_CLASS_CONSTRUCTOR2T(JSONObjectValueIterator,
-    BinaryBaseIterator<JSONObjectValueIterator, PlanIteratorState>);
-
-  void serialize( ::zorba::serialization::Archiver& ar);
-
-  JSONObjectValueIterator(
-    static_context* sctx,
-    const QueryLoc& loc,
-    PlanIter_t& child1, PlanIter_t& child2)
-    : 
-    BinaryBaseIterator<JSONObjectValueIterator, PlanIteratorState>(sctx, loc, child1, child2)
-  {}
-
-  virtual ~JSONObjectValueIterator();
+class MultiObjectLookupIteratorState : public PlanIteratorState
+{
+public:
+  store::Item_t theKey; //
+
+  MultiObjectLookupIteratorState();
+
+  ~MultiObjectLookupIteratorState();
+
+  void init(PlanState&);
+  void reset(PlanState&);
+};
+
+class MultiObjectLookupIterator : public BinaryBaseIterator<MultiObjectLookupIterator, MultiObjectLookupIteratorState>
+{ 
+public:
+  SERIALIZABLE_CLASS(MultiObjectLookupIterator);
+
+  SERIALIZABLE_CLASS_CONSTRUCTOR2T(MultiObjectLookupIterator,
+    BinaryBaseIterator<MultiObjectLookupIterator, MultiObjectLookupIteratorState>);
+
+  void serialize( ::zorba::serialization::Archiver& ar);
+
+  MultiObjectLookupIterator(
+    static_context* sctx,
+    const QueryLoc& loc,
+    PlanIter_t& child1, PlanIter_t& child2)
+    : 
+    BinaryBaseIterator<MultiObjectLookupIterator, MultiObjectLookupIteratorState>(sctx, loc, child1, child2)
+  {}
+
+  virtual ~MultiObjectLookupIterator();
+
+  void accept(PlanIterVisitor& v) const;
+
+  bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
+};
+
+
+/**
+ * 
+ * Author: 
+ */
+class SingleObjectLookupIterator : public BinaryBaseIterator<SingleObjectLookupIterator, PlanIteratorState>
+{ 
+public:
+  SERIALIZABLE_CLASS(SingleObjectLookupIterator);
+
+  SERIALIZABLE_CLASS_CONSTRUCTOR2T(SingleObjectLookupIterator,
+    BinaryBaseIterator<SingleObjectLookupIterator, PlanIteratorState>);
+
+  void serialize( ::zorba::serialization::Archiver& ar);
+
+  SingleObjectLookupIterator(
+    static_context* sctx,
+    const QueryLoc& loc,
+    PlanIter_t& child1, PlanIter_t& child2)
+    : 
+    BinaryBaseIterator<SingleObjectLookupIterator, PlanIteratorState>(sctx, loc, child1, child2)
+  {}
+
+  virtual ~SingleObjectLookupIterator();
 
   void accept(PlanIterVisitor& v) const;
 
@@ -443,68 +444,38 @@
  * 
  * Author: 
  */
-class JSONArrayMemberIterator : public BinaryBaseIterator<JSONArrayMemberIterator, PlanIteratorState>
-{ 
-public:
-  SERIALIZABLE_CLASS(JSONArrayMemberIterator);
-
-  SERIALIZABLE_CLASS_CONSTRUCTOR2T(JSONArrayMemberIterator,
-    BinaryBaseIterator<JSONArrayMemberIterator, PlanIteratorState>);
-
-  void serialize( ::zorba::serialization::Archiver& ar);
-
-  JSONArrayMemberIterator(
-    static_context* sctx,
-    const QueryLoc& loc,
-    PlanIter_t& child1, PlanIter_t& child2)
-    : 
-    BinaryBaseIterator<JSONArrayMemberIterator, PlanIteratorState>(sctx, loc, child1, child2)
-  {}
-
-  virtual ~JSONArrayMemberIterator();
-
-  void accept(PlanIterVisitor& v) const;
-
-  bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
-};
-
-
-/**
- * 
- * Author: 
- */
-class JSONArrayMembersIteratorState : public PlanIteratorState
+class MultiArrayMembersIteratorState : public PlanIteratorState
 {
 public:
   store::Iterator_t theMembers; //
 
-  JSONArrayMembersIteratorState();
+  MultiArrayMembersIteratorState();
 
-  ~JSONArrayMembersIteratorState();
+  ~MultiArrayMembersIteratorState();
 
   void init(PlanState&);
   void reset(PlanState&);
 };
 
-class JSONArrayMembersIterator : public UnaryBaseIterator<JSONArrayMembersIterator, JSONArrayMembersIteratorState>
+class MultiArrayMembersIterator : public UnaryBaseIterator<MultiArrayMembersIterator, MultiArrayMembersIteratorState>
 { 
 public:
-  SERIALIZABLE_CLASS(JSONArrayMembersIterator);
+  SERIALIZABLE_CLASS(MultiArrayMembersIterator);
 
-  SERIALIZABLE_CLASS_CONSTRUCTOR2T(JSONArrayMembersIterator,
-    UnaryBaseIterator<JSONArrayMembersIterator, JSONArrayMembersIteratorState>);
+  SERIALIZABLE_CLASS_CONSTRUCTOR2T(MultiArrayMembersIterator,
+    UnaryBaseIterator<MultiArrayMembersIterator, MultiArrayMembersIteratorState>);
 
   void serialize( ::zorba::serialization::Archiver& ar);
 
-  JSONArrayMembersIterator(
+  MultiArrayMembersIterator(
     static_context* sctx,
     const QueryLoc& loc,
     PlanIter_t& child)
     : 
-    UnaryBaseIterator<JSONArrayMembersIterator, JSONArrayMembersIteratorState>(sctx, loc, child)
+    UnaryBaseIterator<MultiArrayMembersIterator, MultiArrayMembersIteratorState>(sctx, loc, child)
   {}
 
-  virtual ~JSONArrayMembersIterator();
+  virtual ~MultiArrayMembersIterator();
 
 public:
   bool count(store::Item_t& result, PlanState& planState) const;
@@ -563,6 +534,79 @@
  * 
  * Author: 
  */
+class MultiArrayLookupIteratorState : public PlanIteratorState
+{
+public:
+  store::Item_t thePosition; //
+
+  MultiArrayLookupIteratorState();
+
+  ~MultiArrayLookupIteratorState();
+
+  void init(PlanState&);
+  void reset(PlanState&);
+};
+
+class MultiArrayLookupIterator : public BinaryBaseIterator<MultiArrayLookupIterator, MultiArrayLookupIteratorState>
+{ 
+public:
+  SERIALIZABLE_CLASS(MultiArrayLookupIterator);
+
+  SERIALIZABLE_CLASS_CONSTRUCTOR2T(MultiArrayLookupIterator,
+    BinaryBaseIterator<MultiArrayLookupIterator, MultiArrayLookupIteratorState>);
+
+  void serialize( ::zorba::serialization::Archiver& ar);
+
+  MultiArrayLookupIterator(
+    static_context* sctx,
+    const QueryLoc& loc,
+    PlanIter_t& child1, PlanIter_t& child2)
+    : 
+    BinaryBaseIterator<MultiArrayLookupIterator, MultiArrayLookupIteratorState>(sctx, loc, child1, child2)
+  {}
+
+  virtual ~MultiArrayLookupIterator();
+
+  void accept(PlanIterVisitor& v) const;
+
+  bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
+};
+
+
+/**
+ * 
+ * Author: 
+ */
+class SingleArrayLookupIterator : public BinaryBaseIterator<SingleArrayLookupIterator, PlanIteratorState>
+{ 
+public:
+  SERIALIZABLE_CLASS(SingleArrayLookupIterator);
+
+  SERIALIZABLE_CLASS_CONSTRUCTOR2T(SingleArrayLookupIterator,
+    BinaryBaseIterator<SingleArrayLookupIterator, PlanIteratorState>);
+
+  void serialize( ::zorba::serialization::Archiver& ar);
+
+  SingleArrayLookupIterator(
+    static_context* sctx,
+    const QueryLoc& loc,
+    PlanIter_t& child1, PlanIter_t& child2)
+    : 
+    BinaryBaseIterator<SingleArrayLookupIterator, PlanIteratorState>(sctx, loc, child1, child2)
+  {}
+
+  virtual ~SingleArrayLookupIterator();
+
+  void accept(PlanIterVisitor& v) const;
+
+  bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
+};
+
+
+/**
+ * 
+ * Author: 
+ */
 class JSONArraySizeIterator : public UnaryBaseIterator<JSONArraySizeIterator, PlanIteratorState>
 { 
 public:

=== modified file 'src/runtime/pregenerated/iterator_enum.h'
--- src/runtime/pregenerated/iterator_enum.h	2013-08-14 15:16:42 +0000
+++ src/runtime/pregenerated/iterator_enum.h	2013-08-16 13:03:04 +0000
@@ -167,15 +167,16 @@
   TYPE_JSONDecodeFromRoundtripIterator,
   TYPE_JSONEncodeForRoundtripIterator,
   TYPE_JSONParseIterator,
-  TYPE_JSONItemAccessorIterator,
-  TYPE_JSONObjectNamesIterator,
-  TYPE_SingleObjectNamesIterator,
-  TYPE_JSONObjectValueIterator,
+  TYPE_MultiObjectKeysIterator,
+  TYPE_SingleObjectKeysIterator,
+  TYPE_MultiObjectLookupIterator,
+  TYPE_SingleObjectLookupIterator,
   TYPE_JSONObjectProjectIterator,
   TYPE_JSONObjectTrimIterator,
-  TYPE_JSONArrayMemberIterator,
-  TYPE_JSONArrayMembersIterator,
+  TYPE_MultiArrayMembersIterator,
   TYPE_SingleArrayMembersIterator,
+  TYPE_MultiArrayLookupIterator,
+  TYPE_SingleArrayLookupIterator,
   TYPE_JSONArraySizeIterator,
   TYPE_JSONArrayFlattenIterator,
   TYPE_JSONNullIterator,

=== modified file 'src/runtime/spec/json/jsoniq_functions.xml'
--- src/runtime/spec/json/jsoniq_functions.xml	2013-08-14 15:16:42 +0000
+++ src/runtime/spec/json/jsoniq_functions.xml	2013-08-16 13:03:04 +0000
@@ -202,42 +202,7 @@
 /*******************************************************************************
 ********************************************************************************/
 -->
-<zorba:iterator name="JSONItemAccessorIterator">
-
-  <zorba:function isDeterministic="true">
-
-    <zorba:signature localname="json-item-accessor" prefix="op-zorba">
-      <zorba:param>item()?</zorba:param>
-      <zorba:output>item()*</zorba:output>
-    </zorba:signature>
-
-    <zorba:signature localname="json-item-accessor" prefix="op-zorba">
-      <zorba:param>item()?</zorba:param>
-      <zorba:param>item()?</zorba:param>
-      <zorba:output>item()?</zorba:output>
-    </zorba:signature>
-
-    <zorba:methods>
-      <zorba:getReturnType/>
-      <zorba:propagatesInputNodes producer="0"/>
-      <zorba:mustCopyInputNodes value="false"/>
-    </zorba:methods>
-
-  </zorba:function>
-
-  <zorba:state>
-    <zorba:member type="store::Iterator_t" name="theIterator"/>
-  </zorba:state>
-
-</zorba:iterator>
-
-
-
-<!--
-/*******************************************************************************
-********************************************************************************/
--->
-<zorba:iterator name="JSONObjectNamesIterator" arity="unary">
+<zorba:iterator name="MultiObjectKeysIterator" arity="unary">
 
   <zorba:function isDeterministic="true"
                   generateCodegen="false">
@@ -257,10 +222,12 @@
 
   <zorba:state generateInit="false" generateReset="false">
 
-    <zorba:member type="store::Iterator_t" name="theNames"/>
+    <zorba:member type="store::Iterator_t" name="theObjKeysIte"/>
+
+    <zorba:member type="store::Item_t" name="theSecondObj"/>
 
     <zorba:member type="std::unique_ptr&lt;HashSet&lt;zstring, HashMapZStringCmp> >"
-                  name="theNamesSet"/>
+                  name="theUniqueKeys"/>
   </zorba:state>
 
 </zorba:iterator>
@@ -270,7 +237,7 @@
 /*******************************************************************************
 ********************************************************************************/
 -->
-<zorba:iterator name="SingleObjectNamesIterator" arity="unary">
+<zorba:iterator name="SingleObjectKeysIterator" arity="unary">
 
   <zorba:function isDeterministic="true">
 
@@ -287,7 +254,7 @@
   </zorba:function>
 
   <zorba:state>
-    <zorba:member type="store::Iterator_t" name="theNames" brief=""/>
+    <zorba:member type="store::Iterator_t" name="theObjKeysIte" brief=""/>
   </zorba:state>
 
   <zorba:method name="count" const="true" return="bool">
@@ -302,11 +269,40 @@
 /*******************************************************************************
 ********************************************************************************/
 -->
-<zorba:iterator name="JSONObjectValueIterator" arity="binary">
-
-  <zorba:function isDeterministic="true">
-
-    <zorba:signature localname="object-value" prefix="op-zorba">
+<zorba:iterator name="MultiObjectLookupIterator" arity="binary">
+
+  <zorba:function isDeterministic="true">
+
+    <zorba:signature localname="multi-object-lookup" prefix="op-zorba">
+      <zorba:param>item()*</zorba:param>
+      <zorba:param>item()?</zorba:param>
+      <zorba:output>item()*</zorba:output>
+    </zorba:signature>
+
+    <zorba:methods>
+      <zorba:getReturnType/>
+      <zorba:propagatesInputNodes producer="0"/>
+      <zorba:mustCopyInputNodes value="false"/>
+    </zorba:methods>
+
+  </zorba:function>
+
+  <zorba:state>
+    <zorba:member type="store::Item_t" name="theKey"/>
+  </zorba:state>
+
+</zorba:iterator>
+
+
+<!--
+/*******************************************************************************
+********************************************************************************/
+-->
+<zorba:iterator name="SingleObjectLookupIterator" arity="binary">
+
+  <zorba:function isDeterministic="true">
+
+    <zorba:signature localname="single-object-lookup" prefix="op-zorba">
       <zorba:param>item()?</zorba:param>
       <zorba:param>item()?</zorba:param>
       <zorba:output>item()?</zorba:output>
@@ -387,32 +383,7 @@
 /*******************************************************************************
 ********************************************************************************/
 -->
-<zorba:iterator name="JSONArrayMemberIterator" arity="binary">
-
-  <zorba:function isDeterministic="true">
-
-    <zorba:signature localname="array-member" prefix="op-zorba">
-      <zorba:param>item()?</zorba:param>
-      <zorba:param>item()?</zorba:param>
-      <zorba:output>item()?</zorba:output>
-    </zorba:signature>
-
-    <zorba:methods>
-      <zorba:getReturnType/>
-      <zorba:propagatesInputNodes producer="0"/>
-      <zorba:mustCopyInputNodes value="false"/>
-    </zorba:methods>
-
-  </zorba:function>
-
-</zorba:iterator>
-
-
-<!--
-/*******************************************************************************
-********************************************************************************/
--->
-<zorba:iterator name="JSONArrayMembersIterator" arity="unary">
+<zorba:iterator name="MultiArrayMembersIterator" arity="unary">
 
   <zorba:function isDeterministic="true"
                   generateCodegen="false">
@@ -478,6 +449,61 @@
 /*******************************************************************************
 ********************************************************************************/
 -->
+<zorba:iterator name="MultiArrayLookupIterator" arity="binary">
+
+  <zorba:function isDeterministic="true">
+
+    <zorba:signature localname="multi-array-lookup" prefix="op-zorba">
+      <zorba:param>item()*</zorba:param>
+      <zorba:param>item()?</zorba:param>
+      <zorba:output>item()*</zorba:output>
+    </zorba:signature>
+
+    <zorba:methods>
+      <zorba:getReturnType/>
+      <zorba:propagatesInputNodes producer="0"/>
+      <zorba:mustCopyInputNodes value="false"/>
+      <zorba:isMap producer="0"/>
+    </zorba:methods>
+
+  </zorba:function>
+
+  <zorba:state>
+    <zorba:member type="store::Item_t" name="thePosition"/>
+  </zorba:state>
+
+</zorba:iterator>
+
+
+<!--
+/*******************************************************************************
+********************************************************************************/
+-->
+<zorba:iterator name="SingleArrayLookupIterator" arity="binary">
+
+  <zorba:function isDeterministic="true">
+
+    <zorba:signature localname="single-array-lookup" prefix="op-zorba">
+      <zorba:param>item()?</zorba:param>
+      <zorba:param>item()?</zorba:param>
+      <zorba:output>item()?</zorba:output>
+    </zorba:signature>
+
+    <zorba:methods>
+      <zorba:getReturnType/>
+      <zorba:propagatesInputNodes producer="0"/>
+      <zorba:mustCopyInputNodes value="false"/>
+    </zorba:methods>
+
+  </zorba:function>
+
+</zorba:iterator>
+
+
+<!--
+/*******************************************************************************
+********************************************************************************/
+-->
 <zorba:iterator name="JSONArraySizeIterator" arity="unary">
 
   <zorba:function isDeterministic="true">

=== modified file 'src/runtime/visitors/planiter_visitor_impl_code.h'
--- src/runtime/visitors/planiter_visitor_impl_code.h	2013-06-15 02:57:08 +0000
+++ src/runtime/visitors/planiter_visitor_impl_code.h	2013-08-16 13:03:04 +0000
@@ -352,7 +352,8 @@
   PLAN_ITER_VISITOR(CreateInternalIndexIterator);
   PLAN_ITER_VISITOR(DeleteIndexIterator);
 
-  PLAN_ITER_VISITOR(DynamicFnCallIterator);
+  PLAN_ITER_VISITOR(SingleDynamicFnCallIterator);
+  PLAN_ITER_VISITOR(MultiDynamicFnCallIterator);
   PLAN_ITER_VISITOR(ArgumentPlaceholderIterator);
 
   PLAN_ITER_VISITOR(EvalIterator);

=== modified file 'src/runtime/visitors/planiter_visitor_impl_include.h'
--- src/runtime/visitors/planiter_visitor_impl_include.h	2013-06-15 02:57:08 +0000
+++ src/runtime/visitors/planiter_visitor_impl_include.h	2013-08-16 13:03:04 +0000
@@ -172,7 +172,8 @@
 class CreateInternalIndexIterator;
 class DeleteIndexIterator;
 
-class DynamicFnCallIterator;
+class SingleDynamicFnCallIterator;
+class MultiDynamicFnCallIterator;
 class ArgumentPlaceholderIterator;
 
 class EvalIterator;

=== modified file 'src/runtime/visitors/pregenerated/planiter_visitor.h'
--- src/runtime/visitors/pregenerated/planiter_visitor.h	2013-08-14 15:16:42 +0000
+++ src/runtime/visitors/pregenerated/planiter_visitor.h	2013-08-16 13:03:04 +0000
@@ -340,24 +340,26 @@
 
     class JSONParseIterator;
 
-    class JSONItemAccessorIterator;
-
-    class JSONObjectNamesIterator;
-
-    class SingleObjectNamesIterator;
-
-    class JSONObjectValueIterator;
+    class MultiObjectKeysIterator;
+
+    class SingleObjectKeysIterator;
+
+    class MultiObjectLookupIterator;
+
+    class SingleObjectLookupIterator;
 
     class JSONObjectProjectIterator;
 
     class JSONObjectTrimIterator;
 
-    class JSONArrayMemberIterator;
-
-    class JSONArrayMembersIterator;
+    class MultiArrayMembersIterator;
 
     class SingleArrayMembersIterator;
 
+    class MultiArrayLookupIterator;
+
+    class SingleArrayLookupIterator;
+
     class JSONArraySizeIterator;
 
     class JSONArrayFlattenIterator;
@@ -1214,17 +1216,17 @@
     virtual void beginVisit ( const JSONParseIterator& ) = 0;
     virtual void endVisit   ( const JSONParseIterator& ) = 0;
 
-    virtual void beginVisit ( const JSONItemAccessorIterator& ) = 0;
-    virtual void endVisit   ( const JSONItemAccessorIterator& ) = 0;
-
-    virtual void beginVisit ( const JSONObjectNamesIterator& ) = 0;
-    virtual void endVisit   ( const JSONObjectNamesIterator& ) = 0;
-
-    virtual void beginVisit ( const SingleObjectNamesIterator& ) = 0;
-    virtual void endVisit   ( const SingleObjectNamesIterator& ) = 0;
-
-    virtual void beginVisit ( const JSONObjectValueIterator& ) = 0;
-    virtual void endVisit   ( const JSONObjectValueIterator& ) = 0;
+    virtual void beginVisit ( const MultiObjectKeysIterator& ) = 0;
+    virtual void endVisit   ( const MultiObjectKeysIterator& ) = 0;
+
+    virtual void beginVisit ( const SingleObjectKeysIterator& ) = 0;
+    virtual void endVisit   ( const SingleObjectKeysIterator& ) = 0;
+
+    virtual void beginVisit ( const MultiObjectLookupIterator& ) = 0;
+    virtual void endVisit   ( const MultiObjectLookupIterator& ) = 0;
+
+    virtual void beginVisit ( const SingleObjectLookupIterator& ) = 0;
+    virtual void endVisit   ( const SingleObjectLookupIterator& ) = 0;
 
     virtual void beginVisit ( const JSONObjectProjectIterator& ) = 0;
     virtual void endVisit   ( const JSONObjectProjectIterator& ) = 0;
@@ -1232,15 +1234,18 @@
     virtual void beginVisit ( const JSONObjectTrimIterator& ) = 0;
     virtual void endVisit   ( const JSONObjectTrimIterator& ) = 0;
 
-    virtual void beginVisit ( const JSONArrayMemberIterator& ) = 0;
-    virtual void endVisit   ( const JSONArrayMemberIterator& ) = 0;
-
-    virtual void beginVisit ( const JSONArrayMembersIterator& ) = 0;
-    virtual void endVisit   ( const JSONArrayMembersIterator& ) = 0;
+    virtual void beginVisit ( const MultiArrayMembersIterator& ) = 0;
+    virtual void endVisit   ( const MultiArrayMembersIterator& ) = 0;
 
     virtual void beginVisit ( const SingleArrayMembersIterator& ) = 0;
     virtual void endVisit   ( const SingleArrayMembersIterator& ) = 0;
 
+    virtual void beginVisit ( const MultiArrayLookupIterator& ) = 0;
+    virtual void endVisit   ( const MultiArrayLookupIterator& ) = 0;
+
+    virtual void beginVisit ( const SingleArrayLookupIterator& ) = 0;
+    virtual void endVisit   ( const SingleArrayLookupIterator& ) = 0;
+
     virtual void beginVisit ( const JSONArraySizeIterator& ) = 0;
     virtual void endVisit   ( const JSONArraySizeIterator& ) = 0;
 

=== modified file 'src/runtime/visitors/pregenerated/printer_visitor.cpp'
--- src/runtime/visitors/pregenerated/printer_visitor.cpp	2013-08-14 15:16:42 +0000
+++ src/runtime/visitors/pregenerated/printer_visitor.cpp	2013-08-16 13:03:04 +0000
@@ -2052,60 +2052,60 @@
 // </JSONParseIterator>
 
 
-// <JSONItemAccessorIterator>
-void PrinterVisitor::beginVisit ( const JSONItemAccessorIterator& a) {
-  thePrinter.startBeginVisit("JSONItemAccessorIterator", ++theId);
-  printCommons( &a, theId );
-  thePrinter.endBeginVisit( theId );
-}
-
-void PrinterVisitor::endVisit ( const JSONItemAccessorIterator& ) {
-  thePrinter.startEndVisit();
-  thePrinter.endEndVisit();
-}
-// </JSONItemAccessorIterator>
-
-
-// <JSONObjectNamesIterator>
-void PrinterVisitor::beginVisit ( const JSONObjectNamesIterator& a) {
-  thePrinter.startBeginVisit("JSONObjectNamesIterator", ++theId);
-  printCommons( &a, theId );
-  thePrinter.endBeginVisit( theId );
-}
-
-void PrinterVisitor::endVisit ( const JSONObjectNamesIterator& ) {
-  thePrinter.startEndVisit();
-  thePrinter.endEndVisit();
-}
-// </JSONObjectNamesIterator>
-
-
-// <SingleObjectNamesIterator>
-void PrinterVisitor::beginVisit ( const SingleObjectNamesIterator& a) {
-  thePrinter.startBeginVisit("SingleObjectNamesIterator", ++theId);
-  printCommons( &a, theId );
-  thePrinter.endBeginVisit( theId );
-}
-
-void PrinterVisitor::endVisit ( const SingleObjectNamesIterator& ) {
-  thePrinter.startEndVisit();
-  thePrinter.endEndVisit();
-}
-// </SingleObjectNamesIterator>
-
-
-// <JSONObjectValueIterator>
-void PrinterVisitor::beginVisit ( const JSONObjectValueIterator& a) {
-  thePrinter.startBeginVisit("JSONObjectValueIterator", ++theId);
-  printCommons( &a, theId );
-  thePrinter.endBeginVisit( theId );
-}
-
-void PrinterVisitor::endVisit ( const JSONObjectValueIterator& ) {
-  thePrinter.startEndVisit();
-  thePrinter.endEndVisit();
-}
-// </JSONObjectValueIterator>
+// <MultiObjectKeysIterator>
+void PrinterVisitor::beginVisit ( const MultiObjectKeysIterator& a) {
+  thePrinter.startBeginVisit("MultiObjectKeysIterator", ++theId);
+  printCommons( &a, theId );
+  thePrinter.endBeginVisit( theId );
+}
+
+void PrinterVisitor::endVisit ( const MultiObjectKeysIterator& ) {
+  thePrinter.startEndVisit();
+  thePrinter.endEndVisit();
+}
+// </MultiObjectKeysIterator>
+
+
+// <SingleObjectKeysIterator>
+void PrinterVisitor::beginVisit ( const SingleObjectKeysIterator& a) {
+  thePrinter.startBeginVisit("SingleObjectKeysIterator", ++theId);
+  printCommons( &a, theId );
+  thePrinter.endBeginVisit( theId );
+}
+
+void PrinterVisitor::endVisit ( const SingleObjectKeysIterator& ) {
+  thePrinter.startEndVisit();
+  thePrinter.endEndVisit();
+}
+// </SingleObjectKeysIterator>
+
+
+// <MultiObjectLookupIterator>
+void PrinterVisitor::beginVisit ( const MultiObjectLookupIterator& a) {
+  thePrinter.startBeginVisit("MultiObjectLookupIterator", ++theId);
+  printCommons( &a, theId );
+  thePrinter.endBeginVisit( theId );
+}
+
+void PrinterVisitor::endVisit ( const MultiObjectLookupIterator& ) {
+  thePrinter.startEndVisit();
+  thePrinter.endEndVisit();
+}
+// </MultiObjectLookupIterator>
+
+
+// <SingleObjectLookupIterator>
+void PrinterVisitor::beginVisit ( const SingleObjectLookupIterator& a) {
+  thePrinter.startBeginVisit("SingleObjectLookupIterator", ++theId);
+  printCommons( &a, theId );
+  thePrinter.endBeginVisit( theId );
+}
+
+void PrinterVisitor::endVisit ( const SingleObjectLookupIterator& ) {
+  thePrinter.startEndVisit();
+  thePrinter.endEndVisit();
+}
+// </SingleObjectLookupIterator>
 
 
 // <JSONObjectProjectIterator>
@@ -2136,32 +2136,18 @@
 // </JSONObjectTrimIterator>
 
 
-// <JSONArrayMemberIterator>
-void PrinterVisitor::beginVisit ( const JSONArrayMemberIterator& a) {
-  thePrinter.startBeginVisit("JSONArrayMemberIterator", ++theId);
-  printCommons( &a, theId );
-  thePrinter.endBeginVisit( theId );
-}
-
-void PrinterVisitor::endVisit ( const JSONArrayMemberIterator& ) {
-  thePrinter.startEndVisit();
-  thePrinter.endEndVisit();
-}
-// </JSONArrayMemberIterator>
-
-
-// <JSONArrayMembersIterator>
-void PrinterVisitor::beginVisit ( const JSONArrayMembersIterator& a) {
-  thePrinter.startBeginVisit("JSONArrayMembersIterator", ++theId);
-  printCommons( &a, theId );
-  thePrinter.endBeginVisit( theId );
-}
-
-void PrinterVisitor::endVisit ( const JSONArrayMembersIterator& ) {
-  thePrinter.startEndVisit();
-  thePrinter.endEndVisit();
-}
-// </JSONArrayMembersIterator>
+// <MultiArrayMembersIterator>
+void PrinterVisitor::beginVisit ( const MultiArrayMembersIterator& a) {
+  thePrinter.startBeginVisit("MultiArrayMembersIterator", ++theId);
+  printCommons( &a, theId );
+  thePrinter.endBeginVisit( theId );
+}
+
+void PrinterVisitor::endVisit ( const MultiArrayMembersIterator& ) {
+  thePrinter.startEndVisit();
+  thePrinter.endEndVisit();
+}
+// </MultiArrayMembersIterator>
 
 
 // <SingleArrayMembersIterator>
@@ -2178,6 +2164,34 @@
 // </SingleArrayMembersIterator>
 
 
+// <MultiArrayLookupIterator>
+void PrinterVisitor::beginVisit ( const MultiArrayLookupIterator& a) {
+  thePrinter.startBeginVisit("MultiArrayLookupIterator", ++theId);
+  printCommons( &a, theId );
+  thePrinter.endBeginVisit( theId );
+}
+
+void PrinterVisitor::endVisit ( const MultiArrayLookupIterator& ) {
+  thePrinter.startEndVisit();
+  thePrinter.endEndVisit();
+}
+// </MultiArrayLookupIterator>
+
+
+// <SingleArrayLookupIterator>
+void PrinterVisitor::beginVisit ( const SingleArrayLookupIterator& a) {
+  thePrinter.startBeginVisit("SingleArrayLookupIterator", ++theId);
+  printCommons( &a, theId );
+  thePrinter.endBeginVisit( theId );
+}
+
+void PrinterVisitor::endVisit ( const SingleArrayLookupIterator& ) {
+  thePrinter.startEndVisit();
+  thePrinter.endEndVisit();
+}
+// </SingleArrayLookupIterator>
+
+
 // <JSONArraySizeIterator>
 void PrinterVisitor::beginVisit ( const JSONArraySizeIterator& a) {
   thePrinter.startBeginVisit("JSONArraySizeIterator", ++theId);

=== modified file 'src/runtime/visitors/pregenerated/printer_visitor.h'
--- src/runtime/visitors/pregenerated/printer_visitor.h	2013-08-14 15:16:42 +0000
+++ src/runtime/visitors/pregenerated/printer_visitor.h	2013-08-16 13:03:04 +0000
@@ -520,17 +520,17 @@
     void beginVisit( const JSONParseIterator& );
     void endVisit  ( const JSONParseIterator& );
 
-    void beginVisit( const JSONItemAccessorIterator& );
-    void endVisit  ( const JSONItemAccessorIterator& );
-
-    void beginVisit( const JSONObjectNamesIterator& );
-    void endVisit  ( const JSONObjectNamesIterator& );
-
-    void beginVisit( const SingleObjectNamesIterator& );
-    void endVisit  ( const SingleObjectNamesIterator& );
-
-    void beginVisit( const JSONObjectValueIterator& );
-    void endVisit  ( const JSONObjectValueIterator& );
+    void beginVisit( const MultiObjectKeysIterator& );
+    void endVisit  ( const MultiObjectKeysIterator& );
+
+    void beginVisit( const SingleObjectKeysIterator& );
+    void endVisit  ( const SingleObjectKeysIterator& );
+
+    void beginVisit( const MultiObjectLookupIterator& );
+    void endVisit  ( const MultiObjectLookupIterator& );
+
+    void beginVisit( const SingleObjectLookupIterator& );
+    void endVisit  ( const SingleObjectLookupIterator& );
 
     void beginVisit( const JSONObjectProjectIterator& );
     void endVisit  ( const JSONObjectProjectIterator& );
@@ -538,15 +538,18 @@
     void beginVisit( const JSONObjectTrimIterator& );
     void endVisit  ( const JSONObjectTrimIterator& );
 
-    void beginVisit( const JSONArrayMemberIterator& );
-    void endVisit  ( const JSONArrayMemberIterator& );
-
-    void beginVisit( const JSONArrayMembersIterator& );
-    void endVisit  ( const JSONArrayMembersIterator& );
+    void beginVisit( const MultiArrayMembersIterator& );
+    void endVisit  ( const MultiArrayMembersIterator& );
 
     void beginVisit( const SingleArrayMembersIterator& );
     void endVisit  ( const SingleArrayMembersIterator& );
 
+    void beginVisit( const MultiArrayLookupIterator& );
+    void endVisit  ( const MultiArrayLookupIterator& );
+
+    void beginVisit( const SingleArrayLookupIterator& );
+    void endVisit  ( const SingleArrayLookupIterator& );
+
     void beginVisit( const JSONArraySizeIterator& );
     void endVisit  ( const JSONArraySizeIterator& );
 

=== modified file 'src/runtime/visitors/printer_visitor_impl.cpp'
--- src/runtime/visitors/printer_visitor_impl.cpp	2013-06-15 02:57:08 +0000
+++ src/runtime/visitors/printer_visitor_impl.cpp	2013-08-16 13:03:04 +0000
@@ -1543,7 +1543,8 @@
 
 #undef PRINTER_INSERT_NODES_VISITOR_DEFINITION
 
-  PRINTER_VISITOR_DEFINITION(DynamicFnCallIterator);
+  PRINTER_VISITOR_DEFINITION(SingleDynamicFnCallIterator);
+  PRINTER_VISITOR_DEFINITION(MultiDynamicFnCallIterator);
   PRINTER_VISITOR_DEFINITION(ArgumentPlaceholderIterator);
 
   PRINTER_VISITOR_DEFINITION(EvalIterator);

=== modified file 'src/runtime/visitors/printer_visitor_impl.h'
--- src/runtime/visitors/printer_visitor_impl.h	2013-06-15 02:57:08 +0000
+++ src/runtime/visitors/printer_visitor_impl.h	2013-08-16 13:03:04 +0000
@@ -307,7 +307,8 @@
   DECLARE_VISITOR(CreateInternalIndexIterator);
   DECLARE_VISITOR(DeleteIndexIterator);
 
-  DECLARE_VISITOR(DynamicFnCallIterator);
+  DECLARE_VISITOR(SingleDynamicFnCallIterator);
+  DECLARE_VISITOR(MultiDynamicFnCallIterator);
   DECLARE_VISITOR(ArgumentPlaceholderIterator);
 
   DECLARE_VISITOR(EvalIterator);

=== modified file 'src/zorbaserialization/archiver_consts.h'
--- src/zorbaserialization/archiver_consts.h	2013-06-27 15:54:27 +0000
+++ src/zorbaserialization/archiver_consts.h	2013-08-16 13:03:04 +0000
@@ -250,7 +250,8 @@
 
   TYPE_FunctionItemIterator,
   TYPE_FunctionItemInfo,
-  TYPE_DynamicFnCallIterator,
+  TYPE_SingleDynamicFnCallIterator,
+  TYPE_MultiDynamicFnCallIterator,
   TYPE_ArgumentPlaceholderIterator,
 
   TYPE_CountCollectionIterator,

=== modified file 'test/fots/CMakeLists.txt'
--- test/fots/CMakeLists.txt	2013-08-12 19:48:58 +0000
+++ test/fots/CMakeLists.txt	2013-08-16 13:03:04 +0000
@@ -141,6 +141,8 @@
 
 EXPECTED_FOTS_FAILURE (fn-fold-left fold-left-009 1187685)
 EXPECTED_FOTS_FAILURE (fn-for-each-pair fn-for-each-pair-026 1187685)
+EXPECTED_FOTS_FAILURE (fn-for-each-pair fn-for-each-pair-034 000)
+EXPECTED_FOTS_FAILURE (fn-for-each-pair fn-for-each-pair-035 000)
 EXPECTED_FOTS_FAILURE (fn-format-number numberformat20 1167641)
 EXPECTED_FOTS_FAILURE (fn-format-number numberformat60a 1167609)
 EXPECTED_FOTS_FAILURE (fn-format-number numberformat60m 1167609)

=== modified file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/jsoniq/member_01.iter'
--- test/rbkt/ExpCompilerResults/IterPlan/zorba/jsoniq/member_01.iter	2013-08-09 10:31:23 +0000
+++ test/rbkt/ExpCompilerResults/IterPlan/zorba/jsoniq/member_01.iter	2013-08-16 13:03:04 +0000
@@ -10,20 +10,20 @@
   <ReturnClause>
     <FnConcatIterator>
       <FnEmptyIterator>
-        <JSONItemAccessorIterator>
+        <SingleDynamicFnCallIterator>
           <LetVarIterator varname="j"/>
           <SingletonIterator value="xs:integer(0)"/>
-        </JSONItemAccessorIterator>
+        </SingleDynamicFnCallIterator>
       </FnEmptyIterator>
-      <JSONItemAccessorIterator>
+      <SingleDynamicFnCallIterator>
         <LetVarIterator varname="j"/>
         <SingletonIterator value="xs:integer(1)"/>
-      </JSONItemAccessorIterator>
+      </SingleDynamicFnCallIterator>
       <FnEmptyIterator>
-        <JSONItemAccessorIterator>
+        <SingleDynamicFnCallIterator>
           <LetVarIterator varname="j"/>
           <SingletonIterator value="xs:integer(3)"/>
-        </JSONItemAccessorIterator>
+        </SingleDynamicFnCallIterator>
       </FnEmptyIterator>
     </FnConcatIterator>
   </ReturnClause>

=== added file 'test/rbkt/ExpQueryResults/zorba/jsoniq/keys_06.xml.res'
--- test/rbkt/ExpQueryResults/zorba/jsoniq/keys_06.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/jsoniq/keys_06.xml.res	2013-08-16 13:03:04 +0000
@@ -0,0 +1,1 @@
+foo1 foo2 foo1 foo2

=== added file 'test/rbkt/ExpQueryResults/zorba/jsoniq/keys_07.xml.res'
--- test/rbkt/ExpQueryResults/zorba/jsoniq/keys_07.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/jsoniq/keys_07.xml.res	2013-08-16 13:03:04 +0000
@@ -0,0 +1,1 @@
+foo1 foo2 foo1 foo2

=== added file 'test/rbkt/Queries/zorba/jsoniq/keys_06.xq'
--- test/rbkt/Queries/zorba/jsoniq/keys_06.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/jsoniq/keys_06.xq	2013-08-16 13:03:04 +0000
@@ -0,0 +1,6 @@
+
+for $j in (1, 2)
+let $a :=
+  for $i in 1 to 10
+  return ($i, { if ($i mod 2 eq 0) then "foo2" else "foo1" : "bar" || $i })
+return $a()

=== added file 'test/rbkt/Queries/zorba/jsoniq/keys_07.xq'
--- test/rbkt/Queries/zorba/jsoniq/keys_07.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/jsoniq/keys_07.xq	2013-08-16 13:03:04 +0000
@@ -0,0 +1,6 @@
+
+for $j in (1, 2)
+let $a as object()+ :=
+  for $i in 1 to 10
+  return { if ($i mod 2 eq 0) then "foo2" else "foo1" : "bar" || $i }
+return $a()


Follow ups