← Back to team overview

zorba-coders team mailing list archive

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

 

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

Requested reviews:
  Markos Zaharioudakis (markos-za)

For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/markos-no-copy/+merge/83865

No-node-copy optimization
-- 
https://code.launchpad.net/~zorba-coders/zorba/markos-no-copy/+merge/83865
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'bin/zorbacmd.cpp'
--- bin/zorbacmd.cpp	2011-11-08 03:11:02 +0000
+++ bin/zorbacmd.cpp	2011-11-29 22:22:26 +0000
@@ -507,12 +507,24 @@
   Zorba_CompilerHints lHints;
 
   // default is O1 in the Zorba_CompilerHints constructor
-  if (properties.optimizationLevel() == "O0") {
+  if (properties.optimizationLevel() == "O0") 
+  {
     lHints.opt_level = ZORBA_OPT_LEVEL_O0;
-  } else if (properties.optimizationLevel() == "O2") {
+  }
+  else if (properties.optimizationLevel() == "O2") 
+  {
     lHints.opt_level = ZORBA_OPT_LEVEL_O2;
   }
 
+  lHints.for_serialization_only = true;
+
+#if ZORBACMD_LOAD_SYSTEM_PROPERTIES
+  if (!Properties::instance()->serializeOnlyQuery())
+  {
+    lHints.for_serialization_only = false;
+  }
+#endif
+
   // default is false
   if (properties.libModule())
   {
@@ -791,7 +803,8 @@
     //
     // Print the query if requested
     //
-    if (lProperties.printQuery()) {
+    if (lProperties.printQuery()) 
+    {
       *lOutputStream << "\nQuery number " << queryNo << " :\n";
       std::copy (std::istreambuf_iterator<char> (*qfile),
                  std::istreambuf_iterator<char> (),
@@ -834,8 +847,10 @@
     }
 
     // Parse the query
-    if (lProperties.parseOnly()) {
-      try {
+    if (lProperties.parseOnly()) 
+    {
+      try 
+      {
         zorba::XQuery_t lQuery = lZorbaInstance->createQuery();
         if (asFile) {
           lQuery->setFileName(path.get_path());
@@ -843,7 +858,8 @@
 
         lQuery->parse (*qfile);
       }
-      catch (zorba::ZorbaException const& ze) {
+      catch (zorba::ZorbaException const& ze) 
+      {
         std::cerr << ze << std::endl;
         return 6;
       }
@@ -851,9 +867,12 @@
 
     // Compile and run it if necessary.
     // Print timing information if requested.
-    else if (!debug) {
-      if (compileOnly) {
-        try {
+    else if (!debug) 
+    {
+      if (compileOnly) 
+      {
+        try 
+        {
           zorba::XQuery_t aQuery = lZorbaInstance->createQuery();
           if (asFile) {
             aQuery->setFileName(path.get_path());
@@ -861,7 +880,9 @@
           aQuery->parse(*qfile);
           qfile->clear();
           qfile->seekg(0); // go back to the beginning
-        } catch (zorba::XQueryException const& qe) {
+        }
+        catch (zorba::XQueryException const& qe)
+        {
           ErrorPrinter::print(qe, std::cerr, lProperties.printErrorsAsXml(), lProperties.indent());
           return 6;
         }

=== modified file 'include/zorba/options.h'
--- include/zorba/options.h	2011-07-24 22:28:31 +0000
+++ include/zorba/options.h	2011-11-29 22:22:26 +0000
@@ -51,11 +51,20 @@
  * example_6 in file \link simple.cpp \endlink shows an example
  * how CompilerHints can be used.
  */
-typedef struct Zorba_CompilerHints {
+typedef struct Zorba_CompilerHints 
+{
   /** \brief The optimization level that is used */
   Zorba_opt_level_t opt_level;
   /** \brief Treat the query as a library module */
   bool lib_module;
+
+  /**
+   * \brief By default, this flag is set to false. Applications may set it to
+   * true if they plan to execute the query only via one of the methods that 
+   * serialize the query result.
+   */
+  bool for_serialization_only;
+
 #ifdef __cplusplus
   /** \brief Default constructor for CompilerHints which assigns default values to all hints (C++ only).
    *
@@ -67,7 +76,9 @@
 #endif
 } Zorba_CompilerHints_t;
 
-typedef enum {
+
+typedef enum 
+{
   ZORBA_SERIALIZATION_METHOD_XML,
   ZORBA_SERIALIZATION_METHOD_HTML,
   ZORBA_SERIALIZATION_METHOD_XHTML,
@@ -75,12 +86,16 @@
   ZORBA_SERIALIZATION_METHOD_BINARY
 } Zorba_serialization_method_t;
 
-typedef enum {
+
+typedef enum 
+{
   ZORBA_BYTE_ORDER_MARK_YES,
   ZORBA_BYTE_ORDER_MARK_NO
 } Zorba_byte_order_mark_t;
 
-typedef enum {
+
+typedef enum 
+{
   ZORBA_ESCAPE_URI_ATTRIBUTES_YES,
   ZORBA_ESCAPE_URI_ATTRIBUTES_NO
 } Zorba_escape_uri_attributes_t;

=== modified file 'src/annotations/annotations.cpp'
--- src/annotations/annotations.cpp	2011-11-07 06:32:00 +0000
+++ src/annotations/annotations.cpp	2011-11-29 22:22:26 +0000
@@ -73,8 +73,8 @@
 
 #define ZANN(a, b)                                                     \
   GENV_ITEMFACTORY->createQName(qname, ZORBA_ANNOTATIONS_NS, "", #a);  \
-  id = zann_##b;                                                      \
-  theAnnotId2NameMap[id] = qname;                                     \
+  id = zann_##b;                                                       \
+  theAnnotId2NameMap[id] = qname;                                      \
   theAnnotName2IdMap.insert(qname, id);
 
 
@@ -94,6 +94,11 @@
   ZANN(nonsequential, nonsequential);
 
   //
+  // Zorba annotations - optimizer
+  //
+  ZANN(propagates-input-nodes, propagates_input_nodes);
+
+  //
   // Zorba annotations - misc
   //
   ZANN(variadic, variadic);
@@ -191,7 +196,7 @@
 
 
 /*******************************************************************************
-  Static method, called from GlobalEnvironment::init()
+  Static method, called from GlobalEnvironment::destroy()
 ********************************************************************************/
 void AnnotationInternal::destroyBuiltIn()
 {
@@ -328,7 +333,7 @@
 /*******************************************************************************
 
 ********************************************************************************/
-AnnotationInternal* AnnotationList::getAnnotation(csize index) const
+AnnotationInternal* AnnotationList::get(csize index) const
 {
   if (index < theAnnotationList.size())
     return theAnnotationList[index].getp();
@@ -340,6 +345,32 @@
 /*******************************************************************************
 
 ********************************************************************************/
+AnnotationInternal* AnnotationList::get(AnnotationInternal::AnnotationId id) const
+{
+  for (ListConstIter_t ite = theAnnotationList.begin();
+       ite != theAnnotationList.end();
+       ++ite)
+  {
+    if ((*ite)->getId() == id)
+      return (*ite).getp();
+  }
+
+  return NULL;
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+bool AnnotationList::contains(AnnotationInternal::AnnotationId id) const
+{
+  return (get(id) != NULL);
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
 void AnnotationList::push_back(
     const store::Item_t& qname,
     const std::vector<rchandle<const_expr> >& literals)
@@ -358,23 +389,6 @@
 
 
 /*******************************************************************************
-
-********************************************************************************/
-bool AnnotationList::contains(AnnotationInternal::AnnotationId id) const
-{
-  for (ListConstIter_t ite = theAnnotationList.begin();
-       ite != theAnnotationList.end();
-       ++ite)
-  {
-    if ((*ite)->getId() == id)
-      return true;
-  }
-
-  return false;
-}
-
-
-/*******************************************************************************
   Called from translator::end_visit(const AnnotationListParsenode& v, void*)
 ********************************************************************************/
 void AnnotationList::checkConflictingDeclarations(const QueryLoc& loc) const

=== modified file 'src/annotations/annotations.h'
--- src/annotations/annotations.h	2011-11-01 13:47:10 +0000
+++ src/annotations/annotations.h	2011-11-29 22:22:26 +0000
@@ -55,6 +55,8 @@
     zann_nonassignable,
     zann_sequential,
     zann_nonsequential,
+    zann_propagates_input_nodes,
+    zann_must_copy_input_nodes,
     zann_variadic,
     zann_streamable,
     zann_unique,
@@ -135,7 +137,7 @@
 class AnnotationList : public SimpleRCObject
 {
 public:
-  typedef  AnnotationInternal::RuleBitSet RuleBitSet;
+  typedef AnnotationInternal::RuleBitSet RuleBitSet;
 
   typedef AnnotationInternal::AnnotationId AnnotationId;
 
@@ -158,14 +160,16 @@
 
   csize size() const { return theAnnotationList.size(); }
 
-  AnnotationInternal* getAnnotation(csize index) const;
+  AnnotationInternal* get(csize index) const;
+
+  AnnotationInternal* get(AnnotationInternal::AnnotationId id) const;
+
+  bool contains(AnnotationInternal::AnnotationId id) const;
 
   void push_back(
       const store::Item_t& qname,
       const std::vector<rchandle<const_expr> >& literals);
 
-  bool contains(AnnotationInternal::AnnotationId id) const;
-
   void checkConflictingDeclarations(const QueryLoc& loc) const;
 };
 

=== modified file 'src/api/dynamiccontextimpl.cpp'
--- src/api/dynamiccontextimpl.cpp	2011-10-20 17:17:48 +0000
+++ src/api/dynamiccontextimpl.cpp	2011-11-29 22:22:26 +0000
@@ -182,6 +182,7 @@
   return var;
 }
 
+
 /****************************************************************************//**
 
 ********************************************************************************/

=== modified file 'src/api/functionimpl.cpp'
--- src/api/functionimpl.cpp	2011-09-05 02:06:22 +0000
+++ src/api/functionimpl.cpp	2011-11-29 22:22:26 +0000
@@ -63,7 +63,7 @@
   try
   {
     for (unsigned int i = 0; i < ann_list->size(); ++i)
-      annotations.push_back(new AnnotationImpl(ann_list->getAnnotation(i)));
+      annotations.push_back(new AnnotationImpl(ann_list->get(i)));
   }
   catch (ZorbaException const& e)
   {

=== modified file 'src/api/options.cpp'
--- src/api/options.cpp	2011-06-14 17:26:33 +0000
+++ src/api/options.cpp	2011-11-29 22:22:26 +0000
@@ -19,12 +19,24 @@
 #include <zorba/options.h>
 
 Zorba_CompilerHints::Zorba_CompilerHints()
-: opt_level(ZORBA_OPT_LEVEL_O1),
-  lib_module(false)
-{}
+  :
+  opt_level(ZORBA_OPT_LEVEL_O1),
+  lib_module(false),
+  for_serialization_only(false)
+{
+}
+
+
+void Zorba_CompilerHints_default(Zorba_CompilerHints_t* aHints)
+{
+  Zorba_CompilerHints_t lDefault;
+  *aHints = lDefault;
+}
+
 
 Zorba_SerializerOptions::Zorba_SerializerOptions()
-: ser_method(ZORBA_SERIALIZATION_METHOD_XML),
+  :
+  ser_method(ZORBA_SERIALIZATION_METHOD_XML),
   byte_order_mark(ZORBA_BYTE_ORDER_MARK_NO),
   escape_uri_attributes(ZORBA_ESCAPE_URI_ATTRIBUTES_NO),
   include_content_type(ZORBA_INCLUDE_CONTENT_TYPE_NO),
@@ -34,9 +46,13 @@
   standalone(ZORBA_STANDALONE_OMIT),
   undeclare_prefixes(ZORBA_UNDECLARE_PREFIXES_NO),
   encoding(ZORBA_ENCODING_UTF8)
-{}
-
-void Zorba_SerializerOptions::SetSerializerOption(const char* parameter, const char* value)
+{
+}
+
+
+void Zorba_SerializerOptions::SetSerializerOption(
+    const char* parameter,
+    const char* value)
 {
   if (parameter == NULL || value == NULL)
     return;
@@ -112,6 +128,7 @@
   }
 }
 
+
 Zorba_SerializerOptions_t Zorba_SerializerOptions::SerializerOptionsFromStringParams(const std::vector<std::pair<std::string, std::string> >& params)
 {
   Zorba_SerializerOptions_t opt;
@@ -127,11 +144,6 @@
   return opt;
 }
 
-void Zorba_CompilerHints_default(Zorba_CompilerHints_t* aHints)
-{
-  Zorba_CompilerHints_t lDefault;
-  *aHints = lDefault;
-}
 
 Zorba_SerializerOptions_t* Zorba_SerializerOptions_default()
 {
@@ -139,11 +151,13 @@
   return lDefault;
 }
 
+
 void Zorba_SerializerOptions_free(Zorba_SerializerOptions_t* serializerOptions)
 {
   delete serializerOptions;
 }
 
+
 void Zorba_SerializerOptions_set(Zorba_SerializerOptions_t* serializerOptions, const char* parameter, const char* value)
 {
   if (serializerOptions == NULL || parameter == NULL || value == NULL)

=== modified file 'src/api/serialization/serializer.cpp'
--- src/api/serialization/serializer.cpp	2011-11-11 07:44:01 +0000
+++ src/api/serialization/serializer.cpp	2011-11-29 22:22:26 +0000
@@ -692,11 +692,34 @@
 {
   // emit namespace bindings
   store::NsBindings nsBindings;
-
   if (depth == 0)
+  {
     item->getNamespaceBindings(nsBindings);
+  }
   else
-    item->getNamespaceBindings(nsBindings, store::StoreConsts::ONLY_LOCAL_NAMESPACES);
+  {
+    //item->getNamespaceBindings(nsBindings, store::StoreConsts::ONLY_LOCAL_NAMESPACES);
+    item->getNamespaceBindings(nsBindings);
+
+    store::Item* nodeName = item->getNodeName();
+
+    const zstring& prefix = nodeName->getPrefix();
+    const zstring& nsuri = nodeName->getNamespace();
+    if (prefix.empty() && nsuri.empty())
+    {
+      store::NsBindings::const_iterator ite = nsBindings.begin();
+      store::NsBindings::const_iterator end = nsBindings.end();
+
+      for (; ite != end; ++ite)
+      {
+        if (ite->second.empty() && ite->first.empty())
+          break;
+      }
+
+      if (ite == end)
+        nsBindings.push_back(std::pair<zstring, zstring>(prefix, nsuri));
+    }
+  }
 
   csize numBindings = nsBindings.size();
 

=== modified file 'src/api/staticcontextimpl.cpp'
--- src/api/staticcontextimpl.cpp	2011-11-17 04:59:42 +0000
+++ src/api/staticcontextimpl.cpp	2011-11-29 22:22:26 +0000
@@ -836,7 +836,7 @@
   try
   {
     for (unsigned int i = 0; i < ann_list->size(); i++)
-      aAnnotations.push_back(new AnnotationImpl(ann_list->getAnnotation(i)));
+      aAnnotations.push_back(new AnnotationImpl(ann_list->get(i)));
   }
   catch (ZorbaException const& e)
   {

=== modified file 'src/api/xqueryimpl.cpp'
--- src/api/xqueryimpl.cpp	2011-11-11 18:32:12 +0000
+++ src/api/xqueryimpl.cpp	2011-11-29 22:22:26 +0000
@@ -558,6 +558,7 @@
   // Set the compiler config.
   // If lib_module is set to true the query will be considered a library module
   theCompilerCB->theConfig.lib_module = aHints.lib_module;
+  theCompilerCB->theConfig.for_serialization_only = aHints.for_serialization_only;
   CompilerCB::config::opt_level_t optLevel;
   if (aHints.opt_level == ZORBA_OPT_LEVEL_O0)
     optLevel = CompilerCB::config::O0;
@@ -571,10 +572,10 @@
 
 #ifdef ZORBA_WITH_DEBUGGER
   // if the debug mode is set, we force the gflwor, we set the query input stream
-  if (theIsDebugMode) {
+  if (theIsDebugMode) 
+  {
     theCompilerCB->theConfig.force_gflwor = true;
-    theCompilerCB->theDebuggerCommons =
-      new DebuggerCommons(theCompilerCB->theRootSctx);
+    theCompilerCB->theDebuggerCommons = new DebuggerCommons(theCompilerCB->theRootSctx);
     theCompilerCB->theConfig.opt_level = CompilerCB::config::O0;
   }
 #endif

=== modified file 'src/compiler/api/compiler_api.h'
--- src/compiler/api/compiler_api.h	2011-07-12 20:15:01 +0000
+++ src/compiler/api/compiler_api.h	2011-11-29 22:22:26 +0000
@@ -32,6 +32,7 @@
 
   CompilerCB  * theCompilerCB;
 
+public:
   XQueryCompiler(CompilerCB* aCompilerCB);
     
   virtual ~XQueryCompiler();
@@ -85,14 +86,14 @@
 {
   friend class GlobalEnvironment;
 
- public:
+public:
   XQueryCompilerSubsystem();
 
   virtual ~XQueryCompilerSubsystem();
 
   virtual Rewriter* getDefaultOptimizingRewriter() = 0;
 
- private:
+private:
   static std::auto_ptr<XQueryCompilerSubsystem> create();
 };
 

=== modified file 'src/compiler/api/compilercb.cpp'
--- src/compiler/api/compilercb.cpp	2011-10-12 20:57:12 +0000
+++ src/compiler/api/compilercb.cpp	2011-11-29 22:22:26 +0000
@@ -60,6 +60,7 @@
   :
   opt_level(O1),
   lib_module(false),
+  for_serialization_only(false),
   parse_cb(NULL)
 {
   translate_cb = optimize_cb = NULL;
@@ -97,6 +98,7 @@
   ar & force_gflwor;
   SERIALIZE_ENUM(opt_level_t, opt_level);
   ar & lib_module;
+  ar & for_serialization_only;
   ar & print_item_flow;
 }
 

=== modified file 'src/compiler/api/compilercb.h'
--- src/compiler/api/compilercb.h	2011-11-01 14:26:48 +0000
+++ src/compiler/api/compilercb.h	2011-11-29 22:22:26 +0000
@@ -93,6 +93,9 @@
   dummy module (see  XQueryCompiler::createMainModule() method). This flag is
   a copy of the lib_module flag in Zorba_CompilerHints_t.
 
+  - theConfig.for_serialization_only :
+  This flag is a copy of the for_serialization_only flag in Zorba_CompilerHints_t.
+
   - theConfig.parse_cb :
   Pointer to the function to call to print the AST that results from parsing
   the query.
@@ -120,6 +123,7 @@
     bool           force_gflwor;
     opt_level_t    opt_level;
     bool           lib_module;
+    bool           for_serialization_only;
     ast_callback   parse_cb;
     expr_callback  translate_cb;
     expr_callback  optimize_cb;
@@ -139,11 +143,11 @@
   typedef std::map<short, static_context_t> SctxMap;
 
 public:  
-  XQueryDiagnostics*        theXQueryDiagnostics;
+  XQueryDiagnostics       * theXQueryDiagnostics;
 
   SctxMap                   theSctxMap;
 
-  static_context*           theRootSctx;
+  static_context          * theRootSctx;
 
 #ifdef ZORBA_WITH_DEBUGGER
   DebuggerCommons*          theDebuggerCommons;

=== modified file 'src/compiler/codegen/plan_visitor.cpp'
--- src/compiler/codegen/plan_visitor.cpp	2011-11-17 16:32:04 +0000
+++ src/compiler/codegen/plan_visitor.cpp	2011-11-29 22:22:26 +0000
@@ -325,6 +325,7 @@
 
   std::stack<expr*>                          theConstructorsStack;
   std::stack<EnclosedExprContext>            theEnclosedContextStack;
+  std::stack<bool>                           theCopyNodesStack;
 
   ulong                                      theNextDynamicVarId;
 
@@ -2060,13 +2061,13 @@
 {
   CODEGEN_TRACE_OUT("");
 
-  ulong numVars = v.var_count();
+  csize numVars = v.var_count();
 
   checked_vector<PlanIter_t> args(numVars+1);
   checked_vector<store::Item_t> varnames(numVars);
   checked_vector<xqtref_t> vartypes(numVars);
 
-  for (ulong i = 0; i < numVars; ++i)
+  for (csize i = 0; i < numVars; ++i)
   {
     varnames[i] = v.get_var(i)->get_name();
     vartypes[i] = v.get_var(i)->get_type();
@@ -2085,7 +2086,8 @@
                                 varnames,
                                 vartypes, 
                                 v.get_inner_scripting_kind(),
-                                localBindings));
+                                localBindings,
+                                v.getNodeCopy()));
 }
 
 #ifdef ZORBA_WITH_DEBUGGER
@@ -2111,16 +2113,18 @@
 
   std::vector<PlanIter_t> argvEvalIter;
 
-  ulong numVars = v.var_count();
+  csize numVars = v.var_count();
   std::vector<store::Item_t> varnames(numVars);
   std::vector<xqtref_t> vartypes(numVars);
 
   //create the eval iterator children
-  for (ulong i = 0; i < numVars; i++) {
+  for (csize i = 0; i < numVars; i++) 
+  {
     varnames[i] = v.get_var(i)->get_name();
     vartypes[i] = v.get_var(i)->get_type();
     argvEvalIter.push_back(pop_itstack());
   }
+
   argvEvalIter.push_back(
     new DebuggerSingletonIterator(sctx, qloc, theCCB->theDebuggerCommons));
 
@@ -2142,16 +2146,19 @@
 
   // child 1
   store::NsBindings localBindings;
-  if (v.getNSCtx()) {
+  if (v.getNSCtx()) 
+  {
     v.getNSCtx()->getAllBindings(localBindings);
   }
+
   argv.push_back(new EvalIterator(sctx,
                                   qloc,
                                   argvEvalIter,
                                   varnames,
                                   vartypes,
                                   SIMPLE_EXPR,
-                                  localBindings));
+                                  localBindings,
+                                  true));
 
   lDebugIterator->setChildren(&argv);
   lDebugIterator->setVariables(varnames, vartypes);
@@ -2838,6 +2845,9 @@
   theConstructorsStack.push(&v);
   theEnclosedContextStack.push(ELEMENT_CONTENT);
 
+  if (v.copyInputNodes())
+    theCopyNodesStack.push(true);
+
   return true;
 }
 
@@ -2847,13 +2857,18 @@
   CODEGEN_TRACE_OUT("");
 
   PlanIter_t lContent = pop_itstack();
-  PlanIter_t lContIter = new DocumentContentIterator(sctx, qloc, lContent);
-  PlanIter_t lDocIter = new DocumentIterator(sctx, qloc, lContIter);
+  PlanIter_t lDocIter = new DocumentIterator(sctx,
+                                             qloc,
+                                             lContent, 
+                                             !theCopyNodesStack.empty());
   push_itstack(lDocIter);
 
   theEnclosedContextStack.pop();
   expr* e = plan_visitor_ns::pop_stack(theConstructorsStack);
   ZORBA_ASSERT(e == &v);
+
+  if (v.copyInputNodes())
+    theCopyNodesStack.pop();
 }
 
 
@@ -2864,6 +2879,9 @@
   theConstructorsStack.push(&v);
   theEnclosedContextStack.push(ELEMENT_CONTENT);
 
+  if (v.copyInputNodes())
+    theCopyNodesStack.push(true);
+
   return true;
 }
 
@@ -2889,9 +2907,9 @@
   expr* e = plan_visitor_ns::pop_stack(theConstructorsStack);
   ZORBA_ASSERT(e == &v);
 
-  // Handling of the special case where the QName expression of a direct element constructor
-  // has in itself a direct constructor. In that case the QName expression should have
-  // isRoot set to true.
+  // Handling of the special case where the QName expression of a direct element
+  // constructor has in itself a direct constructor. In that case the QName 
+  // expression should have isRoot set to true.
   elem_expr* top_elem_expr = NULL;
   if (!theConstructorsStack.empty())
     top_elem_expr = dynamic_cast<elem_expr*>(theConstructorsStack.top());
@@ -2909,8 +2927,12 @@
                                         lAttrsIter,
                                         lContentIter,
                                         v.getNSCtx(),
-                                        isRoot);
+                                        isRoot,
+                                        !theCopyNodesStack.empty());
   push_itstack(iter);
+
+  if (v.copyInputNodes())
+    theCopyNodesStack.pop();
 }
 
 

=== modified file 'src/compiler/expression/expr.cpp'
--- src/compiler/expression/expr.cpp	2011-10-12 17:42:50 +0000
+++ src/compiler/expression/expr.cpp	2011-11-29 22:22:26 +0000
@@ -720,10 +720,12 @@
 doc_expr::doc_expr(
     static_context* sctx,
     const QueryLoc& loc,
-    expr_t aContent)
+    expr* aContent,
+    bool copyNodes)
   :
   expr(sctx, loc, doc_expr_kind),
-  theContent(aContent)
+  theContent(aContent),
+  theCopyInputNodes(copyNodes)
 {
   compute_scripting_kind();
 }
@@ -733,6 +735,7 @@
 {
   serialize_baseclass(ar, (expr*)this);
   ar & theContent;
+  ar & theCopyInputNodes;
 }
 
 
@@ -749,7 +752,11 @@
 
 expr_t doc_expr::clone(substitution_t& subst) const
 {
-  return new doc_expr(theSctx, get_loc(), CLONE(getContent(), subst));
+  doc_expr* clone = new doc_expr(theSctx,
+                                 get_loc(),
+                                 CLONE(getContent(), subst),
+                                 theCopyInputNodes);
+  return clone;
 }
 
 
@@ -759,15 +766,17 @@
 elem_expr::elem_expr(
     static_context* sctx,
     const QueryLoc& aLoc,
-    expr_t aQNameExpr,
-    expr_t aAttrs,
-    expr_t aContent,
-    const namespace_context* aNSCtx)
+    expr* aQNameExpr,
+    expr* attrs,
+    expr* content,
+    const namespace_context* aNSCtx,
+    bool copyNodes)
   :
   namespace_context_base_expr(sctx, aLoc, elem_expr_kind, aNSCtx),
   theQNameExpr(aQNameExpr),
-  theAttrs(aAttrs),
-  theContent(aContent)
+  theAttrs(attrs),
+  theContent(content),
+  theCopyInputNodes(copyNodes)
 {
   compute_scripting_kind();
 
@@ -778,14 +787,16 @@
 elem_expr::elem_expr(
     static_context* sctx,
     const QueryLoc& aLoc,
-    expr_t aQNameExpr,
-    expr_t aContent,
-    const namespace_context* aNSCtx)
+    expr* aQNameExpr,
+    expr* content,
+    const namespace_context* aNSCtx,
+    bool copyNodes)
   :
   namespace_context_base_expr(sctx, aLoc, elem_expr_kind, aNSCtx),
   theQNameExpr(aQNameExpr),
   theAttrs(0),
-  theContent(aContent)
+  theContent(content),
+  theCopyInputNodes(copyNodes)
 {
   compute_scripting_kind();
 
@@ -800,6 +811,7 @@
   ar & theAttrs;
   ar & theContent;
   ar & theNSCtx;
+  ar & theCopyInputNodes;
 }
 
 
@@ -831,12 +843,14 @@
 
 expr_t elem_expr::clone(substitution_t& subst) const
 {
-  return new elem_expr(theSctx,
-                       get_loc(),
-                       CLONE(getQNameExpr(), subst),
-                       CLONE(getAttrs(), subst),
-                       CLONE(getContent(), subst),
-                       getNSCtx());
+  elem_expr* clone =  new elem_expr(theSctx,
+                                    get_loc(),
+                                    CLONE(getQNameExpr(), subst),
+                                    CLONE(getAttrs(), subst),
+                                    CLONE(getContent(), subst),
+                                    getNSCtx(),
+                                    theCopyInputNodes);
+  return clone;
 }
 
 
@@ -1394,7 +1408,8 @@
   :
   namespace_context_base_expr(sctx, loc, eval_expr_kind, nsCtx),
   theExpr(e),
-  theInnerScriptingKind(scriptingKind)
+  theInnerScriptingKind(scriptingKind),
+  theDoNodeCopy(false)
 {
   compute_scripting_kind();
 }
@@ -1407,6 +1422,7 @@
   ar & theVars;
   ar & theArgs;
   SERIALIZE_ENUM(expr_script_kind_t, theInnerScriptingKind);
+  ar & theDoNodeCopy;
 }
 
 
@@ -1439,8 +1455,9 @@
                                                theExpr->clone(s),
                                                theInnerScriptingKind,
                                                theNSCtx.getp());
+  new_eval->setNodeCopy(theDoNodeCopy);
 
-  for (ulong i = 0; i < theVars.size(); ++i)
+  for (csize i = 0; i < theVars.size(); ++i)
   {
     var_expr_t cloneVar = dynamic_cast<var_expr*>(theVars[i]->clone(s).getp());
     assert(cloneVar != NULL);

=== modified file 'src/compiler/expression/expr.h'
--- src/compiler/expression/expr.h	2011-09-20 14:33:34 +0000
+++ src/compiler/expression/expr.h	2011-11-29 22:22:26 +0000
@@ -117,7 +117,7 @@
 
   order_type_t get_type() const { return theType; }
 
-  const expr* get_expr() const { return theExpr; }
+  expr* get_expr() const { return theExpr.getp(); }
 
   void compute_scripting_kind();
 
@@ -157,7 +157,7 @@
         expr_t,
         rchandle<TypeManager>);
 
-  const expr* get_expr() const { return theExpr; }
+  expr* get_expr() const { return theExpr.getp(); }
 
   const store::Item* get_type_name() const { return theTypeName; }
 
@@ -557,6 +557,7 @@
 
 protected:
   expr_t theContent;
+  bool   theCopyInputNodes;
 
 public:
   SERIALIZABLE_CLASS(doc_expr)
@@ -564,9 +565,13 @@
   void serialize(::zorba::serialization::Archiver& ar);
 
 public:
-  doc_expr(static_context* sctx, const QueryLoc&, expr_t aContent);
-
-  const expr* getContent() const { return theContent.getp(); }
+  doc_expr(static_context* sctx, const QueryLoc&, expr* content, bool copyNodes);
+
+  expr* getContent() const { return theContent.getp(); }
+
+  bool copyInputNodes() const { return theCopyInputNodes; }
+
+  void setCopyInputNodes() { theCopyInputNodes = true; }
 
   void compute_scripting_kind();
 
@@ -613,7 +618,8 @@
   expr_t theQNameExpr;
   expr_t theAttrs;
   expr_t theContent;
-  
+  bool   theCopyInputNodes;
+
 public:
   SERIALIZABLE_CLASS(elem_expr)
   SERIALIZABLE_CLASS_CONSTRUCTOR2(elem_expr, namespace_context_base_expr)
@@ -623,23 +629,29 @@
   elem_expr(
         static_context* sctx,
         const QueryLoc&,
-        expr_t aQNameExpr,
-        expr_t aAttrs,
-        expr_t aContent,
-        const namespace_context* aNSCtx);
+        expr* qnameExpr,
+        expr* attrs,
+        expr* content,
+        const namespace_context* nsCtx,
+        bool copyNodes);
   
   elem_expr(
         static_context* sctx,
         const QueryLoc&,
-        expr_t aQNameExpr,
-        expr_t aContent,
-        const namespace_context* aNSCtx);
+        expr* qnameExpr,
+        expr* content,
+        const namespace_context* nsCtx,
+        bool copyNodes);
   
-  const expr* getQNameExpr() const { return theQNameExpr.getp(); }
-
-  const expr* getContent() const { return theContent.getp(); }
-
-  const expr* getAttrs() const { return theAttrs; }
+  expr* getQNameExpr() const { return theQNameExpr.getp(); }
+
+  expr* getContent() const { return theContent.getp(); }
+
+  expr* getAttrs() const { return theAttrs.getp(); }
+
+  bool copyInputNodes() const { return theCopyInputNodes; }
+
+  void setCopyInputNodes() { theCopyInputNodes = true; }
 
   void compute_scripting_kind();
   
@@ -696,9 +708,9 @@
     expr_t aQNameExpr,
     expr_t aValueExpr);
 
-  const expr* getQNameExpr() const { return theQNameExpr.getp(); }
+  expr* getQNameExpr() const { return theQNameExpr.getp(); }
 
-  const expr* getValueExpr() const { return theValueExpr.getp(); }
+  expr* getValueExpr() const { return theValueExpr.getp(); }
 
   const store::Item* getQName() const;
 
@@ -738,10 +750,10 @@
 
 public:
   text_expr(
-        static_context* sctx,
-        const QueryLoc&,
-        text_constructor_type,
-        expr_t);
+      static_context* sctx,
+      const QueryLoc&,
+      text_constructor_type,
+      expr_t);
 
   expr* get_text() const { return theContentExpr.getp(); }
 
@@ -777,9 +789,9 @@
 public:
   pi_expr(static_context* sctx, const QueryLoc&, expr_t, expr_t);
  
-  const expr* get_target_expr() const { return theTargetExpr.getp(); }
+  expr* get_target_expr() const { return theTargetExpr.getp(); }
 
-  const expr* get_content_expr() const { return theContentExpr.getp(); }
+  expr* get_content_expr() const { return theContentExpr.getp(); }
 
   void compute_scripting_kind();
   
@@ -883,7 +895,7 @@
 
   void add(rchandle<pragma> p) { thePragmas.push_back(p); }
 
-  const expr* get_expr() const { return theExpr; }
+  expr* get_expr() const { return theExpr.getp(); }
 
   void compute_scripting_kind();
 
@@ -918,8 +930,10 @@
 
 ********************************************************************************/
 class catch_clause;
+
 typedef rchandle<catch_clause> catch_clause_t;
 
+
 class catch_clause : public SimpleRCObject 
 {
   friend class expr;
@@ -990,15 +1004,15 @@
 
   expr* get_try_expr() const { return theTryExpr.getp(); }
 
-  expr* get_catch_expr(ulong i) const { return theCatchExprs[i].getp(); }
+  expr* get_catch_expr(csize i) const { return theCatchExprs[i].getp(); }
 
   void add_catch_expr(expr_t e);
 
   void add_clause(catch_clause_t cc);
   
-  uint32_t clause_count() const { return (uint32_t)theCatchClauses.size(); }
+  csize clause_count() const { return theCatchClauses.size(); }
   
-  catch_clause_t const& operator[](int i) const { return theCatchClauses[i]; }
+  catch_clause_t const& operator[](csize i) const { return theCatchClauses[i]; }
 
   void compute_scripting_kind();
 
@@ -1135,10 +1149,27 @@
   There is no syntax corresponding to the eval_expr. Instead, an eval_expr is
   created by the translator whenever a call to the eval() function is reached.
 
-  theExpr  : The expr that computes the query string to be evaluated by eval.
-  theVars  : There is one eval var for each non-global var that is in scope
-             where the call to the eval function appears at.
-  theArgs  : The domain expr of each eval var.
+  theExpr:
+  --------
+  The expr that computes the query string to be evaluated by eval.
+
+  theVars:
+  --------
+  There is one "eval" var for each non-global var that is in scope where the call
+  to the eval function appears at.
+
+  theArgs:
+  --------
+  The domain expr of each eval var. Initially, the domain expr of an eval var
+  is always another var. However, that other var may be later inlined, so in
+  general, the domain expr of an eval var may be any expr.
+
+  theInnerScriptingKind:
+  ----------------------
+
+  theDoNodeCopy:
+  --------------
+
 ********************************************************************************/
 class eval_expr : public namespace_context_base_expr
 {
@@ -1147,9 +1178,10 @@
 
 protected:
   expr_t                      theExpr;
-  checked_vector<var_expr_t>  theVars;
+  std::vector<var_expr_t>     theVars;
   std::vector<expr_t>         theArgs;
   expr_script_kind_t          theInnerScriptingKind;
+  bool                        theDoNodeCopy;
 
 public:
   SERIALIZABLE_CLASS(eval_expr)
@@ -1166,11 +1198,11 @@
 
   expr* get_expr() const { return theExpr.getp(); }
 
-  expr* get_arg_expr(ulong i) { return theArgs[i].getp(); }
-
-  ulong var_count() const { return (ulong)theVars.size(); }
-
-  const var_expr* get_var(ulong i) const { return theVars[i]; }
+  expr* get_arg_expr(csize i) { return theArgs[i].getp(); }
+
+  csize var_count() const { return theVars.size(); }
+
+  const var_expr* get_var(csize i) const { return theVars[i]; }
 
   void add_var(const var_expr_t& var, const expr_t& arg) 
   {
@@ -1180,6 +1212,10 @@
 
   expr_script_kind_t get_inner_scripting_kind() const;
 
+  bool getNodeCopy() const { return theDoNodeCopy; }
+
+  void setNodeCopy(bool v) { theDoNodeCopy = true; }
+
   void compute_scripting_kind();
 
   void accept(expr_visitor&);

=== modified file 'src/compiler/expression/expr_base.cpp'
--- src/compiler/expression/expr_base.cpp	2011-11-17 16:32:04 +0000
+++ src/compiler/expression/expr_base.cpp	2011-11-29 22:22:26 +0000
@@ -526,6 +526,52 @@
 
 
 /*******************************************************************************
+
+********************************************************************************/
+BoolAnnotationValue expr::getWillBeSerialized() const
+{
+  return (BoolAnnotationValue)
+         ((theFlags1 & WILL_BE_SERIALIZED_MASK) >> WILL_BE_SERIALIZED);
+}
+
+
+void expr::setWillBeSerialized(BoolAnnotationValue v)
+{
+  theFlags1 &= ~WILL_BE_SERIALIZED_MASK;
+  theFlags1 |= (v << WILL_BE_SERIALIZED);
+}
+
+
+bool expr::willBeSerialized() const
+{
+  BoolAnnotationValue v = getWillBeSerialized();
+  return (v == ANNOTATION_TRUE || v == ANNOTATION_TRUE_FIXED);
+}
+
+
+/*******************************************************************************
+  This annotation tells whether the expr must produce nodes that belong to 
+  "standalone" trees or not. A tree is standalone if it does not contain 
+  references to other trees. Such references are created when the optimizer 
+  decides that it is ok to avoid copying the referenced subtree (as would be
+  required by required by a strict implementation of the spec, eg., during 
+  node construction).
+********************************************************************************/
+BoolAnnotationValue expr::getMustCopyNodes() const
+{
+  return (BoolAnnotationValue)
+         ((theFlags1 & MUST_COPY_NODES_MASK) >> MUST_COPY_NODES);
+}
+
+
+void expr::setMustCopyNodes(BoolAnnotationValue v)
+{
+  theFlags1 &= ~MUST_COPY_NODES_MASK;
+  theFlags1 |= (v << MUST_COPY_NODES);
+}
+
+
+/*******************************************************************************
   Return true if the expr does not reference any variables.
 ********************************************************************************/
 bool expr::is_constant() const

=== modified file 'src/compiler/expression/expr_base.h'
--- src/compiler/expression/expr_base.h	2011-11-17 16:32:04 +0000
+++ src/compiler/expression/expr_base.h	2011-11-29 22:22:26 +0000
@@ -49,33 +49,41 @@
 
 enum expr_kind_t
 {
-  attr_expr_kind,
-  axis_step_expr_kind,
-  castable_expr_kind,
-  cast_expr_kind,
   const_expr_kind,
+
+  var_expr_kind,
+
   doc_expr_kind,
   elem_expr_kind,
-  extension_expr_kind,
+  attr_expr_kind,
+  text_expr_kind,
+  pi_expr_kind,
+
+  relpath_expr_kind,
+  axis_step_expr_kind,
+  match_expr_kind,
+
   flwor_expr_kind,
-  fo_expr_kind,
   gflwor_expr_kind,
   if_expr_kind,
+  trycatch_expr_kind,
+
+  fo_expr_kind,
+  dynamic_function_invocation_expr_kind,
+  function_item_expr_kind,
+
+  castable_expr_kind,
+  cast_expr_kind,
   instanceof_expr_kind,
-  match_expr_kind,
+  treat_expr_kind,
+  promote_expr_kind,
   name_cast_expr_kind,
+
+  validate_expr_kind,
+
+  extension_expr_kind,
+
   order_expr_kind,
-  pi_expr_kind,
-  promote_expr_kind,
-  relpath_expr_kind,
-  text_expr_kind,
-  treat_expr_kind,
-  validate_expr_kind,
-  var_expr_kind,
-
-  dynamic_function_invocation_expr_kind,
-  function_item_expr_kind,
-  trycatch_expr_kind,
 
 #ifndef ZORBA_NO_FULL_TEXT
 	ft_expr_kind,
@@ -133,18 +141,24 @@
     IGNORES_DUPLICATE_NODES = 6,
     NON_DISCARDABLE         = 8,
     UNFOLDABLE              = 10,
-    CONTAINS_RECURSIVE_CALL = 12
+    CONTAINS_RECURSIVE_CALL = 12,
+    PROPAGATES_INPUT_NODES  = 14,
+    WILL_BE_SERIALIZED      = 16,
+    MUST_COPY_NODES         = 18
   } Annotationkey;
 
   typedef enum
   {
-    PRODUCES_SORTED_NODES_MASK   = 0x003,
-    PRODUCES_DISTINCT_NODES_MASK = 0x00C,
-    IGNORES_SORTED_NODES_MASK  = 0x030,
+    PRODUCES_SORTED_NODES_MASK    = 0x003,
+    PRODUCES_DISTINCT_NODES_MASK  = 0x00C,
+    IGNORES_SORTED_NODES_MASK     = 0x030,
     IGNORES_DUPLICATE_NODES_MASK  = 0x0C0,
-    NON_DISCARDABLE_MASK         = 0x300,
-    UNFOLDABLE_MASK              = 0xC00,
-    CONTAINS_RECURSIVE_CALL_MASK = 0x3000
+    NON_DISCARDABLE_MASK          = 0x300,
+    UNFOLDABLE_MASK               = 0xC00,
+    CONTAINS_RECURSIVE_CALL_MASK  = 0x3000,
+    PROPAGATES_INPUT_NODES_MASK   = 0xC000,
+    WILL_BE_SERIALIZED_MASK       = 0x30000,
+    MUST_COPY_NODES_MASK          = 0xC0000
   } AnnotationMask;
 
 
@@ -244,6 +258,11 @@
 
   bool producesDistinctNodes() const;
 
+  // Annotation : propagatesInputNodes
+  BoolAnnotationValue getPropagatesInputNodes() const;
+
+  void setPropagatesInputNodes(BoolAnnotationValue v);
+
   // Annotation : ignores-sorted-nodes
   BoolAnnotationValue getIgnoresSortedNodes() const;
 
@@ -279,6 +298,18 @@
 
   bool containsRecursiveCall() const;
 
+  // Annotation : mustCopyNodes
+  BoolAnnotationValue getMustCopyNodes() const;
+
+  void setMustCopyNodes(BoolAnnotationValue v);
+
+  // Annotation : willBeSerialized
+  BoolAnnotationValue getWillBeSerialized() const;
+
+  void setWillBeSerialized(BoolAnnotationValue v);
+
+  bool willBeSerialized() const;
+
   bool is_constant() const;
 
   bool is_nondeterministic() const;

=== modified file 'src/compiler/expression/expr_iter.cpp'
--- src/compiler/expression/expr_iter.cpp	2011-11-17 16:32:04 +0000
+++ src/compiler/expression/expr_iter.cpp	2011-11-29 22:22:26 +0000
@@ -518,7 +518,7 @@
     EXPR_ITER_BEGIN();
 
     EXPR_ITER_NEXT(repExpr->theTargetExpr);
-    EXPR_ITER_NEXT(repExpr->theReplaceExpr);
+    EXPR_ITER_NEXT(repExpr->theSourceExpr);
 
     EXPR_ITER_END();
     break;
@@ -531,7 +531,7 @@
     EXPR_ITER_BEGIN();
 
     EXPR_ITER_NEXT(renExpr->theTargetExpr);
-    EXPR_ITER_NEXT(renExpr->theNameExpr);
+    EXPR_ITER_NEXT(renExpr->theSourceExpr);
 
     EXPR_ITER_END();
     break;

=== modified file 'src/compiler/expression/expr_put.cpp'
--- src/compiler/expression/expr_put.cpp	2011-11-17 16:32:04 +0000
+++ src/compiler/expression/expr_put.cpp	2011-11-29 22:22:26 +0000
@@ -761,32 +761,46 @@
 
 ostream& elem_expr::put(ostream& os) const
 {
-  BEGIN_PUT( elem_expr );
+  BEGIN_PUT(elem_expr);
+
+  os << indent << "copy nodes = " << theCopyInputNodes << std::endl;
+
   if (theQNameExpr != NULL)
     theQNameExpr->put(os);
+
   if (theAttrs != NULL)
     theAttrs->put(os);
+
   if (theContent != NULL)
     theContent->put(os);
+
   END_PUT();
 }
 
-ostream& doc_expr::put( ostream& os) const
+
+ostream& doc_expr::put(ostream& os) const
 {
-  BEGIN_PUT( doc_expr );
+  BEGIN_PUT(doc_expr);
+
+  os << indent << "copy nodes = " << theCopyInputNodes << std::endl;
+
   theContent->put(os);
+
   END_PUT();
 }
 
-ostream& attr_expr::put( ostream& os) const
+
+ostream& attr_expr::put(ostream& os) const
 {
-  BEGIN_PUT( attr_expr );
+  BEGIN_PUT(attr_expr);
 
-  theQNameExpr->put (os);
+  theQNameExpr->put(os);
   PUT_SUB( "=", theValueExpr );
+
   END_PUT();
 }
 
+
 ostream& text_expr::put(ostream& os) const
 {
   BEGIN_PUT( text_expr );
@@ -822,7 +836,7 @@
 {
   BEGIN_PUT( replace_expr );
   theTargetExpr->put(os);
-  PUT_SUB( ",", theReplaceExpr );
+  PUT_SUB( ",", theSourceExpr );
   END_PUT();
 }
 
@@ -830,7 +844,7 @@
 {
   BEGIN_PUT(rename_expr);
   theTargetExpr->put(os);
-  PUT_SUB(",", theNameExpr);
+  PUT_SUB(",", theSourceExpr);
   END_PUT();
 }
 

=== modified file 'src/compiler/expression/expr_type.cpp'
--- src/compiler/expression/expr_type.cpp	2011-11-23 09:19:30 +0000
+++ src/compiler/expression/expr_type.cpp	2011-11-29 22:22:26 +0000
@@ -666,23 +666,17 @@
   {
     exit_catcher_expr* e = static_cast<exit_catcher_expr*>(this);
 
-    expr* body = e->theExpr;
-
     newType = e->theExpr->get_return_type();
 
-    std::vector<expr*> exitExprs;
-    
-    body->get_exprs_of_kind(exit_expr_kind, exitExprs);
-
-    ulong numExitExprs = exitExprs.size();
-    ulong i;
-
-    for (i = 0; i < numExitExprs; ++i)
+    std::vector<expr*>::const_iterator ite = e->exitExprsBegin();
+    std::vector<expr*>::const_iterator end = e->exitExprsEnd();
+
+    for (; ite != end; ++ite)
     {
-      exit_expr* e = static_cast<exit_expr*>(exitExprs[i]);
+      exit_expr* e = static_cast<exit_expr*>(*ite);
 
       newType = TypeOps::union_type(*newType.getp(),
-                                    *e->get_value()->get_return_type(),
+                                    *e->get_expr()->get_return_type(),
                                     tm);
     }
 

=== modified file 'src/compiler/expression/flwor_expr.h'
--- src/compiler/expression/flwor_expr.h	2011-10-12 17:42:50 +0000
+++ src/compiler/expression/flwor_expr.h	2011-11-29 22:22:26 +0000
@@ -393,11 +393,12 @@
 
 public:
   flwor_wincond(
-        static_context* sctx,
-        bool isOnly,
-        const vars& in_vars,
-        const vars& out_vars,
-        expr_t cond);
+      static_context* sctx,
+      bool isOnly,
+      const vars& in_vars,
+      const vars& out_vars,
+      expr_t cond);
+
   ~flwor_wincond();
 
   expr* get_cond() const { return theCondExpr.getp(); }
@@ -470,14 +471,22 @@
 
   const std::vector<std::string>& get_collations() const { return theCollations; }
 
-  ulong getNumGroupingVars() const { return (ulong)theGroupVars.size(); }
+  csize getNumGroupingVars() const { return theGroupVars.size(); }
 
-  ulong getNumNonGroupingVars() const { return (ulong)theNonGroupVars.size(); }
+  csize getNumNonGroupingVars() const { return theNonGroupVars.size(); }
 
   const rebind_list_t& get_grouping_vars() const { return theGroupVars; }
 
   const rebind_list_t& get_nongrouping_vars() const { return theNonGroupVars; }
 
+  rebind_list_t::iterator beginGroupVars() { return theGroupVars.begin(); }
+
+  rebind_list_t::iterator endGroupVars() { return theGroupVars.end(); }
+
+  rebind_list_t::iterator beginNonGroupVars() { return theNonGroupVars.begin(); }
+
+  rebind_list_t::iterator endNonGroupVars() { return theNonGroupVars.end(); }
+
   expr* get_input_for_group_var(const var_expr* var);
 
   expr* get_input_for_nongroup_var(const var_expr* var);
@@ -520,11 +529,11 @@
 
 public:
   orderby_clause (
-        static_context* sctx,
-        const QueryLoc& loc,
-        bool stable,
-        const std::vector<OrderModifier>& modifiers,
-        const std::vector<expr_t>& orderingExprs);
+      static_context* sctx,
+      const QueryLoc& loc,
+      bool stable,
+      const std::vector<OrderModifier>& modifiers,
+      const std::vector<expr_t>& orderingExprs);
 
   bool is_stable() const { return theStableOrder; }
 
@@ -532,11 +541,15 @@
 
   const std::vector<expr_t>& get_column_exprs() const { return theOrderingExprs; }
 
-  ulong num_columns() const { return (ulong)theOrderingExprs.size(); }
-
-  expr* get_column_expr(ulong i) const { return theOrderingExprs[i].getp(); }
-
-  void set_column_expr(ulong i, expr_t e) { theOrderingExprs[i] = e; }
+  std::vector<expr_t>::iterator begin() { return theOrderingExprs.begin(); }
+
+  std::vector<expr_t>::iterator end() { return theOrderingExprs.end(); }
+
+  csize num_columns() const { return theOrderingExprs.size(); }
+
+  expr* get_column_expr(csize i) const { return theOrderingExprs[i].getp(); }
+
+  void set_column_expr(csize i, expr_t e) { theOrderingExprs[i] = e; }
 
   flwor_clause_t clone(expr::substitution_t& substitution) const;
 

=== modified file 'src/compiler/expression/fo_expr.h'
--- src/compiler/expression/fo_expr.h	2011-06-14 17:26:33 +0000
+++ src/compiler/expression/fo_expr.h	2011-11-29 22:22:26 +0000
@@ -79,11 +79,11 @@
 
   const store::Item* get_fname() const;
 
-  ulong num_args() const { return (ulong)theArgs.size(); }
-
-  expr* get_arg(ulong i) const { return theArgs[i].getp(); }
-
-  void set_arg(ulong i, expr* e) { theArgs[i] = e; }
+  csize num_args() const { return theArgs.size(); }
+
+  expr* get_arg(csize i) const { return theArgs[i].getp(); }
+
+  void set_arg(csize i, expr* e) { theArgs[i] = e; }
 
   void compute_scripting_kind();
 

=== modified file 'src/compiler/expression/ft_expr.h'
--- src/compiler/expression/ft_expr.h	2011-06-14 17:26:33 +0000
+++ src/compiler/expression/ft_expr.h	2011-11-29 22:22:26 +0000
@@ -27,7 +27,8 @@
 /**
  * An ftcontains_expr is-an expr for the FTContainsExpr.
  */
-class ftcontains_expr : public expr {
+class ftcontains_expr : public expr 
+{
   friend class ExprIterator;
 
 public:

=== modified file 'src/compiler/expression/path_expr.h'
--- src/compiler/expression/path_expr.h	2011-06-14 17:26:33 +0000
+++ src/compiler/expression/path_expr.h	2011-11-29 22:22:26 +0000
@@ -69,11 +69,11 @@
 
 	void add_back(expr_t step);
 
-  void erase(ulong i) { theSteps.erase(theSteps.begin() + i); }
-
-  ulong numSteps() const { return (ulong)theSteps.size(); }
-
-	const expr_t& operator[](int n) const { return theSteps[n]; }
+  void erase(csize i) { theSteps.erase(theSteps.begin() + i); }
+
+  csize numSteps() const { return theSteps.size(); }
+
+  expr* operator[](csize n) const { return theSteps[n].getp(); }
 
   std::vector<expr_t>::const_iterator begin() const { return theSteps.begin(); }
 

=== modified file 'src/compiler/expression/script_exprs.cpp'
--- src/compiler/expression/script_exprs.cpp	2011-11-17 16:32:04 +0000
+++ src/compiler/expression/script_exprs.cpp	2011-11-29 22:22:26 +0000
@@ -112,9 +112,9 @@
 
   theScriptingKind = VACUOUS_EXPR;
 
-  ulong numChildren = (ulong)theArgs.size();
+  csize numChildren = theArgs.size();
 
-  for (ulong i = 0; i < numChildren; ++i)
+  for (csize i = 0; i < numChildren; ++i)
   {
     short kind = theArgs[i]->get_scripting_detail();
 
@@ -258,6 +258,9 @@
 
   // var_decl_expr is unfoldable because it requires access to the dyn ctx.
   setUnfoldable(ANNOTATION_TRUE_FIXED);
+
+  if (initExpr)
+    varExpr->add_set_expr(this);
 }
 
 
@@ -319,6 +322,14 @@
 
   // var_set_expr is unfoldable because it requires access to the dyn ctx.
   setUnfoldable(ANNOTATION_TRUE_FIXED);
+
+  varExpr->add_set_expr(this);
+}
+
+
+var_set_expr::~var_set_expr()
+{
+  theVarExpr->remove_set_expr(this);
 }
 
 
@@ -365,7 +376,8 @@
     const expr_t& inExpr)
   :
   expr(sctx, loc, exit_expr_kind),
-  theExpr(inExpr)
+  theExpr(inExpr),
+  theCatcherExpr(NULL)
 {
   compute_scripting_kind();
 
@@ -375,10 +387,20 @@
 }
 
 
+exit_expr::~exit_expr()
+{
+  if (theCatcherExpr)
+  {
+    theCatcherExpr->removeExitExpr(this);
+  }
+}
+
+
 void exit_expr::serialize(::zorba::serialization::Archiver& ar)
 {
   serialize_baseclass(ar, (expr*)this);
   ar & theExpr;
+  ar & theCatcherExpr;
 }
 
 
@@ -390,7 +412,11 @@
 
 expr_t exit_expr::clone(substitution_t& subst) const
 {
-  return new exit_expr(theSctx, get_loc(), get_value()->clone(subst));
+  expr* clone = new exit_expr(theSctx, get_loc(), get_expr()->clone(subst));
+
+  subst[this] = clone;
+
+  return clone;
 }
 
 
@@ -400,11 +426,21 @@
 exit_catcher_expr::exit_catcher_expr(
     static_context* sctx,
     const QueryLoc& loc,
-    const expr_t& inExpr)
+    const expr_t& inExpr,
+    std::vector<expr*>& exitExprs)
   :
   expr(sctx, loc, exit_catcher_expr_kind),
   theExpr(inExpr)
 {
+  theExitExprs.swap(exitExprs);
+
+  std::vector<expr*>::const_iterator ite = theExitExprs.begin();
+  std::vector<expr*>::const_iterator end = theExitExprs.end();
+  for (; ite != end; ++ite)
+  {
+    static_cast<exit_expr*>(*ite)->setCatcherExpr(this);
+  }
+
   compute_scripting_kind();
 
   setUnfoldable(ANNOTATION_TRUE_FIXED);
@@ -415,6 +451,7 @@
 {
   serialize_baseclass(ar, (expr*)this);
   ar & theExpr;
+  ar & theExitExprs;
 }
 
 
@@ -424,9 +461,36 @@
 }
 
 
+void exit_catcher_expr::removeExitExpr(const expr* exitExpr)
+{
+  std::vector<expr*>::iterator ite = theExitExprs.begin();
+  std::vector<expr*>::iterator end = theExitExprs.end();
+  for (; ite != end; ++ite)
+  {
+    if (*ite == exitExpr)
+    {
+      theExitExprs.erase(ite);
+      return;
+    }
+  }
+}
+
+
 expr_t exit_catcher_expr::clone(substitution_t& subst) const
 {
-  return new exit_catcher_expr(theSctx, get_loc(), get_expr()->clone(subst));
+  expr_t clonedInput = get_expr()->clone(subst);
+
+  std::vector<expr*> clonedExits;
+  std::vector<expr*>::const_iterator ite = theExitExprs.begin();
+  std::vector<expr*>::const_iterator end = theExitExprs.end();
+  for (; ite != end; ++ite)
+  {
+    assert(subst.find(*ite) != subst.end());
+
+    clonedExits.push_back(subst[*ite]);
+  }
+
+  return new exit_catcher_expr(theSctx, get_loc(), clonedInput, clonedExits);
 }
 
 

=== modified file 'src/compiler/expression/script_exprs.h'
--- src/compiler/expression/script_exprs.h	2011-11-17 16:32:04 +0000
+++ src/compiler/expression/script_exprs.h	2011-11-29 22:22:26 +0000
@@ -41,6 +41,7 @@
 
 class expr_visitor;
 class var_expr;
+class exit_catcher_expr;
 
 
 /***************************************************************************//**
@@ -139,9 +140,9 @@
 
   csize size() const { return theArgs.size(); }
 
-  const expr_t& operator[](csize i) const { return theArgs[i]; }
+  const expr* operator[](csize i) const { return theArgs[i]; }
 
-  expr_t& operator[](csize i) { return theArgs[i]; }
+  expr* operator[](csize i) { return theArgs[i]; }
 
   expr_t clone(substitution_t& s) const;
 
@@ -291,6 +292,8 @@
       const var_expr_t& varExpr,
       const expr_t& setExpr);
 
+  ~var_set_expr();
+
   var_expr* get_var_expr() const { return theVarExpr.getp(); }
 
   expr* get_expr() const { return theExpr.getp(); }
@@ -314,7 +317,9 @@
   friend class expr;
 
 private:
-  expr_t theExpr;
+  expr_t               theExpr;
+
+  exit_catcher_expr  * theCatcherExpr;
 
 public:
   SERIALIZABLE_CLASS(exit_expr)
@@ -324,7 +329,11 @@
 public:
   exit_expr(static_context* sctx, const QueryLoc& loc, const expr_t& inExpr);
 
-  expr* get_value() const { return theExpr.getp(); }
+  ~exit_expr();
+
+  expr* get_expr() const { return theExpr.getp(); }
+
+  void setCatcherExpr(exit_catcher_expr* e) { theCatcherExpr = e; }
 
   void compute_scripting_kind();
 
@@ -337,7 +346,17 @@
 
 
 /*******************************************************************************
-  A "helper" expr to catch the ExitExpr thrown by an exit_expr.
+  A "helper" expr to catch the exception thrown by an exit_expr that appears
+  inside a UDF. It is placed between the return-type-checking expr(s) at the
+  top of the UDF body and the effective UDF body.
+
+  theExpr:
+  --------
+  The child expr of "this" exit_catcher_expr (i.e., the effective UDF body).
+
+  theExitExprs:
+  -------------
+  All the exit_exprs that appear in the body of the udf.
 ********************************************************************************/
 class exit_catcher_expr : public expr 
 {
@@ -345,7 +364,9 @@
   friend class expr;
 
 private:
-  expr_t theExpr;
+  expr_t             theExpr;
+
+  std::vector<expr*> theExitExprs;
 
 public:
   SERIALIZABLE_CLASS(exit_catcher_expr)
@@ -353,10 +374,26 @@
   void serialize(::zorba::serialization::Archiver& ar);
 
 public:
-  exit_catcher_expr(static_context* sctx, const QueryLoc& loc, const expr_t& inExpr);
+  exit_catcher_expr(
+      static_context* sctx,
+      const QueryLoc& loc,
+      const expr_t& inExpr,
+      std::vector<expr*>& exitExprs);
 
   expr* get_expr() const { return theExpr.getp(); }
 
+  std::vector<expr*>::const_iterator exitExprsBegin() const 
+  {
+    return theExitExprs.begin(); 
+  }
+
+  std::vector<expr*>::const_iterator exitExprsEnd() const 
+  {
+    return theExitExprs.end(); 
+  }
+
+  void removeExitExpr(const expr* exitExpr);
+
   void compute_scripting_kind();
 
   expr_t clone(substitution_t& s) const;

=== modified file 'src/compiler/expression/update_exprs.cpp'
--- src/compiler/expression/update_exprs.cpp	2011-08-18 15:36:49 +0000
+++ src/compiler/expression/update_exprs.cpp	2011-11-29 22:22:26 +0000
@@ -24,6 +24,8 @@
 namespace zorba 
 {
 
+SERIALIZABLE_CLASS_VERSIONS(update_expr_base)
+END_SERIALIZABLE_CLASS_VERSIONS(update_expr_base)
 
 SERIALIZABLE_CLASS_VERSIONS(insert_expr)
 END_SERIALIZABLE_CLASS_VERSIONS(insert_expr)
@@ -54,37 +56,60 @@
 /*******************************************************************************
 
 ********************************************************************************/
+update_expr_base::update_expr_base(
+    static_context* sctx,
+    const QueryLoc& loc,
+    expr_kind_t kind,
+    const expr_t& targetExpr,
+    const expr_t& sourceExpr)
+  :
+	expr(sctx, loc, kind),
+	theTargetExpr(targetExpr),
+  theSourceExpr(sourceExpr)
+{
+  compute_scripting_kind();
+}
+
+
+void update_expr_base::serialize(::zorba::serialization::Archiver& ar)
+{
+  serialize_baseclass(ar, (expr*)this);
+  ar & theTargetExpr;
+  ar & theSourceExpr;
+}
+
+
+void update_expr_base::compute_scripting_kind()
+{
+  theScriptingKind = UPDATING_EXPR;
+
+  checkSimpleExpr(theTargetExpr);
+
+  if (theSourceExpr)
+    checkSimpleExpr(theSourceExpr);
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
 insert_expr::insert_expr(
     static_context* sctx,
     const QueryLoc& loc,
     store::UpdateConsts::InsertType aType,
-    expr_t aSourceExpr,
-    expr_t aTargetExpr)
+    const expr_t& sourceExpr,
+    const expr_t& targetExpr)
   :
-	expr(sctx, loc, insert_expr_kind),
-  theType(aType),
-	theSourceExpr(aSourceExpr),
-	theTargetExpr(aTargetExpr)
+	update_expr_base(sctx, loc, insert_expr_kind, targetExpr, sourceExpr),
+  theType(aType)
 {
-  compute_scripting_kind();
 }
 
 
 void insert_expr::serialize(::zorba::serialization::Archiver& ar)
 {
-  serialize_baseclass(ar, (expr*)this);
+  serialize_baseclass(ar, (update_expr_base*)this);
   SERIALIZE_ENUM(store::UpdateConsts::InsertType, theType);
-  ar & theSourceExpr;
-  ar & theTargetExpr;
-}
-
-
-void insert_expr::compute_scripting_kind()
-{
-  theScriptingKind = UPDATING_EXPR;
-
-  checkSimpleExpr(theSourceExpr);
-  checkSimpleExpr(theTargetExpr);
 }
 
 
@@ -104,30 +129,20 @@
 delete_expr::delete_expr(
     static_context* sctx,
     const QueryLoc& loc,
-    expr_t aTargetExpr)
+    const expr_t& targetExpr)
   :
-	expr(sctx, loc, delete_expr_kind),
-	theTargetExpr(aTargetExpr)
+	update_expr_base(sctx, loc, delete_expr_kind, targetExpr, NULL)
 {
-  compute_scripting_kind();
 }
 
 
 void delete_expr::serialize(::zorba::serialization::Archiver& ar)
 {
-  serialize_baseclass(ar, (expr*)this);
-  ar & theTargetExpr;
-}
-
-void delete_expr::compute_scripting_kind()
-{
-  theScriptingKind = UPDATING_EXPR;
-
-  checkSimpleExpr(theTargetExpr);
-}
-
-
-expr_t delete_expr::clone (substitution_t& subst) const
+  serialize_baseclass(ar, (update_expr_base*)this);
+}
+
+
+expr_t delete_expr::clone(substitution_t& subst) const
 {
   return new delete_expr(theSctx, get_loc(), getTargetExpr()->clone(subst));
 }
@@ -140,33 +155,19 @@
     static_context* sctx,
     const QueryLoc& loc,
     store::UpdateConsts::ReplaceType aType,
-    expr_t aTargetExpr,
-    expr_t aReplaceExpr)
+    const expr_t& targetExpr,
+    const expr_t& replaceExpr)
   :
-	expr(sctx, loc, replace_expr_kind),
-  theType(aType),
-	theTargetExpr(aTargetExpr),
-	theReplaceExpr(aReplaceExpr)
+	update_expr_base(sctx, loc, replace_expr_kind, targetExpr, replaceExpr),
+  theType(aType)
 {
-  compute_scripting_kind();
 }
 
 
 void replace_expr::serialize(::zorba::serialization::Archiver& ar)
 {
-  serialize_baseclass(ar, (expr*)this);
+  serialize_baseclass(ar, (update_expr_base*)this);
   SERIALIZE_ENUM(store::UpdateConsts::ReplaceType, theType);
-  ar & theTargetExpr;
-  ar & theReplaceExpr;
-}
-
-
-void replace_expr::compute_scripting_kind()
-{
-  theScriptingKind = UPDATING_EXPR;
-
-  checkSimpleExpr(theTargetExpr);
-  checkSimpleExpr(theReplaceExpr);
 }
 
 
@@ -186,31 +187,17 @@
 rename_expr::rename_expr(
     static_context* sctx,
     const QueryLoc& loc,
-    expr_t aTargetExpr,
-    expr_t aNameExpr)
+    const expr_t& targetExpr,
+    const expr_t& nameExpr)
   :
-	expr(sctx, loc, rename_expr_kind),
-	theTargetExpr(aTargetExpr),
-	theNameExpr(aNameExpr)
+	update_expr_base(sctx, loc, rename_expr_kind, targetExpr, nameExpr)
 {
-  compute_scripting_kind();
 }
 
 
 void rename_expr::serialize(::zorba::serialization::Archiver& ar)
 {
-  serialize_baseclass(ar, (expr*)this);
-  ar & theTargetExpr;
-  ar & theNameExpr;
-}
-
-
-void rename_expr::compute_scripting_kind()
-{
-  theScriptingKind = UPDATING_EXPR;
-
-  checkSimpleExpr(theTargetExpr);
-  checkSimpleExpr(theNameExpr);
+  serialize_baseclass(ar, (update_expr_base*)this);
 }
 
 

=== modified file 'src/compiler/expression/update_exprs.h'
--- src/compiler/expression/update_exprs.h	2011-06-14 17:26:33 +0000
+++ src/compiler/expression/update_exprs.h	2011-11-29 22:22:26 +0000
@@ -37,19 +37,47 @@
 /*******************************************************************************
 
 ********************************************************************************/
-class insert_expr : public expr
+class update_expr_base : public expr
+{
+protected:
+	expr_t  theTargetExpr;
+	expr_t  theSourceExpr;
+
+public:
+  SERIALIZABLE_ABSTRACT_CLASS(update_expr_base)
+  SERIALIZABLE_CLASS_CONSTRUCTOR2(update_expr_base, expr)
+  void serialize(::zorba::serialization::Archiver& ar);
+
+public:
+	update_expr_base(
+    static_context* sctx,
+		const QueryLoc&,
+    expr_kind_t kind,
+		const expr_t& targetExpr,
+    const expr_t& sourceExpr);
+
+	expr* getTargetExpr() const { return theTargetExpr.getp(); }
+
+	expr* getSourceExpr() const { return theSourceExpr.getp(); }
+
+  void compute_scripting_kind();
+};
+
+
+/*******************************************************************************
+
+********************************************************************************/
+class insert_expr : public update_expr_base
 {
   friend class ExprIterator;
   friend class expr;
 
 protected:
   store::UpdateConsts::InsertType theType;
-	expr_t                          theSourceExpr;
-	expr_t                          theTargetExpr;
 
 public:
   SERIALIZABLE_CLASS(insert_expr)
-  SERIALIZABLE_CLASS_CONSTRUCTOR2(insert_expr, expr)
+  SERIALIZABLE_CLASS_CONSTRUCTOR2(insert_expr, update_expr_base)
   void serialize(::zorba::serialization::Archiver& ar);
 
 public:
@@ -57,17 +85,11 @@
     static_context* sctx,
 		const QueryLoc&,
     store::UpdateConsts::InsertType,
-		expr_t aSourceExpr,
-		expr_t aTargetExpr);
+		const expr_t& aSourceExpr,
+		const expr_t& aTargetExpr);
 
   store::UpdateConsts::InsertType getType() const { return theType; }
-
-	expr* getSourceExpr() const { return theSourceExpr.getp(); }
-
-	expr* getTargetExpr() const { return theTargetExpr.getp(); }
   
-  void compute_scripting_kind();
-
   expr_t clone(substitution_t& s) const;
 
   void accept(expr_visitor&);
@@ -79,25 +101,18 @@
 /*******************************************************************************
 
 ********************************************************************************/
-class delete_expr : public expr
+class delete_expr : public update_expr_base
 {
   friend class ExprIterator;
   friend class expr;
 
-protected:
-	expr_t theTargetExpr;
-
 public:
   SERIALIZABLE_CLASS(delete_expr)
-  SERIALIZABLE_CLASS_CONSTRUCTOR2(delete_expr, expr)
+  SERIALIZABLE_CLASS_CONSTRUCTOR2(delete_expr, update_expr_base)
   void serialize(::zorba::serialization::Archiver& ar);
 
 public:
-	delete_expr(static_context* sctx, const QueryLoc&, expr_t);
-
-	expr* getTargetExpr() const { return theTargetExpr.getp(); }
-
-  void compute_scripting_kind();
+	delete_expr(static_context* sctx, const QueryLoc&, const expr_t&);
 
   expr_t clone(substitution_t& s) const;
 
@@ -110,19 +125,17 @@
 /*******************************************************************************
 
 ********************************************************************************/
-class replace_expr : public expr
+class replace_expr : public update_expr_base
 {
   friend class ExprIterator;
   friend class expr;
 
 protected:
   store::UpdateConsts::ReplaceType theType;
-	expr_t                           theTargetExpr;
-	expr_t                           theReplaceExpr;
 
 public:
   SERIALIZABLE_CLASS(replace_expr)
-  SERIALIZABLE_CLASS_CONSTRUCTOR2(replace_expr, expr)
+  SERIALIZABLE_CLASS_CONSTRUCTOR2(replace_expr, update_expr_base)
   void serialize(::zorba::serialization::Archiver& ar);
 
 public:
@@ -130,16 +143,12 @@
     static_context* sctx,
 		const QueryLoc&,
     store::UpdateConsts::ReplaceType aType,
-		expr_t,
-		expr_t);
+		const expr_t&,
+		const expr_t&);
 
   store::UpdateConsts::ReplaceType getType() const { return theType; }
 
-	expr* getTargetExpr() const { return theTargetExpr.getp(); }
-
-	expr* getReplaceExpr() const { return theReplaceExpr.getp(); }
-
-  void compute_scripting_kind();
+	expr* getReplaceExpr() const { return theSourceExpr.getp(); }
 
   expr_t clone(substitution_t& s) const;
 
@@ -152,32 +161,24 @@
 /*******************************************************************************
 
 ********************************************************************************/
-class rename_expr : public expr
+class rename_expr : public update_expr_base
 {
   friend class ExprIterator;
   friend class expr;
 
-protected:
-	expr_t             theTargetExpr;
-	expr_t             theNameExpr;
-
 public:
   SERIALIZABLE_CLASS(rename_expr)
-  SERIALIZABLE_CLASS_CONSTRUCTOR2(rename_expr, expr)
+  SERIALIZABLE_CLASS_CONSTRUCTOR2(rename_expr, update_expr_base)
   void serialize(::zorba::serialization::Archiver& ar);
 
 public:
 	rename_expr(
-        static_context* sctx,
-        const QueryLoc&,
-        expr_t,
-        expr_t);
-
-	expr* getTargetExpr() const { return theTargetExpr.getp(); }
-
-	expr* getNameExpr() const { return theNameExpr.getp(); }
-
-  void compute_scripting_kind();
+      static_context* sctx,
+      const QueryLoc&,
+      const expr_t&,
+      const expr_t&);
+
+	expr* getNameExpr() const { return theSourceExpr.getp(); }
 
   expr_t clone(substitution_t& s) const;
 
@@ -261,7 +262,7 @@
 	std::vector<copy_clause_t>::const_iterator end() const
   { return theCopyClauses.end(); }
 
-	size_t size() const { return theCopyClauses.size(); }
+	csize size() const { return theCopyClauses.size(); }
 
   void compute_scripting_kind();
 

=== modified file 'src/compiler/expression/var_expr.cpp'
--- src/compiler/expression/var_expr.cpp	2011-11-01 14:26:48 +0000
+++ src/compiler/expression/var_expr.cpp	2011-11-29 22:22:26 +0000
@@ -15,6 +15,8 @@
  */
 #include "stdafx.h"
 
+#include "functions/udf.h"
+
 #include "compiler/expression/var_expr.h"
 #include "compiler/expression/update_exprs.h"
 #include "compiler/expression/flwor_expr.h"
@@ -83,6 +85,8 @@
   theDeclaredType(NULL),
   theFlworClause(NULL),
   theCopyClause(NULL),
+  theParamPos(0),
+  theUDF(NULL),
   theIsExternal(false),
   theIsPrivate(false),
   theIsMutable(true),
@@ -106,6 +110,8 @@
   ar & theDeclaredType;
   ar & theFlworClause;
   ar & theCopyClause;
+  ar & theParamPos;
+  ar & theUDF;
   ar & theIsPrivate;
   ar & theIsExternal;
   ar & theIsMutable;
@@ -212,6 +218,28 @@
 /*******************************************************************************
 
 ********************************************************************************/
+void var_expr::remove_set_expr(expr* e) 
+{
+  assert(theKind == local_var || theKind == prolog_var);
+
+  std::vector<expr*>::iterator ite = theSetExprs.begin();
+  std::vector<expr*>::iterator end = theSetExprs.end();
+  for (; ite != end; ++ite)
+  {
+    if (*ite == e)
+    {
+      theSetExprs.erase(ite);
+      break;
+    }
+  }
+
+  assert(ite != end);
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
 bool var_expr::is_context_item() const
 {
   return theName->getLocalName() == ".";

=== modified file 'src/compiler/expression/var_expr.h'
--- src/compiler/expression/var_expr.h	2011-11-17 16:32:04 +0000
+++ src/compiler/expression/var_expr.h	2011-11-29 22:22:26 +0000
@@ -56,21 +56,65 @@
   For vars declared in FOR, LET, or WINDOW clauses, their defining expr is
   stored in the associated clause (see theForletClause data member below).
 
-  theUniqueId    : A unique numeric id for variales whose value is stored in
-                   the dynamic context, ie, prolog and local vars. It is used
-                   as an index into an array that stores the values.
-
-  theKind        : The kind of the variable (see var_kind enum below)
-  theVarName     : The fully expanded qname of the var (qname item)
-  theStaticType  : The static type of the variable
-  theFlworClause : If this is a var declared in flwor clause, theFlworClause
-                   points to the defining clause. That clause also contains
-                   the defining expr for the var and a pointer back to this
-                   var_exr.
-  theCopyClause  : If this is a var declared in a copy clause of a transform
-                   expr, theCopyClause points to that clause. That clause
-                   contains the defining expr for the var and a pointer back
-                   to this var_exr.
+  theUniqueId:
+  ------------
+  A unique numeric id for variales whose value is stored in the dynamic context,
+  ie, prolog and local vars. It is used as an index into an array that stores
+  the values.
+
+  theKind:
+  --------
+  The kind of the variable (see var_kind enum below)
+
+  theVarName:
+  -----------
+  The fully expanded qname of the var (qname item)
+
+  theDeclaredType:
+  ----------------
+  The type, if any, specified in the declaration of the variable
+
+  theFlworClause:
+  ---------------
+  If this is a var declared in flwor clause, theFlworClause points to the 
+  defining clause. That clause also contains the defining expr for the var
+  and a pointer back to this var_exr.
+
+  theCopyClause:
+  --------------
+  If this is a var declared in a copy clause of a transform expr, theCopyClause
+  points to that clause. That clause contains the defining expr for the var and
+  a pointer back to this var_exr.
+
+  theParamPos:
+  ------------
+  For arg vars, it is the position, within the param list, of parameter that is
+  bound to this arg var.
+  
+  theUDF:
+  -------
+  For arg vars, the corresponding UDF.
+
+  theSetExprs:
+  ------------
+  For global and local vars, this vector contains a pointer to the var_decl_expr
+  for the variable and to each var_set_expr for the same var.
+
+  theIsExternal:
+  --------------
+  Whether this is an external variable or not (for prolog vars only).
+
+  theIsPrivate:
+  -------------
+  Whether this is a private variable or not (for prolog vars only).
+
+  theIsMutable:
+  -------------
+  Whether this is a mutable variable or not (for prolog and local vars).
+
+  theHasInitializer:
+  ------------------
+   Whether the variable has an initializing expr or not (for prolog vars only).
 *******************************************************************************/
 class var_expr : public expr
 {
@@ -108,20 +152,31 @@
   };
 
 protected:
-  ulong          theUniqueId;
-
-  var_kind       theKind;
-  store::Item_t  theName;
-  xqtref_t       theDeclaredType;
-
-  flwor_clause * theFlworClause;
-  copy_clause  * theCopyClause;
-
-  bool           theIsExternal;
-
-  bool           theIsPrivate; 
-  bool           theIsMutable;
-  bool           theHasInitializer;
+  ulong                 theUniqueId;
+
+  var_kind              theKind;
+
+  store::Item_t         theName;
+
+  xqtref_t              theDeclaredType;
+
+  flwor_clause        * theFlworClause;
+
+  copy_clause         * theCopyClause;
+
+  csize                 theParamPos;
+
+  user_function       * theUDF;
+
+  std::vector<expr*>    theSetExprs;
+
+  bool                  theIsExternal;
+
+  bool                  theIsPrivate; 
+
+  bool                  theIsMutable;
+
+  bool                  theHasInitializer;
 
 public:
   SERIALIZABLE_CLASS(var_expr)
@@ -184,6 +239,22 @@
 
   const var_expr* get_pos_var() const;
 
+  csize get_param_pos() const { return theParamPos; }
+
+  void set_param_pos(csize pos) { theParamPos = pos; }
+
+  user_function* get_udf() const { return theUDF; }
+
+  void set_udf(const user_function* udf) { theUDF = const_cast<user_function*>(udf); }
+
+  void add_set_expr(expr* e) { theSetExprs.push_back(e); }
+
+  void remove_set_expr(expr* e);
+
+  std::vector<expr*>::const_iterator setExprsBegin() const { return theSetExprs.begin(); }
+
+  std::vector<expr*>::const_iterator setExprsEnd() const { return theSetExprs.end(); }
+  
   bool is_context_item() const;
 
   void compute_scripting_kind();

=== modified file 'src/compiler/rewriter/framework/rewriter_context.h'
--- src/compiler/rewriter/framework/rewriter_context.h	2011-08-16 16:13:50 +0000
+++ src/compiler/rewriter/framework/rewriter_context.h	2011-11-29 22:22:26 +0000
@@ -35,31 +35,40 @@
 typedef std::vector<var_expr*> IdVarMap;
 typedef std::map<const expr *, DynamicBitset> ExprVarsMap;
 
+typedef std::set<fo_expr*> UdfCalls;
 
 /*******************************************************************************
 
-  theVarIdMap        : Maps a var_expr to its unique "prefix" id. The "prefix"
-                       id has the follwoing property: for 2 vars v1 and v2,
-                       v1 is defined before v2 if and only if prefix-id(v1) <
-                       prefix-id(v2). See index_flwor_vars() function in
-                       tools/expr_tools.cpp for more details.
-
-  theIdVarMap        : This is the reverse mapping of theVarIdMap.
-
-  theExprVarsMap     : An entry into this map maps an expression to the variables
-                       that are referenced by that expr and/or its sub-exprs.
-                       (Note: given that the domain expr of a var $x is not
-                       considered a sub-expr of $x, if $x is referenced by an
-                       expr E and the domain expr of $x references another var
-                       $y, $y is NOT considered to be referenced by E). Only
-                       variables that have been assigned a prolog id (i.e., the
-                       ones that appear in theVarIdMap) are considered. The set
-                       of vars referenced by an expr is implemented by a bitset
-                       that is indexed by prolog var ids and whose size (in
-                       number of bits) is equal to the size of theVarIdMap.
-
-  theFlworStack      : The current "in-scope" flwor exprs, ie., flwor exprs that
-                       the rule has entered but not exited yet.
+  theRoot:
+  --------
+  The root node of the expr DAG that is going to be optimized using this context.
+
+  theVarIdMap:
+  ------------
+  Maps a var_expr to its unique "prefix" id. The "prefix" id has the following
+  property: for 2 vars v1 and v2, v1 is defined before v2 if and only if 
+  prefix-id(v1) < prefix-id(v2). See index_flwor_vars() function in
+  tools/expr_tools.cpp for more details.
+
+  theIdVarMap:
+  ------------
+  This is the reverse mapping of theVarIdMap.
+
+  theExprVarsMap:
+  ---------------
+  An entry into this map maps an expr to the variables that are referenced by
+  that expr and/or its sub-exprs. (Note: given that the domain expr of a var
+  $x is not considered a sub-expr of $x, if $x is referenced by an expr E and
+  the domain expr of $x references another var $y, $y is NOT considered to be
+  referenced by E). Only variables that have been assigned a prolog id (i.e.,
+  the ones that appear in theVarIdMap) are considered. The set of vars referenced
+  by an expr is implemented by a bitset that is indexed by prolog var ids and
+  whose size (in number of bits) is equal to the size of theVarIdMap.
+
+  theFlworStack:
+  --------------
+  The current "in-scope" flwor exprs, ie., flwor exprs that the rule has 
+  entered but not exited yet.
 ********************************************************************************/
 class RewriterContext 
 {
@@ -82,13 +91,15 @@
   std::vector<expr_t>          theFlworStack;
   std::vector<bool>            theInReturnClause;
 
+  UdfCalls                     theProcessedUDFCalls;
+
 public:
   RewriterContext(
-        CompilerCB* cb,
-        const expr_t& root,
-        user_function* udf,
-        const zstring& msg,
-        bool orderedMode);
+      CompilerCB* cb,
+      const expr_t& root,
+      user_function* udf,
+      const zstring& msg,
+      bool orderedMode);
 
   ~RewriterContext();
 
@@ -99,10 +110,30 @@
   void setRoot(expr_t root);
 
   rchandle<var_expr> createTempVar(
-        static_context* sctx,
-        const QueryLoc& loc,
-        var_expr::var_kind kind);
-};
+      static_context* sctx,
+      const QueryLoc& loc,
+      var_expr::var_kind kind);
+};
+
+
+/*******************************************************************************
+
+********************************************************************************/
+struct UDFCallChain
+{
+  fo_expr      * theFo;
+  UDFCallChain * thePrev;
+
+  UDFCallChain() : theFo(NULL), thePrev(NULL) {}
+
+  UDFCallChain(fo_expr* caller, UDFCallChain* prevCaller)
+    :
+    theFo(caller),
+    thePrev(prevCaller) 
+  {
+  }
+};
+
 
 }
 

=== modified file 'src/compiler/rewriter/rewriters/default_optimizer.cpp'
--- src/compiler/rewriter/rewriters/default_optimizer.cpp	2011-08-12 10:21:10 +0000
+++ src/compiler/rewriter/rewriters/default_optimizer.cpp	2011-11-29 22:22:26 +0000
@@ -236,6 +236,16 @@
     while (local_modified);
   }
 
+  // Mark node copy property
+  if (Properties::instance()->noCopyOptim())
+  {
+    if (rCtx.theUDF == NULL)
+    {
+      RuleOnceDriver<MarkNodeCopyProps> driverMarkNodeCopyProps;
+      driverMarkNodeCopyProps.rewrite(rCtx);
+    }
+  }
+
   return modified;
 }
 

=== modified file 'src/compiler/rewriter/rules/nodeid_rules.cpp'
--- src/compiler/rewriter/rules/nodeid_rules.cpp	2011-11-17 16:32:04 +0000
+++ src/compiler/rewriter/rules/nodeid_rules.cpp	2011-11-29 22:22:26 +0000
@@ -22,13 +22,17 @@
 
 #include "compiler/expression/flwor_expr.h"
 #include "compiler/expression/path_expr.h"
+#include "compiler/expression/ft_expr.h"
+#include "compiler/expression/ftnode.h"
 #include "compiler/expression/expr.h"
 #include "compiler/expression/script_exprs.h"
+#include "compiler/expression/function_item_expr.h"
 #include "compiler/expression/expr_iter.h"
 
 #include "types/typeops.h"
 
 #include "functions/func_node_sort_distinct.h"
+#include "functions/udf.h"
 
 #include "diagnostics/assert.h"
 
@@ -128,14 +132,14 @@
 
     for (csize i = 0; i < numChildren-1; ++i)
     {
-      expr_t& child = (*seqExpr)[i];
-      set_ignores_sorted_nodes(child.getp(), ANNOTATION_TRUE);
-      set_ignores_duplicate_nodes(child.getp(), ANNOTATION_TRUE);
+      expr* child = (*seqExpr)[i];
+      set_ignores_sorted_nodes(child, ANNOTATION_TRUE);
+      set_ignores_duplicate_nodes(child, ANNOTATION_TRUE);
     }
 
-    expr_t& child = (*seqExpr)[numChildren-1];
-    pushdown_ignores_sorted_nodes(node, child.getp());
-    pushdown_ignores_duplicate_nodes(node, child.getp());
+    expr* child = (*seqExpr)[numChildren-1];
+    pushdown_ignores_sorted_nodes(node, child);
+    pushdown_ignores_duplicate_nodes(node, child);
 
     // TODO: go through the children again, and for each child that is a
     // var_decl_expr, push down the annotation of the associated var_expr
@@ -545,5 +549,776 @@
 }
 
 
+/*******************************************************************************
+
+********************************************************************************/
+expr_t MarkNodeCopyProps::apply(
+    RewriterContext& rCtx,
+    expr* node,
+    bool& modified)
+{
+  modified = false;
+
+  theSourceFinder = new SourceFinder;
+
+  try
+  {
+    if (rCtx.theCCB->theConfig.for_serialization_only)
+    {
+      static_context* sctx = node->get_sctx();
+      if (sctx->preserve_mode() == StaticContextConsts::preserve_ns &&
+          sctx->inherit_mode() == StaticContextConsts::inherit_ns)
+      {
+        markForSerialization(rCtx.theRoot);
+      }
+      else
+      {
+        std::vector<expr*> sources;
+        UDFCallChain dummyUdfCaller;
+        theSourceFinder->findNodeSources(rCtx.theRoot, &dummyUdfCaller, sources);
+        markSources(sources);
+      }
+    }
+    else
+    {
+      std::vector<expr*> sources;
+      UDFCallChain dummyUdfCaller;
+      theSourceFinder->findNodeSources(rCtx.theRoot, &dummyUdfCaller, sources);
+      markSources(sources);
+    }
+
+    UDFCallChain dummyUdfCaller;
+    applyInternal(rCtx, node, dummyUdfCaller);
+  }
+  catch (...)
+  {
+    delete theSourceFinder;
+    theSourceFinder = NULL;
+
+    throw;
+  }
+
+  delete theSourceFinder;
+  theSourceFinder = NULL;
+
+  return NULL;
+}
+
+
+void MarkNodeCopyProps::applyInternal(
+    RewriterContext& rCtx,
+    expr* node,
+    UDFCallChain& udfCaller)
+{
+  switch (node->get_expr_kind()) 
+  {
+  case const_expr_kind:
+  {
+    return;
+  }
+  case var_expr_kind:
+  {
+    var_expr* e = static_cast<var_expr*>(node);
+
+    switch (e->get_kind())
+    {
+    case var_expr::for_var:
+    case var_expr::let_var:
+    case var_expr::win_var:
+    case var_expr::wincond_out_var:
+    case var_expr::wincond_in_var:
+    case var_expr::groupby_var:
+    case var_expr::non_groupby_var:
+    case var_expr::wincond_in_pos_var:
+    case var_expr::wincond_out_pos_var:
+    case var_expr::pos_var:
+    case var_expr::score_var:
+    case var_expr::count_var:
+    case var_expr::copy_var:
+    case var_expr::catch_var:
+    case var_expr::arg_var:
+    case var_expr::prolog_var: 
+    case var_expr::local_var:
+    {
+      return;
+    }
+
+    case var_expr::eval_var: // TODO
+    default:
+    {
+      ZORBA_ASSERT(false);
+      return;
+    }
+    }
+  }
+
+  case doc_expr_kind:
+  case elem_expr_kind:
+  case attr_expr_kind:
+  case text_expr_kind:
+  case pi_expr_kind:
+  {
+    break;
+  }
+
+  case relpath_expr_kind:
+  {
+    relpath_expr* e = static_cast<relpath_expr *>(node);
+
+    if (e->willBeSerialized())
+    {
+      std::vector<expr*> sources;
+      theSourceFinder->findNodeSources((*e)[0],  &udfCaller, sources);
+      markSources(sources);
+    }
+    else
+    {
+      std::vector<expr_t>::const_iterator ite = e->begin();
+      std::vector<expr_t>::const_iterator end = e->end();
+
+      for (++ite; ite != end; ++ite)
+      {
+        axis_step_expr* axisExpr = static_cast<axis_step_expr*>((*ite).getp());
+        axis_kind_t axisKind = axisExpr->getAxis();
+
+        if (axisKind != axis_kind_child &&
+            axisKind != axis_kind_descendant &&
+            axisKind != axis_kind_self &&
+            axisKind != axis_kind_attribute)
+        {
+          std::vector<expr*> sources;
+          theSourceFinder->findNodeSources((*e)[0],  &udfCaller, sources);
+          markSources(sources);
+          break;
+        }
+      }
+    }
+
+    applyInternal(rCtx, (*e)[0], udfCaller);
+
+    return;
+  }
+
+  case gflwor_expr_kind:
+  case flwor_expr_kind:
+  case if_expr_kind:
+  case trycatch_expr_kind:
+  {
+    break;
+  }
+
+  case fo_expr_kind:
+  {
+    fo_expr* e = static_cast<fo_expr *>(node);
+    function* f = e->get_func();
+
+    if (f->isUdf())
+    {
+      UdfCalls::iterator ite = rCtx.theProcessedUDFCalls.find(e);
+
+      if (ite == rCtx.theProcessedUDFCalls.end())
+      {
+        rCtx.theProcessedUDFCalls.insert(e);
+
+        user_function* udf = static_cast<user_function*>(f);
+
+        UDFCallChain nextUdfCall(e, &udfCaller);
+
+        applyInternal(rCtx, udf->getBody(), nextUdfCall);
+      }
+    } // f->isUdf()
+    else
+    {
+      csize numArgs = e->num_args();
+      for (csize i = 0; i < numArgs; ++i)
+      {
+        if (f->mustCopyInputNodes(e, i))
+        {
+          std::vector<expr*> sources;
+          theSourceFinder->findNodeSources(e->get_arg(i), &udfCaller, sources);
+          markSources(sources);
+        }
+      }
+    }
+
+    break;
+  }
+
+  case castable_expr_kind:
+  case cast_expr_kind:
+  case instanceof_expr_kind:
+  case name_cast_expr_kind:
+  case promote_expr_kind:
+  case treat_expr_kind:
+  case order_expr_kind:
+  case wrapper_expr_kind:
+  case function_trace_expr_kind:
+  case extension_expr_kind:
+  {
+    break;
+  }
+
+  case validate_expr_kind:
+  {
+    validate_expr* e = static_cast<validate_expr *>(node);
+    std::vector<expr*> sources;
+    theSourceFinder->findNodeSources(e->get_expr(), &udfCaller, sources);
+    markSources(sources);
+    break;
+  }
+
+  case delete_expr_kind:
+  case rename_expr_kind:
+  case insert_expr_kind:
+  case replace_expr_kind:
+  {
+    update_expr_base* e = static_cast<update_expr_base*>(node);
+
+    std::vector<expr*> sources;
+    theSourceFinder->findNodeSources(e->getTargetExpr(), &udfCaller, sources);
+    markSources(sources);
+
+    static_context* sctx = e->get_sctx();
+
+    if (e->getSourceExpr() != NULL &&
+        (e->get_expr_kind() == insert_expr_kind ||
+         static_cast<replace_expr*>(e)->getType() == store::UpdateConsts::NODE) &&
+        (sctx->inherit_mode() != StaticContextConsts::no_inherit_ns ||
+         sctx->preserve_mode() != StaticContextConsts::no_preserve_ns))
+    {
+      std::vector<expr*> sources;
+      theSourceFinder->findNodeSources(e->getSourceExpr(), &udfCaller, sources);
+      markSources(sources);
+    }
+
+    break;
+  }
+
+  case transform_expr_kind:
+  {
+    transform_expr* e = static_cast<transform_expr *>(node);
+
+    static_context* sctx = e->get_sctx();
+
+    if (sctx->preserve_mode() != StaticContextConsts::no_preserve_ns)
+    {
+      std::vector<copy_clause_t>::const_iterator ite = e->begin();
+      std::vector<copy_clause_t>::const_iterator end = e->end();
+
+      for (; ite != end; ++ite)
+      {
+        std::vector<expr*> sources;
+        theSourceFinder->findNodeSources((*ite)->getExpr(), &udfCaller, sources);
+        markSources(sources);
+      }
+    }
+
+    break;
+  }
+
+  case var_decl_expr_kind:
+  case var_set_expr_kind:
+  case apply_expr_kind:
+  case while_expr_kind:
+  case flowctl_expr_kind:
+  case exit_expr_kind:
+  case exit_catcher_expr_kind: 
+  {
+    break;
+  }
+
+  case block_expr_kind:
+  {
+    block_expr* e = static_cast<block_expr *>(node);
+
+    if (e->is_sequential())
+    {
+      csize numChildren = e->size();
+      bool haveUpdates = false;
+
+      for (csize i = numChildren; i > 0; --i)
+      {
+        expr* child = (*e)[i-1];
+
+        if (haveUpdates)
+        {
+          std::vector<expr*> sources;
+          theSourceFinder->findNodeSources(child, &udfCaller, sources);
+          markSources(sources);
+        }
+        else
+        {
+          short scriptingKind = child->get_scripting_detail();
+
+          if (scriptingKind & APPLYING_EXPR || 
+              scriptingKind & EXITING_EXPR ||
+              scriptingKind & SEQUENTIAL_FUNC_EXPR)
+          {
+            haveUpdates = true;
+          }
+        }
+      }
+    }
+
+    break;
+  }
+
+  case eval_expr_kind:
+  {
+    eval_expr* e = static_cast<eval_expr*>(node);
+
+    csize numVars = e->var_count();
+
+    for (csize i = 0; i < numVars; ++i)
+    {
+      std::vector<expr*> sources;
+      theSourceFinder->findNodeSources(e->get_arg_expr(i), &udfCaller, sources);
+      markSources(sources);
+    }
+
+    std::vector<var_expr_t> globalVars;
+    e->get_sctx()->getVariables(globalVars, true, true);
+  
+    FOR_EACH(std::vector<var_expr_t>, ite, globalVars)
+    {
+      var_expr* globalVar = (*ite).getp();
+
+      std::vector<expr*> sources;
+      theSourceFinder->findNodeSources(globalVar, &udfCaller, sources);
+      markSources(sources);
+    }
+
+    break;
+  }
+
+#ifndef ZORBA_NO_FULL_TEXT
+  case ft_expr_kind:
+  {
+    ftcontains_expr* e = static_cast<ftcontains_expr*>(node);
+
+    std::vector<expr*> sources;
+    theSourceFinder->findNodeSources(e->get_range(), &udfCaller, sources);
+    markSources(sources);
+
+    break;
+  }
+#endif
+
+  case dynamic_function_invocation_expr_kind:
+  {
+    // Conservatively assume that the function item that is going to be executed
+    // requires stand-alone trees as inputs, so find and mark the sources in the
+    // arguments. TODO: look for function_item_expr in the subtree to check if
+    // this assumption is really true. 
+    dynamic_function_invocation_expr* e = 
+    static_cast<dynamic_function_invocation_expr*>(node);
+
+    const std::vector<expr_t>& args = e->get_args();
+
+    FOR_EACH(std::vector<expr_t>, ite, args)
+    {
+      std::vector<expr*> sources;
+      theSourceFinder->findNodeSources((*ite).getp(), &udfCaller, sources);
+      markSources(sources);
+    }
+
+    break;
+  }
+
+  case function_item_expr_kind:
+  {
+    function_item_expr* e = static_cast<function_item_expr*>(node);
+
+    user_function* udf = static_cast<user_function*>(e->get_function());
+
+    UDFCallChain dummyUdfCaller;
+
+    applyInternal(rCtx, udf->getBody(), dummyUdfCaller);
+
+    return;
+  }
+
+#if 0
+  case debugger_expr_kind:
+    break;
+#endif
+
+  case axis_step_expr_kind:
+  case match_expr_kind:
+  default:
+    ZORBA_ASSERT(false);
+  }
+
+  ExprIterator iter(node);
+  while(!iter.done()) 
+  {
+    expr* child = (*iter).getp();
+    if (child != NULL) 
+    {
+      applyInternal(rCtx, child, udfCaller);
+    }
+    iter.next();
+  }
+
+  return;
+}
+
+
+void MarkNodeCopyProps::markSources(const std::vector<expr*>& sources)
+{
+  std::vector<expr*>::const_iterator ite = sources.begin();
+  std::vector<expr*>::const_iterator end = sources.end();
+  for (; ite != end; ++ite)
+  {
+    expr* source = (*ite);
+    
+    switch (source->get_expr_kind())
+    {
+    case doc_expr_kind:
+    {
+      doc_expr* e = static_cast<doc_expr*>(source);
+      e->setCopyInputNodes();
+      break;
+    }
+    case elem_expr_kind:
+    {
+      elem_expr* e = static_cast<elem_expr*>(source);
+      e->setCopyInputNodes();
+      break;
+    }
+    default:
+    {
+      ZORBA_ASSERT(false);
+    }
+    }
+  }
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+void MarkNodeCopyProps::markForSerialization(expr* node)
+{
+  TypeManager* tm = node->get_type_manager();
+  RootTypeManager& rtm = GENV_TYPESYSTEM;
+
+  xqtref_t retType = node->get_return_type();
+
+  if (TypeOps::is_subtype(tm, *retType, *rtm.ANY_ATOMIC_TYPE_STAR))
+    return;
+
+  switch (node->get_expr_kind()) 
+  {
+  case const_expr_kind:
+  {
+    return;
+  }
+  case var_expr_kind:
+  {
+    var_expr* e = static_cast<var_expr*>(node);
+
+    switch (e->get_kind())
+    {
+    case var_expr::for_var:
+    case var_expr::let_var:
+    case var_expr::win_var:
+    case var_expr::wincond_out_var:
+    case var_expr::wincond_in_var:
+    case var_expr::groupby_var:
+    case var_expr::non_groupby_var:
+    {
+      if (!e->willBeSerialized())
+      {
+        e->setWillBeSerialized(ANNOTATION_TRUE);
+        markForSerialization(e->get_domain_expr());
+      }
+      return;
+    }
+
+    case var_expr::copy_var:
+    case var_expr::catch_var:
+    {
+      return;
+    }
+
+    case var_expr::arg_var:
+    {
+      e->setWillBeSerialized(ANNOTATION_TRUE);
+      return;
+    }
+
+    case var_expr::prolog_var: 
+    case var_expr::local_var:
+    {
+      if (!e->willBeSerialized())
+      {
+        e->setWillBeSerialized(ANNOTATION_TRUE);
+
+        std::vector<expr*>::const_iterator ite = e->setExprsBegin();
+        std::vector<expr*>::const_iterator end = e->setExprsEnd();
+
+        for (; ite != end; ++ite)
+        {
+          expr* setExpr = *ite;
+
+          if (setExpr->get_expr_kind() == var_decl_expr_kind)
+          {
+            markForSerialization(static_cast<var_decl_expr*>(setExpr)->get_init_expr());
+          }
+          else
+          {
+            assert(setExpr->get_expr_kind() == var_set_expr_kind);
+
+            markForSerialization(static_cast<var_set_expr*>(setExpr)->get_expr());
+          }
+        }
+      }
+      return;
+    }
+
+    case var_expr::wincond_in_pos_var:
+    case var_expr::wincond_out_pos_var:
+    case var_expr::pos_var:
+    case var_expr::score_var:
+    case var_expr::count_var:
+    case var_expr::eval_var:
+    default:
+    {
+      ZORBA_ASSERT(false);
+      return;
+    }
+    }
+  }
+
+  case doc_expr_kind:
+  case elem_expr_kind:
+  case attr_expr_kind:
+  case text_expr_kind:
+  case pi_expr_kind:
+  {
+    break;
+  }
+
+  case relpath_expr_kind:
+  {
+    relpath_expr* e = static_cast<relpath_expr *>(node);
+    e->setWillBeSerialized(ANNOTATION_TRUE);
+    markForSerialization((*e)[0]);
+    return;
+  }
+
+  case gflwor_expr_kind:
+  case flwor_expr_kind:
+  {
+    flwor_expr* e = static_cast<flwor_expr *>(node);
+    e->setWillBeSerialized(ANNOTATION_TRUE);
+    markForSerialization(e->get_return_expr());
+    return;
+  }
+
+  case if_expr_kind:
+  case trycatch_expr_kind:
+  {
+    break;
+  }
+
+  case fo_expr_kind:
+  {
+    fo_expr* e = static_cast<fo_expr *>(node);
+    function* f = e->get_func();
+
+    e->setWillBeSerialized(ANNOTATION_TRUE);
+
+    if (f->isUdf())
+    {
+      user_function* udf = static_cast<user_function*>(f);
+      expr* body = udf->getBody();
+
+      if (!body->willBeSerialized())
+      {
+        markForSerialization(body);
+      }
+
+      std::vector<var_expr_t>::const_iterator ite = udf->getArgVars().begin();
+      std::vector<var_expr_t>::const_iterator end = udf->getArgVars().end();
+      for (; ite != end; ++ite)
+      {
+        expr* argVar = (*ite).getp();
+        if (argVar->willBeSerialized())
+        {
+          expr* argExpr = e->get_arg(ite - udf->getArgVars().begin());
+          markForSerialization(argExpr);
+        }
+      }
+    } // f->isUdf()
+    else
+    {
+      csize numArgs = e->num_args();
+      for (csize i = 0; i < numArgs; ++i)
+      {
+        if (f->propagatesInputNodes(e, i))
+        {
+          markForSerialization(e->get_arg(i));
+        }
+      }
+    }
+
+    return;
+  }
+
+  case promote_expr_kind:
+  case treat_expr_kind:
+  case order_expr_kind:
+  case wrapper_expr_kind:
+  case function_trace_expr_kind:
+  case extension_expr_kind:
+  {
+    break;
+  }
+
+  case validate_expr_kind:
+  {
+    node->setWillBeSerialized(ANNOTATION_TRUE);
+    return;
+  }
+
+  case transform_expr_kind:
+  {
+    transform_expr* e = static_cast<transform_expr *>(node);
+    e->setWillBeSerialized(ANNOTATION_TRUE);
+    markForSerialization(e->getReturnExpr());
+    return;
+  }
+
+  case block_expr_kind:
+  {
+    block_expr* e = static_cast<block_expr *>(node);
+    e->setWillBeSerialized(ANNOTATION_TRUE);
+    expr* lastChild = (*e)[e->size()-1];
+    markForSerialization(lastChild);
+    return;
+  }
+
+  case var_decl_expr_kind:
+  case var_set_expr_kind:
+  {
+    return;
+  }
+
+  case apply_expr_kind:
+  {
+    break;
+  }
+
+  case exit_catcher_expr_kind: 
+  {
+    exit_catcher_expr* e = static_cast<exit_catcher_expr*>(node);
+
+    std::vector<expr*>::const_iterator ite = e->exitExprsBegin();
+    std::vector<expr*>::const_iterator end = e->exitExprsEnd();
+
+    for (; ite != end; ++ite)
+    {
+      exit_expr* ex = static_cast<exit_expr*>(*ite);
+
+      markForSerialization(ex->get_expr());
+    }
+
+    break;
+  }
+
+
+  case eval_expr_kind:
+  {
+    eval_expr* e = static_cast<eval_expr*>(node);
+
+    csize numVars = e->var_count();
+
+    for (csize i = 0; i < numVars; ++i)
+    {
+      markForSerialization(e->get_arg_expr(i));
+    }
+
+    std::vector<var_expr_t> globalVars;
+    e->get_sctx()->getVariables(globalVars, true, true);
+  
+    FOR_EACH(std::vector<var_expr_t>, ite, globalVars)
+    {
+      var_expr* globalVar = (*ite).getp();
+      markForSerialization(globalVar);
+    }
+
+    return;
+  }
+
+  case dynamic_function_invocation_expr_kind:
+  {
+    dynamic_function_invocation_expr* e = 
+    static_cast<dynamic_function_invocation_expr*>(node);
+
+    const std::vector<expr_t>& args = e->get_args();
+
+    FOR_EACH(std::vector<expr_t>, ite, args)
+    {
+      markForSerialization((*ite).getp());
+    }
+
+    break;
+  }
+
+  case function_item_expr_kind:
+  {
+    function_item_expr* e = static_cast<function_item_expr*>(node);
+
+    user_function* udf = static_cast<user_function*>(e->get_function());
+
+    UDFCallChain dummyUdfCaller;
+
+    markForSerialization(udf->getBody());
+
+    return;
+  }
+
+#if 0
+  case debugger_expr_kind:
+    break;
+#endif
+
+  case castable_expr_kind:
+  case cast_expr_kind:
+  case instanceof_expr_kind:
+  case name_cast_expr_kind:
+  case axis_step_expr_kind:
+  case match_expr_kind:
+  case delete_expr_kind:
+  case rename_expr_kind:
+  case insert_expr_kind:
+  case replace_expr_kind:
+  case while_expr_kind:
+  case flowctl_expr_kind:
+  case exit_expr_kind:
+  case ft_expr_kind:
+  default:
+    ZORBA_ASSERT(false);
+  }
+
+  node->setWillBeSerialized(ANNOTATION_TRUE);
+
+  ExprIterator iter(node);
+  while(!iter.done()) 
+  {
+    expr* child = (*iter).getp();
+    if (child != NULL) 
+    {
+      markForSerialization(child);
+    }
+    iter.next();
+  }
+
+  return;
+}
+
+
 }
 /* vim:set et sw=2 ts=2: */

=== modified file 'src/compiler/rewriter/rules/path_rules.cpp'
--- src/compiler/rewriter/rules/path_rules.cpp	2011-08-12 10:21:10 +0000
+++ src/compiler/rewriter/rules/path_rules.cpp	2011-11-29 22:22:26 +0000
@@ -29,17 +29,17 @@
   relpath_expr* re = dynamic_cast<relpath_expr *>(node);
   if (re != NULL) 
   {
-    ulong numSteps = (ulong)re->size();
+    csize numSteps = re->size();
     
-    for (ulong i = 0; i < numSteps - 1; i++) 
+    for (csize i = 0; i < numSteps - 1; i++) 
     {
-      axis_step_expr* axisStep = dynamic_cast<axis_step_expr*>((*re)[i].getp());
+      axis_step_expr* axisStep = dynamic_cast<axis_step_expr*>((*re)[i]);
       
       if (axisStep != NULL &&
           axisStep->getAxis() == axis_kind_descendant_or_self &&
           axisStep->getTest()->getTestKind() == match_anykind_test)
       {
-        axis_step_expr* nextStep = dynamic_cast<axis_step_expr*>((*re)[i+1].getp());
+        axis_step_expr* nextStep = dynamic_cast<axis_step_expr*>((*re)[i+1]);
         if (nextStep != NULL &&
             nextStep->getAxis() == axis_kind_child)
         {

=== modified file 'src/compiler/rewriter/rules/rule_base.h'
--- src/compiler/rewriter/rules/rule_base.h	2011-06-14 17:26:33 +0000
+++ src/compiler/rewriter/rules/rule_base.h	2011-11-29 22:22:26 +0000
@@ -38,6 +38,7 @@
     MarkConsumerNodeProps,
     MarkProducerNodeProps,
     EliminateNodeOps,
+    MarkNodeCopyProps,
     ReplaceExprWithConstantOneWhenPossible,
     SpecializeOperations,
     EliminateTypeEnforcingOperations,

=== modified file 'src/compiler/rewriter/rules/ruleset.h'
--- src/compiler/rewriter/rules/ruleset.h	2011-11-10 14:06:57 +0000
+++ src/compiler/rewriter/rules/ruleset.h	2011-11-29 22:22:26 +0000
@@ -28,6 +28,10 @@
 namespace zorba 
 {
 
+
+class SourceFinder;
+
+
 PREPOST_RULE(EchoNodes);
 
 PREPOST_RULE(PlanPrinter);
@@ -123,6 +127,32 @@
 /*******************************************************************************
 
 ********************************************************************************/
+class MarkNodeCopyProps : public RewriteRule 
+{
+protected:
+  SourceFinder  * theSourceFinder;
+
+public:
+  MarkNodeCopyProps() 
+    :
+    RewriteRule(RewriteRule::MarkNodeCopyProps, "MarkNodeCopyProps")
+  {
+  }
+
+  expr_t apply(RewriterContext& rCtx, expr* node, bool& modified);
+
+protected:
+  void applyInternal(RewriterContext& rCtx, expr* node, UDFCallChain& udfCaller);
+
+  void markSources(const std::vector<expr*>& sources);
+
+  void markForSerialization(expr* node);
+};
+
+
+/*******************************************************************************
+
+********************************************************************************/
 class HoistRule : public RewriteRule 
 {
 public:

=== modified file 'src/compiler/rewriter/tools/dataflow_annotations.cpp'
--- src/compiler/rewriter/tools/dataflow_annotations.cpp	2011-11-17 16:32:04 +0000
+++ src/compiler/rewriter/tools/dataflow_annotations.cpp	2011-11-29 22:22:26 +0000
@@ -21,13 +21,16 @@
 #include "compiler/expression/flwor_expr.h"
 #include "compiler/expression/script_exprs.h"
 #include "compiler/expression/update_exprs.h"
+#include "compiler/expression/function_item_expr.h"
 #include "compiler/expression/expr_iter.h"
 
 #include "compiler/rewriter/tools/dataflow_annotations.h"
+#include "compiler/rewriter/framework/rewriter_context.h"
 
 #include "types/typeops.h"
 
 #include "functions/function.h"
+#include "functions/udf.h"
 #include "functions/library.h"
 
 #include "diagnostics/assert.h"
@@ -36,6 +39,7 @@
 namespace zorba 
 {
 
+
 #define SORTED_NODES(e) \
 e->setProducesSortedNodes(ANNOTATION_TRUE)
 
@@ -621,7 +625,7 @@
 
     for (ulong i = 1; i < num_steps; ++i) 
     {
-      axis_step_expr* ase = dynamic_cast<axis_step_expr *>((*e)[i].getp());
+      axis_step_expr* ase = dynamic_cast<axis_step_expr *>((*e)[i]);
       assert(ase != NULL);
 
       reverse_axes = reverse_axes || ase->is_reverse_axis();
@@ -747,7 +751,7 @@
 
 void DataflowAnnotationsComputer::compute_text_expr(text_expr* e)
 {
-  default_walk(e);
+ default_walk(e);
   SORTED_NODES(e);
   DISTINCT_NODES(e);
 }
@@ -760,5 +764,474 @@
   DISTINCT_NODES(e);
 }
 
+
+////////////////////////////////////////////////////////////////////////////////
+//                                                                            //
+//                                                                            //
+//                                                                            //
+////////////////////////////////////////////////////////////////////////////////
+
+
+SourceFinder::~SourceFinder()
+{
+  UdfSourcesMap::iterator ite = theUdfSourcesMap.begin();
+  UdfSourcesMap::iterator end = theUdfSourcesMap.end();
+  for (; ite != end; ++ite)
+  {
+    delete ite->second;
+  }
+}
+
+
+/*******************************************************************************
+  If the result of the given expr may contain costructed nodes, find the node-
+  constructor exprs where such nodes may come from. 
+
+  If "node" is inside a UDF, "udfCaller" contains the fo expr that invoked that
+  UDF.
+********************************************************************************/
+void SourceFinder::findNodeSources(
+    expr* node,
+    UDFCallChain* udfCaller,
+    std::vector<expr*>& sources)
+{
+  findNodeSourcesRec(node, sources, NULL);
+
+  for (csize i = 0; i < sources.size(); ++i)
+  {
+    expr* source = sources[i];
+
+    if (source->get_expr_kind() == var_expr_kind)
+    {
+      var_expr* varExpr = static_cast<var_expr*>(source);
+
+      ZORBA_ASSERT(udfCaller != NULL);
+      ZORBA_ASSERT(varExpr->get_kind() == var_expr::arg_var);
+
+      sources.erase(sources.begin() + i);
+      --i;
+
+      // If this method is called to find the sources of an expr within the
+      // body of a function_item. then udfCaller->theFo will be NULL. 
+      if (udfCaller->theFo)
+      {
+        ZORBA_ASSERT(varExpr->get_udf() == udfCaller->theFo->get_func());
+
+        fo_expr* foExpr = udfCaller->theFo;
+        expr* foArg = foExpr->get_arg(varExpr->get_param_pos());
+        std::vector<expr*> argSources;
+        findNodeSources(foArg, udfCaller->thePrev, argSources);
+
+        sources.insert(sources.end(), argSources.begin(), argSources.end());
+      }
+    }
+    else
+    {
+      ZORBA_ASSERT(source->get_expr_kind() == doc_expr_kind ||
+                   source->get_expr_kind() == elem_expr_kind);
+    }
+  }
+}
+
+
+void SourceFinder::findNodeSourcesRec(
+    expr* node,
+    std::vector<expr*>& sources,
+    user_function* currentUdf)
+{
+  TypeManager* tm = node->get_type_manager();
+  RootTypeManager& rtm = GENV_TYPESYSTEM;
+
+  xqtref_t retType = node->get_return_type();
+
+  if (TypeOps::is_subtype(tm, *retType, *rtm.ANY_ATOMIC_TYPE_STAR, node->get_loc()))
+    return;
+
+  switch(node->get_expr_kind()) 
+  {
+  case const_expr_kind:
+  {
+    return;
+  }
+
+  case var_expr_kind:
+  {
+    var_expr* e = static_cast<var_expr*>(node);
+
+    switch (e->get_kind())
+    {
+    case var_expr::for_var:
+    case var_expr::let_var:
+    case var_expr::win_var:
+    case var_expr::wincond_out_var:
+    case var_expr::wincond_in_var:
+    case var_expr::groupby_var:
+    case var_expr::non_groupby_var:
+    {
+      VarSourcesMap::iterator ite = theVarSourcesMap.find(e);
+
+      if (ite == theVarSourcesMap.end())
+      {
+        std::vector<expr*> varSources;
+        findNodeSourcesRec(e->get_domain_expr(), varSources, currentUdf);
+
+        ite = (theVarSourcesMap.insert(VarSourcesPair(e, varSources))).first;
+      }
+
+      std::vector<expr*>::iterator ite2 = (*ite).second.begin();
+      std::vector<expr*>::iterator end2 = (*ite).second.end();
+      for (; ite2 != end2; ++ite2)
+      {
+        if (std::find(sources.begin(), sources.end(), *ite2) == sources.end())
+          sources.push_back(*ite2);
+      }
+
+      return;
+    }
+
+    case var_expr::wincond_in_pos_var:
+    case var_expr::wincond_out_pos_var:
+    case var_expr::pos_var:
+    case var_expr::score_var:
+    case var_expr::count_var:
+    {
+      return;
+    }
+
+    case var_expr::copy_var:
+    {
+      // A copy var holds a standalone copy of the node produced by its domain
+      // expr. Although such a copy is a constructed tree, it was not constructed
+      // by node-constructor exprs, and as a resylt, a copy var is not a source.
+      return;
+    }
+
+    case var_expr::arg_var:
+    {
+      if (std::find(sources.begin(), sources.end(), node) == sources.end())
+        sources.push_back(node);
+
+      return;
+    }
+
+    case var_expr::prolog_var: 
+    case var_expr::local_var:
+    {
+      VarSourcesMap::iterator ite = theVarSourcesMap.find(e);
+
+      if (ite == theVarSourcesMap.end())
+      {
+        std::vector<expr*> varSources;
+        theVarSourcesMap.insert(VarSourcesPair(e, varSources));
+
+        std::vector<expr*>::const_iterator ite2 = e->setExprsBegin();
+        std::vector<expr*>::const_iterator end2 = e->setExprsEnd();
+
+        for (; ite2 != end2; ++ite2)
+        {
+          expr* setExpr = *ite2;
+
+          if (setExpr->get_expr_kind() == var_decl_expr_kind)
+          {
+            findNodeSourcesRec(static_cast<var_decl_expr*>(setExpr)->get_init_expr(),
+                               varSources,
+                               currentUdf);
+          }
+          else
+          {
+            assert(setExpr->get_expr_kind() == var_set_expr_kind);
+
+            findNodeSourcesRec(static_cast<var_set_expr*>(setExpr)->get_expr(),
+                               varSources,
+                               currentUdf);
+          }
+        }
+
+        ite = theVarSourcesMap.find(e);
+        
+        (*ite).second.insert((*ite).second.end(), varSources.begin(), varSources.end());
+      }
+
+      sources.insert(sources.end(), (*ite).second.begin(), (*ite).second.end());
+
+      return;
+    }
+
+    case var_expr::catch_var:
+    {
+      // If in the try clause there is an fn:error that generates nodes, it will 
+      // be (conservatively) treated as a "must copy" function, so all of those
+      // nodes will be in standalone trees.
+      return;
+    }
+
+    case var_expr::eval_var: // TODO
+    default:
+    {
+      ZORBA_ASSERT(false);
+    }
+    }
+
+    break;
+  }
+
+  case doc_expr_kind:
+  case elem_expr_kind:
+  {
+    if (std::find(sources.begin(), sources.end(), node) == sources.end())
+      sources.push_back(node);
+
+    break;
+  }
+
+  case attr_expr_kind:
+  case text_expr_kind:
+  case pi_expr_kind:
+  {
+    return;
+  }
+
+  case relpath_expr_kind:
+  {
+    relpath_expr* e = static_cast<relpath_expr *>(node);
+    findNodeSourcesRec((*e)[0], sources, currentUdf);
+    return;
+  }
+
+  case gflwor_expr_kind:
+  case flwor_expr_kind:
+  {
+    flwor_expr* e = static_cast<flwor_expr *>(node);
+
+    // We don't need to drill down to the domain exprs of variables that
+    // are not referenced in the return clause.
+    findNodeSourcesRec(e->get_return_expr(), sources, currentUdf);
+    return;
+  }
+
+  case if_expr_kind:
+  {
+    if_expr* e = static_cast<if_expr *>(node);
+    findNodeSourcesRec(e->get_then_expr(), sources, currentUdf);
+    findNodeSourcesRec(e->get_else_expr(), sources, currentUdf);
+    return;
+  }
+
+  case trycatch_expr_kind:
+  {
+    break;
+  }
+
+  case fo_expr_kind:
+  {
+    fo_expr* e = static_cast<fo_expr *>(node);
+    function* f = e->get_func();
+
+    if (f->isUdf())
+    {
+      user_function* udf = static_cast<user_function*>(f);
+ 
+      bool recursive = (currentUdf ? currentUdf->isMutuallyRecursiveWith(udf) : false);
+
+      UdfSourcesMap::iterator ite = theUdfSourcesMap.find(udf);
+
+      std::vector<expr*>* udfSources;
+
+      if (ite == theUdfSourcesMap.end() ||
+          (recursive &&
+           std::find(theUdfCallPath.begin(), theUdfCallPath.end(), e) ==
+           theUdfCallPath.end()))
+      {
+        if (recursive)
+          theUdfCallPath.push_back(e);
+
+        // must do this before calling findNodeSourcesRec in order to break
+        // recursion cycle
+        if (ite == theUdfSourcesMap.end())
+        {
+          udfSources = new std::vector<expr*>;
+          theUdfSourcesMap.insert(UdfSourcesPair(udf, udfSources));
+        }
+        else
+        {
+          udfSources = (*ite).second;
+        }
+
+        findNodeSourcesRec(udf->getBody(), *udfSources, udf);
+
+        if (recursive)
+          theUdfCallPath.pop_back();
+      }
+      else
+      {
+        udfSources = (*ite).second;
+      }
+
+      csize numUdfSources = udfSources->size();
+
+      for (csize i = 0; i < numUdfSources; ++i)
+      {
+        expr* source = (*udfSources)[i];
+
+        if (source->get_expr_kind() == var_expr_kind)
+        {
+          var_expr* argVar = static_cast<var_expr*>(source);
+
+          ZORBA_ASSERT(argVar->get_kind() == var_expr::arg_var);
+
+          expr* argExpr = e->get_arg(argVar->get_param_pos());
+
+          findNodeSourcesRec(argExpr, sources, currentUdf);
+        }
+        else
+        {
+          if (std::find(sources.begin(), sources.end(), source) == sources.end())
+            sources.push_back(source);
+        }
+      }
+    } // f->isUdf()
+    else
+    {
+      csize numArgs = e->num_args();
+      for (csize i = 0; i < numArgs; ++i)
+      {
+        if (f->propagatesInputNodes(e, i))
+        {
+          findNodeSourcesRec(e->get_arg(i), sources, currentUdf);
+        }
+      }
+    }
+
+    return;
+  }
+
+  case promote_expr_kind:
+  case treat_expr_kind:
+  case order_expr_kind:
+  case wrapper_expr_kind:
+  case function_trace_expr_kind:
+  case extension_expr_kind:
+  case validate_expr_kind:
+  {
+    break;
+  }
+
+  case transform_expr_kind:
+  {
+    transform_expr* e = static_cast<transform_expr*>(node);
+
+    findNodeSourcesRec(e->getReturnExpr(), sources, currentUdf);
+
+    return;
+  }
+
+  case block_expr_kind:
+  {
+    block_expr* e = static_cast<block_expr*>(node);
+
+    findNodeSourcesRec((*e)[e->size()-1], sources, currentUdf);
+
+    return;
+  }
+
+  case var_decl_expr_kind:
+  case var_set_expr_kind:
+  {
+    return;
+  }
+
+  case apply_expr_kind:
+  {
+    break;
+  }
+
+  case exit_catcher_expr_kind: 
+  {
+    exit_catcher_expr* e = static_cast<exit_catcher_expr*>(node);
+
+    std::vector<expr*>::const_iterator ite = e->exitExprsBegin();
+    std::vector<expr*>::const_iterator end = e->exitExprsEnd();
+
+    for (; ite != end; ++ite)
+    {
+      exit_expr* ex = static_cast<exit_expr*>(*ite);
+
+      findNodeSourcesRec(ex->get_expr(), sources, currentUdf);
+    }
+
+    break;
+  }
+
+  case eval_expr_kind:
+  {
+    eval_expr* e = static_cast<eval_expr*>(node);
+    e->setNodeCopy(true);
+    return;
+  }
+
+  case dynamic_function_invocation_expr_kind:
+  {
+    // Conservatively assume that the function item that is going to be executed
+    // is going to propagate its inputs, so find the sources in the arguments.
+    // TODO: look for function_item_expr in the subtree to check if this assumption
+    // is really true. 
+    dynamic_function_invocation_expr* e = 
+    static_cast<dynamic_function_invocation_expr*>(node);
+
+    const std::vector<expr_t>& args = e->get_args();
+
+    FOR_EACH(std::vector<expr_t>, ite, args)
+    {
+      std::vector<expr*> sources;
+      findNodeSourcesRec((*ite).getp(), sources, currentUdf);
+    }
+
+    break;
+  }
+
+  case function_item_expr_kind:
+  {
+    function_item_expr* e = static_cast<function_item_expr*>(node);
+
+    return;
+  }
+
+#if 0
+  case debugger_expr_kind:
+    break;
+#endif
+    
+  case castable_expr_kind:
+  case cast_expr_kind:
+  case instanceof_expr_kind:
+  case name_cast_expr_kind:
+  case axis_step_expr_kind:
+  case match_expr_kind:
+  case delete_expr_kind:
+  case insert_expr_kind:
+  case rename_expr_kind:
+  case replace_expr_kind:
+  case while_expr_kind:
+  case exit_expr_kind:
+  case flowctl_expr_kind:
+#ifndef ZORBA_NO_FULL_TEXT
+  case ft_expr_kind:
+#endif
+  default:
+    ZORBA_ASSERT(false);
+  }
+
+  ExprIterator iter(node);
+  while(!iter.done()) 
+  {
+    expr* child = (*iter).getp();
+    if (child != NULL) 
+    {
+      findNodeSourcesRec(child, sources, currentUdf);
+    }
+    iter.next();
+  }
+}
+
 }
 /* vim:set et sw=2 ts=2: */

=== modified file 'src/compiler/rewriter/tools/dataflow_annotations.h'
--- src/compiler/rewriter/tools/dataflow_annotations.h	2011-11-17 16:32:04 +0000
+++ src/compiler/rewriter/tools/dataflow_annotations.h	2011-11-29 22:22:26 +0000
@@ -22,6 +22,10 @@
 namespace zorba 
 {
 
+class UDFCallChain;
+
+
+
 class DataflowAnnotationsComputer 
 {
 public:
@@ -64,8 +68,37 @@
   bool generic_compute(expr* e);
 };
 
+
+class SourceFinder
+{
+  typedef std::map<var_expr*, std::vector<expr*> > VarSourcesMap;
+  typedef std::pair<var_expr*, std::vector<expr*> > VarSourcesPair;
+
+  typedef std::map<user_function*, std::vector<expr*>* > UdfSourcesMap;
+  typedef std::pair<user_function*, std::vector<expr*>* > UdfSourcesPair;
+
+protected:
+  VarSourcesMap                theVarSourcesMap;
+  UdfSourcesMap                theUdfSourcesMap;
+  std::vector<fo_expr*>        theUdfCallPath;
+
+protected:
+  void findNodeSourcesRec(
+      expr* node,
+      std::vector<expr*>& sources,
+      user_function* currentUdf);
+
+public:
+  ~SourceFinder();
+
+  void findNodeSources(
+      expr* inExpr,
+      UDFCallChain* udfChain,
+      std::vector<expr*>& sources);
+};
+
+
 }
-
 #endif /* ZORBA_DATAFLOW_ANNOTATIONS_H */
 
 /*

=== modified file 'src/compiler/rewriter/tools/expr_tools.cpp'
--- src/compiler/rewriter/tools/expr_tools.cpp	2011-11-17 16:32:04 +0000
+++ src/compiler/rewriter/tools/expr_tools.cpp	2011-11-29 22:22:26 +0000
@@ -19,6 +19,9 @@
 #include "compiler/rewriter/framework/rewriter_context.h"
 #include "compiler/expression/flwor_expr.h"
 #include "compiler/expression/expr.h"
+#include "compiler/expression/path_expr.h"
+#include "compiler/expression/ft_expr.h"
+#include "compiler/expression/ftnode.h"
 #include "compiler/expression/expr_iter.h"
 
 #include "functions/func_errors_and_diagnostics.h"
@@ -201,6 +204,13 @@
 }
 
 
+/////////////////////////////////////////////////////////////////////////////////
+//                                                                             //
+//                                                                             //
+//                                                                             //
+/////////////////////////////////////////////////////////////////////////////////
+
+
 /*******************************************************************************
   Let FLWOR(e) be the set of flwor exprs within the expr tree rooted at expr e.
   Let FV(e) be the set of variables defined in any of the flwor exprs in FLWOR(e).
@@ -523,6 +533,526 @@
 }
 
 
+/////////////////////////////////////////////////////////////////////////////////
+//                                                                             //
+//                                                                             //
+//                                                                             //
+/////////////////////////////////////////////////////////////////////////////////
+
+
+#if 0
+/*******************************************************************************
+
+********************************************************************************/
+static void set_must_copy(expr* target, BoolAnnotationValue v) 
+{
+  assert(v != ANNOTATION_UNKNOWN);
+
+  if (target == NULL)
+    return;
+
+  switch (target->getMustCopyNodes())
+  {
+  case ANNOTATION_UNKNOWN:
+  {
+    target->setMustCopyNodes(v);
+    return;
+  }
+  case ANNOTATION_TRUE_FIXED:
+  {
+    return;
+  }
+  case ANNOTATION_TRUE:
+  {
+    if (v == ANNOTATION_TRUE_FIXED)
+      target->setMustCopyNodes(v);
+
+    return;
+  }
+  case ANNOTATION_FALSE:
+  {
+    target->setMustCopyNodes(v);
+    return;
+  }
+  }
+}
+
+
+/*******************************************************************************
+  If the no-node-copy annotation of the target expr is not set to false
+  already, set it to the value of the no-node-copy annotations of the
+  source expr.
+********************************************************************************/
+static void pushdown_must_copy(expr* src, expr* target) 
+{
+  set_must_copy(target, src->getMustCopyNodes());
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+static void pushdown_window_vars(const flwor_wincond* cond, expr* target) 
+{
+  const flwor_wincond::vars& inVars = cond->get_in_vars();
+
+  if (inVars.curr)
+    pushdown_must_copy(inVars.curr.getp(), target);
+
+  if (inVars.prev)
+    pushdown_must_copy(inVars.prev.getp(), target);
+
+  if (inVars.next)
+    pushdown_must_copy(inVars.next.getp(), target);
+
+  const flwor_wincond::vars& outVars = cond->get_out_vars();
+
+  if (outVars.curr)
+    pushdown_must_copy(outVars.curr.getp(), target);
+
+  if (outVars.prev)
+    pushdown_must_copy(outVars.prev.getp(), target);
+  
+  if (outVars.next)
+    pushdown_must_copy(outVars.next.getp(), target);
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+void computeMustCopyProperty(expr* inExpr)
+{
+  switch(inExpr->get_expr_kind()) 
+  {
+  case const_expr_kind:
+  {
+    return;
+  }
+
+  case var_expr_kind:
+  {
+    var_expr* e = static_cast<var_expr*>(inExpr);
+
+    switch (e->get_kind())
+    {
+    case var_expr::for_var:
+    case var_expr::let_var:
+    case var_expr::pos_var:
+    case var_expr::win_var:
+    case var_expr::score_var:
+    case var_expr::wincond_out_var:
+    case var_expr::wincond_out_pos_var:
+    case var_expr::wincond_in_var:
+    case var_expr::wincond_in_pos_var:
+    case var_expr::count_var:
+    case var_expr::groupby_var:
+    case var_expr::non_groupby_var:
+    case var_expr::copy_var:
+    {
+      return;
+    }
+
+    case var_expr::arg_var:
+    {
+      return;
+      //expr* argExpr = argExprs[e->get_param_pos()];
+      //pushdown_no_node_copy(inExpr, argExpr);
+    }
+
+    case var_expr::prolog_var: 
+    case var_expr::local_var:
+    {
+      // TODO: pass into this function a map with one entry per in-scope var.
+      // The entry maps the var to the most recently encountered assignment 
+      // expr for this var. 
+      return;
+    }
+
+    case var_expr::catch_var:
+    {
+      // TODO: associate the catch var with the try clause and keep track inside the
+      // try_catch expr of all the fn:error() calls that return an item()* seq.
+      return;
+    }
+
+    case var_expr::eval_var: // TODO
+    default:
+    {
+      ZORBA_ASSERT(false);
+    }
+    }
+
+    break;
+  }
+
+  case doc_expr_kind:
+  {
+    doc_expr* e = static_cast<doc_expr*>(inExpr);
+    pushdown_must_copy(inExpr, e->getContent());
+    break;
+  }
+
+  case elem_expr_kind:
+  {
+    elem_expr* e = static_cast<elem_expr*>(inExpr);
+    pushdown_must_copy(inExpr, e->getContent());
+    pushdown_must_copy(inExpr, e->getAttrs());
+    set_must_copy(e->getQNameExpr(), ANNOTATION_FALSE);
+    break;
+  }
+
+  case attr_expr_kind:
+  {
+    attr_expr* e = static_cast<attr_expr*>(inExpr);
+    pushdown_must_copy(inExpr, e->getValueExpr());
+    set_must_copy(e->getQNameExpr(), ANNOTATION_FALSE);
+    break;
+  }
+
+  case text_expr_kind:
+  {
+    text_expr* e = static_cast<text_expr*>(inExpr);
+    set_must_copy(e->get_text(), ANNOTATION_FALSE);
+    break;
+  }
+
+  case pi_expr_kind:
+  {
+    pi_expr* e = static_cast<pi_expr*>(inExpr);
+    set_must_copy(e->get_target_expr(), ANNOTATION_FALSE);
+    set_must_copy(e->get_content_expr(), ANNOTATION_FALSE);
+    break;
+  }
+
+  case relpath_expr_kind:
+  {
+    const relpath_expr* e = static_cast<const relpath_expr*>(inExpr);
+
+    std::vector<expr_t>::const_iterator ite = e->begin();
+    std::vector<expr_t>::const_iterator end = e->end();
+
+    for (++ite; ite != end; ++ite)
+    {
+      axis_step_expr* axisExpr = static_cast<axis_step_expr*>((*ite).getp());
+      axis_kind_t axisKind = axisExpr->getAxis();
+
+      if (axisKind != axis_kind_child &&
+          axisKind != axis_kind_descendant &&
+          axisKind != axis_kind_self &&
+          axisKind != axis_kind_attribute)
+      {
+        set_must_copy((*e)[0].getp(), ANNOTATION_TRUE_FIXED);
+        break;
+      }
+    }
+
+    break;
+  }
+
+  case flwor_expr_kind:
+  case gflwor_expr_kind:
+  {
+    flwor_expr* e = static_cast<flwor_expr*>(inExpr);
+
+    pushdown_must_copy(inExpr, e->get_return_expr());
+
+    csize i = e->num_clauses();
+    for (; i > 0; --i)
+    {
+      flwor_clause* clause = e->get_clause(i-1);
+
+      switch(clause->get_kind())
+      {
+      case flwor_clause::for_clause:
+      {
+        for_clause* fc = static_cast<for_clause*>(clause);
+        pushdown_must_copy(fc->get_var(), fc->get_expr());
+        computeMustCopyProperty(fc->get_expr());
+        break;
+      }
+      case flwor_clause::let_clause:
+      {
+        let_clause* lc = static_cast<let_clause*>(clause);
+        pushdown_must_copy(lc->get_var(), lc->get_expr());
+        computeMustCopyProperty(lc->get_expr());
+        break;
+      }
+      case flwor_clause::window_clause:
+      {
+        window_clause* wc = static_cast<window_clause*>(clause);
+
+        pushdown_must_copy(wc->get_var(), wc->get_expr());
+
+        const flwor_wincond* startCond = wc->get_win_start();
+        const flwor_wincond* endCond = wc->get_win_start();
+
+        if (startCond)
+        {
+          set_must_copy(startCond->get_cond(), ANNOTATION_FALSE);
+
+          computeMustCopyProperty(startCond->get_cond());
+
+          pushdown_window_vars(startCond, wc->get_expr());
+        }
+
+        if (endCond)
+        {
+          set_must_copy(endCond->get_cond(), ANNOTATION_FALSE);
+
+          computeMustCopyProperty(endCond->get_cond());
+
+          pushdown_window_vars(endCond, wc->get_expr());
+        }
+
+        computeMustCopyProperty(wc->get_expr());
+        break;
+      }
+      case flwor_clause::where_clause:
+      {
+        where_clause* cc = static_cast<where_clause*>(clause);
+        set_must_copy(cc->get_expr(), ANNOTATION_FALSE);
+        computeMustCopyProperty(cc->get_expr());
+        break;
+      }
+      case flwor_clause::group_clause:
+      {
+        group_clause* gc = static_cast<group_clause*>(clause);
+
+        flwor_clause::rebind_list_t::iterator ite = gc->beginGroupVars();
+        flwor_clause::rebind_list_t::iterator end = gc->endGroupVars();
+
+        for (; ite != end; ++ite)
+        {
+          pushdown_must_copy((*ite).second.getp(), (*ite).first.getp());
+        }
+
+        ite = gc->beginNonGroupVars();
+        end = gc->endNonGroupVars();
+
+        for (; ite != end; ++ite)
+        {
+          pushdown_must_copy((*ite).second.getp(), (*ite).first.getp());
+        }
+
+        break;
+      }
+      case flwor_clause::order_clause:
+      {
+        orderby_clause* ob = static_cast<orderby_clause*>(clause);
+
+        std::vector<expr_t>::iterator ite = ob->begin();
+        std::vector<expr_t>::iterator end = ob->end();
+
+        for (; ite != end; ++ite)
+        {
+          set_must_copy((*ite), ANNOTATION_FALSE);
+          computeMustCopyProperty(*ite);
+        }
+        break;
+      }
+      case flwor_clause::count_clause:
+      {
+        break;
+      }
+      default:
+        ZORBA_ASSERT(false);
+      }
+    }
+
+    return;
+  }
+
+  case if_expr_kind:
+  {
+    if_expr* e = static_cast<if_expr*>(inExpr);
+    pushdown_must_copy(inExpr, e->get_cond_expr());
+    pushdown_must_copy(inExpr, e->get_then_expr());
+    pushdown_must_copy(inExpr, e->get_else_expr());
+    break;
+  }
+
+  case trycatch_expr_kind:
+  {
+    trycatch_expr* e = static_cast<trycatch_expr*>(inExpr);
+    pushdown_must_copy(inExpr, e->get_try_expr());
+
+    csize numCatches = e->clause_count();
+    for (csize i = 0; i < numCatches; ++i)
+    {
+      pushdown_must_copy(inExpr, e->get_catch_expr(i));
+    }
+    break;
+  }
+
+  case fo_expr_kind:
+  {
+    fo_expr* e = static_cast<fo_expr*>(inExpr);
+    function* func = e->get_func();
+
+    csize numArgs = e->num_args();
+
+    for (csize i = 0; i < numArgs; ++i)
+    {
+      set_must_copy(e->get_arg(i), func->mustCopyInputNodes(e, i));
+    }
+
+    break;
+  }
+
+  case dynamic_function_invocation_expr_kind:
+  case function_item_expr_kind:
+  {
+    ZORBA_ASSERT(false); // TODO
+  }
+
+  case castable_expr_kind:
+  case instanceof_expr_kind:
+  case cast_expr_kind:
+  {
+    cast_or_castable_base_expr* e = static_cast<cast_or_castable_base_expr*>(inExpr);
+    set_must_copy(e, ANNOTATION_FALSE);
+    pushdown_must_copy(inExpr, e->get_input());
+    break;
+  }
+
+  case treat_expr_kind:
+  case promote_expr_kind:
+  {
+    cast_base_expr* e = static_cast<cast_base_expr*>(inExpr);
+
+    if (TypeOps::is_subtype(e->get_type_manager(),
+                            *e->get_target_type(),
+                            *GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_STAR))
+    {
+      set_must_copy(e, ANNOTATION_FALSE);
+    }
+
+    pushdown_must_copy(inExpr, e->get_input());
+    break;
+  }
+
+  case name_cast_expr_kind:
+  {
+    name_cast_expr* e = static_cast<name_cast_expr*>(inExpr);
+    set_must_copy(e, ANNOTATION_FALSE);
+    pushdown_must_copy(inExpr, e->get_input());
+    break;
+  }
+
+  case validate_expr_kind:
+  {
+    validate_expr* e = static_cast<validate_expr*>(inExpr);
+    set_must_copy(e, ANNOTATION_TRUE_FIXED);
+    pushdown_must_copy(inExpr, e->get_expr());
+    break;
+  }
+
+  case extension_expr_kind:
+  {
+    extension_expr* e = static_cast<extension_expr*>(inExpr);
+    pushdown_must_copy(inExpr, e->get_expr());
+    break;
+  }
+
+  case order_expr_kind:
+  {
+    order_expr* e = static_cast<order_expr*>(inExpr);
+    pushdown_must_copy(inExpr, e->get_expr());
+    break;
+  }
+
+  case delete_expr_kind:
+  case insert_expr_kind:
+  case rename_expr_kind:
+  case replace_expr_kind:
+  {
+    update_expr_base* e = static_cast<update_expr_base*>(inExpr);
+
+    set_must_copy(e->getTargetExpr(), ANNOTATION_TRUE_FIXED);
+
+    if (e->get_expr_kind() == rename_expr_kind)
+    {
+      set_must_copy(e->getSourceExpr(), ANNOTATION_FALSE);
+    }
+    else if (e->get_expr_kind() == replace_expr_kind)
+    {
+      replace_expr* re = static_cast<replace_expr*>(inExpr);
+
+      if (re->getType() == store::UpdateConsts::VALUE_OF_NODE)
+      {
+        set_must_copy(e->getSourceExpr(), ANNOTATION_FALSE);
+      }
+      else
+      {
+        set_must_copy(e->getSourceExpr(), ANNOTATION_TRUE_FIXED);
+      }
+    }
+    else
+    {
+      set_must_copy(e->getSourceExpr(), ANNOTATION_TRUE_FIXED);
+    }
+
+    break;
+  }
+
+#if 0
+  case transform_expr_kind:
+
+  case block_expr_kind:
+  case var_decl_expr_kind:
+  case apply_expr_kind:
+  case exit_expr_kind:
+  case exit_catcher_expr_kind:
+  case flowctl_expr_kind:
+  case while_expr_kind:
+
+  case eval_expr_kind:
+  case debugger_expr_kind:
+
+#endif
+
+  case wrapper_expr_kind:
+  {
+    wrapper_expr* e = static_cast<wrapper_expr*>(inExpr);
+    pushdown_must_copy(inExpr, e->get_expr());
+    break;
+  }
+
+  case function_trace_expr_kind:
+  {
+    function_trace_expr* e = static_cast<function_trace_expr*>(inExpr);
+    pushdown_must_copy(inExpr, e->get_expr());
+    break;
+  }
+
+#ifndef ZORBA_NO_FULL_TEXT
+	case ft_expr_kind:
+  {
+    ft_expr* e = static_cast<ft_expr*>(inExpr);
+    set_must_copy(e, ANNOTATION_FALSE);
+    set_must_copy(e->get_range(), ANNOTATION_TRUE_FIXED);
+    set_must_copy(e->get_ignore(), ANNOTATION_TRUE_FIXED);
+    break;
+  }
+#endif /* ZORBA_NO_FULL_TEXT */
+
+  case axis_step_expr_kind:
+  case match_expr_kind:
+  default:
+    ZORBA_ASSERT(false);
+  }
+
+  ExprIterator iter(inExpr);
+  while (!iter.done())
+  {
+    computeMustCopyProperty(*iter);
+    iter.next();
+  }
+}
+#endif
+
+
 }
 }
 

=== modified file 'src/compiler/translator/translator.cpp'
--- src/compiler/translator/translator.cpp	2011-11-29 00:16:24 +0000
+++ src/compiler/translator/translator.cpp	2011-11-29 22:22:26 +0000
@@ -436,6 +436,12 @@
   detect "leaf" udfs, i.e., udfs that do not invoke other udfs. Such udfs are
   inlined by the optimizer.
 
+  theExitExprs:
+  -------------
+  This vector stores the exit_exprs that are encountered during the translation
+  of the body of a UDF. It is used to associated those exot_exprs with the
+  exit_catcher_expr that is added at the top of the UDF body.
+
   theHaveUpdatingExitExprs :
   --------------------------
 
@@ -572,6 +578,8 @@
   PrologGraph                            thePrologGraph;
   PrologGraphVertex                      theCurrentPrologVFDecl;
 
+  std::vector<expr*>                     theExitExprs;
+
   bool                                   theHaveUpdatingExitExprs;
 
   bool                                   theHaveSequentialExitExprs;
@@ -1661,6 +1669,7 @@
   return lExpandedLocation;
 }
 
+
 /*******************************************************************************
   In this expression branch, we create the debugger expressions.
   Furthermore, we create an entry for all expressions in the map
@@ -1911,8 +1920,8 @@
   assert(theAssignedVars.size() == 1);
 
   for (std::list<GlobalBinding>::iterator i = thePrologVars.begin();
-      i != thePrologVars.end();
-      ++i)
+       i != thePrologVars.end();
+       ++i)
   {
     declare_var(*i, theModulesInfo->theInitExprs);
   }
@@ -3001,7 +3010,7 @@
       {
         store::Item_t lMajorOpt;
         theSctx->expand_qname(lMajorOpt,
-                              zstring(ZORBA_VERSIONING_NS),
+                              static_context::ZORBA_VERSIONING_NS,
                               zstring(""),
                               zstring(ZORBA_OPTION_MODULE_VERSION),
                               loc);
@@ -3095,7 +3104,17 @@
       if (qnameItem->getPrefix().empty() && qnameItem->getNamespace().empty())
         RAISE_ERROR(err::XPST0081, loc, ERROR_PARAMS(qnameItem->getStringValue()));
 
-      theSctx->bind_option( qnameItem, value, opt_decl->get_location() );
+      theSctx->bind_option(qnameItem, value, opt_decl->get_location());
+
+      if (qnameItem->getNamespace() == static_context::ZORBA_OPTION_OPTIM_NS &&
+          value == "for-serialization-only")
+      {
+        if (qnameItem->getLocalName() == "enable")
+          theCCB->theConfig.for_serialization_only = true;
+        else
+          theCCB->theConfig.for_serialization_only = false;
+      }
+
       continue;
     }
 
@@ -3462,7 +3481,7 @@
 
     if (udf->isExiting())
     {
-      body = new exit_catcher_expr(theRootSctx, loc, body);
+      body = new exit_catcher_expr(theRootSctx, loc, body, theExitExprs);
     }
 
     // Wrap the UDF body to the type-related expr that enforce the declared
@@ -3553,8 +3572,13 @@
   // hence, we can always lazy evaluation
   if (!theCurrentPrologVFDecl.isNull())
   {
-    //const function* f = theCurrentPrologVFDecl.getFunction();
     //lc->setLazyEval(!f->isSequential());
+
+    const user_function* udf = 
+    static_cast<const user_function*>(theCurrentPrologVFDecl.getFunction());
+
+    arg_var->set_param_pos(flwor->num_clauses());
+    arg_var->set_udf(udf);
   }
   else
   {
@@ -3753,8 +3777,8 @@
 
     push_nodestack(initExpr);
   }
+
   theAnnotations = NULL;
-
 }
 
 
@@ -3796,6 +3820,8 @@
 {
   TRACE_VISIT_OUT();
 
+  bool recognised = false;
+
   store::Item_t lExpandedQName;
   expand_function_qname(lExpandedQName, v.get_qname().getp(), loc);
 
@@ -3816,6 +3842,8 @@
                            : lExpandedQName->getPrefix())
                     + ":" + lExpandedQName->getLocalName()));
     }
+
+    recognised = true;
   }
   else
   {
@@ -3845,7 +3873,8 @@
     }
   }
 
-  theAnnotations->push_back(lExpandedQName, lLiterals);
+  if (recognised)
+    theAnnotations->push_back(lExpandedQName, lLiterals);
 }
 
 
@@ -5511,6 +5540,8 @@
     theHaveSequentialExitExprs = true;
   }
 
+  expr_t exitExpr = new exit_expr(theRootSctx, loc, childExpr);
+
   if (inUDFBody())
   {
     function* f = const_cast<function*>(theCurrentPrologVFDecl.getFunction());
@@ -5518,9 +5549,10 @@
     user_function* udf = static_cast<user_function*>(f);
 
     udf->setExiting(true);
+    theExitExprs.push_back(exitExpr.getp());
   }
 
-  push_nodestack(new exit_expr(theRootSctx, loc, childExpr));
+  push_nodestack(exitExpr);
 }
 
 
@@ -7444,8 +7476,8 @@
 
     if (foArg->get_func()->getKind() == FunctionConsts::OP_AND_N)
     {
-      ulong numArgs = foArg->num_args();
-      for (ulong i = 0; i < numArgs; ++i)
+      csize numArgs = foArg->num_args();
+      for (csize i = 0; i < numArgs; ++i)
         args.push_back(foArg->get_arg(i));
     }
     else
@@ -7464,8 +7496,8 @@
 
     if (foArg->get_func()->getKind() == FunctionConsts::OP_AND_N)
     {
-      ulong numArgs = foArg->num_args();
-      for (ulong i = 0; i < numArgs; ++i)
+      csize numArgs = foArg->num_args();
+      for (csize i = 0; i < numArgs; ++i)
         args.push_back(foArg->get_arg(i));
     }
     else
@@ -10068,9 +10100,9 @@
 
         std::vector<var_expr_t> inscopeVars;
         theSctx->getVariables(inscopeVars);
-        ulong numVars = inscopeVars.size();
+        csize numVars = inscopeVars.size();
 
-        for (ulong i = 0; i < numVars; ++i)
+        for (csize i = 0; i < numVars; ++i)
         {
           if (inscopeVars[i]->get_kind() == var_expr::prolog_var)
             continue;
@@ -10080,7 +10112,7 @@
                                           var_expr::eval_var,
                                           inscopeVars[i]->get_return_type());
 
-          // At this point, the domain expr of an eval var is always another var.
+          // At thgis point, the domain expr of an eval var is always another var.
           // However, that other var may be later inlined, so in general, the domain
           // expr of an eval var may be any expr.
           expr_t valueExpr = inscopeVars[i].getp();
@@ -10223,9 +10255,9 @@
 
         std::vector<var_expr_t> inscopeVars;
         theSctx->getVariables(inscopeVars);
-        ulong numVars = inscopeVars.size();
+        csize numVars = inscopeVars.size();
 
-        for (ulong i = 0; i < numVars; ++i)
+        for (csize i = 0; i < numVars; ++i)
         {
           if (inscopeVars[i]->get_kind() == var_expr::prolog_var)
             continue;
@@ -10235,14 +10267,11 @@
                                           var_expr::eval_var,
                                           inscopeVars[i]->get_return_type());
 
-          // At this point, the domain expr of an eval var is always another var.
-          // However, that other var may be later inlined, so in general, the domain
-          // expr of an eval var may be any expr.
           expr_t valueExpr = inscopeVars[i].getp();
           evalExpr->add_var(evalVar, valueExpr);
         }
 
-        for (ulong i=0; i<temp_vars.size(); i++)
+        for (csize i = 0; i < temp_vars.size(); ++i)
         {
           var_expr_t evalVar = create_var(loc,
                                           temp_vars[i]->get_name(),
@@ -10381,6 +10410,11 @@
   // in a udf UF: function UF(x1 as T1, ..., xN as TN) as R { F(x1, ... xN) }
   if (!fn->isUdf())
   {
+    user_function* udf = new user_function(loc,
+                                           fn->getSignature(),
+                                           NULL, // no body for now
+                                           fn->getScriptingKind());
+
     std::vector<expr_t> foArgs(arity);
     std::vector<var_expr_t> udfArgs(arity);
 
@@ -10388,17 +10422,17 @@
     {
       var_expr_t argVar = create_temp_var(loc, var_expr::arg_var);
 
+      argVar->set_param_pos(i);
+      argVar->set_udf(udf);
+
       udfArgs[i] = argVar;
       foArgs[i] = argVar.getp();
     }
 
     expr_t body = new fo_expr(theRootSctx, loc, fn, foArgs);
 
-    user_function* udf = new user_function(loc,
-                                           fn->getSignature(),
-                                           body,
-                                           fn->getScriptingKind());
     udf->setArgVars(udfArgs);
+    udf->setBody(body);
 
     fn = udf;
   }
@@ -10479,6 +10513,7 @@
 
     let_clause_t lc = wrap_in_letclause(&*arg_var, subst_var);
 
+    arg_var->set_param_pos(flwor->num_clauses());
     arg_var->set_type(varExpr->get_return_type());
 
     // TODO: this could probably be done lazily in some cases
@@ -10682,12 +10717,16 @@
 
   nameExpr = new const_expr(theRootSctx, loc, qnameItem);
 
+  bool copyNodes = (theCCB->theConfig.opt_level < CompilerCB::config::O1 ||
+                    !Properties::instance()->noCopyOptim());
+
   push_nodestack(new elem_expr(theRootSctx,
                                loc,
                                nameExpr,
                                attrExpr,
                                contentExpr,
-                               theNSCtx));
+                               theNSCtx,
+                               copyNodes));
   pop_elem_scope();
   pop_scope();
 }
@@ -11344,7 +11383,10 @@
 
   fo_expr* lEnclosed = new fo_expr(theRootSctx, loc, op_enclosed, lContent);
 
-  push_nodestack(new doc_expr(theRootSctx, loc, lEnclosed));
+  bool copyNodes = (theCCB->theConfig.opt_level < CompilerCB::config::O1 ||
+                    !Properties::instance()->noCopyOptim());
+
+  push_nodestack(new doc_expr(theRootSctx, loc, lEnclosed, copyNodes));
 }
 
 
@@ -11386,7 +11428,15 @@
     nameExpr = new name_cast_expr(theRootSctx, loc, atomExpr.getp(), theNSCtx, false);
   }
 
-  push_nodestack (new elem_expr(theRootSctx, loc, nameExpr, contentExpr, theNSCtx));
+  bool copyNodes = (theCCB->theConfig.opt_level < CompilerCB::config::O1 ||
+                    !Properties::instance()->noCopyOptim());
+
+  push_nodestack(new elem_expr(theRootSctx,
+                               loc,
+                               nameExpr,
+                               contentExpr,
+                               theNSCtx,
+                               copyNodes));
 }
 
 

=== modified file 'src/context/dynamic_loader.cpp'
--- src/context/dynamic_loader.cpp	2011-11-17 04:59:42 +0000
+++ src/context/dynamic_loader.cpp	2011-11-29 22:22:26 +0000
@@ -220,7 +220,7 @@
     // Lookup version of the module
     store::Item_t lMajorOpt;
     GENV.getItemFactory()->createQName(lMajorOpt,
-                                       zstring(ZORBA_VERSIONING_NS),
+                                       static_context::ZORBA_VERSIONING_NS,
                                        zstring(""),
                                        zstring(ZORBA_OPTION_MODULE_VERSION));
     

=== modified file 'src/context/static_context.cpp'
--- src/context/static_context.cpp	2011-11-17 04:59:42 +0000
+++ src/context/static_context.cpp	2011-11-29 22:22:26 +0000
@@ -54,7 +54,9 @@
 #include "api/auditimpl.h"
 
 #include "api/uri_resolver_wrappers.h"
+
 #include "diagnostics/xquery_diagnostics.h"
+#include "diagnostics/util_macros.h"
 
 #include "system/globalenv.h"
 
@@ -326,13 +328,13 @@
 static_context::ZORBA_SCHEMA_FN_NS = static_context::ZORBA_NS_PREFIX + "modules/schema";
 
 const zstring
-static_context::ZORBA_XQDOC_FN_NS = static_context::ZORBA_NS_PREFIX + "modules/xqdoc";
-
-const zstring
-static_context::ZORBA_RANDOM_FN_NS = static_context::ZORBA_NS_PREFIX + "modules/random";
-
-const zstring
-static_context::ZORBA_INTROSP_SCTX_FN_NS = static_context::ZORBA_NS_PREFIX + "modules/introspection/sctx";
+static_context::ZORBA_XQDOC_FN_NS = ZORBA_NS_PREFIX + "modules/xqdoc";
+
+const zstring
+static_context::ZORBA_RANDOM_FN_NS = ZORBA_NS_PREFIX + "modules/random";
+
+const zstring
+static_context::ZORBA_INTROSP_SCTX_FN_NS = NS_PRE + "modules/introspection/sctx";
 
 const zstring
 static_context::ZORBA_REFLECTION_FN_NS = NS_PRE + "modules/reflection";
@@ -364,6 +366,24 @@
 const zstring
 static_context::ZORBA_OP_NS = ZORBA_NS_PREFIX + "internal/zorba-ops";
 
+/***************************************************************************//**
+  Options-related namespaces
+********************************************************************************/
+const zstring 
+static_context::ZORBA_OPTIONS_NS = ZORBA_NS_PREFIX + "options";
+
+const zstring 
+static_context::ZORBA_OPTION_WARN_NS = static_context::ZORBA_OPTIONS_NS + "/warnings";
+
+const zstring 
+static_context::ZORBA_OPTION_FEATURE_NS = static_context::ZORBA_OPTIONS_NS + "/features";
+
+const zstring 
+static_context::ZORBA_OPTION_OPTIM_NS = static_context::ZORBA_OPTIONS_NS + "/optimizer";
+
+const zstring 
+static_context::ZORBA_VERSIONING_NS = static_context::ZORBA_OPTIONS_NS + "/versioning";
+
 
 /***************************************************************************//**
   Static method to check if a given target namespace identifies a zorba
@@ -3144,39 +3164,54 @@
   
   zstring lNamespace = qname2->getNamespace();
 
-
   if ( lNamespace.find(ZORBA_OPTIONS_NS) == 0 ) // starts with zorba options namespace
   {
     zstring lLocalName = qname2->getLocalName();
 
-    if ( lNamespace == ZORBA_OPTION_FEATURE_NS &&
-         ( lLocalName == "enable" || lLocalName == "disable" ) )
+    if (lNamespace == ZORBA_OPTION_FEATURE_NS &&
+        (lLocalName == "enable" || lLocalName == "disable"))
     {
       zstring lVal1 = value;
       zstring lVal2;
       bool lCommaFound = false;
-      while (ztd::split (lVal1, ",", &lVal1, &lVal2))
+      while (ztd::split(lVal1, ",", &lVal1, &lVal2))
       {
         process_feature_option(lVal1, lLocalName == "enable", loc);
         lCommaFound = true;
       }
       process_feature_option(
-        lCommaFound?lVal2:lVal1, 
-        lLocalName == "enable",
-        loc);
-    }
-    else if ( lNamespace == ZORBA_OPTION_WARN_NS &&
-              ( lLocalName == "enable" || lLocalName == "disable" || lLocalName == "error" ) )
-    {
-      zstring lVal1 = value;
-      zstring lVal2;
-      bool lCommaFound = false;
-      while (ztd::split (lVal1, ",", &lVal1, &lVal2))
+        lCommaFound ? lVal2 : lVal1, 
+        lLocalName == "enable",
+        loc);
+    }
+    else if (qname2->getNamespace() == ZORBA_OPTION_OPTIM_NS &&
+             (lLocalName == "enable" || lLocalName == "disable"))
+    {
+      zstring lVal1 = value;
+      zstring lVal2;
+      bool lCommaFound = false;
+      while (ztd::split(lVal1, ",", &lVal1, &lVal2))
+      {
+        process_optim_option(lVal1, lLocalName == "enable", loc);
+        lCommaFound = true;
+      }
+      process_optim_option(
+        lCommaFound ? lVal2 : lVal1, 
+        lLocalName == "enable",
+        loc);
+    }
+    else if (lNamespace == ZORBA_OPTION_WARN_NS &&
+             (lLocalName == "enable" || lLocalName == "disable" || lLocalName == "error"))
+    {
+      zstring lVal1 = value;
+      zstring lVal2;
+      bool lCommaFound = false;
+      while (ztd::split(lVal1, ",", &lVal1, &lVal2))
       {
         process_warning_option(lVal1, lLocalName, loc);
         lCommaFound = true;
       }
-      process_warning_option( lCommaFound?lVal2:lVal1, lLocalName, loc);
+      process_warning_option(lCommaFound?lVal2:lVal1, lLocalName, loc);
     }
 
     // process zorba-version option
@@ -3188,14 +3223,16 @@
       {
         // Re-use "ModuleVersion" class since it does 98% of the work for us;
         // just use a fake URI
-        ModuleVersion lOptVersion(ZORBA_VERSIONING_NS "/corezorba", value);
-        if (! lOptVersion.is_valid_version()) {
+        ModuleVersion lOptVersion(ZORBA_VERSIONING_NS + "/corezorba", value);
+        if (! lOptVersion.is_valid_version()) 
+        {
           throw XQUERY_EXCEPTION(zerr::ZXQP0039_INVALID_VERSION_SPECIFICATION,
                       ERROR_PARAMS(value), ERROR_LOC( loc ));
         }
-        ModuleVersion lZorbaVersion(ZORBA_VERSIONING_NS "/corezorba",
+        ModuleVersion lZorbaVersion(ZORBA_VERSIONING_NS + "/corezorba",
                                     ZORBA_VERSION);
-        if ( ! lZorbaVersion.satisfies(lOptVersion)) {
+        if ( ! lZorbaVersion.satisfies(lOptVersion)) 
+        {
           throw XQUERY_EXCEPTION(zerr::ZXQP0038_INAPPROPRIATE_ZORBA_VERSION,
                       ERROR_PARAMS(value, ZORBA_VERSION),
                       ERROR_LOC( loc ));
@@ -3258,8 +3295,11 @@
   return lQName;
 }
 
-void
-static_context::process_warning_option(
+
+/***************************************************************************//**
+
+********************************************************************************/
+void static_context::process_warning_option(
   const zstring& value,
   const zstring& name,
   const QueryLoc& loc)
@@ -3314,48 +3354,60 @@
   }
 }
 
-void
-static_context::process_feature_option(
-  const zstring& value,
-  bool  enable,
-  const QueryLoc& loc)
+
+/***************************************************************************//**
+
+********************************************************************************/
+void static_context::process_feature_option(
+    const zstring& value,
+    bool enable,
+    const QueryLoc& loc)
 {
-  store::Item_t lQName = parse_and_expand_qname( value, ZORBA_FEATURES_NS, loc );
+  store::Item_t featureName = parse_and_expand_qname(value, ZORBA_FEATURES_NS, loc);
 
-  if ( lQName->getNamespace() != ZORBA_FEATURES_NS )
+  if (featureName->getNamespace() != ZORBA_FEATURES_NS)
   {
-    throw XQUERY_EXCEPTION(
-        zerr::ZDST0060_FEATURE_NOT_SUPPORTED,
-        ERROR_PARAMS (
-          lQName->getStringValue(),
-          ZED( ZDST0060_unknown_namespace ),
-          lQName->getNamespace()
-        ), 
-        ERROR_LOC( loc )
-    );
+    RAISE_ERROR(zerr::ZDST0060_FEATURE_NOT_SUPPORTED, loc,
+    ERROR_PARAMS(featureName->getStringValue(),
+                 ZED(ZDST0060_unknown_namespace),
+                 featureName->getNamespace())); 
   }
 
   feature::kind k;
-  if ( feature::kind_for(lQName->getLocalName().c_str(), k) )
+  if (feature::kind_for(featureName->getLocalName().c_str(), k))
   {
-    if ( enable )
-      set_feature( k );
+    if (enable)
+      set_feature(k);
     else
-      unset_feature( k );
+      unset_feature(k);
   }
   else
   {
-    throw XQUERY_EXCEPTION(
-        zerr::ZDST0060_FEATURE_NOT_SUPPORTED,
-        ERROR_PARAMS (
-          lQName->getStringValue(),
-          ZED( ZDST0060_unknown_localname ),
-          lQName->getLocalName()
-        ), 
-        ERROR_LOC( loc )
-    );
-  }
-}
+    RAISE_ERROR(zerr::ZDST0060_FEATURE_NOT_SUPPORTED, loc,
+    ERROR_PARAMS(featureName->getStringValue(),
+                 ZED(ZDST0060_unknown_localname),
+                 featureName->getLocalName())); 
+  }
+}
+
+
+/***************************************************************************//**
+
+********************************************************************************/
+void static_context::process_optim_option(
+    const zstring& value,
+    bool enable,
+    const QueryLoc& loc)
+{
+  if (value != "for-serialization-only")
+  {
+    RAISE_ERROR(zerr::ZDST0060_FEATURE_NOT_SUPPORTED, loc,
+    ERROR_PARAMS(value,
+                 ZED(ZDST0060_unknown_localname),
+                 "")); 
+  }
+}
+
 
 /***************************************************************************//**
 
@@ -3383,7 +3435,7 @@
 
 /////////////////////////////////////////////////////////////////////////////////
 //                                                                             //
-//  Auditing                                                                    //
+//  Auditing                                                                   //
 //                                                                             //
 /////////////////////////////////////////////////////////////////////////////////
 

=== modified file 'src/context/static_context.h'
--- src/context/static_context.h	2011-11-17 04:59:42 +0000
+++ src/context/static_context.h	2011-11-29 22:22:26 +0000
@@ -427,22 +427,23 @@
   static const zstring DOT_POS_VAR_NAME;
   static const zstring DOT_SIZE_VAR_NAME;
 
-  static const zstring W3C_NS_PREFIX;
-  static const zstring ZORBA_NS_PREFIX;
 
   //
   // W3C namespaces
   //
+  static const zstring W3C_NS_PREFIX; // http://www.w3.org/
+
   static const zstring W3C_XML_NS;    // http://www.w3.org/XML/1998/namespace
 
-  //
-  // http://www.w3.org/2005/xpath-functions
-  //
-  static const zstring W3C_FN_NS;
-
-  //
+  static const zstring W3C_FN_NS;     // http://www.w3.org/2005/xpath-functions
+
+  //
+  // Zorba namespaces
+  //
+
+  static const zstring ZORBA_NS_PREFIX; // http://www.zorba-xquery.com/
+
   // Namespaces of external modules declaring zorba builtin functions
-  //
   static const zstring ZORBA_MATH_FN_NS;
   static const zstring ZORBA_BASE64_FN_NS;
   static const zstring ZORBA_NODEREF_FN_NS;
@@ -467,19 +468,21 @@
   static const zstring ZORBA_NODE_FN_NS;
   static const zstring ZORBA_XML_FN_NS;
 
-  //
   // Namespaces of virtual modules declaring zorba builtin functions
-  //
   static const zstring ZORBA_UTIL_FN_NS;
   static const zstring ZORBA_SCRIPTING_FN_NS;
 
-  //
   // Namespaces of virtual modules declaring internal builtin functions of
   // XQUERY or zorba. Internal functions are not visible to xquery programs.
-  //
   static const zstring XQUERY_OP_NS;
   static const zstring ZORBA_OP_NS;
 
+  // options-related namepsaces
+  static const zstring ZORBA_OPTIONS_NS;
+  static const zstring ZORBA_OPTION_WARN_NS;
+  static const zstring ZORBA_OPTION_FEATURE_NS;
+  static const zstring ZORBA_OPTION_OPTIM_NS;
+  static const zstring ZORBA_VERSIONING_NS;
 
 protected:
   static_context                        * theParent;
@@ -898,6 +901,11 @@
     bool  enable,
     const QueryLoc& loc);
 
+  void process_optim_option(
+    const zstring& value,
+    bool  enable,
+    const QueryLoc& loc);
+
   void process_warning_option(
     const zstring& value,
     const zstring& name,

=== modified file 'src/context/static_context_consts.h'
--- src/context/static_context_consts.h	2011-07-21 23:02:27 +0000
+++ src/context/static_context_consts.h	2011-11-29 22:22:26 +0000
@@ -120,40 +120,7 @@
     decl_manual
   };
 
-  enum annotations_t
-  {
-    fn_public = 0,
-    fn_private,
-    zann_deterministic,
-    zann_nondeterministic,
-    zann_assignable,
-    zann_nonassignable,
-    zann_sequential,
-    zann_nonsequential,
-    zann_variadic,
-    zann_streamable,
-    zann_unique,
-    zann_nonunique,
-    zann_value_equality,
-    zann_general_equality,
-    zann_value_range,
-    zann_general_range,
-    zann_automatic,
-    zann_manual,
-    zann_mutable,
-    zann_queue,
-    zann_append_only,
-    zann_const,
-    zann_ordered,
-    zann_unordered,
-    zann_read_only_nodes,
-    zann_mutable_nodes,
-
-    // must be at the end
-    zann_end
-
-  };
-  
+ 
   enum node_modifier_t
   {
     read_only,

=== modified file 'src/functions/CMakeLists.txt'
--- src/functions/CMakeLists.txt	2011-06-08 18:37:56 +0000
+++ src/functions/CMakeLists.txt	2011-11-29 22:22:26 +0000
@@ -81,4 +81,5 @@
     func_eval.cpp
     func_reflection.cpp
     func_apply.cpp
+    func_serialize_impl.cpp
 )

=== modified file 'src/functions/external_function.cpp'
--- src/functions/external_function.cpp	2011-06-14 17:26:33 +0000
+++ src/functions/external_function.cpp	2011-11-29 22:22:26 +0000
@@ -27,6 +27,9 @@
 END_SERIALIZABLE_CLASS_VERSIONS(external_function)
 
 
+/*******************************************************************************
+
+********************************************************************************/
 external_function::external_function(
     const QueryLoc& loc,
     static_context* modSctx,
@@ -46,6 +49,9 @@
 }
 
 
+/*******************************************************************************
+
+********************************************************************************/
 void external_function::serialize(::zorba::serialization::Archiver& ar)
 {
   zorba::serialization::serialize_baseclass(ar, (function*)this);
@@ -92,12 +98,82 @@
 }
 
 
+/*******************************************************************************
+
+********************************************************************************/
 bool external_function::accessesDynCtx() const
 {
   return theImpl->isContextual();
 }
 
 
+/*******************************************************************************
+
+********************************************************************************/
+bool external_function::propagatesInputNodes(
+    expr* fo,
+    csize input) const
+{
+  bool res = function::propagatesInputNodes(fo, input);
+
+  if (res == false)
+    return res;
+
+  AnnotationInternal* ann = 
+  theAnnotationList->get(AnnotationInternal::zann_propagates_input_nodes);
+
+  if (ann != NULL)
+  {
+    csize numLiterals = ann->getNumLiterals();
+
+    for (csize i = 0; i < numLiterals; ++i)
+    {
+      if (ann->getLiteral(i)->getLongValue() == input)
+        return true;
+    }
+
+    return false;
+  }
+
+  return true;
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+bool external_function::mustCopyInputNodes(
+    expr* fo,
+    csize input) const
+{
+  bool res = function::mustCopyInputNodes(fo, input);
+
+  if (res == false)
+    return res;
+
+  AnnotationInternal* ann = 
+  theAnnotationList->get(AnnotationInternal::zann_must_copy_input_nodes);
+
+  if (ann != NULL)
+  {
+    csize numLiterals = ann->getNumLiterals();
+
+    for (csize i = 0; i < numLiterals; ++i)
+    {
+      if (ann->getLiteral(i)->getLongValue() == input)
+        return true;
+    }
+
+    return false;
+  }
+
+  return true;
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
 PlanIter_t external_function::codegen(
     CompilerCB* /*cb*/,
     static_context* sctx,

=== modified file 'src/functions/external_function.h'
--- src/functions/external_function.h	2011-10-12 08:45:07 +0000
+++ src/functions/external_function.h	2011-11-29 22:22:26 +0000
@@ -65,6 +65,10 @@
 
   bool accessesDynCtx() const;
 
+  bool propagatesInputNodes(expr* fo, csize input) const;
+
+  bool mustCopyInputNodes(expr* fo, csize input) const;
+
   PlanIter_t codegen(
         CompilerCB* /*cb*/,
         static_context* sctx,

=== modified file 'src/functions/func_accessors_impl.cpp'
--- src/functions/func_accessors_impl.cpp	2011-07-01 05:22:12 +0000
+++ src/functions/func_accessors_impl.cpp	2011-11-29 22:22:26 +0000
@@ -37,18 +37,40 @@
 /*******************************************************************************
   
 ********************************************************************************/
-BoolAnnotationValue fn_data::ignoresSortedNodes(expr* fo, ulong input) const
+PlanIter_t fn_string::codegen(
+      CompilerCB* /*cb*/,
+      static_context* sctx,
+      const QueryLoc& loc,
+      std::vector<PlanIter_t>& argv,
+      AnnotationHolder& ann) const
+{
+  return new FnStringIterator(sctx, loc, argv, true);
+}
+
+
+/*******************************************************************************
+  
+********************************************************************************/
+BoolAnnotationValue fn_data::ignoresSortedNodes(expr* fo, csize input) const
 {
   return fo->getIgnoresSortedNodes();
 }
 
 
-BoolAnnotationValue fn_data::ignoresDuplicateNodes(expr* fo, ulong input) const
+BoolAnnotationValue fn_data::ignoresDuplicateNodes(expr* fo, csize input) const
 {
   return fo->getIgnoresDuplicateNodes();
 }
 
 
+bool fn_data::mustCopyInputNodes(expr* fo, csize input) const
+{
+  static_context* sctx = fo->get_sctx();
+
+  return (sctx->construction_mode() != StaticContextConsts::cons_preserve);
+}
+
+
 xqtref_t fn_data::getReturnType(
     const TypeManager* tm,
     const std::vector<xqtref_t>& arg_types) const
@@ -103,21 +125,30 @@
                                         TypeConstants::QUANT_STAR);
 }
 
+
 /*******************************************************************************
   
 ********************************************************************************/
-BoolAnnotationValue fn_data_3_0::ignoresSortedNodes(expr* fo, ulong input) const
+BoolAnnotationValue fn_data_3_0::ignoresSortedNodes(expr* fo, csize input) const
 {
   return fo->getIgnoresSortedNodes();
 }
 
 
-BoolAnnotationValue fn_data_3_0::ignoresDuplicateNodes(expr* fo, ulong input) const
+BoolAnnotationValue fn_data_3_0::ignoresDuplicateNodes(expr* fo, csize input) const
 {
   return fo->getIgnoresDuplicateNodes();
 }
 
 
+bool fn_data_3_0::mustCopyInputNodes(expr* fo, csize input) const
+{
+  static_context* sctx = fo->get_sctx();
+
+  return (sctx->construction_mode() != StaticContextConsts::cons_preserve);
+}
+
+
 xqtref_t fn_data_3_0::getReturnType(
     const TypeManager* tm,
     const std::vector<xqtref_t>& arg_types) const
@@ -147,20 +178,6 @@
 /*******************************************************************************
   
 ********************************************************************************/
-PlanIter_t fn_string::codegen(
-      CompilerCB* /*cb*/,
-      static_context* sctx,
-      const QueryLoc& loc,
-      std::vector<PlanIter_t>& argv,
-      AnnotationHolder& ann) const
-{
-  return new FnStringIterator(sctx, loc, argv, true);
-}
-
-
-/*******************************************************************************
-  
-********************************************************************************/
 void populate_context_accessors_impl(static_context* sctx)
 {
   DECL(sctx, fn_name_func,

=== modified file 'src/functions/func_accessors_impl.h'
--- src/functions/func_accessors_impl.h	2011-06-14 17:26:33 +0000
+++ src/functions/func_accessors_impl.h	2011-11-29 22:22:26 +0000
@@ -42,6 +42,11 @@
               FunctionConsts::FN_NAME_1);
   }
 
+  bool mustCopyInputNodes(expr* fo, csize input) const
+  {
+    return false;
+  }
+
   CODEGEN_DECL();
 };
 

=== modified file 'src/functions/func_booleans_impl.cpp'
--- src/functions/func_booleans_impl.cpp	2011-07-01 05:22:12 +0000
+++ src/functions/func_booleans_impl.cpp	2011-11-29 22:22:26 +0000
@@ -61,12 +61,12 @@
         static_context* sctx,
         const std::vector<xqtref_t>& argTypes) const;
 
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong input) const
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize input) const
   {
     return ANNOTATION_TRUE;
   }
 
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong input) const 
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize input) const 
   {
     return ANNOTATION_TRUE;
   }
@@ -602,12 +602,17 @@
   {
   }
 
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong input) const 
+  bool mustCopyInputNodes(expr* fo, csize input) const
+  {
+    return false;
+  }
+
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize input) const 
   {
     return ANNOTATION_TRUE;
   }
 
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong input) const 
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize input) const 
   {
     return ANNOTATION_TRUE;
   }
@@ -634,12 +639,17 @@
   {
   }
 
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong input) const 
+  bool mustCopyInputNodes(expr* fo, csize input) const
+  {
+    return false;
+  }
+
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize input) const 
   {
     return ANNOTATION_TRUE;
   }
 
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong input) const 
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize input) const 
   {
     return ANNOTATION_TRUE;
   }
@@ -714,12 +724,17 @@
 public:
   fn_not(const signature& sig) : function(sig, FunctionConsts::FN_NOT_1) {}
 
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong input) const 
+  bool mustCopyInputNodes(expr* fo, csize input) const
+  {
+    return false;
+  }
+
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize input) const 
   {
     return ANNOTATION_TRUE;
   }
 
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong input) const 
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize input) const 
   {
     return ANNOTATION_TRUE;
   }
@@ -747,12 +762,17 @@
   {
   }
 
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong input) const
+  bool mustCopyInputNodes(expr* fo, csize input) const
+  {
+    return false;
+  }
+
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize input) const
   {
     return ANNOTATION_TRUE;
   }
 
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong input) const 
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize input) const 
   {
     return ANNOTATION_TRUE;
   }

=== modified file 'src/functions/func_collections_impl.cpp'
--- src/functions/func_collections_impl.cpp	2011-08-12 16:07:57 +0000
+++ src/functions/func_collections_impl.cpp	2011-11-29 22:22:26 +0000
@@ -173,6 +173,14 @@
 }
 
 
+bool zorba_store_collections_static_dml_apply_insert_nodes::propagatesInputNodes(
+    expr* fo,
+    csize input) const
+{
+  return false;
+}
+
+
 /*******************************************************************************
 
 ********************************************************************************/
@@ -188,6 +196,14 @@
 }
 
 
+bool zorba_store_collections_static_dml_apply_insert_nodes_first::propagatesInputNodes(
+    expr* fo,
+    csize input) const
+{
+  return false;
+}
+
+
 /*******************************************************************************
 
 ********************************************************************************/
@@ -203,6 +219,14 @@
 }
 
 
+bool zorba_store_collections_static_dml_apply_insert_nodes_last::propagatesInputNodes(
+    expr* fo,
+    csize input) const
+{
+  return false;
+}
+
+
 /*******************************************************************************
 
 ********************************************************************************/
@@ -218,6 +242,15 @@
 }
 
 
+bool 
+zorba_store_collections_static_dml_apply_insert_nodes_before::propagatesInputNodes(
+    expr* fo,
+    csize input) const
+{
+  return false;
+}
+
+
 /*******************************************************************************
 
 ********************************************************************************/
@@ -233,6 +266,15 @@
 }
 
 
+bool 
+zorba_store_collections_static_dml_apply_insert_nodes_after::propagatesInputNodes(
+    expr* fo,
+    csize input) const
+{
+  return false;
+}
+
+
 /*******************************************************************************
 
 ********************************************************************************/
@@ -312,7 +354,7 @@
 ********************************************************************************/
 BoolAnnotationValue zorba_store_collections_static_dml_delete_nodes::ignoresSortedNodes(
     expr* fo,
-    ulong input) const 
+    csize input) const 
 {
   return ANNOTATION_TRUE;
 }
@@ -323,7 +365,7 @@
 ********************************************************************************/
 BoolAnnotationValue zorba_store_collections_static_dml_delete_nodes::ignoresDuplicateNodes(
     expr* fo, 
-    ulong input) const 
+    csize input) const 
 {
   return ANNOTATION_TRUE;
 }

=== modified file 'src/functions/func_enclosed.cpp'
--- src/functions/func_enclosed.cpp	2011-06-14 17:26:33 +0000
+++ src/functions/func_enclosed.cpp	2011-11-29 22:22:26 +0000
@@ -44,12 +44,17 @@
         const TypeManager* tm,
         const std::vector<xqtref_t>& arg_types) const;
 
-  bool propagatesDistinctNodes(ulong producer) const
+  bool mustCopyInputNodes(expr* fo, csize input) const
+  {
+    return false;
+  }
+
+  bool propagatesDistinctNodes(csize producer) const
   {
     return producer == 0;
   }
 
-  bool propagatesSortedNodes(ulong producer) const
+  bool propagatesSortedNodes(csize producer) const
   {
     return producer == 0;
   }

=== modified file 'src/functions/func_errors_and_diagnostics_impl.cpp'
--- src/functions/func_errors_and_diagnostics_impl.cpp	2011-11-17 16:44:50 +0000
+++ src/functions/func_errors_and_diagnostics_impl.cpp	2011-11-29 22:22:26 +0000
@@ -33,7 +33,7 @@
 ********************************************************************************/
 BoolAnnotationValue fn_trace::ignoresSortedNodes(
     expr* fo,
-    ulong input) const 
+    csize input) const 
 {
   return fo->getIgnoresSortedNodes();
 }
@@ -41,7 +41,7 @@
 
 BoolAnnotationValue fn_trace::ignoresDuplicateNodes(
     expr* fo, 
-    ulong input) const 
+    csize input) const 
 {
   return fo->getIgnoresDuplicateNodes();
 }

=== modified file 'src/functions/func_hoist.cpp'
--- src/functions/func_hoist.cpp	2011-06-14 17:26:33 +0000
+++ src/functions/func_hoist.cpp	2011-11-29 22:22:26 +0000
@@ -43,23 +43,28 @@
     return true;
   }
 
-  bool propagatesSortedNodes(ulong producer) const
-  {
-    return producer == 0;
-  }
-
-  bool propagatesDistinctNodes(ulong producer) const
-  {
-    return producer == 0;
-  }
-
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong input) const
+  bool mustCopyInputNodes(expr* fo, csize input) const
+  {
+    return false;
+  }
+
+  bool propagatesSortedNodes(csize producer) const
+  {
+    return producer == 0;
+  }
+
+  bool propagatesDistinctNodes(csize producer) const
+  {
+    return producer == 0;
+  }
+
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize input) const
   {
     return fo->getIgnoresDuplicateNodes();
   }
 
 
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong input) const
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize input) const
   {
     return fo->getIgnoresDuplicateNodes();
   }
@@ -85,23 +90,28 @@
     return true;
   }
 
-  bool propagatesSortedNodes(ulong producer) const
-  {
-    return producer == 0;
-  }
-
-  bool propagatesDistinctNodes(ulong producer) const
-  {
-    return producer == 0;
-  }
-
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong input) const
+  bool mustCopyInputNodes(expr* fo, csize input) const
+  {
+    return false;
+  }
+
+  bool propagatesSortedNodes(csize producer) const
+  {
+    return producer == 0;
+  }
+
+  bool propagatesDistinctNodes(csize producer) const
+  {
+    return producer == 0;
+  }
+
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize input) const
   {
     return fo->getIgnoresDuplicateNodes();
   }
 
 
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong input) const
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize input) const
   {
     return fo->getIgnoresDuplicateNodes();
   }

=== modified file 'src/functions/func_index_ddl.h'
--- src/functions/func_index_ddl.h	2011-08-12 16:07:57 +0000
+++ src/functions/func_index_ddl.h	2011-11-29 22:22:26 +0000
@@ -45,17 +45,13 @@
   {
   }
 
-  short getScriptingKind() const 
-  { 
-    return SIMPLE_EXPR;
-  }
-
-  bool accessesDynCtx() const 
-  {
-    return true;
-  }
-
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong input) const 
+  short getScriptingKind() const { return SIMPLE_EXPR; }
+
+  bool accessesDynCtx() const { return true; }
+
+  bool mustCopyInputNodes(expr* fo, csize input) const { return false; }
+
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize input) const 
   {
     return ANNOTATION_TRUE;
   }
@@ -141,6 +137,8 @@
 
   bool accessesDynCtx() const { return true; }
 
+  bool mustCopyInputNodes(expr* fo, csize input) const { return false; }
+
   CODEGEN_DECL();
 };
 
@@ -159,6 +157,8 @@
 
   bool accessesDynCtx() const { return true; }
 
+  bool mustCopyInputNodes(expr* fo, csize input) const {  return false;  }
+
   CODEGEN_DECL();
 };
 

=== modified file 'src/functions/func_node_sort_distinct.cpp'
--- src/functions/func_node_sort_distinct.cpp	2011-06-14 17:26:33 +0000
+++ src/functions/func_node_sort_distinct.cpp	2011-11-29 22:22:26 +0000
@@ -154,7 +154,7 @@
 ********************************************************************************/
 BoolAnnotationValue op_node_sort_distinct_base::ignoresSortedNodes(
     expr* fo,
-    ulong input) const 
+    csize input) const 
 {
   const bool* myActions = action();
 
@@ -176,7 +176,7 @@
 ********************************************************************************/
 BoolAnnotationValue op_node_sort_distinct_base::ignoresDuplicateNodes(
     expr* fo, 
-    ulong input) const 
+    csize input) const 
 {
   const bool* myActions = action();
 
@@ -196,6 +196,26 @@
 /*******************************************************************************
 
 ********************************************************************************/
+bool op_node_sort_distinct_base::propagatesInputNodes(
+    expr* fo,
+    csize input) const
+{
+  const bool* myActions = action();
+
+  bool atomics = myActions[NOA];
+
+  if (atomics)
+  {
+    return function::propagatesInputNodes(fo, input);
+  }
+
+  return true;
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
 PlanIter_t op_node_sort_distinct_base::codegen(
     CompilerCB* /*cb*/,
     static_context* sctx,
@@ -256,12 +276,17 @@
     return a;
   }
 
-  bool propagatesSortedNodes(ulong producer) const
+  bool mustCopyInputNodes(expr* fo, csize input) const
+  {
+    return false;
+  }
+
+  bool propagatesSortedNodes(csize producer) const
   {
     return producer == 0;
   }
 
-  bool propagatesDistinctNodes(ulong producer) const
+  bool propagatesDistinctNodes(csize producer) const
   {
     return producer == 0;
   }
@@ -287,7 +312,7 @@
     return a;
   }
 
-  bool propagatesSortedNodes(ulong producer) const
+  bool propagatesSortedNodes(csize producer) const
   {
     return producer == 0;
   }
@@ -319,7 +344,7 @@
     return a;
   }
 
-  bool propagatesSortedNodes(ulong producer) const
+  bool propagatesSortedNodes(csize producer) const
   {
     return producer == 0;
   }
@@ -352,7 +377,7 @@
     return a;
   }
 
-  bool propagatesSortedNodes(ulong producer) const
+  bool propagatesSortedNodes(csize producer) const
   {
     return producer == 0;
   }
@@ -388,7 +413,7 @@
     return FunctionConsts::YES;
   }
 
-  bool propagatesDistinctNodes(ulong producer) const
+  bool propagatesDistinctNodes(csize producer) const
   {
     return producer == 0;
   }
@@ -421,7 +446,7 @@
     return FunctionConsts::YES;
   }
 
-  bool propagatesDistinctNodes(ulong producer) const
+  bool propagatesDistinctNodes(csize producer) const
   {
     return producer == 0;
   }
@@ -452,7 +477,7 @@
     return FunctionConsts::YES;
   }
 
-  bool propagatesDistinctNodes(ulong producer) const
+  bool propagatesDistinctNodes(csize producer) const
   {
     return producer == 0;
   }
@@ -485,7 +510,7 @@
     return FunctionConsts::YES;
   }
 
-  bool propagatesDistinctNodes(ulong producer) const
+  bool propagatesDistinctNodes(csize producer) const
   {
     return producer == 0;
   }

=== modified file 'src/functions/func_node_sort_distinct.h'
--- src/functions/func_node_sort_distinct.h	2011-06-14 17:26:33 +0000
+++ src/functions/func_node_sort_distinct.h	2011-11-29 22:22:26 +0000
@@ -79,9 +79,16 @@
     return arg_types[0]; 
   }
 
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong input) const;
-
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong input) const;
+  bool propagatesInputNodes(expr* fo, csize input) const;
+
+  virtual bool mustCopyInputNodes(expr* fo, csize input) const
+  {
+    return true;
+  }
+
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize input) const;
+
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize input) const;
 
   CODEGEN_DECL();
 };

=== modified file 'src/functions/func_reflection.cpp'
--- src/functions/func_reflection.cpp	2011-07-29 06:13:28 +0000
+++ src/functions/func_reflection.cpp	2011-11-29 22:22:26 +0000
@@ -38,6 +38,7 @@
   CODEGEN_DECL();
 };
 
+
 class fn_zorba_invoke_n : public function
 {
 public:
@@ -88,6 +89,7 @@
   CODEGEN_DECL();
 };
 
+
 PlanIter_t fn_zorba_invoke::codegen(
   CompilerCB*,
   static_context* sctx,
@@ -99,6 +101,7 @@
   return NULL;
 }
 
+
 PlanIter_t fn_zorba_invoke_n::codegen(
   CompilerCB*,
   static_context* sctx,

=== modified file 'src/functions/func_sequences_impl.cpp'
--- src/functions/func_sequences_impl.cpp	2011-11-15 16:04:38 +0000
+++ src/functions/func_sequences_impl.cpp	2011-11-29 22:22:26 +0000
@@ -71,13 +71,13 @@
 }
 
 
-BoolAnnotationValue op_concatenate::ignoresSortedNodes(expr* fo, ulong input) const
+BoolAnnotationValue op_concatenate::ignoresSortedNodes(expr* fo, csize input) const
 {
   return fo->getIgnoresSortedNodes();
 }
 
 
-BoolAnnotationValue op_concatenate::ignoresDuplicateNodes(expr* fo, ulong input) const
+BoolAnnotationValue op_concatenate::ignoresDuplicateNodes(expr* fo, csize input) const
 {
   return fo->getIgnoresDuplicateNodes();
 }
@@ -86,13 +86,13 @@
 /*******************************************************************************
 
 ********************************************************************************/
-BoolAnnotationValue fn_empty::ignoresSortedNodes(expr* fo, ulong input) const
+BoolAnnotationValue fn_empty::ignoresSortedNodes(expr* fo, csize input) const
 {
   return ANNOTATION_TRUE;
 }
 
 
-BoolAnnotationValue fn_empty::ignoresDuplicateNodes(expr* fo, ulong input) const
+BoolAnnotationValue fn_empty::ignoresDuplicateNodes(expr* fo, csize input) const
 {
   return ANNOTATION_TRUE;
 }
@@ -101,13 +101,13 @@
 /*******************************************************************************
 
 ********************************************************************************/
-BoolAnnotationValue fn_exists::ignoresSortedNodes(expr* fo, ulong input) const
+BoolAnnotationValue fn_exists::ignoresSortedNodes(expr* fo, csize input) const
 {
   return ANNOTATION_TRUE;
 }
 
 
-BoolAnnotationValue fn_exists::ignoresDuplicateNodes(expr* fo, ulong input) const
+BoolAnnotationValue fn_exists::ignoresDuplicateNodes(expr* fo, csize input) const
 {
   return ANNOTATION_TRUE;
 }
@@ -126,7 +126,7 @@
 
 BoolAnnotationValue fn_distinct_values::ignoresSortedNodes(
     expr* fo,
-    ulong input) const
+    csize input) const
 {
   if (input == 0)
     return fo->getIgnoresSortedNodes();
@@ -137,7 +137,7 @@
 
 BoolAnnotationValue fn_distinct_values::ignoresDuplicateNodes(
     expr* fo,
-    ulong input) const
+    csize input) const
 {
   if (input == 0)
     return ANNOTATION_TRUE;
@@ -151,7 +151,7 @@
 ********************************************************************************/
 BoolAnnotationValue fn_insert_before::ignoresSortedNodes(
     expr* fo,
-    ulong input) const
+    csize input) const
 {
   if (input == 0 || input == 2)
     return fo->getIgnoresSortedNodes();
@@ -162,7 +162,7 @@
 
 BoolAnnotationValue fn_insert_before::ignoresDuplicateNodes(
     expr* fo,
-    ulong input) const
+    csize input) const
 {
   if (input == 0 || input == 2)
     return fo->getIgnoresSortedNodes();
@@ -184,7 +184,7 @@
 
 BoolAnnotationValue fn_remove::ignoresSortedNodes(
     expr* fo,
-    ulong input) const
+    csize input) const
 {
   if (input == 0)
     return ANNOTATION_FALSE;
@@ -195,7 +195,7 @@
 
 BoolAnnotationValue fn_remove::ignoresDuplicateNodes(
     expr* fo,
-    ulong input) const
+    csize input) const
 {
   return ANNOTATION_FALSE;
 }
@@ -214,7 +214,7 @@
 
 BoolAnnotationValue fn_reverse::ignoresSortedNodes(
     expr* fo,
-    ulong input) const
+    csize input) const
 {
   return fo->getIgnoresSortedNodes();
 }
@@ -222,7 +222,7 @@
 
 BoolAnnotationValue fn_reverse::ignoresDuplicateNodes(
     expr* fo,
-    ulong input) const
+    csize input) const
 {
   return fo->getIgnoresSortedNodes();
 }
@@ -513,13 +513,13 @@
 /*******************************************************************************
 
 ********************************************************************************/
-BoolAnnotationValue fn_unordered::ignoresSortedNodes(expr* fo, ulong input) const
+BoolAnnotationValue fn_unordered::ignoresSortedNodes(expr* fo, csize input) const
 {
   return ANNOTATION_TRUE;
 }
 
 
-BoolAnnotationValue fn_unordered::ignoresDuplicateNodes(expr* fo, ulong input) const
+BoolAnnotationValue fn_unordered::ignoresDuplicateNodes(expr* fo, csize input) const
 {
   return fo->getIgnoresDuplicateNodes();
 }
@@ -550,7 +550,7 @@
 }
 
 
-BoolAnnotationValue fn_zero_or_one::ignoresSortedNodes(expr* fo, ulong input) const
+BoolAnnotationValue fn_zero_or_one::ignoresSortedNodes(expr* fo, csize input) const
 {
   return ANNOTATION_TRUE;
 }
@@ -582,13 +582,13 @@
 }
 
 
-BoolAnnotationValue fn_one_or_more::ignoresSortedNodes(expr* fo, ulong input) const
+BoolAnnotationValue fn_one_or_more::ignoresSortedNodes(expr* fo, csize input) const
 {
   return fo->getIgnoresSortedNodes();
 }
 
 
-BoolAnnotationValue fn_one_or_more::ignoresDuplicateNodes(expr* fo, ulong input) const
+BoolAnnotationValue fn_one_or_more::ignoresDuplicateNodes(expr* fo, csize input) const
 {
   return fo->getIgnoresDuplicateNodes();
 }
@@ -680,7 +680,7 @@
 /*******************************************************************************
 
 ********************************************************************************/
-BoolAnnotationValue fn_count::ignoresSortedNodes(expr* fo, ulong input) const
+BoolAnnotationValue fn_count::ignoresSortedNodes(expr* fo, csize input) const
 {
   return ANNOTATION_TRUE;
 }
@@ -689,7 +689,7 @@
 /*******************************************************************************
 
 ********************************************************************************/
-BoolAnnotationValue fn_avg::ignoresSortedNodes(expr* fo, ulong input) const
+BoolAnnotationValue fn_avg::ignoresSortedNodes(expr* fo, csize input) const
 {
   return ANNOTATION_TRUE;
 }
@@ -726,7 +726,7 @@
 /*******************************************************************************
 
 ********************************************************************************/
-BoolAnnotationValue fn_sum::ignoresSortedNodes(expr* fo, ulong input) const
+BoolAnnotationValue fn_sum::ignoresSortedNodes(expr* fo, csize input) const
 {
   return ANNOTATION_TRUE;
 }
@@ -784,49 +784,49 @@
 /*******************************************************************************
 
 ********************************************************************************/
-BoolAnnotationValue op_sum_double::ignoresSortedNodes(expr* fo, ulong input) const
-{
-  return ANNOTATION_TRUE;
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
-BoolAnnotationValue op_sum_float::ignoresSortedNodes(expr* fo, ulong input) const
-{
-  return ANNOTATION_TRUE;
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
-BoolAnnotationValue op_sum_decimal::ignoresSortedNodes(expr* fo, ulong input) const
-{
-  return ANNOTATION_TRUE;
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
-BoolAnnotationValue op_sum_integer::ignoresSortedNodes(expr* fo, ulong input) const
-{
-  return ANNOTATION_TRUE;
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
-BoolAnnotationValue fn_id::ignoresSortedNodes(expr* fo, ulong input) const
-{
-  return ANNOTATION_TRUE;
-}
-
-
-BoolAnnotationValue fn_id::ignoresDuplicateNodes(expr* fo, ulong input) const
+BoolAnnotationValue op_sum_double::ignoresSortedNodes(expr* fo, csize input) const
+{
+  return ANNOTATION_TRUE;
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+BoolAnnotationValue op_sum_float::ignoresSortedNodes(expr* fo, csize input) const
+{
+  return ANNOTATION_TRUE;
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+BoolAnnotationValue op_sum_decimal::ignoresSortedNodes(expr* fo, csize input) const
+{
+  return ANNOTATION_TRUE;
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+BoolAnnotationValue op_sum_integer::ignoresSortedNodes(expr* fo, csize input) const
+{
+  return ANNOTATION_TRUE;
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+BoolAnnotationValue fn_id::ignoresSortedNodes(expr* fo, csize input) const
+{
+  return ANNOTATION_TRUE;
+}
+
+
+BoolAnnotationValue fn_id::ignoresDuplicateNodes(expr* fo, csize input) const
 {
   if (input == 0)
     return ANNOTATION_TRUE;
@@ -840,7 +840,7 @@
 ********************************************************************************/
 BoolAnnotationValue fn_element_with_id::ignoresSortedNodes(
     expr* fo,
-    ulong input) const
+    csize input) const
 {
   return ANNOTATION_TRUE;
 }
@@ -848,7 +848,7 @@
 
 BoolAnnotationValue fn_element_with_id::ignoresDuplicateNodes(
     expr* fo,
-    ulong input) const
+    csize input) const
 {
   if (input == 0)
     return ANNOTATION_TRUE;
@@ -860,13 +860,13 @@
 /*******************************************************************************
 
 ********************************************************************************/
-BoolAnnotationValue fn_idref::ignoresSortedNodes(expr* fo, ulong input) const
+BoolAnnotationValue fn_idref::ignoresSortedNodes(expr* fo, csize input) const
 {
   return ANNOTATION_TRUE;
 }
 
 
-BoolAnnotationValue fn_idref::ignoresDuplicateNodes(expr* fo, ulong input) const
+BoolAnnotationValue fn_idref::ignoresDuplicateNodes(expr* fo, csize input) const
 {
   if (input == 0)
     return ANNOTATION_TRUE;

=== modified file 'src/functions/func_sequences_impl.h'
--- src/functions/func_sequences_impl.h	2011-06-14 17:26:33 +0000
+++ src/functions/func_sequences_impl.h	2011-11-29 22:22:26 +0000
@@ -52,6 +52,11 @@
     return true; 
   }
 
+  bool mustCopyInputNodes(expr* fo, csize input) const
+  {
+    return false;
+  }
+
   FunctionConsts::AnnotationValue producesSortedNodes() const
   {
     return FunctionConsts::PRESERVE;
@@ -62,9 +67,9 @@
     return FunctionConsts::PRESERVE;
   }
 
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong input) const;
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize input) const;
 
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong input) const;
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize input) const;
 
   CODEGEN_DECL();
 };
@@ -93,7 +98,12 @@
         const TypeManager* tm,
         const std::vector<xqtref_t>& arg_types) const;
 
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong input) const 
+  bool mustCopyInputNodes(expr* fo, csize input) const
+  {
+    return false;
+  }
+
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize input) const 
   {
     return ANNOTATION_TRUE;
   }
@@ -117,7 +127,12 @@
     theKind = FunctionConsts::FN_EXACTLY_ONE_1;
   }
 
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong input) const 
+  bool mustCopyInputNodes(expr* fo, csize input) const
+  {
+    return false;
+  }
+
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize input) const 
   {
     return ANNOTATION_TRUE;
   }
@@ -136,14 +151,24 @@
   {
   }
 
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong input) const 
-  {
-    return ANNOTATION_TRUE;
-  }
-
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong input) const 
-  {
-    return ANNOTATION_TRUE;
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize input) const 
+  {
+    return ANNOTATION_TRUE;
+  }
+
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize input) const 
+  {
+    return ANNOTATION_TRUE;
+  }
+
+  bool propagatesInputNodes(expr* fo, csize input) const
+  {
+    return true;
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize input) const
+  {
+    return true;
   }
 
   CODEGEN_DECL();
@@ -175,17 +200,17 @@
   {
   }
 
-  bool propagatesSortedNodes(ulong producer) const
-  {
-    return producer == 0;
-  }
-
-  bool propagatesDistinctNodes(ulong producer) const
-  {
-    return producer == 0;
-  }
-
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong input) const 
+  bool propagatesSortedNodes(csize producer) const
+  {
+    return producer == 0;
+  }
+
+  bool propagatesDistinctNodes(csize producer) const
+  {
+    return producer == 0;
+  }
+
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize input) const 
   {
     if (input == 0)
       return fo->getIgnoresSortedNodes();
@@ -193,7 +218,7 @@
     return ANNOTATION_TRUE;
   }
 
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong input) const 
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize input) const 
   {
     if (input == 0)
       return fo->getIgnoresDuplicateNodes();
@@ -201,6 +226,16 @@
     return ANNOTATION_TRUE;
   }
 
+  bool propagatesInputNodes(expr* fo, csize input) const
+  {
+    return ANNOTATION_TRUE_FIXED;
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize input) const
+  {
+    return true;
+  }
+
   CODEGEN_DECL();
 };
 
@@ -217,17 +252,17 @@
   {
   }
 
-  bool propagatesSortedNodes(ulong producer) const
+  bool propagatesSortedNodes(csize producer) const
   {
     return producer == 0;
   }
 
-  bool propagatesDistinctNodes(ulong producer) const
+  bool propagatesDistinctNodes(csize producer) const
   {
     return  producer == 0;
   }
 
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong input) const 
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize input) const 
   {
     if (input == 0)
       return fo->getIgnoresSortedNodes();
@@ -235,7 +270,7 @@
     return ANNOTATION_TRUE;
   }
 
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong input) const 
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize input) const 
   {
     if (input == 0)
       return fo->getIgnoresDuplicateNodes();
@@ -243,6 +278,16 @@
     return ANNOTATION_TRUE;
   }
 
+  bool propagatesInputNodes(expr* fo, csize input) const
+  {
+    return ANNOTATION_TRUE_FIXED;
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize input) const
+  {
+    return true;
+  }
+
   CODEGEN_DECL();
 };
 
@@ -262,12 +307,12 @@
                FunctionConsts::FN_MAX_2);
   }
 
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong input) const 
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize input) const 
   {
     return ANNOTATION_TRUE;
   }
 
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong input) const 
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize input) const 
   {
     return ANNOTATION_TRUE;
   }
@@ -291,12 +336,12 @@
                FunctionConsts::FN_MIN_2);
   }
 
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong input) const 
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize input) const 
   {
     return ANNOTATION_TRUE;
   }
 
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong input) const 
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize input) const 
   {
     return ANNOTATION_TRUE;
   }

=== added file 'src/functions/func_serialize_impl.cpp'
--- src/functions/func_serialize_impl.cpp	1970-01-01 00:00:00 +0000
+++ src/functions/func_serialize_impl.cpp	2011-11-29 22:22:26 +0000
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2006-2008 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "functions/function.h"
+#include "functions/func_parsing_and_serializing.h"
+
+namespace zorba
+{
+
+
+/*******************************************************************************
+  
+********************************************************************************/
+bool fn_serialize_3_0::mustCopyInputNodes(expr* fo, csize input) const
+{
+  bool res = function::mustCopyInputNodes(fo, input);
+
+  if (res == false)
+    return res;
+
+  return input == 0;
+}
+
+
+}
+

=== modified file 'src/functions/func_strings_impl.cpp'
--- src/functions/func_strings_impl.cpp	2011-11-15 18:24:02 +0000
+++ src/functions/func_strings_impl.cpp	2011-11-29 22:22:26 +0000
@@ -36,23 +36,29 @@
 ********************************************************************************/
 BoolAnnotationValue fn_concat::ignoresSortedNodes(
     expr* fo,
-    ulong input) const
+    csize input) const 
 {
   return ANNOTATION_TRUE;
 }
 
 
 BoolAnnotationValue fn_concat::ignoresDuplicateNodes(
-    expr* fo,
-    ulong input) const
+    expr* fo, 
+    csize input) const 
 {
   return ANNOTATION_TRUE;
 }
 
-function* fn_substring::specialize( static_context* sctx,
+
+/*******************************************************************************
+
+********************************************************************************/
+function* fn_substring::specialize( 
+    static_context* sctx,
     const std::vector<xqtref_t>& argTypes) const
 {
-    return NULL;
+  assert(false);
+  return NULL;
 }
 
 }

=== modified file 'src/functions/func_var_decl.cpp'
--- src/functions/func_var_decl.cpp	2011-11-17 16:32:04 +0000
+++ src/functions/func_var_decl.cpp	2011-11-29 22:22:26 +0000
@@ -53,6 +53,11 @@
 
   bool accessesDynCtx() const { return true; }
 
+  bool mustCopyInputNodes(expr* fo, csize input) const
+  {
+    return false;
+  }
+
   CODEGEN_DECL();
 };
 

=== modified file 'src/functions/function.cpp'
--- src/functions/function.cpp	2011-11-01 13:47:10 +0000
+++ src/functions/function.cpp	2011-11-29 22:22:26 +0000
@@ -16,6 +16,7 @@
 #include "stdafx.h"
 
 #include "compiler/expression/expr_base.h"
+#include "compiler/expression/fo_expr.h"
 
 #include "system/globalenv.h"
 
@@ -143,6 +144,53 @@
 
 
 /*******************************************************************************
+  Check whether this function may return a node that belongs to the same tree
+  as a node inside the sequence that is bound to the given input parameter.
+
+  Note: this method is not applicable to udfs.
+********************************************************************************/
+bool function::propagatesInputNodes(expr* fo, csize input) const
+{
+  TypeManager* tm = fo->get_type_manager();
+
+  // This method should be called only if the function may indeed return nodes
+  assert(!TypeOps::is_subtype(tm,
+                              *fo->get_return_type(),
+                              *GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_STAR));
+
+  xqtref_t argType = static_cast<fo_expr*>(fo)->get_arg(input)->get_return_type();
+
+  if (TypeOps::is_subtype(tm, *argType, *GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_STAR))
+    return false;
+
+  return true; // conservative answer
+}
+
+
+/*******************************************************************************
+  Check whether this function cares whether nodes bound to the given input 
+  parameter belong to "standalone" trees or not. A tree is standalone if it
+  does not contain references to other trees. Such references are created when
+  the optimizer decides that it is ok to avoid copying the referenced subtree
+  (as would be required by required by a strict implementation of the spec,
+  eg. during node construction). 
+
+  Note: this method is not applicable to udfs.
+********************************************************************************/
+bool function::mustCopyInputNodes(expr* fo, csize input) const
+{
+  TypeManager* tm = fo->get_type_manager();
+
+  xqtref_t argType = static_cast<fo_expr*>(fo)->get_arg(input)->get_return_type();
+
+  if (TypeOps::is_subtype(tm, *argType, *GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_STAR))
+    return false;
+
+  return true;
+}
+
+
+/*******************************************************************************
   Check whether this function produces, preserves, or eliminates duplicate nodes.
 ********************************************************************************/
 FunctionConsts::AnnotationValue function::producesDistinctNodes() const
@@ -193,7 +241,7 @@
   whether the result of this function, at the point where it is called, must
   be in doc order or not.
 ********************************************************************************/
-BoolAnnotationValue function::ignoresSortedNodes(expr* fo, ulong input) const
+BoolAnnotationValue function::ignoresSortedNodes(expr* fo, csize input) const
 {
   if (isVariadic() && input > 0)
   {
@@ -219,11 +267,10 @@
   whether the result of this function, at the point where it is called, must
   contain distinct nodes or not.
 ********************************************************************************/
-BoolAnnotationValue function::ignoresDuplicateNodes(expr* fo, ulong input) const
+BoolAnnotationValue function::ignoresDuplicateNodes(expr* fo, csize input) const
 {
   return ANNOTATION_FALSE;
 }
 
-
 }
 /* vim:set et sw=2 ts=2: */

=== modified file 'src/functions/function.h'
--- src/functions/function.h	2011-07-29 06:13:28 +0000
+++ src/functions/function.h	2011-11-29 22:22:26 +0000
@@ -168,17 +168,21 @@
 
   virtual bool isMap(ulong input) const;
 
+  virtual bool propagatesInputNodes(expr* fo, csize input) const;
+
+  virtual bool mustCopyInputNodes(expr* fo, csize input) const;
+
+  virtual bool propagatesSortedNodes(csize input) const { return false; }
+
+  virtual bool propagatesDistinctNodes(csize input) const { return false; }
+
   virtual FunctionConsts::AnnotationValue producesDistinctNodes() const;
 
   virtual FunctionConsts::AnnotationValue producesSortedNodes() const;
 
-  virtual bool propagatesSortedNodes(ulong input) const { return false; }
-
-  virtual bool propagatesDistinctNodes(ulong input) const { return false; }
-
-  virtual BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong input) const;
-
-  virtual BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong input) const;
+  virtual BoolAnnotationValue ignoresSortedNodes(expr* fo, csize input) const;
+
+  virtual BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize input) const;
 
   virtual bool isArithmeticFunction() const { return false; }
 

=== modified file 'src/functions/function_consts.h'
--- src/functions/function_consts.h	2011-11-17 16:32:04 +0000
+++ src/functions/function_consts.h	2011-11-29 22:22:26 +0000
@@ -153,8 +153,6 @@
   OP_NUMERIC_INTEGER_DIVIDE_2,
   OP_NUMERIC_MOD_2,
 
-  OP_NOTATION_EQUAL_2,
-
   OP_UNARY_PLUS_1,
   OP_UNARY_MINUS_1,
   OP_DOUBLE_UNARY_PLUS_1,
@@ -225,8 +223,6 @@
   OP_HOIST_1,
   OP_UNHOIST_1,
 
-  FN_FOP_1,
-
 #include "functions/function_enum.h"
 
   FN_MAX_FUNC
@@ -249,7 +245,9 @@
   isDeterministic = 4,
   isPrivate = 8,
   isBuiltin = 16,
-  isUDF = 32
+  isUDF = 32,
+  propagatesInputNodes = 64,
+  mustCopyInputNodes = 128
 } AnnotationFlags;
 
 };

=== modified file 'src/functions/pregenerated/func_accessors.h'
--- src/functions/pregenerated/func_accessors.h	2011-10-19 15:28:51 +0000
+++ src/functions/pregenerated/func_accessors.h	2011-11-29 22:22:26 +0000
@@ -43,9 +43,13 @@
 {
 public:
   fn_node_name_3_0(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 theXQueryVersion = StaticContextConsts::xquery_version_3_0;
-}
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
 
   CODEGEN_DECL();
 };
@@ -55,9 +59,13 @@
 {
 public:
   fn_node_name(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
 
   CODEGEN_DECL();
 };
@@ -68,9 +76,13 @@
 {
 public:
   fn_nilled(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
 
   CODEGEN_DECL();
 };
@@ -81,9 +93,13 @@
 {
 public:
   fn_string(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
 
   CODEGEN_DECL();
 };
@@ -94,9 +110,11 @@
 {
 public:
   fn_data_3_0(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 theXQueryVersion = StaticContextConsts::xquery_version_3_0;
-}
+  }
 
   xqtref_t getReturnType(
         const TypeManager* tm,
@@ -104,9 +122,11 @@
 
   bool isMap(ulong producer) const { return producer == 0; }
 
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong producer) const;
-
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong producer) const;
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize producer) const;
+
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize producer) const;
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const;
 
   CODEGEN_DECL();
 };
@@ -116,9 +136,11 @@
 {
 public:
   fn_data(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   xqtref_t getReturnType(
         const TypeManager* tm,
@@ -126,9 +148,11 @@
 
   bool isMap(ulong producer) const { return producer == 0; }
 
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong producer) const;
-
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong producer) const;
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize producer) const;
+
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize producer) const;
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const;
 
   CODEGEN_DECL();
 };
@@ -139,9 +163,13 @@
 {
 public:
   fn_base_uri(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return true; }
 
   CODEGEN_DECL();
 };
@@ -152,9 +180,13 @@
 {
 public:
   fn_document_uri_3_0(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 theXQueryVersion = StaticContextConsts::xquery_version_3_0;
-}
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
 
   CODEGEN_DECL();
 };
@@ -164,9 +196,13 @@
 {
 public:
   fn_document_uri(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
 
   CODEGEN_DECL();
 };
@@ -177,9 +213,13 @@
 {
 public:
   fn_root(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return true; }
 
   CODEGEN_DECL();
 };

=== modified file 'src/functions/pregenerated/func_any_uri.h'
--- src/functions/pregenerated/func_any_uri.h	2011-11-09 05:42:08 +0000
+++ src/functions/pregenerated/func_any_uri.h	2011-11-29 22:22:26 +0000
@@ -43,9 +43,11 @@
 {
 public:
   fn_resolve_uri(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 

=== modified file 'src/functions/pregenerated/func_base64.h'
--- src/functions/pregenerated/func_base64.h	2011-11-09 05:42:08 +0000
+++ src/functions/pregenerated/func_base64.h	2011-11-29 22:22:26 +0000
@@ -43,9 +43,11 @@
 {
 public:
   fn_zorba_base64_decode(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -56,9 +58,11 @@
 {
 public:
   fn_zorba_base64_encode(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };

=== modified file 'src/functions/pregenerated/func_booleans.h'
--- src/functions/pregenerated/func_booleans.h	2011-11-09 05:42:08 +0000
+++ src/functions/pregenerated/func_booleans.h	2011-11-29 22:22:26 +0000
@@ -43,9 +43,13 @@
 {
 public:
   op_is_same_node(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return true; }
 
   CODEGEN_DECL();
 };
@@ -56,9 +60,13 @@
 {
 public:
   op_node_before(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return true; }
 
   CODEGEN_DECL();
 };
@@ -69,9 +77,13 @@
 {
 public:
   op_node_after(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return true; }
 
   CODEGEN_DECL();
 };

=== modified file 'src/functions/pregenerated/func_collections.h'
--- src/functions/pregenerated/func_collections.h	2011-11-09 05:42:08 +0000
+++ src/functions/pregenerated/func_collections.h	2011-11-29 22:22:26 +0000
@@ -43,9 +43,11 @@
 {
 public:
   fn_collection(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 
@@ -60,9 +62,11 @@
 {
 public:
   zorba_store_collections_static_dml_collection(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 
@@ -87,12 +91,16 @@
 {
 public:
   zorba_store_collections_static_dml_index_of(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
+
   CODEGEN_DECL();
 };
 
@@ -102,14 +110,18 @@
 {
 public:
   zorba_store_collections_static_ddl_create(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   short getScriptingKind() const { return UPDATING_EXPR; }
 
   bool accessesDynCtx() const { return true; }
 
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return producer == 1; }
+
   CODEGEN_DECL();
 };
 
@@ -119,14 +131,18 @@
 {
 public:
   zorba_store_collections_static_ddl_delete(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   short getScriptingKind() const { return UPDATING_EXPR; }
 
   bool accessesDynCtx() const { return true; }
 
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
+
   CODEGEN_DECL();
 };
 
@@ -136,14 +152,18 @@
 {
 public:
   zorba_store_collections_static_dml_insert_nodes(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   short getScriptingKind() const { return UPDATING_EXPR; }
 
   bool accessesDynCtx() const { return true; }
 
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return producer == 1; }
+
   CODEGEN_DECL();
 };
 
@@ -153,14 +173,18 @@
 {
 public:
   zorba_store_collections_static_dml_insert_nodes_first(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   short getScriptingKind() const { return UPDATING_EXPR; }
 
   bool accessesDynCtx() const { return true; }
 
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return producer == 1; }
+
   CODEGEN_DECL();
 };
 
@@ -170,14 +194,18 @@
 {
 public:
   zorba_store_collections_static_dml_insert_nodes_last(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   short getScriptingKind() const { return UPDATING_EXPR; }
 
   bool accessesDynCtx() const { return true; }
 
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return producer == 1; }
+
   CODEGEN_DECL();
 };
 
@@ -187,14 +215,18 @@
 {
 public:
   zorba_store_collections_static_dml_insert_nodes_before(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   short getScriptingKind() const { return UPDATING_EXPR; }
 
   bool accessesDynCtx() const { return true; }
 
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return producer == 2; }
+
   CODEGEN_DECL();
 };
 
@@ -204,14 +236,18 @@
 {
 public:
   zorba_store_collections_static_dml_insert_nodes_after(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   short getScriptingKind() const { return UPDATING_EXPR; }
 
   bool accessesDynCtx() const { return true; }
 
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return producer == 2; }
+
   CODEGEN_DECL();
 };
 
@@ -221,14 +257,20 @@
 {
 public:
   zorba_store_collections_static_dml_apply_insert_nodes(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   short getScriptingKind() const { return APPLYING_EXPR; }
 
   bool accessesDynCtx() const { return true; }
 
+  bool propagatesInputNodes(expr* fo, csize producer) const;
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return producer == 1; }
+
   CODEGEN_DECL();
 };
 
@@ -238,14 +280,20 @@
 {
 public:
   zorba_store_collections_static_dml_apply_insert_nodes_first(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   short getScriptingKind() const { return APPLYING_EXPR; }
 
   bool accessesDynCtx() const { return true; }
 
+  bool propagatesInputNodes(expr* fo, csize producer) const;
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return producer == 1; }
+
   CODEGEN_DECL();
 };
 
@@ -255,14 +303,20 @@
 {
 public:
   zorba_store_collections_static_dml_apply_insert_nodes_last(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   short getScriptingKind() const { return APPLYING_EXPR; }
 
   bool accessesDynCtx() const { return true; }
 
+  bool propagatesInputNodes(expr* fo, csize producer) const;
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return producer == 1; }
+
   CODEGEN_DECL();
 };
 
@@ -272,14 +326,20 @@
 {
 public:
   zorba_store_collections_static_dml_apply_insert_nodes_before(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   short getScriptingKind() const { return APPLYING_EXPR; }
 
   bool accessesDynCtx() const { return true; }
 
+  bool propagatesInputNodes(expr* fo, csize producer) const;
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return producer == 2; }
+
   CODEGEN_DECL();
 };
 
@@ -289,14 +349,20 @@
 {
 public:
   zorba_store_collections_static_dml_apply_insert_nodes_after(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   short getScriptingKind() const { return APPLYING_EXPR; }
 
   bool accessesDynCtx() const { return true; }
 
+  bool propagatesInputNodes(expr* fo, csize producer) const;
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return producer == 2; }
+
   CODEGEN_DECL();
 };
 
@@ -306,17 +372,21 @@
 {
 public:
   zorba_store_collections_static_dml_delete_nodes(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   short getScriptingKind() const { return UPDATING_EXPR; }
 
   bool accessesDynCtx() const { return true; }
 
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong producer) const;
-
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong producer) const;
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize producer) const;
+
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize producer) const;
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return producer == 0; }
 
   CODEGEN_DECL();
 };
@@ -327,14 +397,18 @@
 {
 public:
   zorba_store_collections_static_dml_delete_node_first(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   short getScriptingKind() const { return UPDATING_EXPR; }
 
   bool accessesDynCtx() const { return true; }
 
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
+
   CODEGEN_DECL();
 };
 
@@ -344,14 +418,18 @@
 {
 public:
   zorba_store_collections_static_dml_delete_node_last(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   short getScriptingKind() const { return UPDATING_EXPR; }
 
   bool accessesDynCtx() const { return true; }
 
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
+
   CODEGEN_DECL();
 };
 
@@ -361,12 +439,16 @@
 {
 public:
   zorba_store_collections_static_dml_collection_name(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return true; }
+
   CODEGEN_DECL();
 };
 
@@ -376,9 +458,11 @@
 {
 public:
   zorba_store_collections_static_ddl_is_available_collection(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 
@@ -391,9 +475,11 @@
 {
 public:
   zorba_store_collections_static_ddl_available_collections(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 
@@ -406,9 +492,11 @@
 {
 public:
   zorba_store_indexes_static_ddl_is_available_index(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 
@@ -421,9 +509,11 @@
 {
 public:
   zorba_store_indexes_static_ddl_available_indexes(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 
@@ -436,9 +526,11 @@
 {
 public:
   zorba_store_integrity_constraints_static_ddl_is_activated_integrity_constraint(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 
@@ -451,9 +543,11 @@
 {
 public:
   zorba_store_integrity_constraints_static_ddl_activated_integrity_constraints(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 
@@ -466,9 +560,11 @@
 {
 public:
   zorba_store_collections_static_ddl_is_declared_collection(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -479,9 +575,11 @@
 {
 public:
   zorba_store_collections_static_ddl_declared_collections(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -492,9 +590,11 @@
 {
 public:
   zorba_store_indexes_static_ddl_is_declared_index(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -505,9 +605,11 @@
 {
 public:
   zorba_store_indexes_static_ddl_declared_indexes(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -518,9 +620,11 @@
 {
 public:
   zorba_store_integrity_constraints_static_ddl_is_declared_integrity_constraint(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -531,9 +635,11 @@
 {
 public:
   zorba_store_integrity_constraints_static_ddl_declared_integrity_constraints(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };

=== modified file 'src/functions/pregenerated/func_context.h'
--- src/functions/pregenerated/func_context.h	2011-11-09 05:42:08 +0000
+++ src/functions/pregenerated/func_context.h	2011-11-29 22:22:26 +0000
@@ -43,9 +43,11 @@
 {
 public:
   fn_current_dateTime(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 
@@ -58,9 +60,11 @@
 {
 public:
   fn_current_date(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 
@@ -73,9 +77,11 @@
 {
 public:
   fn_current_time(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 
@@ -88,9 +94,11 @@
 {
 public:
   fn_implicit_timezone(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 
@@ -103,9 +111,11 @@
 {
 public:
   fn_default_collation(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 
@@ -118,9 +128,11 @@
 {
 public:
   fn_position(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -131,9 +143,11 @@
 {
 public:
   fn_last(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -144,9 +158,11 @@
 {
 public:
   fn_static_base_uri(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };

=== modified file 'src/functions/pregenerated/func_documents.h'
--- src/functions/pregenerated/func_documents.h	2011-11-09 05:42:08 +0000
+++ src/functions/pregenerated/func_documents.h	2011-11-29 22:22:26 +0000
@@ -43,14 +43,18 @@
 {
 public:
   zorba_store_documents_put(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   short getScriptingKind() const { return UPDATING_EXPR; }
 
   bool accessesDynCtx() const { return true; }
 
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return producer == 1; }
+
   CODEGEN_DECL();
 };
 
@@ -60,9 +64,11 @@
 {
 public:
   zorba_store_documents_remove(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   short getScriptingKind() const { return UPDATING_EXPR; }
 
@@ -77,9 +83,11 @@
 {
 public:
   zorba_store_documents_document(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 
@@ -92,9 +100,11 @@
 {
 public:
   zorba_store_documents_available_documents(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 
@@ -107,9 +117,11 @@
 {
 public:
   zorba_store_documents_is_available_document(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 

=== modified file 'src/functions/pregenerated/func_durations_dates_times.h'
--- src/functions/pregenerated/func_durations_dates_times.h	2011-11-09 05:42:08 +0000
+++ src/functions/pregenerated/func_durations_dates_times.h	2011-11-29 22:22:26 +0000
@@ -43,9 +43,11 @@
 {
 public:
   fn_years_from_duration(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -56,9 +58,11 @@
 {
 public:
   fn_months_from_duration(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -69,9 +73,11 @@
 {
 public:
   fn_days_from_duration(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -82,9 +88,11 @@
 {
 public:
   fn_hours_from_duration(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -95,9 +103,11 @@
 {
 public:
   fn_minutes_from_duration(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -108,9 +118,11 @@
 {
 public:
   fn_seconds_from_duration(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -121,9 +133,11 @@
 {
 public:
   fn_year_from_dateTime(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -134,9 +148,11 @@
 {
 public:
   fn_month_from_dateTime(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -147,9 +163,11 @@
 {
 public:
   fn_day_from_dateTime(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -160,9 +178,11 @@
 {
 public:
   fn_hours_from_dateTime(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -173,9 +193,11 @@
 {
 public:
   fn_minutes_from_dateTime(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -186,9 +208,11 @@
 {
 public:
   fn_seconds_from_dateTime(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -199,9 +223,11 @@
 {
 public:
   fn_timezone_from_dateTime(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -212,9 +238,11 @@
 {
 public:
   fn_year_from_date(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -225,9 +253,11 @@
 {
 public:
   fn_month_from_date(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -238,9 +268,11 @@
 {
 public:
   fn_day_from_date(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -251,9 +283,11 @@
 {
 public:
   fn_timezone_from_date(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -264,9 +298,11 @@
 {
 public:
   fn_hours_from_time(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -277,9 +313,11 @@
 {
 public:
   fn_minutes_from_time(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -290,9 +328,11 @@
 {
 public:
   fn_seconds_from_time(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -303,9 +343,11 @@
 {
 public:
   fn_timezone_from_time(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };

=== modified file 'src/functions/pregenerated/func_errors_and_diagnostics.h'
--- src/functions/pregenerated/func_errors_and_diagnostics.h	2011-11-17 16:44:50 +0000
+++ src/functions/pregenerated/func_errors_and_diagnostics.h	2011-11-29 22:22:26 +0000
@@ -43,12 +43,16 @@
 {
 public:
   fn_error(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   short getScriptingKind() const { return VACUOUS_EXPR; }
 
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return producer == 2; }
+
   CODEGEN_DECL();
 };
 
@@ -58,19 +62,21 @@
 {
 public:
   fn_trace(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool isMap(ulong producer) const { return producer == 0; }
 
-  bool propagatesDistinctNodes(ulong producer) const { return producer == 0; }
-
-  bool propagatesSortedNodes(ulong producer) const { return producer == 0; }
-
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong producer) const;
-
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong producer) const;
+  bool propagatesDistinctNodes(csize producer) const { return producer == 0; }
+
+  bool propagatesSortedNodes(csize producer) const { return producer == 0; }
+
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize producer) const;
+
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize producer) const;
 
   bool accessesDynCtx() const { return true; }
 

=== modified file 'src/functions/pregenerated/func_fetch.h'
--- src/functions/pregenerated/func_fetch.h	2011-11-09 05:42:08 +0000
+++ src/functions/pregenerated/func_fetch.h	2011-11-29 22:22:26 +0000
@@ -43,9 +43,11 @@
 {
 public:
   fn_zorba_fetch_content(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 
@@ -58,9 +60,11 @@
 {
 public:
   fn_zorba_fetch_content_type(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 

=== modified file 'src/functions/pregenerated/func_fnput.h'
--- src/functions/pregenerated/func_fnput.h	2011-11-09 05:42:08 +0000
+++ src/functions/pregenerated/func_fnput.h	2011-11-29 22:22:26 +0000
@@ -43,14 +43,18 @@
 {
 public:
   fn_put(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   short getScriptingKind() const { return UPDATING_EXPR; }
 
   bool accessesDynCtx() const { return true; }
 
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return producer == 0; }
+
   CODEGEN_DECL();
 };
 

=== modified file 'src/functions/pregenerated/func_function_item_iter.h'
--- src/functions/pregenerated/func_function_item_iter.h	2011-11-09 05:42:08 +0000
+++ src/functions/pregenerated/func_function_item_iter.h	2011-11-29 22:22:26 +0000
@@ -43,9 +43,11 @@
 {
 public:
   fn_function_name_3_0(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 theXQueryVersion = StaticContextConsts::xquery_version_3_0;
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -56,9 +58,11 @@
 {
 public:
   fn_function_arity_3_0(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 theXQueryVersion = StaticContextConsts::xquery_version_3_0;
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -69,9 +73,11 @@
 {
 public:
   fn_partial_apply_3_0(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 theXQueryVersion = StaticContextConsts::xquery_version_3_0;
-}
+  }
 
   CODEGEN_DECL();
 };

=== modified file 'src/functions/pregenerated/func_ic_ddl.h'
--- src/functions/pregenerated/func_ic_ddl.h	2011-11-09 05:42:08 +0000
+++ src/functions/pregenerated/func_ic_ddl.h	2011-11-29 22:22:26 +0000
@@ -43,9 +43,11 @@
 {
 public:
   zorba_store_integrity_constraints_static_ddl_activate(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   short getScriptingKind() const { return UPDATING_EXPR; }
 
@@ -60,9 +62,11 @@
 {
 public:
   zorba_store_integrity_constraints_static_ddl_deactivate(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   short getScriptingKind() const { return UPDATING_EXPR; }
 
@@ -77,9 +81,11 @@
 {
 public:
   zorba_store_integrity_constraints_static_dml_check_integrity_constraint(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 

=== modified file 'src/functions/pregenerated/func_maps.h'
--- src/functions/pregenerated/func_maps.h	2011-11-09 05:42:08 +0000
+++ src/functions/pregenerated/func_maps.h	2011-11-29 22:22:26 +0000
@@ -43,9 +43,11 @@
 {
 public:
   zorba_store_data_structure_unordered_map_create(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   short getScriptingKind() const { return SEQUENTIAL_FUNC_EXPR; }
 
@@ -60,9 +62,11 @@
 {
 public:
   zorba_store_data_structure_unordered_map_delete(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   short getScriptingKind() const { return SEQUENTIAL_FUNC_EXPR; }
 
@@ -77,9 +81,11 @@
 {
 public:
   zorba_store_data_structure_unordered_map_get(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 
@@ -92,9 +98,11 @@
 {
 public:
   zorba_store_data_structure_unordered_map_insert(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   short getScriptingKind() const { return SEQUENTIAL_FUNC_EXPR; }
 
@@ -109,9 +117,11 @@
 {
 public:
   zorba_store_data_structure_unordered_map_remove(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   short getScriptingKind() const { return SEQUENTIAL_FUNC_EXPR; }
 
@@ -126,9 +136,11 @@
 {
 public:
   zorba_store_data_structure_unordered_map_keys(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 
@@ -141,9 +153,11 @@
 {
 public:
   zorba_store_data_structure_unordered_map_size(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 
@@ -156,9 +170,11 @@
 {
 public:
   zorba_store_data_structure_unordered_map_available_maps(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 

=== modified file 'src/functions/pregenerated/func_maths.h'
--- src/functions/pregenerated/func_maths.h	2011-11-09 05:42:08 +0000
+++ src/functions/pregenerated/func_maths.h	2011-11-29 22:22:26 +0000
@@ -43,9 +43,11 @@
 {
 public:
   math_sqrt(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -56,9 +58,11 @@
 {
 public:
   math_exp(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -69,9 +73,11 @@
 {
 public:
   math_exp10(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -82,9 +88,11 @@
 {
 public:
   math_log(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -95,9 +103,11 @@
 {
 public:
   math_log10(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -108,9 +118,11 @@
 {
 public:
   math_sin(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -121,9 +133,11 @@
 {
 public:
   math_cos(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -134,9 +148,11 @@
 {
 public:
   math_tan(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -147,9 +163,11 @@
 {
 public:
   math_asin(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -160,9 +178,11 @@
 {
 public:
   math_acos(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -173,9 +193,11 @@
 {
 public:
   math_atan(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -186,9 +208,11 @@
 {
 public:
   math_atan2(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -199,9 +223,11 @@
 {
 public:
   fn_zorba_math_cosh(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -212,9 +238,11 @@
 {
 public:
   fn_zorba_math_acosh(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -225,9 +253,11 @@
 {
 public:
   fn_zorba_math_fmod(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -238,9 +268,11 @@
 {
 public:
   fn_zorba_math_ldexp(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -251,9 +283,11 @@
 {
 public:
   math_pow(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -264,9 +298,11 @@
 {
 public:
   fn_zorba_math_sinh(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -277,9 +313,11 @@
 {
 public:
   fn_zorba_math_asinh(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -290,9 +328,11 @@
 {
 public:
   fn_zorba_math_tanh(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -303,9 +343,11 @@
 {
 public:
   fn_zorba_math_atanh(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -316,9 +358,11 @@
 {
 public:
   math_pi(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -329,9 +373,11 @@
 {
 public:
   fn_zorba_math_is_inf(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -342,9 +388,11 @@
 {
 public:
   fn_zorba_math_is_nan(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -355,9 +403,11 @@
 {
 public:
   fn_zorba_math_modf(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -368,9 +418,11 @@
 {
 public:
   fn_zorba_math_frexp(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };

=== modified file 'src/functions/pregenerated/func_node_position.h'
--- src/functions/pregenerated/func_node_position.h	2011-10-15 10:41:19 +0000
+++ src/functions/pregenerated/func_node_position.h	2011-11-29 22:22:26 +0000
@@ -43,9 +43,11 @@
 {
 public:
   fn_zorba_pos_node_position(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -56,9 +58,11 @@
 {
 public:
   fn_zorba_pos_ancestor_of(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -69,9 +73,11 @@
 {
 public:
   fn_zorba_pos_following_sibling_of(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -82,9 +88,11 @@
 {
 public:
   fn_zorba_pos_following_of(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -95,9 +103,11 @@
 {
 public:
   fn_zorba_pos_in_subtree_of(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -108,9 +118,11 @@
 {
 public:
   fn_zorba_pos_descendant_of(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -121,9 +133,11 @@
 {
 public:
   fn_zorba_pos_preceding_sibling_of(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -134,9 +148,11 @@
 {
 public:
   fn_zorba_pos_preceding_of(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -147,9 +163,11 @@
 {
 public:
   fn_zorba_pos_child_of(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -160,9 +178,11 @@
 {
 public:
   fn_zorba_pos_attribute_of(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -173,9 +193,11 @@
 {
 public:
   fn_zorba_pos_parent_of(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -186,9 +208,11 @@
 {
 public:
   fn_zorba_pos_preceding_in_document_order_of(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -199,9 +223,11 @@
 {
 public:
   fn_zorba_pos_following_in_document_order_of(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -212,9 +238,11 @@
 {
 public:
   fn_zorba_pos_level(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -225,9 +253,11 @@
 {
 public:
   fn_zorba_pos_is_attribute(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -238,9 +268,11 @@
 {
 public:
   fn_zorba_pos_is_comment(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -251,9 +283,11 @@
 {
 public:
   fn_zorba_pos_is_document(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -264,9 +298,11 @@
 {
 public:
   fn_zorba_pos_is_element(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -277,9 +313,11 @@
 {
 public:
   fn_zorba_pos_is_processing_instruction(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -290,9 +328,11 @@
 {
 public:
   fn_zorba_pos_is_text(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -303,9 +343,11 @@
 {
 public:
   fn_zorba_pos_sibling_of(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -316,9 +358,11 @@
 {
 public:
   fn_zorba_pos_in_same_tree_of(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -329,9 +373,11 @@
 {
 public:
   fn_zorba_pos_in_collection(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -342,9 +388,11 @@
 {
 public:
   fn_zorba_pos_in_same_collection_of(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };

=== modified file 'src/functions/pregenerated/func_nodes.h'
--- src/functions/pregenerated/func_nodes.h	2011-11-09 05:42:08 +0000
+++ src/functions/pregenerated/func_nodes.h	2011-11-29 22:22:26 +0000
@@ -43,9 +43,13 @@
 {
 public:
   fn_zorba_ref_node_reference(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return true; }
 
   CODEGEN_DECL();
 };
@@ -56,9 +60,11 @@
 {
 public:
   fn_zorba_ref_node_by_reference(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -69,9 +75,13 @@
 {
 public:
   fn_local_name(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
 
   CODEGEN_DECL();
 };
@@ -82,9 +92,13 @@
 {
 public:
   fn_namespace_uri(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
 
   CODEGEN_DECL();
 };
@@ -95,9 +109,13 @@
 {
 public:
   fn_lang(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
 
   CODEGEN_DECL();
 };
@@ -108,9 +126,11 @@
 {
 public:
   fn_number(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -121,9 +141,11 @@
 {
 public:
   fn_has_children_3_0(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 theXQueryVersion = StaticContextConsts::xquery_version_3_0;
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -134,9 +156,13 @@
 {
 public:
   fn_innermost_3_0(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 theXQueryVersion = StaticContextConsts::xquery_version_3_0;
-}
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return true; }
 
   CODEGEN_DECL();
 };
@@ -147,9 +173,13 @@
 {
 public:
   fn_outermost_3_0(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 theXQueryVersion = StaticContextConsts::xquery_version_3_0;
-}
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return true; }
 
   CODEGEN_DECL();
 };
@@ -160,9 +190,13 @@
 {
 public:
   fn_generate_id_3_0(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 theXQueryVersion = StaticContextConsts::xquery_version_3_0;
-}
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return true; }
 
   CODEGEN_DECL();
 };
@@ -173,9 +207,13 @@
 {
 public:
   fn_zorba_node_ancestor_of(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return true; }
 
   CODEGEN_DECL();
 };
@@ -186,9 +224,13 @@
 {
 public:
   fn_zorba_node_descendant_of(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return true; }
 
   CODEGEN_DECL();
 };
@@ -199,9 +241,13 @@
 {
 public:
   fn_zorba_node_parent_of(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return true; }
 
   CODEGEN_DECL();
 };
@@ -212,9 +258,13 @@
 {
 public:
   fn_zorba_node_child_of(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return true; }
 
   CODEGEN_DECL();
 };
@@ -225,9 +275,13 @@
 {
 public:
   fn_zorba_node_following_of(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return true; }
 
   CODEGEN_DECL();
 };
@@ -238,9 +292,13 @@
 {
 public:
   fn_zorba_node_preceding_of(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return true; }
 
   CODEGEN_DECL();
 };
@@ -251,9 +309,13 @@
 {
 public:
   fn_zorba_node_following_sibling_of(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return true; }
 
   CODEGEN_DECL();
 };
@@ -264,9 +326,13 @@
 {
 public:
   fn_zorba_node_preceding_sibling_of(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return true; }
 
   CODEGEN_DECL();
 };
@@ -277,9 +343,13 @@
 {
 public:
   fn_zorba_node_level(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return true; }
 
   CODEGEN_DECL();
 };
@@ -290,9 +360,13 @@
 {
 public:
   fn_zorba_node_least_common_ancestor(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return true; }
 
   CODEGEN_DECL();
 };

=== modified file 'src/functions/pregenerated/func_numerics.h'
--- src/functions/pregenerated/func_numerics.h	2011-11-09 05:42:08 +0000
+++ src/functions/pregenerated/func_numerics.h	2011-11-29 22:22:26 +0000
@@ -43,9 +43,11 @@
 {
 public:
   fn_abs(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -56,9 +58,11 @@
 {
 public:
   fn_ceiling(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -69,9 +73,11 @@
 {
 public:
   fn_floor(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   xqtref_t getReturnType(
         const TypeManager* tm,
@@ -86,9 +92,11 @@
 {
 public:
   fn_round_3_0(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 theXQueryVersion = StaticContextConsts::xquery_version_3_0;
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -98,9 +106,11 @@
 {
 public:
   fn_round(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -111,9 +121,11 @@
 {
 public:
   fn_round_half_to_even(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -124,9 +136,11 @@
 {
 public:
   fn_format_number_3_0(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 theXQueryVersion = StaticContextConsts::xquery_version_3_0;
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -137,9 +151,11 @@
 {
 public:
   fn_format_integer_3_0(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 theXQueryVersion = StaticContextConsts::xquery_version_3_0;
-}
+  }
 
   CODEGEN_DECL();
 };

=== modified file 'src/functions/pregenerated/func_other_diagnostics.h'
--- src/functions/pregenerated/func_other_diagnostics.h	2011-11-09 05:42:08 +0000
+++ src/functions/pregenerated/func_other_diagnostics.h	2011-11-29 22:22:26 +0000
@@ -43,9 +43,11 @@
 {
 public:
   op_zorba_read_line(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 
@@ -58,9 +60,11 @@
 {
 public:
   fn_zorba_util_print(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 

=== modified file 'src/functions/pregenerated/func_parse_fragment.h'
--- src/functions/pregenerated/func_parse_fragment.h	2011-11-09 05:42:08 +0000
+++ src/functions/pregenerated/func_parse_fragment.h	2011-11-29 22:22:26 +0000
@@ -43,9 +43,11 @@
 {
 public:
   fn_zorba_xml_parse_xml_fragment(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 

=== modified file 'src/functions/pregenerated/func_parsing_and_serializing.h'
--- src/functions/pregenerated/func_parsing_and_serializing.h	2011-11-09 05:42:08 +0000
+++ src/functions/pregenerated/func_parsing_and_serializing.h	2011-11-29 22:22:26 +0000
@@ -43,9 +43,11 @@
 {
 public:
   fn_parse_xml_3_0(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 theXQueryVersion = StaticContextConsts::xquery_version_3_0;
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 
@@ -60,14 +62,18 @@
 {
 public:
   fn_serialize_3_0(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 theXQueryVersion = StaticContextConsts::xquery_version_3_0;
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 
   bool isSource() const { return true; }
 
+  bool mustCopyInputNodes(expr* fo, csize producer) const;
+
   CODEGEN_DECL();
 };
 

=== modified file 'src/functions/pregenerated/func_qnames.h'
--- src/functions/pregenerated/func_qnames.h	2011-11-09 05:42:08 +0000
+++ src/functions/pregenerated/func_qnames.h	2011-11-29 22:22:26 +0000
@@ -43,9 +43,13 @@
 {
 public:
   fn_resolve_QName(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return producer == 1; }
 
   CODEGEN_DECL();
 };
@@ -56,9 +60,11 @@
 {
 public:
   fn_QName(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -69,9 +75,11 @@
 {
 public:
   op_QName_equal(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -82,9 +90,11 @@
 {
 public:
   fn_prefix_from_QName(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -95,9 +105,11 @@
 {
 public:
   fn_local_name_from_QName(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -108,9 +120,11 @@
 {
 public:
   fn_namespace_uri_from_QName(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -121,9 +135,13 @@
 {
 public:
   fn_namespace_uri_for_prefix(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return producer == 1; }
 
   CODEGEN_DECL();
 };
@@ -134,9 +152,13 @@
 {
 public:
   fn_in_scope_prefixes(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return true; }
 
   CODEGEN_DECL();
 };

=== modified file 'src/functions/pregenerated/func_random.h'
--- src/functions/pregenerated/func_random.h	2011-11-09 05:42:08 +0000
+++ src/functions/pregenerated/func_random.h	2011-11-29 22:22:26 +0000
@@ -43,9 +43,11 @@
 {
 public:
   fn_zorba_random_seeded_random(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -56,9 +58,11 @@
 {
 public:
   fn_zorba_random_random(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -69,10 +73,12 @@
 {
 public:
   fn_zorba_util_uuid(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 setDeterministic(false);
 
-}
+  }
 
   CODEGEN_DECL();
 };

=== modified file 'src/functions/pregenerated/func_schema.h'
--- src/functions/pregenerated/func_schema.h	2011-11-09 05:42:08 +0000
+++ src/functions/pregenerated/func_schema.h	2011-11-29 22:22:26 +0000
@@ -43,14 +43,18 @@
 {
 public:
   fn_zorba_schema_validate_in_place(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   short getScriptingKind() const { return UPDATING_EXPR; }
 
   bool accessesDynCtx() const { return true; }
 
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return true; }
+
   CODEGEN_DECL();
 };
 
@@ -60,9 +64,13 @@
 {
 public:
   fn_zorba_util_schema_type(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
 
   CODEGEN_DECL();
 };
@@ -73,9 +81,13 @@
 {
 public:
   fn_zorba_schema_schema_type(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
 
   CODEGEN_DECL();
 };
@@ -86,9 +98,13 @@
 {
 public:
   fn_zorba_schema_is_validated(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
 
   CODEGEN_DECL();
 };

=== modified file 'src/functions/pregenerated/func_sctx.h'
--- src/functions/pregenerated/func_sctx.h	2011-11-09 05:42:08 +0000
+++ src/functions/pregenerated/func_sctx.h	2011-11-29 22:22:26 +0000
@@ -43,9 +43,11 @@
 {
 public:
   fn_zorba_introspect_sctx_statically_known_namespaces(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -56,9 +58,11 @@
 {
 public:
   fn_zorba_introspect_sctx_default_function_namespace(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -69,9 +73,11 @@
 {
 public:
   fn_zorba_introspect_sctx_base_uri(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -82,9 +88,11 @@
 {
 public:
   fn_zorba_introspect_sctx_default_collation(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -95,9 +103,11 @@
 {
 public:
   fn_zorba_introspect_sctx_statically_known_namespace_binding(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -108,9 +118,11 @@
 {
 public:
   fn_zorba_introspect_sctx_in_scope_variables(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -121,9 +133,11 @@
 {
 public:
   fn_zorba_introspect_sctx_default_collection_type(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -134,9 +148,11 @@
 {
 public:
   fn_zorba_introspect_sctx_xpath10_compatibility_mode(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -147,9 +163,11 @@
 {
 public:
   fn_zorba_introspect_sctx_statically_known_documents(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -160,9 +178,11 @@
 {
 public:
   fn_zorba_introspect_sctx_statically_known_document_type(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -173,9 +193,11 @@
 {
 public:
   fn_zorba_introspect_sctx_statically_known_collations(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -186,9 +208,11 @@
 {
 public:
   fn_zorba_introspect_sctx_construction_mode(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -199,9 +223,11 @@
 {
 public:
   fn_zorba_introspect_sctx_ordering_mode(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -212,9 +238,11 @@
 {
 public:
   fn_zorba_introspect_sctx_default_order(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -225,9 +253,11 @@
 {
 public:
   fn_zorba_introspect_sctx_boundary_space_policy(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -238,9 +268,11 @@
 {
 public:
   fn_zorba_introspect_sctx_copy_namespaces_mode(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -251,9 +283,11 @@
 {
 public:
   fn_zorba_introspect_sctx_function_names(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -264,9 +298,11 @@
 {
 public:
   fn_zorba_introspect_sctx_function_arguments_count(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -277,9 +313,11 @@
 {
 public:
   fn_zorba_introspect_sctx_in_scope_schema_types(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -290,9 +328,11 @@
 {
 public:
   fn_zorba_introspect_sctx_in_scope_element_declarations(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -303,9 +343,11 @@
 {
 public:
   fn_zorba_introspect_sctx_in_scope_attribute_declarations(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -316,9 +358,11 @@
 {
 public:
   fn_zorba_introspect_sctx_in_scope_element_groups(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -329,9 +373,11 @@
 {
 public:
   fn_zorba_introspect_sctx_in_scope_attribute_groups(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -342,9 +388,11 @@
 {
 public:
   fn_zorba_introspect_sctx_option(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -355,9 +403,11 @@
 {
 public:
   fn_zorba_introspect_sctx_function_annotations(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };

=== modified file 'src/functions/pregenerated/func_sequences.h'
--- src/functions/pregenerated/func_sequences.h	2011-11-09 05:42:08 +0000
+++ src/functions/pregenerated/func_sequences.h	2011-11-29 22:22:26 +0000
@@ -43,17 +43,21 @@
 {
 public:
   op_concatenate(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   xqtref_t getReturnType(
         const TypeManager* tm,
         const std::vector<xqtref_t>& arg_types) const;
 
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong producer) const;
-
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong producer) const;
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize producer) const;
+
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize producer) const;
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
 
   CODEGEN_DECL();
 };
@@ -64,9 +68,11 @@
 {
 public:
   fn_index_of(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -77,13 +83,17 @@
 {
 public:
   fn_empty(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
-
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong producer) const;
-
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong producer) const;
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize producer) const;
+
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize producer) const;
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
 
   CODEGEN_DECL();
 };
@@ -94,13 +104,17 @@
 {
 public:
   fn_exists(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
-
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong producer) const;
-
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong producer) const;
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize producer) const;
+
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize producer) const;
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
 
   CODEGEN_DECL();
 };
@@ -111,17 +125,19 @@
 {
 public:
   fn_distinct_values(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   xqtref_t getReturnType(
         const TypeManager* tm,
         const std::vector<xqtref_t>& arg_types) const;
 
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong producer) const;
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize producer) const;
 
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong producer) const;
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize producer) const;
 
   CODEGEN_DECL();
 };
@@ -132,13 +148,17 @@
 {
 public:
   fn_insert_before(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
-
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong producer) const;
-
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong producer) const;
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize producer) const;
+
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize producer) const;
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
 
   CODEGEN_DECL();
 };
@@ -149,21 +169,25 @@
 {
 public:
   fn_remove(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   xqtref_t getReturnType(
         const TypeManager* tm,
         const std::vector<xqtref_t>& arg_types) const;
 
-  bool propagatesDistinctNodes(ulong producer) const { return producer == 0; }
-
-  bool propagatesSortedNodes(ulong producer) const { return producer == 0; }
-
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong producer) const;
-
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong producer) const;
+  bool propagatesDistinctNodes(csize producer) const { return producer == 0; }
+
+  bool propagatesSortedNodes(csize producer) const { return producer == 0; }
+
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize producer) const;
+
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize producer) const;
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
 
   CODEGEN_DECL();
 };
@@ -174,19 +198,23 @@
 {
 public:
   fn_reverse(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   xqtref_t getReturnType(
         const TypeManager* tm,
         const std::vector<xqtref_t>& arg_types) const;
 
-  bool propagatesDistinctNodes(ulong producer) const { return producer == 0; }
-
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong producer) const;
-
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong producer) const;
+  bool propagatesDistinctNodes(csize producer) const { return producer == 0; }
+
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize producer) const;
+
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize producer) const;
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
 
   CODEGEN_DECL();
 };
@@ -197,17 +225,21 @@
 {
 public:
   fn_subsequence(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   xqtref_t getReturnType(
         const TypeManager* tm,
         const std::vector<xqtref_t>& arg_types) const;
 
-  bool propagatesDistinctNodes(ulong producer) const { return producer == 0; }
-
-  bool propagatesSortedNodes(ulong producer) const { return producer == 0; }
+  bool propagatesDistinctNodes(csize producer) const { return producer == 0; }
+
+  bool propagatesSortedNodes(csize producer) const { return producer == 0; }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
 
   bool serializable() const { return true; }
 
@@ -220,17 +252,21 @@
 {
 public:
   op_zorba_subsequence_int(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   xqtref_t getReturnType(
         const TypeManager* tm,
         const std::vector<xqtref_t>& arg_types) const;
 
-  bool propagatesDistinctNodes(ulong producer) const { return producer == 0; }
-
-  bool propagatesSortedNodes(ulong producer) const { return producer == 0; }
+  bool propagatesDistinctNodes(csize producer) const { return producer == 0; }
+
+  bool propagatesSortedNodes(csize producer) const { return producer == 0; }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
 
   CODEGEN_DECL();
 };
@@ -241,17 +277,21 @@
 {
 public:
   op_zorba_sequence_point_access(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   xqtref_t getReturnType(
         const TypeManager* tm,
         const std::vector<xqtref_t>& arg_types) const;
 
-  bool propagatesDistinctNodes(ulong producer) const { return producer == 0; }
-
-  bool propagatesSortedNodes(ulong producer) const { return producer == 0; }
+  bool propagatesDistinctNodes(csize producer) const { return producer == 0; }
+
+  bool propagatesSortedNodes(csize producer) const { return producer == 0; }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
 
   CODEGEN_DECL();
 };
@@ -262,15 +302,19 @@
 {
 public:
   fn_zero_or_one(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   xqtref_t getReturnType(
         const TypeManager* tm,
         const std::vector<xqtref_t>& arg_types) const;
 
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong producer) const;
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize producer) const;
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
 
   CODEGEN_DECL();
 };
@@ -281,9 +325,11 @@
 {
 public:
   fn_one_or_more(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   xqtref_t getReturnType(
         const TypeManager* tm,
@@ -291,13 +337,15 @@
 
   bool isMap(ulong producer) const { return producer == 0; }
 
-  bool propagatesDistinctNodes(ulong producer) const { return producer == 0; }
-
-  bool propagatesSortedNodes(ulong producer) const { return producer == 0; }
-
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong producer) const;
-
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong producer) const;
+  bool propagatesDistinctNodes(csize producer) const { return producer == 0; }
+
+  bool propagatesSortedNodes(csize producer) const { return producer == 0; }
+
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize producer) const;
+
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize producer) const;
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
 
   CODEGEN_DECL();
 };
@@ -308,12 +356,16 @@
 {
 public:
   fn_deep_equal(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
+
   CODEGEN_DECL();
 };
 
@@ -323,11 +375,15 @@
 {
 public:
   fn_count(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
-
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong producer) const;
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize producer) const;
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
 
   CODEGEN_DECL();
 };
@@ -338,11 +394,13 @@
 {
 public:
   fn_avg(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
-
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong producer) const;
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize producer) const;
 
   CODEGEN_DECL();
 };
@@ -353,16 +411,18 @@
 {
 public:
   fn_sum(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool specializable() const { return true; }
 
   function* specialize( static_context* sctx,
                         const std::vector<xqtref_t>& argTypes) const;
 
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong producer) const;
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize producer) const;
 
   CODEGEN_DECL();
 };
@@ -373,11 +433,13 @@
 {
 public:
   op_sum_double(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
-
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong producer) const;
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize producer) const;
 
   CODEGEN_DECL();
 };
@@ -388,11 +450,13 @@
 {
 public:
   op_sum_float(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
-
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong producer) const;
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize producer) const;
 
   CODEGEN_DECL();
 };
@@ -403,11 +467,13 @@
 {
 public:
   op_sum_decimal(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
-
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong producer) const;
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize producer) const;
 
   CODEGEN_DECL();
 };
@@ -418,11 +484,13 @@
 {
 public:
   op_sum_integer(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
-
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong producer) const;
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize producer) const;
 
   CODEGEN_DECL();
 };
@@ -433,9 +501,11 @@
 {
 public:
   op_to(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -446,9 +516,11 @@
 {
 public:
   fn_id(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   FunctionConsts::AnnotationValue producesDistinctNodes() const 
   {
@@ -460,9 +532,11 @@
     return FunctionConsts::YES;
   }
 
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong producer) const;
-
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong producer) const;
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize producer) const;
+
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize producer) const;
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return producer == 1; }
 
   CODEGEN_DECL();
 };
@@ -473,9 +547,11 @@
 {
 public:
   fn_element_with_id(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   FunctionConsts::AnnotationValue producesDistinctNodes() const 
   {
@@ -487,9 +563,11 @@
     return FunctionConsts::YES;
   }
 
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong producer) const;
-
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong producer) const;
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize producer) const;
+
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize producer) const;
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return producer == 1; }
 
   CODEGEN_DECL();
 };
@@ -500,9 +578,11 @@
 {
 public:
   fn_idref(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   FunctionConsts::AnnotationValue producesDistinctNodes() const 
   {
@@ -514,9 +594,11 @@
     return FunctionConsts::YES;
   }
 
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong producer) const;
-
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong producer) const;
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize producer) const;
+
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize producer) const;
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return producer == 1; }
 
   CODEGEN_DECL();
 };
@@ -527,9 +609,11 @@
 {
 public:
   fn_doc(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool accessesDynCtx() const { return true; }
 
@@ -544,9 +628,11 @@
 {
 public:
   fn_doc_available(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };

=== modified file 'src/functions/pregenerated/func_strings.h'
--- src/functions/pregenerated/func_strings.h	2011-11-22 04:19:18 +0000
+++ src/functions/pregenerated/func_strings.h	2011-11-29 22:22:26 +0000
@@ -43,9 +43,11 @@
 {
 public:
   fn_codepoints_to_string(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -56,9 +58,11 @@
 {
 public:
   fn_string_to_codepoints(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -69,9 +73,11 @@
 {
 public:
   fn_compare(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -82,9 +88,11 @@
 {
 public:
   fn_codepoint_equal(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -95,13 +103,15 @@
 {
 public:
   fn_concat(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
-
-}
-
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong producer) const;
-
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong producer) const;
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize producer) const;
+
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize producer) const;
 
   CODEGEN_DECL();
 };
@@ -112,9 +122,11 @@
 {
 public:
   fn_string_join_3_0(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 theXQueryVersion = StaticContextConsts::xquery_version_3_0;
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -124,9 +136,11 @@
 {
 public:
   fn_string_join(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -137,9 +151,11 @@
 {
 public:
   fn_substring(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   bool specializable() const { return true; }
 
@@ -155,9 +171,11 @@
 {
 public:
   op_substring_int(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -168,9 +186,11 @@
 {
 public:
   fn_string_length(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -181,9 +201,11 @@
 {
 public:
   fn_normalize_space(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -194,9 +216,11 @@
 {
 public:
   fn_normalize_unicode(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -207,9 +231,11 @@
 {
 public:
   fn_upper_case(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -220,9 +246,11 @@
 {
 public:
   fn_lower_case(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -233,9 +261,11 @@
 {
 public:
   fn_translate(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -246,9 +276,11 @@
 {
 public:
   fn_encode_for_uri(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -259,9 +291,11 @@
 {
 public:
   fn_iri_to_uri(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -272,9 +306,11 @@
 {
 public:
   fn_escape_html_uri(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -285,9 +321,11 @@
 {
 public:
   fn_contains(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -298,9 +336,11 @@
 {
 public:
   fn_starts_with(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -311,9 +351,11 @@
 {
 public:
   fn_ends_with(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -324,9 +366,11 @@
 {
 public:
   fn_substring_before(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -337,9 +381,11 @@
 {
 public:
   fn_substring_after(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -350,9 +396,11 @@
 {
 public:
   fn_matches(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -363,9 +411,11 @@
 {
 public:
   fn_replace(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -376,9 +426,11 @@
 {
 public:
   fn_tokenize(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -389,9 +441,11 @@
 {
 public:
   fn_analyze_string_3_0(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 theXQueryVersion = StaticContextConsts::xquery_version_3_0;
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -402,9 +456,11 @@
 {
 public:
   fn_zorba_string_materialize(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -415,9 +471,11 @@
 {
 public:
   fn_zorba_string_is_streamable(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };

=== modified file 'src/functions/pregenerated/func_xqdoc.h'
--- src/functions/pregenerated/func_xqdoc.h	2011-11-09 05:42:08 +0000
+++ src/functions/pregenerated/func_xqdoc.h	2011-11-29 22:22:26 +0000
@@ -43,9 +43,11 @@
 {
 public:
   fn_zorba_xqdoc_xqdoc(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };
@@ -56,9 +58,11 @@
 {
 public:
   fn_zorba_xqdoc_xqdoc_content(const signature& sig, FunctionConsts::FunctionKind kind)
-    : function(sig, kind) {
+    : 
+    function(sig, kind)
+  {
 
-}
+  }
 
   CODEGEN_DECL();
 };

=== modified file 'src/functions/udf.cpp'
--- src/functions/udf.cpp	2011-10-18 17:37:41 +0000
+++ src/functions/udf.cpp	2011-11-29 22:22:26 +0000
@@ -281,9 +281,7 @@
 /*******************************************************************************
 
 ********************************************************************************/
-BoolAnnotationValue user_function::ignoresSortedNodes(
-    expr* fo,
-    ulong input) const
+BoolAnnotationValue user_function::ignoresSortedNodes(expr* fo, csize input) const
 {
   assert(isOptimized());
   assert(input < theArgVars.size());
@@ -297,7 +295,7 @@
 ********************************************************************************/
 BoolAnnotationValue user_function::ignoresDuplicateNodes(
     expr* fo,
-    ulong input) const
+    csize input) const
 {
   assert(isOptimized());
   assert(input < theArgVars.size());
@@ -309,6 +307,24 @@
 /*******************************************************************************
 
 ********************************************************************************/
+BoolAnnotationValue user_function::mustCopyNodes(expr* fo, csize input) const
+{
+  BoolAnnotationValue callerMustCopy = fo->getMustCopyNodes();
+  BoolAnnotationValue argMustCopy = theArgVars[input]->getMustCopyNodes();
+
+  if (argMustCopy == ANNOTATION_TRUE)
+  {
+    // The decision depends on the caller
+    return callerMustCopy;
+  }
+
+  return argMustCopy;
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
 const std::vector<user_function::ArgVarRefs>& user_function::getArgVarsRefs() const
 {
   return theArgVarsRefs;
@@ -318,7 +334,7 @@
 /*******************************************************************************
 
 ********************************************************************************/
-  PlanIter_t user_function::getPlan(CompilerCB* ccb, uint32_t& planStateSize)
+PlanIter_t user_function::getPlan(CompilerCB* ccb, uint32_t& planStateSize)
 {
   if (thePlan == NULL)
   {

=== modified file 'src/functions/udf.h'
--- src/functions/udf.h	2011-10-18 17:37:41 +0000
+++ src/functions/udf.h	2011-11-29 22:22:26 +0000
@@ -150,9 +150,11 @@
 
   bool accessesDynCtx() const;
 
-  BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong input) const;
-
-  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong input) const;
+  BoolAnnotationValue ignoresSortedNodes(expr* fo, csize input) const;
+
+  BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize input) const;
+
+  BoolAnnotationValue mustCopyNodes(expr* fo, csize input) const;
 
   PlanIter_t getPlan(CompilerCB* cb, uint32_t& planStateSize);
   

=== modified file 'src/runtime/collections/collections_impl.cpp'
--- src/runtime/collections/collections_impl.cpp	2011-11-09 21:38:25 +0000
+++ src/runtime/collections/collections_impl.cpp	2011-11-29 22:22:26 +0000
@@ -580,7 +580,7 @@
     for (size_t i = 0; i < lDeclaredAnnotations->size(); ++i)
     {
       store::Annotation_t lAnn = new store::Annotation();
-      AnnotationInternal* lTmp = lDeclaredAnnotations->getAnnotation(i);
+      AnnotationInternal* lTmp = lDeclaredAnnotations->get(i);
 
       lAnn->theName = lTmp->getQName();
 

=== modified file 'src/runtime/core/constructors.cpp'
--- src/runtime/core/constructors.cpp	2011-08-26 15:58:33 +0000
+++ src/runtime/core/constructors.cpp	2011-11-29 22:22:26 +0000
@@ -17,6 +17,7 @@
 
 #include "zorbautils/fatal.h"
 #include "diagnostics/assert.h"
+#include "diagnostics/util_macros.h"
 #include "diagnostics/xquery_diagnostics.h"
 
 #include "system/globalenv.h"
@@ -50,9 +51,6 @@
 SERIALIZABLE_CLASS_VERSIONS(DocumentIterator)
 END_SERIALIZABLE_CLASS_VERSIONS(DocumentIterator)
 
-SERIALIZABLE_CLASS_VERSIONS(DocumentContentIterator)
-END_SERIALIZABLE_CLASS_VERSIONS(DocumentContentIterator)
-
 SERIALIZABLE_CLASS_VERSIONS(ElementIterator)
 END_SERIALIZABLE_CLASS_VERSIONS(ElementIterator)
 
@@ -77,6 +75,33 @@
 /*******************************************************************************
 
 ********************************************************************************/
+DocumentIterator::DocumentIterator(
+    static_context* sctx,
+    const QueryLoc& loc,
+    PlanIter_t& child,
+    bool copyInputNodes)
+  :
+  UnaryBaseIterator<DocumentIterator, PlanIteratorState>(sctx, loc, child),
+  theTypePreserve(false),
+  theNsPreserve(false),
+  theNsInherit(false),
+  theCopyInputNodes(copyInputNodes)
+{
+}
+
+
+void DocumentIterator::serialize(::zorba::serialization::Archiver& ar)
+{
+  serialize_baseclass(ar, 
+  (UnaryBaseIterator<DocumentIterator, PlanIteratorState>*)this);
+
+  ar & theTypePreserve;
+  ar & theNsPreserve;
+  ar & theNsInherit;
+  ar & theCopyInputNodes;
+}
+
+
 void DocumentIterator::openImpl(PlanState& planState, uint32_t& offset)
 {
   UnaryBaseIterator<DocumentIterator, PlanIteratorState>::openImpl(planState, offset);
@@ -112,14 +137,19 @@
   path.push(result);
 
   // Compute the children of the element node
-  copymode.set(true, theTypePreserve, theNsPreserve, theNsInherit);
+  copymode.set(theCopyInputNodes, theTypePreserve, theNsPreserve, theNsInherit);
 
   try
   {
     while (consumeNext(child, theChild, planState))
     {
       ZORBA_FATAL(child->isNode(), "");
-      ZORBA_FATAL(child->getNodeKind() != store::StoreConsts::attributeNode, "");
+
+      if (child->getNodeKind() == store::StoreConsts::attributeNode)
+      {
+        RAISE_ERROR(err::XPTY0004, loc,
+        ERROR_PARAMS(ZED(NoAttrNodesInDocument)));
+      }
 
       if (child->getParent() != result.getp())
       {
@@ -156,39 +186,6 @@
 /*******************************************************************************
 
 ********************************************************************************/
-bool DocumentContentIterator::nextImpl(store::Item_t& result, PlanState& planState) const
-{
-  PlanIteratorState* state;
-  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
-
-  while (true)
-  {
-    if (!consumeNext(result, theChild.getp(), planState))
-      break;
-
-    if (result->isNode() &&
-        result->getNodeKind() == store::StoreConsts::attributeNode)
-    {
-      throw XQUERY_EXCEPTION(
-        err::XPTY0004,
-        ERROR_PARAMS( ZED( NoAttrNodesInDocument ) ),
-        ERROR_LOC( loc )
-      );
-    }
-
-    STACK_PUSH(true, state);
-  }
-
-  STACK_END (state);
-}
-
-
-UNARY_ACCEPT(DocumentContentIterator);
-
-
-/*******************************************************************************
-
-********************************************************************************/
 void ElementIteratorState::init(PlanState&)
 {
 }
@@ -201,13 +198,14 @@
 
 
 ElementIterator::ElementIterator (
-    static_context*          sctx,
-    const QueryLoc&          loc,
-    PlanIter_t&              qnameIter,
-    PlanIter_t&              attrsIter,
-    PlanIter_t&              childrenIter,
+    static_context* sctx,
+    const QueryLoc& loc,
+    PlanIter_t& qnameIter,
+    PlanIter_t& attrsIter,
+    PlanIter_t& childrenIter,
     const namespace_context* localBindings,
-    bool                     isRoot)
+    bool isRoot,
+    bool copyInputNodes)
   :
   NoaryBaseIterator<ElementIterator, ElementIteratorState>(sctx, loc),
   theQNameIter(qnameIter),
@@ -217,8 +215,26 @@
   theIsRoot(isRoot),
   theTypePreserve(false),
   theNsPreserve(false),
-  theNsInherit(false)
-{
+  theNsInherit(false),
+  theCopyInputNodes(copyInputNodes)
+{
+}
+
+
+void ElementIterator::serialize(::zorba::serialization::Archiver& ar)
+{
+  serialize_baseclass(ar, (NoaryBaseIterator<ElementIterator,
+                           ElementIteratorState>*)this);
+  ar & theQNameIter;
+  ar & theAttributesIter;
+  ar & theChildrenIter;
+  ar & theNamespacesIter;
+  ar & theLocalBindings;
+  ar & theIsRoot;
+  ar & theTypePreserve;
+  ar & theNsPreserve;
+  ar & theNsInherit;
+  ar & theCopyInputNodes;
 }
 
 
@@ -319,20 +335,16 @@
 
   if (nodeName->getLocalName().empty())
   {
-    throw XQUERY_EXCEPTION(
-      err::XQDY0074,
-      ERROR_PARAMS( "", ZED( NoEmptyLocalname ) ),
-      ERROR_LOC( loc )
-    );
+    RAISE_ERROR(err::XQDY0074, loc,  ERROR_PARAMS("", ZED(NoEmptyLocalname)));
   }
 
   if (nodeName->getPrefix() == "xmlns" ||
-        nodeName->getNamespace() == "http://www.w3.org/2000/xmlns/"; ||
-        (nodeName->getPrefix() == "xml" && nodeName->getNamespace() != "http://www.w3.org/XML/1998/namespace";) ||
-        (nodeName->getPrefix() != "xml" && nodeName->getNamespace() == "http://www.w3.org/XML/1998/namespace";))
-      throw XQUERY_EXCEPTION(
-        err::XQDY0096, ERROR_PARAMS(nodeName->getStringValue()), ERROR_LOC(loc)
-      );
+      nodeName->getNamespace() == "http://www.w3.org/2000/xmlns/"; ||
+      (nodeName->getPrefix() == "xml" && nodeName->getNamespace() != "http://www.w3.org/XML/1998/namespace";) ||
+      (nodeName->getPrefix() != "xml" && nodeName->getNamespace() == "http://www.w3.org/XML/1998/namespace";))
+  {
+    RAISE_ERROR(err::XQDY0096, loc, ERROR_PARAMS(nodeName->getStringValue()));
+  }
 
   typeName = (theTypePreserve ?
               GENV_TYPESYSTEM.XS_ANY_TYPE_QNAME :
@@ -353,9 +365,7 @@
     // replaced with the explicit one.
     state->baseUri = theSctx->get_base_uri();
     if (state->baseUri.empty())
-      throw XQUERY_EXCEPTION(
-        err::XPST0001, ERROR_PARAMS( "", ZED( BaseURI ) ), ERROR_LOC( loc )
-      );
+      RAISE_ERROR(err::XPST0001, loc, ERROR_PARAMS("", ZED(BaseURI)));
 
     store::NsBindings bindings;
     theLocalBindings->getAllBindings(bindings);
@@ -386,7 +396,7 @@
   path.push(result);
 
   // Compute the attributes and children of the element node
-  copymode.set(true, theTypePreserve, theNsPreserve, theNsInherit);
+  copymode.set(theCopyInputNodes, theTypePreserve, theNsPreserve, theNsInherit);
 
   try
   {
@@ -420,7 +430,8 @@
         {
           // Remove empty text nodes, as per 3.8.3.1 Computed Element Constructors
           // http://www.w3.org/TR/xquery-30/#id-computedElements
-          if (child->getNodeKind() == store::StoreConsts::textNode && child->getStringValue().empty())
+          if (child->getNodeKind() == store::StoreConsts::textNode &&
+              child->getStringValue().empty())
             continue;
           else
             break;
@@ -452,7 +463,9 @@
         // Else copy the child node if it was not a node constructed by a
         // directly nested constructor
         else if (child->getParent() != result.getp())
+        {
           child->copy(result, copymode);
+        }
 
         valid = consumeNext(child, theChildrenIter, planState);
       }
@@ -537,22 +550,16 @@
   {
     if (theQName->getLocalName().empty())
     {
-      throw XQUERY_EXCEPTION(
-        err::XQDY0074,
-        ERROR_PARAMS( "", ZED( NoEmptyLocalname ) ),
-        ERROR_LOC( loc )
-      );
+      RAISE_ERROR(err::XQDY0074, loc,
+      ERROR_PARAMS("", ZED(NoEmptyLocalname)));
     }
 
     if (ZSTREQ(theQName->getNamespace(), "http://www.w3.org/2000/xmlns/";) ||
         (theQName->getNamespace().empty() &&
          ZSTREQ(theQName->getLocalName(), "xmlns")))
     {
-      throw XQUERY_EXCEPTION(
-        err::XQDY0044,
-        ERROR_PARAMS( theQName->getStringValue() ),
-        ERROR_LOC( loc )
-      );
+      RAISE_ERROR(err::XQDY0044, loc,
+      ERROR_PARAMS(theQName->getStringValue()));
     }
 
     if ((ZSTREQ(theQName->getNamespace(), "http://www.w3.org/XML/1998/namespace";) &&
@@ -561,11 +568,8 @@
         (ZSTREQ(theQName->getPrefix(), "xml") &&
          !ZSTREQ(theQName->getNamespace(), "http://www.w3.org/XML/1998/namespace";)))
     {
-      throw XQUERY_EXCEPTION(
-        err::XQDY0044,
-        ERROR_PARAMS( theQName->getStringValue() ),
-        ERROR_LOC( loc )
-      );
+      RAISE_ERROR(err::XQDY0044, loc,
+      ERROR_PARAMS(theQName->getStringValue()));
     }
 
     if ((ZSTREQ(theQName->getNamespace(), "http://www.w3.org/2000/xmlns/";) &&

=== modified file 'src/runtime/core/constructors.h'
--- src/runtime/core/constructors.h	2011-08-26 15:58:33 +0000
+++ src/runtime/core/constructors.h	2011-11-29 22:22:26 +0000
@@ -47,6 +47,7 @@
   bool      theTypePreserve;
   bool      theNsPreserve;
   bool      theNsInherit;
+  bool      theCopyInputNodes;
 
 public:
   SERIALIZABLE_CLASS(DocumentIterator);
@@ -55,25 +56,16 @@
   DocumentIterator,
   UnaryBaseIterator<DocumentIterator, PlanIteratorState>);
 
-  void serialize(::zorba::serialization::Archiver& ar)
-  {
-    serialize_baseclass(ar, 
-    (UnaryBaseIterator<DocumentIterator, PlanIteratorState>*)this);
-
-    ar & theTypePreserve;
-    ar & theNsPreserve;
-    ar & theNsInherit;
-  }
+  void serialize(::zorba::serialization::Archiver& ar);
 
 public:
-  DocumentIterator(static_context* sctx, const QueryLoc& loc, PlanIter_t& aChild)
-    :
-    UnaryBaseIterator<DocumentIterator, PlanIteratorState>(sctx, loc, aChild)
-  {
-    theTypePreserve = false;//pre initialize things to avoid valgrind warnings during serialization
-    theNsPreserve = false;
-    theNsInherit = false;
-  }
+  DocumentIterator(
+      static_context* sctx,
+      const QueryLoc& loc,
+      PlanIter_t& aChild,
+      bool copyInputNodes);
+
+  bool copyInputNodes() const { return theCopyInputNodes; }
 
   void accept(PlanIterVisitor& v) const;
 
@@ -83,18 +75,6 @@
 };
 
 
-/*********************************************************************************
-
-  DocumentContentIterator checks that the children of a doc node do not include
-  any attribute nodes.
-  
-  theChild:      Iter that produces the content of the document element
-
-*********************************************************************************/
-UNARY_ITER(DocumentContentIterator);
-
-
-
 /*******************************************************************************
 
   ElementIterator constructs an element node and its subtree.
@@ -137,6 +117,7 @@
   bool                theTypePreserve;
   bool                theNsPreserve;
   bool                theNsInherit;
+  bool                theCopyInputNodes;
 
 public:
   SERIALIZABLE_CLASS(ElementIterator);
@@ -145,20 +126,7 @@
   ElementIterator,
   NoaryBaseIterator<ElementIterator, ElementIteratorState>);
 
-  void serialize(::zorba::serialization::Archiver& ar)
-  {
-    serialize_baseclass(ar, (NoaryBaseIterator<ElementIterator,
-                                               ElementIteratorState>*)this);
-    ar & theQNameIter;
-    ar & theAttributesIter;
-    ar & theChildrenIter;
-    ar & theNamespacesIter;
-    ar & theLocalBindings;
-    ar & theIsRoot;
-    ar & theTypePreserve;
-    ar & theNsPreserve;
-    ar & theNsInherit;
-  }
+  void serialize(::zorba::serialization::Archiver& ar);
 
 public:
   ElementIterator (
@@ -168,7 +136,10 @@
       PlanIter_t&         aAttrs,
       PlanIter_t&         aChildren,
       const namespace_context* localBindings,
-      bool                isRoot);
+      bool                isRoot,
+      bool                copyInputNodes);
+
+  bool copyInputNodes() const { return theCopyInputNodes; }
 
   uint32_t getStateSizeOfSubtree() const;
   

=== modified file 'src/runtime/core/flwor_iterator.cpp'
=== modified file 'src/runtime/eval/eval.cpp'
--- src/runtime/eval/eval.cpp	2011-08-19 23:22:48 +0000
+++ src/runtime/eval/eval.cpp	2011-11-29 22:22:26 +0000
@@ -72,13 +72,15 @@
     const std::vector<store::Item_t>& aVarNames,
     const std::vector<xqtref_t>& aVarTypes,
     expr_script_kind_t scriptingKind,
-    const store::NsBindings& localBindings)
+    const store::NsBindings& localBindings,
+    bool doNodeCopy)
   : 
   NaryBaseIterator<EvalIterator, EvalIteratorState>(sctx, loc, children),
   theVarNames(aVarNames),
   theVarTypes(aVarTypes),
   theScriptingKind(scriptingKind),
-  theLocalBindings(localBindings)
+  theLocalBindings(localBindings),
+  theDoNodeCopy(doNodeCopy)
 {
 }
 
@@ -104,6 +106,7 @@
   ar & theVarTypes;
   SERIALIZE_ENUM(enum expr_script_kind_t, theScriptingKind);
   ar & theLocalBindings;
+  ar & theDoNodeCopy;
 }
 
 
@@ -120,14 +123,14 @@
   CONSUME(item, 0);
 
   {
-    ulong numEvalVars = theVarNames.size();
+    csize numEvalVars = theVarNames.size();
 
     // Create an "outer" sctx and register into it (a) global vars corresponding
     // to the eval vars and (b) the expression-level ns bindings at the place 
     // where the eval call appears at.
     static_context* outerSctx = theSctx->create_child_context();
 
-    for (ulong i = 0; i < numEvalVars; ++i)
+    for (csize i = 0; i < numEvalVars; ++i)
     {
       var_expr_t ve = new var_expr(outerSctx,
                                    loc,
@@ -154,6 +157,7 @@
     CompilerCB* evalCCB = new CompilerCB(*planState.theCompilerCB);
     evalCCB->theIsEval = true;
     evalCCB->theRootSctx = evalSctx;
+    evalCCB->theConfig.for_serialization_only = !theDoNodeCopy;
     (evalCCB->theSctxMap)[1] = evalSctx;
 
     state->ccb.reset(evalCCB);
@@ -253,7 +257,7 @@
   // For each of the eval vars, place its value into the evalDctx. The var
   // value is represented as a PlanIteratorWrapper over the subplan that
   // evaluates the domain expr of the eval var.
-  for (ulong i = 0; i < theChildren.size() - 1; ++i)
+  for (csize i = 0; i < theChildren.size() - 1; ++i)
   {
     var_expr* evalVar = outerSctx->lookup_var(theVarNames[i],
                                               loc,

=== modified file 'src/runtime/eval/eval.h'
--- src/runtime/eval/eval.h	2011-06-14 17:26:33 +0000
+++ src/runtime/eval/eval.h	2011-11-29 22:22:26 +0000
@@ -42,13 +42,18 @@
 
 /****************************************************************************//**
   The 1st child iterator computes the query string, and the next N child
-  iterators compute the domain expression of each of the "using" variables.
-
-  theVarNames : The names of the "using" vars. These will be added to the prolog
-                of the eval query as external var declarations. An error will be
-                raised if the prolog of the eval query declares or imports any 
-                variable with the same name as the name of a "using" variable.
-  theVarTypes : The data types of the "using" vars.
+  iterators compute the domain expression of each of the "eval" variables.
+
+  theVarNames:
+  ------------
+  The names of the "eval" vars. These will be added to the prolog of the eval 
+  query as external var declarations. If the prolog of the eval query declares
+  or imports any variable with the same name as the name of an eval variable,
+  then the inner var will hide the eval var. Furthermore, if the inner
+
+  theVarTypes:
+  ------------
+  The data types of the "eval" vars.
 ********************************************************************************/
 class EvalIterator : public NaryBaseIterator<EvalIterator, EvalIteratorState>
 { 
@@ -57,6 +62,7 @@
   std::vector<xqtref_t>       theVarTypes;
   expr_script_kind_t          theScriptingKind;
   store::NsBindings           theLocalBindings;
+  bool                        theDoNodeCopy;
 
 public:
   SERIALIZABLE_CLASS(EvalIterator);
@@ -64,7 +70,7 @@
   SERIALIZABLE_CLASS_CONSTRUCTOR2T(EvalIterator,
   NaryBaseIterator<EvalIterator, EvalIteratorState>);
 
-  void serialize( ::zorba::serialization::Archiver& ar);
+  void serialize(::zorba::serialization::Archiver& ar);
 
   EvalIterator(
       static_context* sctx,
@@ -73,7 +79,8 @@
       const std::vector<store::Item_t>& aVarNames,
       const std::vector<xqtref_t>& aVarTypes,
       expr_script_kind_t scriptingKind,
-      const store::NsBindings& localBindings);
+      const store::NsBindings& localBindings,
+      bool doNodeCopy);
 
   ~EvalIterator();
 

=== modified file 'src/runtime/introspection/sctx_impl.cpp'
--- src/runtime/introspection/sctx_impl.cpp	2011-07-11 15:20:26 +0000
+++ src/runtime/introspection/sctx_impl.cpp	2011-11-29 22:22:26 +0000
@@ -1057,7 +1057,7 @@
          &&
          lState->thePosition < lState->theFunction->getAnnotationList()->size())
   {
-    aResult = lState->theFunction->getAnnotationList()->getAnnotation(lState->thePosition)->getQName();
+    aResult = lState->theFunction->getAnnotationList()->get(lState->thePosition)->getQName();
     STACK_PUSH(true, lState);
     ++lState->thePosition;
   }

=== modified file 'src/runtime/scripting/scripting.cpp'
--- src/runtime/scripting/scripting.cpp	2011-06-14 17:26:33 +0000
+++ src/runtime/scripting/scripting.cpp	2011-11-29 22:22:26 +0000
@@ -77,7 +77,7 @@
 
   std::vector<PlanIter_t>::const_iterator lIter = theChildren.begin();
   std::vector<PlanIter_t>::const_iterator lEnd = theChildren.end();
-  for ( ; lIter != lEnd; ++lIter )
+  for (; lIter != lEnd; ++lIter)
   {
     (*lIter)->accept(v);
   }
@@ -86,27 +86,26 @@
 }
 
 
-bool
-SequentialIterator::nextImpl(store::Item_t& result, PlanState& planState) const
+bool SequentialIterator::nextImpl(store::Item_t& result, PlanState& planState) const
 {
-  ulong i = 0;
+  csize i = 0;
 
   PlanIteratorState* state;
   DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
 
-  for (; i < (ulong)theChildren.size(); ++i) 
+  for (; i < theChildren.size(); ++i) 
   {
     while (consumeNext(result, theChildren[i].getp(), planState))
     {
-      if (i == (ulong)theChildren.size() - 1)
+      if (i == theChildren.size() - 1)
       {
         STACK_PUSH(true, state);
-        i = (ulong)theChildren.size() - 1;
+        i = theChildren.size() - 1;
       }
     }
   }
 
-  STACK_END (state);
+  STACK_END(state);
 }
 
 

=== modified file 'src/runtime/spec/accessors/accessors.xml'
--- src/runtime/spec/accessors/accessors.xml	2011-06-10 16:58:54 +0000
+++ src/runtime/spec/accessors/accessors.xml	2011-11-29 22:22:26 +0000
@@ -32,13 +32,20 @@
     <zorba:description author="Zorba Team">fn:node-name</zorba:description>
     
     <zorba:function>
+
       <zorba:signature localname="node-name" prefix="fn" version="3.0">
         <zorba:output>xs:QName?</zorba:output>
       </zorba:signature>
+
       <zorba:signature localname="node-name" prefix="fn">
-            <zorba:param>node()?</zorba:param>
-            <zorba:output>xs:QName?</zorba:output>
-        </zorba:signature>
+        <zorba:param>node()?</zorba:param>
+        <zorba:output>xs:QName?</zorba:output>
+      </zorba:signature>
+
+      <zorba:methods>
+        <zorba:mustCopyInputNodes value="false"/>
+      </zorba:methods>
+
     </zorba:function>
     
 </zorba:iterator>
@@ -54,10 +61,16 @@
     <zorba:description author="Zorba Team">fn:nilled</zorba:description>
     
     <zorba:function>
-        <zorba:signature localname="nilled" prefix="fn">
-            <zorba:param>node()?</zorba:param>
-            <zorba:output>xs:boolean?</zorba:output>
-        </zorba:signature>
+
+      <zorba:signature localname="nilled" prefix="fn">
+        <zorba:param>node()?</zorba:param>
+        <zorba:output>xs:boolean?</zorba:output>
+      </zorba:signature>
+
+      <zorba:methods>
+        <zorba:mustCopyInputNodes value="false"/>
+      </zorba:methods>
+
     </zorba:function>
     
 </zorba:iterator>
@@ -74,6 +87,7 @@
   <zorba:description author="Zorba Team">fn:string</zorba:description>
 
   <zorba:function generateCodegen="false">
+
     <zorba:signature localname="string" prefix="fn">
       <zorba:output>xs:string</zorba:output>
     </zorba:signature>
@@ -82,6 +96,11 @@
       <zorba:param>item()?</zorba:param>
       <zorba:output>xs:string</zorba:output>
     </zorba:signature>
+
+    <zorba:methods>
+      <zorba:mustCopyInputNodes value="false"/>
+    </zorba:methods>
+
   </zorba:function>
 
   <zorba:state  generateInit="true" generateReset="true"
@@ -111,6 +130,7 @@
     <zorba:signature localname="data" prefix="fn" version="3.0">
       <zorba:output>xs:anyAtomicType*</zorba:output>
     </zorba:signature>
+
     <zorba:signature localname="data" prefix="fn">
       <zorba:param>item()*</zorba:param>
       <zorba:output>xs:anyAtomicType*</zorba:output>
@@ -121,6 +141,7 @@
       <zorba:isMap producer="0"/>
       <zorba:ignoresSortedNodes/>
       <zorba:ignoresDuplicateNodes/>
+      <zorba:mustCopyInputNodes/>
     </zorba:methods>
 
   </zorba:function>
@@ -149,6 +170,11 @@
       <zorba:param>node()?</zorba:param>
       <zorba:output>xs:anyURI?</zorba:output>
     </zorba:signature>
+
+    <zorba:methods>
+      <zorba:mustCopyInputNodes value="true"/>
+    </zorba:methods>
+
   </zorba:function>
 
 </zorba:iterator>
@@ -161,9 +187,9 @@
 -->
 <zorba:iterator name="DocumentUriIterator">
 
-    <zorba:description author="Zorba Team">fn:document-uri</zorba:description>
+  <zorba:description author="Zorba Team">fn:document-uri</zorba:description>
     
-    <zorba:function>
+  <zorba:function>
         <zorba:signature localname="document-uri" prefix="fn" version="3.0">
             <zorba:output>xs:anyURI?</zorba:output>
         </zorba:signature>
@@ -171,7 +197,12 @@
             <zorba:param>node()?</zorba:param>
             <zorba:output>xs:anyURI?</zorba:output>
         </zorba:signature>
-    </zorba:function>
+
+    <zorba:methods>
+      <zorba:mustCopyInputNodes value="false"/>
+    </zorba:methods>
+
+  </zorba:function>
     
 </zorba:iterator>
 
@@ -202,6 +233,11 @@
       <zorba:param>node()?</zorba:param>
       <zorba:output>node()?</zorba:output>
     </zorba:signature>
+
+    <zorba:methods>
+      <zorba:mustCopyInputNodes value="true"/>
+    </zorba:methods>
+
   </zorba:function>
 
 </zorba:iterator>

=== modified file 'src/runtime/spec/booleans/booleans.xml'
--- src/runtime/spec/booleans/booleans.xml	2010-03-30 09:15:10 +0000
+++ src/runtime/spec/booleans/booleans.xml	2011-11-29 22:22:26 +0000
@@ -18,18 +18,23 @@
 * 14.6 op:is-same-node
 ********************************************************************************/
 -->
-<zorba:iterator
-    name="IsSameNodeIterator">
+<zorba:iterator name="IsSameNodeIterator">
 
-    <zorba:description author="Zorba Team">op:is-same-node</zorba:description>
+  <zorba:description author="Zorba Team">op:is-same-node</zorba:description>
     
-    <zorba:function>
+  <zorba:function>
+
         <zorba:signature localname="is-same-node" prefix="op">
             <zorba:param>node()?</zorba:param>
             <zorba:param>node()?</zorba:param>
             <zorba:output>xs:boolean?</zorba:output>
         </zorba:signature>
-    </zorba:function>
+
+    <zorba:methods>
+      <zorba:mustCopyInputNodes value="true"/>
+    </zorba:methods>
+
+  </zorba:function>
     
 </zorba:iterator>
 
@@ -39,18 +44,22 @@
 ********************************************************************************/
 -->
 
-<zorba:iterator
-    name="NodeBeforeIterator">
+<zorba:iterator name="NodeBeforeIterator">
 
-    <zorba:description author="Zorba Team">op:node-before</zorba:description>
+  <zorba:description author="Zorba Team">op:node-before</zorba:description>
     
-    <zorba:function>
+  <zorba:function>
         <zorba:signature localname="node-before" prefix="op">
             <zorba:param>node()?</zorba:param>
             <zorba:param>node()?</zorba:param>
             <zorba:output>xs:boolean?</zorba:output>
         </zorba:signature>
-    </zorba:function>
+
+    <zorba:methods>
+      <zorba:mustCopyInputNodes value="true"/>
+    </zorba:methods>
+
+  </zorba:function>
     
 </zorba:iterator>
 
@@ -60,18 +69,22 @@
 ********************************************************************************/
 -->
 
-<zorba:iterator
-    name="NodeAfterIterator">
+<zorba:iterator name="NodeAfterIterator">
 
-    <zorba:description author="Zorba Team">op:node-after</zorba:description>
+  <zorba:description author="Zorba Team">op:node-after</zorba:description>
     
-    <zorba:function>
+  <zorba:function>
         <zorba:signature localname="node-after" prefix="op">
             <zorba:param>node()?</zorba:param>
             <zorba:param>node()?</zorba:param>
             <zorba:output>xs:boolean?</zorba:output>
         </zorba:signature>
-    </zorba:function>
+
+    <zorba:methods>
+      <zorba:mustCopyInputNodes value="true"/>
+    </zorba:methods>
+
+  </zorba:function>
     
 </zorba:iterator>
 

=== modified file 'src/runtime/spec/codegen-h.xq'
--- src/runtime/spec/codegen-h.xq	2011-08-17 20:22:07 +0000
+++ src/runtime/spec/codegen-h.xq	2011-11-29 22:22:26 +0000
@@ -94,7 +94,11 @@
       concat($name, '(const signature&amp; sig, FunctionConsts::FunctionKind kind)',
              $gen:newline, $gen:indent,
              $gen:indent, ': ',
-             local:base-class($function), '(sig, kind) {&#xA;', $setNoneDeterministic, $funcVersion, '&#xA;}'),
+             $gen:newline, $gen:indent, $gen:indent,
+             local:base-class($function), 
+             '(sig, kind)',
+             $gen:newline, $gen:indent,
+             '{&#xA;', $setNoneDeterministic, $funcVersion, '&#xA;', $gen:indent, '}'),
   
   $gen:newline,
         
@@ -268,29 +272,53 @@
       else if (name($meth) eq 'zorba:propagatesDistinctNodes')
       then
         string-join(($gen:newline, $gen:indent,
-                     'bool propagatesDistinctNodes(ulong producer) const ',
+                     'bool propagatesDistinctNodes(csize producer) const ',
                      '{ return producer == ', $meth/@producer, '; }',
                       $gen:newline),'')
 
       else if (name($meth) eq 'zorba:propagatesSortedNodes')
       then
         string-join(($gen:newline, $gen:indent,
-                     'bool propagatesSortedNodes(ulong producer) const ',
+                     'bool propagatesSortedNodes(csize producer) const ',
                      '{ return producer == ', $meth/@producer, '; }',
                       $gen:newline),'')
 
       else if (name($meth) eq 'zorba:ignoresSortedNodes')
       then
         string-join(($gen:newline, $gen:indent,
-                     'BoolAnnotationValue ignoresSortedNodes(expr* fo, ulong producer) const;',
+                     'BoolAnnotationValue ignoresSortedNodes(expr* fo, csize producer) const;',
                       $gen:newline),'')
 
       else if (name($meth) eq 'zorba:ignoresDuplicateNodes')
       then
         string-join(($gen:newline, $gen:indent,
-                     'BoolAnnotationValue ignoresDuplicateNodes(expr* fo, ulong producer) const;',
-                      $gen:newline),'')
-
+                     'BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize producer) const;',
+                      $gen:newline),'')
+
+      else if (name($meth) eq 'zorba:propagatesInputNodes')
+      then
+        string-join(($gen:newline, $gen:indent,
+                     'bool propagatesInputNodes(expr* fo, csize producer) const;',
+                      $gen:newline),'')
+
+      else if (name($meth) eq 'zorba:mustCopyInputNodes')
+      then
+        if ($meth/@producer)
+        then
+        string-join(($gen:newline, $gen:indent,
+                     'bool mustCopyInputNodes(expr* fo, csize producer) const ',
+                     '{ return producer == ', $meth/@producer, '; }',
+                     $gen:newline),'')
+        else if ($meth/@value)
+        then
+        string-join(($gen:newline, $gen:indent,
+                     'bool mustCopyInputNodes(expr* fo, csize producer) const ',
+                     '{ return ', $meth/@value, '; }',
+                     $gen:newline),'')
+        else
+        string-join(($gen:newline, $gen:indent,
+                     'bool mustCopyInputNodes(expr* fo, csize producer) const;',
+                     $gen:newline),'')
       else
         ()
   else

=== modified file 'src/runtime/spec/collections/collections.xml'
--- src/runtime/spec/collections/collections.xml	2011-10-07 23:56:40 +0000
+++ src/runtime/spec/collections/collections.xml	2011-11-29 22:22:26 +0000
@@ -138,6 +138,7 @@
 
       <zorba:methods>
         <zorba:accessesDynCtx returnValue="true"/>
+        <zorba:mustCopyInputNodes value="false"/>
       </zorba:methods>
 
     </zorba:function>
@@ -198,6 +199,7 @@
       <zorba:methods>
         <zorba:getScriptingKind returnValue="UPDATING_EXPR"/>
         <zorba:accessesDynCtx returnValue="true"/>
+        <zorba:mustCopyInputNodes producer="1"/>
       </zorba:methods>
 
     </zorba:function>
@@ -246,6 +248,7 @@
       <zorba:methods>
         <zorba:getScriptingKind returnValue="UPDATING_EXPR"/>
         <zorba:accessesDynCtx returnValue="true"/>
+       <zorba:mustCopyInputNodes value="false"/>
       </zorba:methods>
 
     </zorba:function>
@@ -298,6 +301,7 @@
       <zorba:methods>
         <zorba:getScriptingKind returnValue="UPDATING_EXPR"/>
         <zorba:accessesDynCtx returnValue="true"/>
+        <zorba:mustCopyInputNodes producer="1"/>
       </zorba:methods>
 
     </zorba:function>
@@ -345,6 +349,7 @@
       <zorba:methods>
         <zorba:getScriptingKind returnValue="UPDATING_EXPR"/>
         <zorba:accessesDynCtx returnValue="true"/>
+        <zorba:mustCopyInputNodes producer="1"/>
       </zorba:methods>
 
     </zorba:function>
@@ -391,6 +396,7 @@
       <zorba:methods>
         <zorba:getScriptingKind returnValue="UPDATING_EXPR"/>
         <zorba:accessesDynCtx returnValue="true"/>
+        <zorba:mustCopyInputNodes producer="1"/>
       </zorba:methods>
 
     </zorba:function>
@@ -439,6 +445,7 @@
       <zorba:methods>
         <zorba:getScriptingKind returnValue="UPDATING_EXPR"/>
         <zorba:accessesDynCtx returnValue="true"/>
+        <zorba:mustCopyInputNodes producer="2"/>
       </zorba:methods>
 
     </zorba:function>
@@ -487,6 +494,7 @@
       <zorba:methods>
         <zorba:getScriptingKind returnValue="UPDATING_EXPR"/>
         <zorba:accessesDynCtx returnValue="true"/>
+        <zorba:mustCopyInputNodes producer="2"/>
       </zorba:methods>
 
     </zorba:function>
@@ -538,6 +546,8 @@
       <zorba:methods>
         <zorba:getScriptingKind returnValue="APPLYING_EXPR"/>
         <zorba:accessesDynCtx returnValue="true"/>
+        <zorba:propagatesInputNodes/>
+        <zorba:mustCopyInputNodes producer="1"/>
       </zorba:methods>
     </zorba:function>
 
@@ -582,6 +592,8 @@
       <zorba:methods>
         <zorba:getScriptingKind returnValue="APPLYING_EXPR"/>
         <zorba:accessesDynCtx returnValue="true"/>
+        <zorba:propagatesInputNodes/>
+        <zorba:mustCopyInputNodes producer="1"/>
       </zorba:methods>
 
     </zorba:function>
@@ -627,6 +639,8 @@
       <zorba:methods>
         <zorba:getScriptingKind returnValue="APPLYING_EXPR"/>
         <zorba:accessesDynCtx returnValue="true"/>
+        <zorba:propagatesInputNodes/>
+        <zorba:mustCopyInputNodes producer="1"/>
       </zorba:methods>
 
     </zorba:function>
@@ -674,6 +688,8 @@
       <zorba:methods>
         <zorba:getScriptingKind returnValue="APPLYING_EXPR"/>
         <zorba:accessesDynCtx returnValue="true"/>
+        <zorba:propagatesInputNodes/>
+        <zorba:mustCopyInputNodes producer="2"/>
       </zorba:methods>
 
     </zorba:function>
@@ -720,6 +736,8 @@
       <zorba:methods>
         <zorba:getScriptingKind returnValue="APPLYING_EXPR"/>
         <zorba:accessesDynCtx returnValue="true"/>
+        <zorba:propagatesInputNodes/>
+        <zorba:mustCopyInputNodes producer="2"/>
       </zorba:methods>
 
     </zorba:function>
@@ -765,6 +783,7 @@
         <zorba:accessesDynCtx returnValue="true"/>
         <zorba:ignoresSortedNodes/>
         <zorba:ignoresDuplicateNodes/>
+        <zorba:mustCopyInputNodes producer="0"/>
       </zorba:methods>
 
     </zorba:function>
@@ -822,6 +841,7 @@
       <zorba:methods>
         <zorba:getScriptingKind returnValue="UPDATING_EXPR"/>
         <zorba:accessesDynCtx returnValue="true"/>
+        <zorba:mustCopyInputNodes value="false"/>
       </zorba:methods>
 
     </zorba:function>
@@ -879,6 +899,7 @@
       <zorba:methods>
         <zorba:getScriptingKind returnValue="UPDATING_EXPR"/>
         <zorba:accessesDynCtx returnValue="true"/>
+        <zorba:mustCopyInputNodes value="false"/>
       </zorba:methods>
 
     </zorba:function>
@@ -923,6 +944,7 @@
 
       <zorba:methods>
         <zorba:accessesDynCtx returnValue="true"/>
+        <zorba:mustCopyInputNodes value="true"/>
       </zorba:methods>
 
     </zorba:function>

=== modified file 'src/runtime/spec/errors_and_diagnostics/errors_and_diagnostics.xml'
--- src/runtime/spec/errors_and_diagnostics/errors_and_diagnostics.xml	2011-11-17 16:44:50 +0000
+++ src/runtime/spec/errors_and_diagnostics/errors_and_diagnostics.xml	2011-11-29 22:22:26 +0000
@@ -48,6 +48,7 @@
 
       <zorba:methods>
         <zorba:getScriptingKind returnValue="VACUOUS_EXPR"/>
+        <zorba:mustCopyInputNodes producer="2"/>
       </zorba:methods>
 
     </zorba:function>

=== modified file 'src/runtime/spec/fnput/fnput.xml'
--- src/runtime/spec/fnput/fnput.xml	2011-04-13 19:33:42 +0000
+++ src/runtime/spec/fnput/fnput.xml	2011-11-29 22:22:26 +0000
@@ -24,7 +24,8 @@
 
     <zorba:methods>
       <zorba:getScriptingKind returnValue="UPDATING_EXPR"/>
-      <zorba:accessesDynCtx returnValue="true"/>      
+      <zorba:accessesDynCtx returnValue="true"/> 
+      <zorba:mustCopyInputNodes producer="0"/>
     </zorba:methods>
 
   </zorba:function>

=== modified file 'src/runtime/spec/nodes/nodes.xml'
--- src/runtime/spec/nodes/nodes.xml	2011-10-06 18:24:44 +0000
+++ src/runtime/spec/nodes/nodes.xml	2011-11-29 22:22:26 +0000
@@ -29,6 +29,10 @@
         <zorba:output>xs:anyURI</zorba:output>
       </zorba:signature>
       
+      <zorba:methods>
+        <zorba:mustCopyInputNodes value="true"/>
+      </zorba:methods>
+
     </zorba:function>
 
   </zorba:iterator>
@@ -73,7 +77,13 @@
       <zorba:param>node()?</zorba:param>
       <zorba:output>xs:string</zorba:output>
     </zorba:signature>
+
+      <zorba:methods>
+        <zorba:mustCopyInputNodes value="false"/>
+      </zorba:methods>
+
   </zorba:function>
+
 </zorba:iterator>
 
 <!--
@@ -95,7 +105,13 @@
       <zorba:param>node()?</zorba:param>
       <zorba:output>xs:anyURI?</zorba:output>
     </zorba:signature>
+
+    <zorba:methods>
+      <zorba:mustCopyInputNodes value="false"/>
+    </zorba:methods>
+
   </zorba:function>
+
 </zorba:iterator>
 
 <!--
@@ -119,6 +135,11 @@
       <zorba:param>node()</zorba:param>
       <zorba:output>xs:boolean</zorba:output>
     </zorba:signature>
+
+    <zorba:methods>
+      <zorba:mustCopyInputNodes value="false"/>
+    </zorba:methods>
+
   </zorba:function>
 
   <zorba:method return="bool" name="isLangAttr" const="true">
@@ -180,26 +201,30 @@
 ********************************************************************************/
 -->
 
-  <zorba:iterator name="FnInnermostIterator">
-
-    <zorba:description author="Zorba Team">fn:innermost</zorba:description>
-
-    <zorba:function>
-      <zorba:signature localname="innermost" prefix="fn" version="3.0">
-        <zorba:param>node()*</zorba:param>
-        <zorba:output>node()*</zorba:output>
-      </zorba:signature>
-
-    </zorba:function>
-
-    <zorba:state>
-      <zorba:member type="std::list&lt;store::Item_t&gt;" name="node_list"
-                    brief="temporary list of nodes"/>
-      <zorba:member type="std::list&lt;store::Item_t&gt;::iterator" name="list_it"
-                    brief="iterator through result sequence"/>
-    </zorba:state>
-
-  </zorba:iterator>
+<zorba:iterator name="FnInnermostIterator">
+
+  <zorba:description author="Zorba Team">fn:innermost</zorba:description>
+
+  <zorba:function>
+    <zorba:signature localname="innermost" prefix="fn" version="3.0">
+      <zorba:param>node()*</zorba:param>
+      <zorba:output>node()*</zorba:output>
+    </zorba:signature>
+
+    <zorba:methods>
+      <zorba:mustCopyInputNodes value="true"/>
+    </zorba:methods>
+
+  </zorba:function>
+
+  <zorba:state>
+    <zorba:member type="std::list&lt;store::Item_t&gt;" name="node_list"
+                  brief="temporary list of nodes"/>
+    <zorba:member type="std::list&lt;store::Item_t&gt;::iterator" name="list_it"
+                  brief="iterator through result sequence"/>
+  </zorba:state>
+
+</zorba:iterator>
 
 <!--
 /*******************************************************************************
@@ -207,26 +232,30 @@
 ********************************************************************************/
 -->
 
-  <zorba:iterator name="FnOutermostIterator">
-
-    <zorba:description author="Zorba Team">fn:outermost</zorba:description>
-
-    <zorba:function>
-      <zorba:signature localname="outermost" prefix="fn" version="3.0">
-        <zorba:param>node()*</zorba:param>
-        <zorba:output>node()*</zorba:output>
-      </zorba:signature>
-
-    </zorba:function>
-
-    <zorba:state>
-      <zorba:member type="std::list&lt;store::Item_t&gt;" name="node_list"
-                    brief="temporary list of nodes"/>
-      <zorba:member type="std::list&lt;store::Item_t&gt;::iterator" name="list_it"
-                    brief="iterator through result sequence"/>
-    </zorba:state>
-
-  </zorba:iterator>
+<zorba:iterator name="FnOutermostIterator">
+
+  <zorba:description author="Zorba Team">fn:outermost</zorba:description>
+
+  <zorba:function>
+    <zorba:signature localname="outermost" prefix="fn" version="3.0">
+      <zorba:param>node()*</zorba:param>
+      <zorba:output>node()*</zorba:output>
+    </zorba:signature>
+
+    <zorba:methods>
+      <zorba:mustCopyInputNodes value="true"/>
+    </zorba:methods>
+
+  </zorba:function>
+
+  <zorba:state>
+    <zorba:member type="std::list&lt;store::Item_t&gt;" name="node_list"
+                  brief="temporary list of nodes"/>
+    <zorba:member type="std::list&lt;store::Item_t&gt;::iterator" name="list_it"
+                  brief="iterator through result sequence"/>
+  </zorba:state>
+
+</zorba:iterator>
 
   <!--
 /*******************************************************************************
@@ -234,201 +263,256 @@
 ********************************************************************************/
 -->
 
-  <zorba:iterator name="FnGenerateIdIterator">
-
-    <zorba:description author="Zorba Team">fn:generate-id</zorba:description>
-
-    <zorba:function>
-      <zorba:signature localname="generate-id" prefix="fn" version="3.0">
-        <zorba:output>xs:string</zorba:output>
-      </zorba:signature>
-      <zorba:signature localname="generate-id" prefix="fn" version="3.0">
-        <zorba:param>node()?</zorba:param>
-        <zorba:output>xs:string</zorba:output>
-      </zorba:signature>
-
-    </zorba:function>
-
-  </zorba:iterator>
-
-  <!--
-/*******************************************************************************
-********************************************************************************/
--->
-  <zorba:iterator name="IsAncestorIterator">
-
-    <zorba:description author="Zorba Team"></zorba:description>
-
-    <zorba:function>
-      <zorba:signature localname="ancestor-of" prefix="fn-zorba-node">
-        <zorba:param>node()</zorba:param>
-        <zorba:param>node()</zorba:param>
-        <zorba:output>xs:boolean</zorba:output>
-      </zorba:signature>
-    </zorba:function>
-
-  </zorba:iterator>
-
-  <!--
-/*******************************************************************************
-********************************************************************************/
--->
-  <zorba:iterator name="IsDescendantIterator">
-
-    <zorba:description author="Zorba Team"></zorba:description>
-
-    <zorba:function>
-      <zorba:signature localname="descendant-of" prefix="fn-zorba-node">
-        <zorba:param>node()</zorba:param>
-        <zorba:param>node()</zorba:param>
-        <zorba:output>xs:boolean</zorba:output>
-      </zorba:signature>
-    </zorba:function>
-
-  </zorba:iterator>
-
-  <!--
-/*******************************************************************************
-********************************************************************************/
--->
-  <zorba:iterator name="IsParentIterator">
-
-    <zorba:description author="Zorba Team"></zorba:description>
-
-    <zorba:function>
-      <zorba:signature localname="parent-of" prefix="fn-zorba-node">
-        <zorba:param>node()</zorba:param>
-        <zorba:param>node()</zorba:param>
-        <zorba:output>xs:boolean</zorba:output>
-      </zorba:signature>
-    </zorba:function>
-
-  </zorba:iterator>
-
-  <!--
-/*******************************************************************************
-********************************************************************************/
--->
-  <zorba:iterator name="IsChildIterator">
-
-    <zorba:description author="Zorba Team"></zorba:description>
-
-    <zorba:function>
-      <zorba:signature localname="child-of" prefix="fn-zorba-node">
-        <zorba:param>node()</zorba:param>
-        <zorba:param>node()</zorba:param>
-        <zorba:output>xs:boolean</zorba:output>
-      </zorba:signature>
-    </zorba:function>
-
-  </zorba:iterator>
-
-  <!--
-/*******************************************************************************
-********************************************************************************/
--->
-  <zorba:iterator name="IsFollowingIterator">
-
-    <zorba:description author="Zorba Team"></zorba:description>
-
-    <zorba:function>
-      <zorba:signature localname="following-of" prefix="fn-zorba-node">
-        <zorba:param>node()</zorba:param>
-        <zorba:param>node()</zorba:param>
-        <zorba:output>xs:boolean</zorba:output>
-      </zorba:signature>
-    </zorba:function>
-
-  </zorba:iterator>
-
-  <!--
-/*******************************************************************************
-********************************************************************************/
--->
-  <zorba:iterator name="IsPrecedingIterator">
-
-    <zorba:description author="Zorba Team"></zorba:description>
-
-    <zorba:function>
-      <zorba:signature localname="preceding-of" prefix="fn-zorba-node">
-        <zorba:param>node()</zorba:param>
-        <zorba:param>node()</zorba:param>
-        <zorba:output>xs:boolean</zorba:output>
-      </zorba:signature>
-    </zorba:function>
-
-  </zorba:iterator>
-
-
-  <!--
-/*******************************************************************************
-********************************************************************************/
--->
-  <zorba:iterator name="IsFollowingSiblingIterator">
-
-    <zorba:description author="Zorba Team"></zorba:description>
-
-    <zorba:function>
-      <zorba:signature localname="following-sibling-of" prefix="fn-zorba-node">
-        <zorba:param>node()</zorba:param>
-        <zorba:param>node()</zorba:param>
-        <zorba:output>xs:boolean</zorba:output>
-      </zorba:signature>
-    </zorba:function>
-
-  </zorba:iterator>
-
-  <!--
-/*******************************************************************************
-********************************************************************************/
--->
-  <zorba:iterator name="IsPrecedingSiblingIterator">
-
-    <zorba:description author="Zorba Team"></zorba:description>
-
-    <zorba:function>
-      <zorba:signature localname="preceding-sibling-of" prefix="fn-zorba-node">
-        <zorba:param>node()</zorba:param>
-        <zorba:param>node()</zorba:param>
-        <zorba:output>xs:boolean</zorba:output>
-      </zorba:signature>
-    </zorba:function>
-
-  </zorba:iterator>
-
-  <!--
-/*******************************************************************************
-********************************************************************************/
--->
-  <zorba:iterator name="LevelIterator">
-
-    <zorba:description author="Zorba Team"></zorba:description>
-
-    <zorba:function>
-      <zorba:signature localname="level" prefix="fn-zorba-node">
-        <zorba:param>node()</zorba:param>
-        <zorba:output>xs:integer</zorba:output>
-      </zorba:signature>
-    </zorba:function>
-
-  </zorba:iterator>
-
-  <!--
-/*******************************************************************************
-********************************************************************************/
--->
-  <zorba:iterator name="LeastCommonAncestor">
-
-    <zorba:description author="Zorba Team"></zorba:description>
-
-    <zorba:function>
-      <zorba:signature localname="least-common-ancestor" prefix="fn-zorba-node">
-        <zorba:param>node()</zorba:param>
-        <zorba:param>node()</zorba:param>
-        <zorba:output>node()?</zorba:output>
-      </zorba:signature>
-    </zorba:function>
-
-  </zorba:iterator>
+<zorba:iterator name="FnGenerateIdIterator">
+
+  <zorba:description author="Zorba Team">fn:generate-id</zorba:description>
+
+  <zorba:function>
+    <zorba:signature localname="generate-id" prefix="fn" version="3.0">
+      <zorba:output>xs:string</zorba:output>
+    </zorba:signature>
+
+    <zorba:signature localname="generate-id" prefix="fn" version="3.0">
+      <zorba:param>node()?</zorba:param>
+      <zorba:output>xs:string</zorba:output>
+    </zorba:signature>
+
+    <zorba:methods>
+      <zorba:mustCopyInputNodes value="true"/>
+    </zorba:methods>
+
+  </zorba:function>
+
+</zorba:iterator>
+
+  <!--
+/*******************************************************************************
+********************************************************************************/
+-->
+<zorba:iterator name="IsAncestorIterator">
+
+  <zorba:description author="Zorba Team"></zorba:description>
+
+  <zorba:function>
+    <zorba:signature localname="ancestor-of" prefix="fn-zorba-node">
+      <zorba:param>node()</zorba:param>
+      <zorba:param>node()</zorba:param>
+      <zorba:output>xs:boolean</zorba:output>
+    </zorba:signature>
+
+    <zorba:methods>
+      <zorba:mustCopyInputNodes value="true"/>
+    </zorba:methods>
+
+  </zorba:function>
+
+</zorba:iterator>
+
+  <!--
+/*******************************************************************************
+********************************************************************************/
+-->
+<zorba:iterator name="IsDescendantIterator">
+
+  <zorba:description author="Zorba Team"></zorba:description>
+
+  <zorba:function>
+    <zorba:signature localname="descendant-of" prefix="fn-zorba-node">
+      <zorba:param>node()</zorba:param>
+      <zorba:param>node()</zorba:param>
+      <zorba:output>xs:boolean</zorba:output>
+    </zorba:signature>
+
+    <zorba:methods>
+      <zorba:mustCopyInputNodes value="true"/>
+    </zorba:methods>
+
+  </zorba:function>
+
+</zorba:iterator>
+
+  <!--
+/*******************************************************************************
+********************************************************************************/
+-->
+<zorba:iterator name="IsParentIterator">
+
+  <zorba:description author="Zorba Team"></zorba:description>
+
+  <zorba:function>
+    <zorba:signature localname="parent-of" prefix="fn-zorba-node">
+      <zorba:param>node()</zorba:param>
+      <zorba:param>node()</zorba:param>
+      <zorba:output>xs:boolean</zorba:output>
+    </zorba:signature>
+
+    <zorba:methods>
+      <zorba:mustCopyInputNodes value="true"/>
+    </zorba:methods>
+
+  </zorba:function>
+
+</zorba:iterator>
+
+  <!--
+/*******************************************************************************
+********************************************************************************/
+-->
+<zorba:iterator name="IsChildIterator">
+
+  <zorba:description author="Zorba Team"></zorba:description>
+
+  <zorba:function>
+    <zorba:signature localname="child-of" prefix="fn-zorba-node">
+      <zorba:param>node()</zorba:param>
+      <zorba:param>node()</zorba:param>
+      <zorba:output>xs:boolean</zorba:output>
+    </zorba:signature>
+
+    <zorba:methods>
+      <zorba:mustCopyInputNodes value="true"/>
+    </zorba:methods>
+
+  </zorba:function>
+
+</zorba:iterator>
+
+  <!--
+/*******************************************************************************
+********************************************************************************/
+-->
+<zorba:iterator name="IsFollowingIterator">
+
+  <zorba:description author="Zorba Team"></zorba:description>
+
+  <zorba:function>
+    <zorba:signature localname="following-of" prefix="fn-zorba-node">
+      <zorba:param>node()</zorba:param>
+      <zorba:param>node()</zorba:param>
+      <zorba:output>xs:boolean</zorba:output>
+    </zorba:signature>
+
+    <zorba:methods>
+      <zorba:mustCopyInputNodes value="true"/>
+    </zorba:methods>
+
+  </zorba:function>
+
+</zorba:iterator>
+
+  <!--
+/*******************************************************************************
+********************************************************************************/
+-->
+<zorba:iterator name="IsPrecedingIterator">
+
+  <zorba:description author="Zorba Team"></zorba:description>
+
+  <zorba:function>
+    <zorba:signature localname="preceding-of" prefix="fn-zorba-node">
+      <zorba:param>node()</zorba:param>
+      <zorba:param>node()</zorba:param>
+      <zorba:output>xs:boolean</zorba:output>
+    </zorba:signature>
+
+    <zorba:methods>
+      <zorba:mustCopyInputNodes value="true"/>
+    </zorba:methods>
+
+  </zorba:function>
+
+</zorba:iterator>
+
+
+  <!--
+/*******************************************************************************
+********************************************************************************/
+-->
+<zorba:iterator name="IsFollowingSiblingIterator">
+
+  <zorba:description author="Zorba Team"></zorba:description>
+
+  <zorba:function>
+    <zorba:signature localname="following-sibling-of" prefix="fn-zorba-node">
+      <zorba:param>node()</zorba:param>
+      <zorba:param>node()</zorba:param>
+      <zorba:output>xs:boolean</zorba:output>
+    </zorba:signature>
+
+    <zorba:methods>
+      <zorba:mustCopyInputNodes value="true"/>
+    </zorba:methods>
+
+  </zorba:function>
+
+</zorba:iterator>
+
+  <!--
+/*******************************************************************************
+********************************************************************************/
+-->
+<zorba:iterator name="IsPrecedingSiblingIterator">
+
+  <zorba:description author="Zorba Team"></zorba:description>
+
+  <zorba:function>
+    <zorba:signature localname="preceding-sibling-of" prefix="fn-zorba-node">
+      <zorba:param>node()</zorba:param>
+      <zorba:param>node()</zorba:param>
+      <zorba:output>xs:boolean</zorba:output>
+    </zorba:signature>
+
+    <zorba:methods>
+      <zorba:mustCopyInputNodes value="true"/>
+    </zorba:methods>
+
+  </zorba:function>
+
+</zorba:iterator>
+
+  <!--
+/*******************************************************************************
+********************************************************************************/
+-->
+<zorba:iterator name="LevelIterator">
+
+  <zorba:description author="Zorba Team"></zorba:description>
+
+  <zorba:function>
+    <zorba:signature localname="level" prefix="fn-zorba-node">
+      <zorba:param>node()</zorba:param>
+      <zorba:output>xs:integer</zorba:output>
+    </zorba:signature>
+
+    <zorba:methods>
+      <zorba:mustCopyInputNodes value="true"/>
+    </zorba:methods>
+
+  </zorba:function>
+
+</zorba:iterator>
+
+  <!--
+/*******************************************************************************
+********************************************************************************/
+-->
+<zorba:iterator name="LeastCommonAncestor">
+
+  <zorba:description author="Zorba Team"></zorba:description>
+
+  <zorba:function>
+    <zorba:signature localname="least-common-ancestor" prefix="fn-zorba-node">
+      <zorba:param>node()</zorba:param>
+      <zorba:param>node()</zorba:param>
+      <zorba:output>node()?</zorba:output>
+    </zorba:signature>
+
+    <zorba:methods>
+      <zorba:mustCopyInputNodes value="true"/>
+    </zorba:methods>
+
+  </zorba:function>
+
+</zorba:iterator>
 
 </zorba:iterators>

=== modified file 'src/runtime/spec/parsing_and_serializing/parsing_and_serializing.xml'
--- src/runtime/spec/parsing_and_serializing/parsing_and_serializing.xml	2011-07-03 13:45:27 +0000
+++ src/runtime/spec/parsing_and_serializing/parsing_and_serializing.xml	2011-11-29 22:22:26 +0000
@@ -69,6 +69,7 @@
       <zorba:methods>
         <zorba:accessesDynCtx returnValue="true"/>
         <zorba:isSource returnValue="true"/>
+        <zorba:mustCopyInputNodes/>
       </zorba:methods>
 
     </zorba:function>

=== modified file 'src/runtime/spec/plan_iter_visitor_h.xq'
--- src/runtime/spec/plan_iter_visitor_h.xq	2011-08-05 02:21:55 +0000
+++ src/runtime/spec/plan_iter_visitor_h.xq	2011-11-29 22:22:26 +0000
@@ -47,7 +47,7 @@
  
 
 (:type can be 'fwd-decl' or 'class' :)
-declare %ann:nondeterministic %ann:sequential function local:process-files(
+declare %ann:nondeterministic function local:process-files(
     $files as xs:string, 
     $type as xs:string) as xs:string
 {
@@ -59,7 +59,7 @@
 };
 
 
-declare %ann:nondeterministic %ann:sequential function local:process-file($file, $type as xs:string) as xs:string
+declare %ann:nondeterministic function local:process-file($file, $type as xs:string) as xs:string
 {
   let $doc := fn:parse-xml(file:read-text($file))/zorba:iterators
 
@@ -93,7 +93,7 @@
   )
 };
 
-declare %ann:nondeterministic %ann:sequential function local:create-fwd-decl($files as xs:string) as xs:string
+declare %ann:nondeterministic function local:create-fwd-decl($files as xs:string) as xs:string
 {
   variable $temp := local:process-files($files,'fwd-decl');
 

=== modified file 'src/runtime/spec/printer_visitor_cpp.xq'
--- src/runtime/spec/printer_visitor_cpp.xq	2011-08-05 02:21:55 +0000
+++ src/runtime/spec/printer_visitor_cpp.xq	2011-11-29 22:22:26 +0000
@@ -20,7 +20,7 @@
 import module namespace gen = "http://www.zorba-xquery.com/internal/gen"; at "utils.xq";
 import module namespace file = "http://expath.org/ns/file";;
 
-declare %ann:nondeterministic %ann:sequential function local:get-files($files as xs:string) as xs:string
+declare %ann:nondeterministic function local:get-files($files as xs:string) as xs:string
 {
   variable $xml-files as xs:string* := tokenize($files,',');
 
@@ -29,7 +29,7 @@
   string-join($temp, $gen:newline)
 };
 
-declare %ann:nondeterministic %ann:sequential function local:process-file($file) as xs:string
+declare %ann:nondeterministic function local:process-file($file) as xs:string
 {
   let $doc := fn:parse-xml(file:read-text($file))/zorba:iterators
   

=== modified file 'src/runtime/spec/printer_visitor_h.xq'
--- src/runtime/spec/printer_visitor_h.xq	2011-08-05 02:21:55 +0000
+++ src/runtime/spec/printer_visitor_h.xq	2011-11-29 22:22:26 +0000
@@ -20,7 +20,7 @@
 import module namespace gen = "http://www.zorba-xquery.com/internal/gen"; at "utils.xq";
 import module namespace file = "http://expath.org/ns/file";;
 
-declare %ann:nondeterministic %ann:sequential function local:get-files($files as xs:string) as xs:string
+declare %ann:nondeterministic function local:get-files($files as xs:string) as xs:string
 {
   variable $xml-files as xs:string* := tokenize($files,',');
   variable $temp := for $file in $xml-files

=== modified file 'src/runtime/spec/qnames/qnames.xml'
--- src/runtime/spec/qnames/qnames.xml	2010-11-10 14:27:22 +0000
+++ src/runtime/spec/qnames/qnames.xml	2011-11-29 22:22:26 +0000
@@ -24,11 +24,17 @@
   <zorba:description author="Zorba Team">fn:resolve-QName</zorba:description>
 
   <zorba:function>
+
     <zorba:signature localname="resolve-QName" prefix="fn">
       <zorba:param>xs:string?</zorba:param>
       <zorba:param>element()</zorba:param> <!-- was node() -->
       <zorba:output>xs:QName?</zorba:output>
     </zorba:signature>
+
+    <zorba:methods>
+      <zorba:mustCopyInputNodes producer="1"/>
+    </zorba:methods>
+
   </zorba:function>
     
 </zorba:iterator>
@@ -135,11 +141,17 @@
   <zorba:description author="Zorba Team">fn:namespace-uri-for-prefix</zorba:description>
 
   <zorba:function>
+
     <zorba:signature localname="namespace-uri-for-prefix" prefix="fn">
       <zorba:param>xs:string?</zorba:param>
       <zorba:param>element()</zorba:param> <!-- was node()  -->
       <zorba:output>xs:anyURI?</zorba:output>
     </zorba:signature>
+
+    <zorba:methods>
+      <zorba:mustCopyInputNodes producer="1"/>
+    </zorba:methods>
+
   </zorba:function>
     
 </zorba:iterator>
@@ -158,6 +170,11 @@
       <zorba:param>element()</zorba:param> <!-- was node() -->
       <zorba:output>xs:string*</zorba:output>
     </zorba:signature>
+
+    <zorba:methods>
+      <zorba:mustCopyInputNodes value="true"/>
+    </zorba:methods>
+
   </zorba:function>
 
   <zorba:state generateInit="false" generateReset="false">

=== modified file 'src/runtime/spec/schema/schema.xml'
--- src/runtime/spec/schema/schema.xml	2011-04-13 19:33:42 +0000
+++ src/runtime/spec/schema/schema.xml	2011-11-29 22:22:26 +0000
@@ -56,14 +56,18 @@
   <zorba:description author="Zorba Team">iterator backing the validate-updating function</zorba:description>
 
   <zorba:function>
+
     <zorba:signature localname="validate-in-place" prefix="fn-zorba-schema">
       <zorba:param>node()</zorba:param>
       <zorba:output>empty-sequence()</zorba:output>
     </zorba:signature>
+
     <zorba:methods>
       <zorba:getScriptingKind returnValue="UPDATING_EXPR"/>
       <zorba:accessesDynCtx returnValue="true"/>
+      <zorba:mustCopyInputNodes value="true"/>
     </zorba:methods>
+
   </zorba:function>
  
 </zorba:iterator>
@@ -81,6 +85,11 @@
       <zorba:param>item()</zorba:param>
       <zorba:output>xs:QName?</zorba:output>
     </zorba:signature>
+
+    <zorba:methods>
+      <zorba:mustCopyInputNodes value="false"/>
+    </zorba:methods>
+
   </zorba:function>
 
   <zorba:function>
@@ -88,6 +97,11 @@
       <zorba:param>item()</zorba:param>
       <zorba:output>xs:QName?</zorba:output>
     </zorba:signature>
+
+    <zorba:methods>
+      <zorba:mustCopyInputNodes value="false"/>
+    </zorba:methods>
+
   </zorba:function>
 
 </zorba:iterator>
@@ -105,6 +119,11 @@
       <zorba:param>node()</zorba:param>
       <zorba:output>xs:boolean</zorba:output>
     </zorba:signature>
+
+    <zorba:methods>
+      <zorba:mustCopyInputNodes value="false"/>
+    </zorba:methods>
+
   </zorba:function>
 
 </zorba:iterator>

=== modified file 'src/runtime/spec/sequences/sequences.xml'
--- src/runtime/spec/sequences/sequences.xml	2011-10-07 23:56:40 +0000
+++ src/runtime/spec/sequences/sequences.xml	2011-11-29 22:22:26 +0000
@@ -55,6 +55,7 @@
       <zorba:getReturnType/>
       <zorba:ignoresSortedNodes/>
       <zorba:ignoresDuplicateNodes/>
+      <zorba:mustCopyInputNodes value="false"/>
     </zorba:methods>
 
   </zorba:function>
@@ -153,6 +154,7 @@
     <zorba:methods>
       <zorba:ignoresSortedNodes/>
       <zorba:ignoresDuplicateNodes/>
+      <zorba:mustCopyInputNodes value="false"/>
     </zorba:methods>
 
   </zorba:function>
@@ -180,6 +182,7 @@
     <zorba:methods>
       <zorba:ignoresSortedNodes/>
       <zorba:ignoresDuplicateNodes/>
+      <zorba:mustCopyInputNodes value="false"/>
     </zorba:methods>
   </zorba:function>
 
@@ -266,6 +269,7 @@
     <zorba:methods>
       <zorba:ignoresSortedNodes/>
       <zorba:ignoresDuplicateNodes/>
+      <zorba:mustCopyInputNodes value="false"/>
     </zorba:methods>
 
   </zorba:function>
@@ -310,6 +314,7 @@
       <zorba:propagatesSortedNodes producer="0"/>
       <zorba:ignoresSortedNodes/>
       <zorba:ignoresDuplicateNodes/>
+      <zorba:mustCopyInputNodes value="false"/>
     </zorba:methods>
 
   </zorba:function>
@@ -350,6 +355,7 @@
       <zorba:propagatesDistinctNodes producer="0"/>
       <zorba:ignoresSortedNodes/>
       <zorba:ignoresDuplicateNodes/>
+      <zorba:mustCopyInputNodes value="false"/>
     </zorba:methods>
 
   </zorba:function>
@@ -397,6 +403,7 @@
       <zorba:getReturnType/>
       <zorba:propagatesDistinctNodes producer="0"/>
       <zorba:propagatesSortedNodes producer="0"/>
+      <zorba:mustCopyInputNodes value="false"/>
       <zorba:specializable/>
     </zorba:methods>
 
@@ -444,6 +451,7 @@
       <zorba:getReturnType/>
       <zorba:propagatesDistinctNodes producer="0"/>
       <zorba:propagatesSortedNodes producer="0"/>
+      <zorba:mustCopyInputNodes value="false"/>
     </zorba:methods>
 
   </zorba:function>
@@ -484,6 +492,7 @@
       <zorba:getReturnType/>
       <zorba:propagatesDistinctNodes producer="0"/>
       <zorba:propagatesSortedNodes producer="0"/>
+      <zorba:mustCopyInputNodes value="false"/>
     </zorba:methods>
 
   </zorba:function>
@@ -524,6 +533,7 @@
     <zorba:methods>
       <zorba:getReturnType/>
       <zorba:ignoresSortedNodes/>
+      <zorba:mustCopyInputNodes value="false"/>
     </zorba:methods>
 
    </zorba:function>
@@ -561,6 +571,7 @@
       <zorba:propagatesSortedNodes producer="0"/>
       <zorba:ignoresSortedNodes/>
       <zorba:ignoresDuplicateNodes/>
+      <zorba:mustCopyInputNodes value="false"/>
     </zorba:methods>
 
   </zorba:function>
@@ -624,6 +635,7 @@
 
     <zorba:methods>
       <zorba:accessesDynCtx returnValue="true"/>
+      <zorba:mustCopyInputNodes value="false"/>
     </zorba:methods>
 
   </zorba:function>
@@ -711,6 +723,7 @@
 
     <zorba:methods>
       <zorba:ignoresSortedNodes/>
+      <zorba:mustCopyInputNodes value="false"/>
     </zorba:methods>
 
   </zorba:function>
@@ -978,6 +991,7 @@
       <zorba:producesSortedNodes returnValue="YES"/>
       <zorba:ignoresSortedNodes/>
       <zorba:ignoresDuplicateNodes/>
+      <zorba:mustCopyInputNodes producer="1"/>
     </zorba:methods>
 
   </zorba:function>
@@ -1028,6 +1042,7 @@
       <zorba:producesSortedNodes returnValue="YES"/>
       <zorba:ignoresSortedNodes/>
       <zorba:ignoresDuplicateNodes/>
+      <zorba:mustCopyInputNodes producer="1"/>
     </zorba:methods>
 
   </zorba:function>
@@ -1070,6 +1085,7 @@
       <zorba:producesSortedNodes returnValue="YES"/>
       <zorba:ignoresSortedNodes/>
       <zorba:ignoresDuplicateNodes/>
+      <zorba:mustCopyInputNodes producer="1"/>
     </zorba:methods>
 
   </zorba:function>

=== modified file 'src/runtime/spec/store/documents.xml'
--- src/runtime/spec/store/documents.xml	2011-08-04 02:14:56 +0000
+++ src/runtime/spec/store/documents.xml	2011-11-29 22:22:26 +0000
@@ -38,6 +38,7 @@
       <zorba:methods>
         <zorba:getScriptingKind returnValue="UPDATING_EXPR"/>
         <zorba:accessesDynCtx returnValue="true"/>
+        <zorba:mustCopyInputNodes producer="1"/>
       </zorba:methods>
 
     </zorba:function>

=== modified file 'src/runtime/update/update.cpp'
--- src/runtime/update/update.cpp	2011-09-16 19:36:18 +0000
+++ src/runtime/update/update.cpp	2011-11-29 22:22:26 +0000
@@ -794,7 +794,8 @@
   v.beginVisit(*this);
   CopyClause::const_iter_t lIter = theCopyClauses.begin();
   CopyClause::const_iter_t lEnd = theCopyClauses.end();
-  for ( ; lIter != lEnd; ++lIter ) {
+  for ( ; lIter != lEnd; ++lIter ) 
+  {
     lIter->theInput->accept ( v );
   } 
   theModifyIter->accept(v);

=== modified file 'src/runtime/visitors/planiter_visitor_impl_code.h'
--- src/runtime/visitors/planiter_visitor_impl_code.h	2011-11-10 01:26:24 +0000
+++ src/runtime/visitors/planiter_visitor_impl_code.h	2011-11-29 22:22:26 +0000
@@ -31,8 +31,6 @@
 
   PLAN_ITER_VISITOR (DocumentIterator);
 
-  PLAN_ITER_VISITOR (DocumentContentIterator);
-
   PLAN_ITER_VISITOR (UDFunctionCallIterator);
 
   PLAN_ITER_VISITOR (ExtFunctionCallIterator);

=== modified file 'src/runtime/visitors/planiter_visitor_impl_include.h'
--- src/runtime/visitors/planiter_visitor_impl_include.h	2011-11-10 01:26:24 +0000
+++ src/runtime/visitors/planiter_visitor_impl_include.h	2011-11-29 22:22:26 +0000
@@ -100,7 +100,6 @@
   class FnMinMaxIterator;
   class TextIterator;
   class DocumentIterator;
-  class DocumentContentIterator;
   class CastIterator;
   class NameCastIterator;
   class CastableIterator;

=== modified file 'src/runtime/visitors/printer_visitor_impl.cpp'
--- src/runtime/visitors/printer_visitor_impl.cpp	2011-11-10 01:26:24 +0000
+++ src/runtime/visitors/printer_visitor_impl.cpp	2011-11-29 22:22:26 +0000
@@ -1127,12 +1127,14 @@
   thePrinter.endBeginVisit(theId);
 }
 
-void PrinterVisitor::endVisit(const CastIterator&) {
+void PrinterVisitor::endVisit(const CastIterator&) 
+{
   thePrinter.startEndVisit();
   thePrinter.endEndVisit();
 }
 
-void PrinterVisitor::beginVisit(const PromoteIterator& a) {
+void PrinterVisitor::beginVisit(const PromoteIterator& a) 
+{
   thePrinter.startBeginVisit("PromoteIterator", ++theId);
   std::ostringstream lStream;
   TypeOps::serialize(lStream, *a.thePromoteType);
@@ -1141,12 +1143,14 @@
   thePrinter.endBeginVisit(theId);
 }
 
-void PrinterVisitor::endVisit(const PromoteIterator&) {
+void PrinterVisitor::endVisit(const PromoteIterator&) 
+{
   thePrinter.startEndVisit();
   thePrinter.endEndVisit();
 }
 
-void PrinterVisitor::beginVisit(const CastableIterator& a) {
+void PrinterVisitor::beginVisit(const CastableIterator& a) 
+{
   thePrinter.startBeginVisit("CastableIterator", ++theId);
   std::ostringstream lStream;
   TypeOps::serialize(lStream, *a.theCastType);
@@ -1216,7 +1220,40 @@
   PRINTER_VISITOR_DEFINITION (AndIterator)
   PRINTER_VISITOR_DEFINITION (CompareIterator)
   PRINTER_VISITOR_DEFINITION (AtomicValuesEquivalenceIterator)
-  PRINTER_VISITOR_DEFINITION (ElementIterator)
+
+  void PrinterVisitor::beginVisit(const DocumentIterator& a)
+  {
+    thePrinter.startBeginVisit("DocumentIterator", ++theId);
+    if (!a.copyInputNodes())
+    {
+      thePrinter.addAttribute("copyInputNodes", "false");
+    }
+    printCommons(&a, theId);
+    thePrinter.endBeginVisit(theId);
+  }
+
+  void PrinterVisitor::endVisit(const DocumentIterator&)
+  {                            
+    thePrinter.startEndVisit();
+    thePrinter.endEndVisit(); 
+  }
+
+  void PrinterVisitor::beginVisit(const ElementIterator& a)
+  {
+    thePrinter.startBeginVisit("ElementIterator", ++theId);
+    if (!a.copyInputNodes())
+    {
+      thePrinter.addAttribute("copyInputNodes", "false");
+    }
+    printCommons(&a, theId);
+    thePrinter.endBeginVisit(theId);
+  }
+
+  void PrinterVisitor::endVisit(const ElementIterator&)
+  {                            
+    thePrinter.startEndVisit();
+    thePrinter.endEndVisit(); 
+  }
 
   void PrinterVisitor::beginVisit(const AttributeIterator& a)
   {
@@ -1235,8 +1272,6 @@
     thePrinter.endEndVisit();
   }
 
-  PRINTER_VISITOR_DEFINITION (DocumentIterator)
-  PRINTER_VISITOR_DEFINITION (DocumentContentIterator)
   PRINTER_VISITOR_DEFINITION (CommentIterator)
   PRINTER_VISITOR_DEFINITION (PiIterator)
   PRINTER_VISITOR_DEFINITION (EmptyIterator)

=== modified file 'src/runtime/visitors/printer_visitor_impl.h'
--- src/runtime/visitors/printer_visitor_impl.h	2011-11-10 01:26:24 +0000
+++ src/runtime/visitors/printer_visitor_impl.h	2011-11-29 22:22:26 +0000
@@ -15,6 +15,11 @@
  */
 #pragma once
 
+//
+// This file is included inside <BUILD_DIR>/src/runtime/visitors/printer_visitor.h.
+// That file defines the PrinterVisitor class as a subclass of PlanIterVisitor.
+//
+
 #define DECLARE_VISITOR(class)          \
   void beginVisit(const class& a);      \
   void endVisit(const class& );
@@ -226,7 +231,6 @@
   DECLARE_VISITOR (ElementIterator)
   DECLARE_VISITOR (AttributeIterator)
   DECLARE_VISITOR (DocumentIterator)
-  DECLARE_VISITOR (DocumentContentIterator)
   DECLARE_VISITOR (CommentIterator)
   DECLARE_VISITOR (PiIterator)
   DECLARE_VISITOR (EmptyIterator)

=== modified file 'src/store/api/item.h'
--- src/store/api/item.h	2011-10-15 10:41:19 +0000
+++ src/store/api/item.h	2011-11-29 22:22:26 +0000
@@ -586,31 +586,6 @@
   virtual const Item_t
   getFunctionName() const;
 
-#if 0
-  /**
-   * Make a copy of the xml tree rooted at this node and place the copied
-   * tree at a given position under a given node.
-   *
-   * @param parent   The node P under which the copied tree is to be placed.
-   *                 P may be NULL, in which case the copied tree becomes a
-   *                 new standalone xml tree.
-   * @param pos      The position under P where the copied tree is to be placed.
-   *                 If "this" is an attribute node, pos is a position among the
-   *                 attributes of P; otherwise it is a position among the 
-   *                 children of P. If is greater or equal to the current number
-   *                 of attributes/children in P, then the copied tree is appended
-   *                 to P's attributes/children.
-   * @param copymode Encapsulates the construction-mode and copy-namespace-mode
-   *                 components of the query's static context. 
-   * @return         A pointer to the root node of the copied tree, or to this
-   *                 node if no copy was actually done. 
-   */
-  virtual Item* copy(
-        Item* parent,
-        vsize_t pos,
-        const CopyMode& copymode) const;
-#endif
-
   /**
    * Make a copy of the xml tree rooted at this node and place the copied
    * tree as the last child of a given node.

=== modified file 'src/store/api/update_consts.h'
--- src/store/api/update_consts.h	2011-10-12 20:59:49 +0000
+++ src/store/api/update_consts.h	2011-11-29 22:22:26 +0000
@@ -24,7 +24,7 @@
 /*******************************************************************************
 
 ********************************************************************************/
-class  UpdateConsts
+class UpdateConsts
 {
 public:
   typedef enum

=== modified file 'src/store/naive/node_items.cpp'
--- src/store/naive/node_items.cpp	2011-11-12 06:43:44 +0000
+++ src/store/naive/node_items.cpp	2011-11-29 22:22:26 +0000
@@ -264,87 +264,13 @@
 /////////////////////////////////////////////////////////////////////////////////
 
 
-/*******************************************************************************
-  Create a new node C within a given tree T and with a given node Pas parent.
-
-  If P is NULL, C becomes the root (and single node) of T. If P is not NULL,
-  then T is the same as the tree that P belongs to.
-********************************************************************************/
-XmlNode::XmlNode(
-    XmlTree* tree,
-    InternalNode* parent,
-    store::StoreConsts::NodeKind nodeKind)
-  :
-  theParent(parent),
-  theFlags(0)
-{
-  assert(tree || parent);
-  assert(parent == NULL || parent->getTree() != NULL);
-  assert(tree == NULL || parent == NULL || parent->getTree() == tree);
-
-  theFlags = (uint32_t)nodeKind;
-
-  if (parent == NULL)
-  {
-    setTree(tree);
-    tree->setRoot(this);
-  }
-  else
-  {
-    setTree(parent->getTree());
-  }
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
-#ifndef NDEBUG
-XmlNode::~XmlNode()
-{
-  NODE_TRACE1("Deleted " << store::StoreConsts::toString(getNodeKind()) << this);
-}
-#endif
-
-
-/*******************************************************************************
-  Private method
-********************************************************************************/
-void XmlNode::setTree(const XmlTree* t)
-{
-  theUnion.treeRCPtr = (long*)t;
-}
-
-
-/*******************************************************************************
-  Method called only from the loader and PutUpd::apply()
-********************************************************************************/
-void XmlNode::setId(XmlTree* tree, const OrdPathStack* op)
-{
-  ZORBA_ASSERT(getTree() == NULL);
-
-  setTree(tree);
-
-#ifndef TEXT_ORDPATH
-  if (getNodeKind() != store::StoreConsts::textNode)
-  {
-#endif
-    if (op != NULL)
-      static_cast<OrdPathNode*>(this)->getOrdPath() = *op;
-    else
-      static_cast<OrdPathNode*>(this)->getOrdPath().setAsRoot();
-#ifndef TEXT_ORDPATH
-  }
-#endif
-}
-
-
-#ifndef TEXT_ORDPATH
-/*******************************************************************************
-
-********************************************************************************/
-long XmlNode::compareInSameTree(const XmlNode* n1, const XmlNode* n2) const
-{
+#ifndef TEXT_ORDPATH
+/*******************************************************************************
+  Static method.
+********************************************************************************/
+long XmlNode::compareInSameTree(const XmlNode* n1, const XmlNode* n2)
+{
+  assert(!n1->isConnectorNode() && !n2->isConnectorNode());
   assert(n1 != n2);
   assert(n1->getTree() == n2->getTree());
   assert(n1->theParent != NULL || n2->theParent != NULL);
@@ -459,8 +385,8 @@
   else
   {
     // both nodes are under the same parent, and none of them is an attribute
-    InternalNode::const_iterator ite = theParent->childrenBegin();
-    InternalNode::const_iterator end = theParent->childrenEnd();
+    InternalNode::const_iterator ite = n1->theParent->childrenBegin();
+    InternalNode::const_iterator end = n1->theParent->childrenEnd();
 
     for (; ite != end; ++ite)
     {
@@ -481,10 +407,87 @@
 
 
 /*******************************************************************************
+  Create a new node C within a given tree T and with a given node Pas parent.
+
+  If P is NULL, C becomes the root (and single node) of T. If P is not NULL,
+  then T is the same as the tree that P belongs to.
+********************************************************************************/
+XmlNode::XmlNode(
+    XmlTree* tree,
+    InternalNode* parent,
+    store::StoreConsts::NodeKind nodeKind)
+  :
+  theParent(parent),
+  theFlags(0)
+{
+  assert(tree || parent);
+  assert(parent == NULL || parent->getTree() != NULL);
+  assert(tree == NULL || parent == NULL || parent->getTree() == tree);
+
+  theFlags = (uint32_t)nodeKind;
+
+  if (parent == NULL)
+  {
+    setTree(tree);
+    tree->setRoot(this);
+  }
+  else
+  {
+    setTree(parent->getTree());
+  }
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+#ifndef NDEBUG
+XmlNode::~XmlNode()
+{
+  NODE_TRACE1("Deleted " << store::StoreConsts::toString(getNodeKind()) << this);
+}
+#endif
+
+
+/*******************************************************************************
+  Private method
+********************************************************************************/
+void XmlNode::setTree(const XmlTree* t)
+{
+  theUnion.treeRCPtr = (long*)t;
+}
+
+
+/*******************************************************************************
+  Method called only from the loader and PutUpd::apply()
+********************************************************************************/
+void XmlNode::setId(XmlTree* tree, const OrdPathStack* op)
+{
+  assert(!isConnectorNode());
+  ZORBA_ASSERT(getTree() == NULL);
+
+  setTree(tree);
+
+#ifndef TEXT_ORDPATH
+  if (getNodeKind() != store::StoreConsts::textNode)
+  {
+#endif
+    if (op != NULL)
+      static_cast<OrdPathNode*>(this)->getOrdPath() = *op;
+    else
+      static_cast<OrdPathNode*>(this)->getOrdPath().setAsRoot();
+#ifndef TEXT_ORDPATH
+  }
+#endif
+}
+
+
+/*******************************************************************************
 
 ********************************************************************************/
 store::Item_t XmlNode::getEBV() const
 {
+  assert(!isConnectorNode());
   store::Item_t bVal;
   GET_FACTORY().createBoolean(bVal, true);
   return bVal;
@@ -496,6 +499,8 @@
 ********************************************************************************/
 void XmlNode::getBaseURIInternal(zstring& uri, bool& local) const
 {
+  assert(!isConnectorNode());
+
   local = false;
 
   if (theParent)
@@ -517,33 +522,93 @@
     store::Item* inParent,
     const store::CopyMode& copymode) const
 {
+  assert(!isConnectorNode());
+
   InternalNode* parent = NULL;
   csize pos = 0;
 
   if (inParent)
   {
+    assert(inParent->getNodeKind() == store::StoreConsts::elementNode ||
+           inParent->getNodeKind() == store::StoreConsts::documentNode);
+
     parent = reinterpret_cast<InternalNode*>(inParent);
-    pos = parent->numChildren();
-
-    ZORBA_ASSERT(inParent->getNodeKind() == store::StoreConsts::elementNode ||
-                 inParent->getNodeKind() == store::StoreConsts::documentNode);
-  }
-
-  if (getNodeKind() == store::StoreConsts::attributeNode)
-  {
-    if (parent)
+
+    if (copymode.theDoCopy == false)
+    {
+      if (getNodeKind() == store::StoreConsts::textNode)
+      {
+        pos = parent->numChildren();
+
+        XmlNode* lsib = (pos > 0 ? parent->getChild(pos-1) : NULL);
+
+        if (lsib != NULL &&
+            lsib->getNodeKind() == store::StoreConsts::textNode)
+        {
+          TextNode* textSibling = reinterpret_cast<TextNode*>(lsib);
+          ZORBA_ASSERT(!textSibling->isTyped());
+
+          zstring content = textSibling->getText();
+          appendStringValue(content);
+
+          if (textSibling->theParent != parent)
+          {
+            parent->removeConnector(pos-1);
+
+            TextNode* textNode = 
+            GET_NODE_FACTORY().createTextNode(parent->getTree(),
+                                              parent,
+                                              true,
+                                              0,
+                                              content);
+            return textNode;
+          }
+          else
+          {
+            textSibling->setText(content);
+            return const_cast<XmlNode*>(this);
+          }
+        }
+      }
+      else if (getNodeKind() == store::StoreConsts::attributeNode)
+      {
+        ElementNode* pnode = reinterpret_cast<ElementNode*>(parent);
+        store::Item_t attrName = getNodeName();
+        pnode->checkUniqueAttr(attrName);
+
+        try
+        {
+          
+          pnode->addBindingForQName(attrName, true, false);
+        }
+        catch (...)
+        {
+          goto doCopy;
+        }
+      }
+
+      new ConnectorNode(parent->getTree(), parent, this);
+      return const_cast<XmlNode*>(this);
+    }
+
+  doCopy:
+    if (getNodeKind() == store::StoreConsts::attributeNode)
     {
       ElementNode* pnode = reinterpret_cast<ElementNode*>(parent);
       pnode->checkUniqueAttr(getNodeName());
       pos = pnode->numAttrs();
     }
-  }
+    else
+    {
+      pos = parent->numChildren();
+    }
+  } // have parent
 
   return copyInternal(parent, parent, pos, NULL, copymode);
 }
 
 
-
+#if 0
 /*******************************************************************************
   Make a copy of the xml tree rooted at this node and place the copied tree at
   a given position under a given node. Return a pointer to the root node of the
@@ -564,6 +629,9 @@
     csize pos,
     const store::CopyMode& copymode) const
 {
+  assert(!isConnectorNode());
+  assert(copymode.theDoCopy == true);
+
   InternalNode* parent = NULL;
 
   if (inParent)
@@ -584,6 +652,7 @@
 
   return copyInternal(parent, parent, pos, NULL, copymode);
 }
+#endif
 
 
 /*******************************************************************************
@@ -591,6 +660,8 @@
 ********************************************************************************/
 void XmlNode::connect(InternalNode* parent, csize pos)
 {
+  assert(!isConnectorNode());
+
   ZORBA_FATAL(theParent == NULL, "");
 
   if (getNodeKind() == store::StoreConsts::attributeNode)
@@ -609,6 +680,8 @@
 ********************************************************************************/
 bool XmlNode::disconnect(csize& pos)
 {
+  assert(!isConnectorNode());
+
   if (theParent == NULL)
     return false;
 
@@ -655,6 +728,9 @@
 }
 
 
+/*******************************************************************************
+
+********************************************************************************/
 void XmlNode::destroyInternal(bool removeType)
 {
   store::StoreConsts::NodeKind kind = getNodeKind();
@@ -669,7 +745,14 @@
 
     for (; ite != end; ++ite)
     {
-      (*ite)->destroyInternal(removeType);
+      if ((*ite)->isConnectorNode())
+      {
+        delete (*ite);
+      }
+      else
+      {
+        (*ite)->destroyInternal(removeType);
+      }
     }
 
     ite = node->attrsBegin();
@@ -708,6 +791,67 @@
 
 /////////////////////////////////////////////////////////////////////////////////
 //                                                                             //
+//  class ConnectorNode                                                        //
+//                                                                             //
+/////////////////////////////////////////////////////////////////////////////////
+
+
+/*******************************************************************************
+
+********************************************************************************/
+ConnectorNode::ConnectorNode(
+    XmlTree* tree,
+    InternalNode* parent,
+    const XmlNode* child)
+  :
+  XmlNode(tree, parent, child->getNodeKind()),
+  theNode(const_cast<XmlNode*>(child))
+{
+  ZORBA_ASSERT(parent != NULL && child != NULL);
+  theFlags |= IsConnectorNode;
+
+  if (child->getNodeKind() == store::StoreConsts::attributeNode)
+  {
+    parent->insertAttr(this, parent->numAttrs());
+  }
+  else
+  {
+    parent->insertChild(this, parent->numChildren());
+  }
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+XmlNode* ConnectorNode::copyInternal(
+      InternalNode* rootParent,
+      InternalNode* parent,
+      csize pos,
+      const XmlNode* rootCopy,
+      const store::CopyMode& copyMode) const
+{
+  ZORBA_ASSERT(false);
+  return NULL;
+}
+
+/*******************************************************************************
+
+********************************************************************************/
+zstring ConnectorNode::show() const
+{
+  std::stringstream str;
+
+  str <<  "<connector>" << std::endl;
+  str << theNode->show();
+  str << "</connector>";
+
+  return str.str();
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////
+//                                                                             //
 //  class OrdPathNode                                                          //
 //                                                                             //
 /////////////////////////////////////////////////////////////////////////////////
@@ -915,16 +1059,15 @@
 ********************************************************************************/
 bool OrdPathNode::isAncestor(const store::Item_t& aOther) const
 {
+  assert(!static_cast<XmlNode*>(aOther.getp())->isConnectorNode());
+
   const OrdPathNode* lThisNode = static_cast<const OrdPathNode*>(this);
   const OrdPathNode* lOtherNode = static_cast<const OrdPathNode*>(aOther.getp());
   const OrdPath& lOtherOrdPath = lOtherNode->getOrdPath();
   const OrdPath& lThisOrdPath = lThisNode->getOrdPath();
 
-  return 
-    (
-      lThisNode->getTree() == lOtherNode->getTree() &&
-      (lThisOrdPath.getRelativePosition(lOtherOrdPath) == OrdPath::ANCESTOR)
-    );
+  return (lThisNode->getTree() == lOtherNode->getTree() &&
+          (lThisOrdPath.getRelativePosition(lOtherOrdPath) == OrdPath::ANCESTOR));
 }
 
 
@@ -942,16 +1085,15 @@
 ********************************************************************************/
 bool OrdPathNode::isFollowing(const store::Item_t& aOther) const
 { 
+  assert(!static_cast<XmlNode*>(aOther.getp())->isConnectorNode());
+
   const OrdPathNode* lThisNode = static_cast<const OrdPathNode*>(this);
   const OrdPathNode* lOtherNode = static_cast<const OrdPathNode*>(aOther.getp());
   const OrdPath& lOtherOrdPath = lOtherNode->getOrdPath();
   const OrdPath& lThisOrdPath = lThisNode->getOrdPath();
 
-  return 
-    (
-      lThisNode->getTree() == lOtherNode->getTree() &&
-      (lThisOrdPath.getRelativePosition(lOtherOrdPath) == OrdPath::FOLLOWING)
-    );
+  return (lThisNode->getTree() == lOtherNode->getTree() &&
+          (lThisOrdPath.getRelativePosition(lOtherOrdPath) == OrdPath::FOLLOWING));
 }
 
 
@@ -960,16 +1102,15 @@
 ********************************************************************************/
 bool OrdPathNode::isDescendant(const store::Item_t& aOther) const
 { 
+  assert(!static_cast<XmlNode*>(aOther.getp())->isConnectorNode());
+
   const OrdPathNode* lThisNode = static_cast<const OrdPathNode*>(this);
   const OrdPathNode* lOtherNode = static_cast<const OrdPathNode*>(aOther.getp());
   const OrdPath& lOtherOrdPath = lOtherNode->getOrdPath();
   const OrdPath& lThisOrdPath = lThisNode->getOrdPath();
 
-  return 
-    (
-      lThisNode->getTree() == lOtherNode->getTree() &&
-      (lThisOrdPath.getRelativePosition(lOtherOrdPath) == OrdPath::DESCENDANT)
-    );
+  return (lThisNode->getTree() == lOtherNode->getTree() &&
+          (lThisOrdPath.getRelativePosition(lOtherOrdPath) == OrdPath::DESCENDANT));
 }
 
 
@@ -977,7 +1118,9 @@
 
 ********************************************************************************/
 bool OrdPathNode::isPrecedingSibling(const store::Item_t& aOther) const
-{ 
+{
+  assert(!static_cast<XmlNode*>(aOther.getp())->isConnectorNode());
+ 
   return isPreceding(aOther) && getParent() == aOther->getParent();
 }
 
@@ -986,17 +1129,16 @@
 
 ********************************************************************************/
 bool OrdPathNode::isPreceding(const store::Item_t& aOther) const
-{ 
+{
+  assert(!static_cast<XmlNode*>(aOther.getp())->isConnectorNode());
+ 
   const OrdPathNode* lThisNode = static_cast<const OrdPathNode*>(this);
   const OrdPathNode* lOtherNode = static_cast<const OrdPathNode*>(aOther.getp());
   const OrdPath& lOtherOrdPath = lOtherNode->getOrdPath();
   const OrdPath& lThisOrdPath = lThisNode->getOrdPath();
 
-  return 
-    (
-      lThisNode->getTree() == lOtherNode->getTree() &&
-      (lThisOrdPath.getRelativePosition(lOtherOrdPath) == OrdPath::PRECEDING)
-    );
+  return (lThisNode->getTree() == lOtherNode->getTree() &&
+          (lThisOrdPath.getRelativePosition(lOtherOrdPath) == OrdPath::PRECEDING));
 }
 
 
@@ -1004,7 +1146,9 @@
 
 ********************************************************************************/
 bool OrdPathNode::isChild(const store::Item_t& aOther) const
-{ 
+{
+  assert(!static_cast<XmlNode*>(aOther.getp())->isConnectorNode());
+ 
   return aOther->getParent() == this;
 }
 
@@ -1013,7 +1157,9 @@
 
 ********************************************************************************/
 bool OrdPathNode::isParent(const store::Item_t& aOther) const
-{ 
+{
+  assert(!static_cast<XmlNode*>(aOther.getp())->isConnectorNode());
+ 
   return this->getParent() == aOther;
 }
 
@@ -1041,6 +1187,8 @@
 ********************************************************************************/
 store::Item_t OrdPathNode::leastCommonAncestor(const store::Item_t& aOther) const
 {
+  assert(!static_cast<XmlNode*>(aOther.getp())->isConnectorNode());
+
   const OrdPathNode* lThisNode = static_cast<const OrdPathNode*>(this);
   const OrdPathNode* lOtherNode = static_cast<const OrdPathNode*>(aOther.getp());
 
@@ -1103,6 +1251,8 @@
 #ifndef TEXT_ORDPATH
   for (; ite != end; ++ite)
   {
+    assert(!(*ite)->isConnectorNode());
+
     if ((*ite)->getNodeKind() != store::StoreConsts::textNode)
       break;
   }
@@ -1129,6 +1279,8 @@
 #ifndef TEXT_ORDPATH
   for (; ite != end; ++ite)
   {
+    assert(!(*ite)->isConnectorNode());
+
     if ((*ite)->getNodeKind() != store::StoreConsts::textNode)
       break;
   }
@@ -1146,10 +1298,20 @@
 ********************************************************************************/
 csize InternalNode::findChild(const XmlNode* child) const
 {
+  assert(!child->isConnectorNode());
+
   const_iterator begin = childrenBegin();
   const_iterator end = childrenEnd();
 
-  const_iterator ite = std::find(begin, end, child);
+  const_iterator ite = begin;
+
+  for (; ite != end; ++ite)
+  {
+    assert(!(*ite)->isConnectorNode());
+
+    if (*ite == child)
+      break;
+  }
 
   return (ite - begin);
 }
@@ -1183,6 +1345,7 @@
   {
     iterator ite = childrenBegin() + pos;
     assert((*ite)->theParent == this);
+    assert(!(*ite)->isConnectorNode());
     (*ite)->theParent = NULL;
     theNodes.erase(ite);
   }
@@ -1190,16 +1353,43 @@
 
 
 /*******************************************************************************
+
+********************************************************************************/
+void InternalNode::removeConnector(csize pos)
+{
+  if (pos < numChildren())
+  {
+    iterator ite = childrenBegin() + pos;
+    assert((*ite)->isConnectorNode());
+    ConnectorNode* connector = static_cast<ConnectorNode*>(*ite);
+    assert(connector->theParent == this);
+    connector->theParent = NULL;
+    theNodes.erase(ite);
+    delete connector;
+  }
+}
+
+
+/*******************************************************************************
   If the given node N is a child of "this", disconnect N from "this" and return
   the position of N among the children of "this". Else, return the number of
   children.
 ********************************************************************************/
 csize InternalNode::removeChild(XmlNode* child)
 {
+  assert(!child->isConnectorNode());
+
   iterator begin = childrenBegin();
   iterator end = childrenEnd();
-
-  iterator ite = std::find(begin, end, child);
+  iterator ite = begin;
+
+  for (; ite != end; ++ite)
+  {
+    assert(!(*ite)->isConnectorNode());
+
+    if (*ite == child)
+      break;
+  }
 
   if (ite != end)
   {
@@ -1229,8 +1419,15 @@
 {
   const_iterator begin = attrsBegin();
   const_iterator end = attrsEnd();
-
-  const_iterator ite = std::find(begin, end, attr);
+  const_iterator ite = begin;
+
+  for (; ite != end; ++ite)
+  {
+    assert(!(*ite)->isConnectorNode());
+
+    if (*ite == attr)
+      break;
+  }
 
   return (ite - begin);
 }
@@ -1260,6 +1457,7 @@
   {
     iterator ite = attrsBegin() + pos;
     assert((*ite)->theParent == this);
+    assert(!(*ite)->isConnectorNode());
     (*ite)->theParent = NULL;
     theNodes.erase(ite);
     --theNumAttrs;
@@ -1274,10 +1472,19 @@
 ********************************************************************************/
 csize InternalNode::removeAttr(XmlNode* attr)
 {
+  assert(!attr->isConnectorNode());
+
   iterator begin = attrsBegin();
   iterator end = attrsEnd();
-
-  iterator ite = std::find(begin, end, attr);
+  iterator ite = begin;
+
+  for (; ite != end; ++ite)
+  {
+    assert(!(*ite)->isConnectorNode());
+
+    if (*ite == attr)
+      break;
+  }
 
   if (ite != end)
   {
@@ -1311,6 +1518,7 @@
   }
 }
 
+
 /////////////////////////////////////////////////////////////////////////////////
 //                                                                             //
 //  class DocumentNode                                                         //
@@ -1373,7 +1581,16 @@
 
     for (; ite != end; ++ite)
     {
-      (*ite)->copyInternal(rootParent, copyNode, 0, NULL, copymode);
+      if ((*ite)->isConnectorNode())
+      {
+        ZORBA_ASSERT(copymode.theNsPreserve == false);
+        static_cast<ConnectorNode*>(*ite)->getNode()->
+        copyInternal(rootParent, copyNode, 0, NULL, copymode);
+      }
+      else
+      {
+        (*ite)->copyInternal(rootParent, copyNode, 0, NULL, copymode);
+      }
     }
   }
   catch (...)
@@ -1473,7 +1690,9 @@
 
       if (kind != store::StoreConsts::commentNode &&
           kind != store::StoreConsts::piNode)
+      {
         (*ite)->appendStringValue(val);
+      }
     }
   }
 }
@@ -1640,6 +1859,8 @@
     // stmt), so that we don't have to undo it inside the catch stmt.
     if (parent)
     {
+      assert(!parent->isConnectorNode());
+
       if (append)
         pos = parent->numChildren();
 
@@ -1726,12 +1947,6 @@
   NsBindingsContext* copyParentNsContext = NULL;
   NsBindingsContext* rootNsContext = NULL;
 
-  if (theParent && theParent->getNodeKind() == store::StoreConsts::elementNode)
-    myParentNsContext = static_cast<ElementNode*>(theParent)->getNsContext();
-
-  if (parent && parent->getNodeKind() == store::StoreConsts::elementNode)
-    copyParentNsContext = static_cast<ElementNode*>(parent)->getNsContext();
-
   if (rootParent && rootParent->getNodeKind() == store::StoreConsts::elementNode)
     rootNsContext = reinterpret_cast<ElementNode*>(rootParent)->getNsContext();
 
@@ -1771,6 +1986,12 @@
 
     if (copymode.theNsPreserve)
     {
+      if (theParent && theParent->getNodeKind() == store::StoreConsts::elementNode)
+        myParentNsContext = static_cast<ElementNode*>(theParent)->getNsContext();
+
+      if (parent && parent->getNodeKind() == store::StoreConsts::elementNode)
+        copyParentNsContext = static_cast<ElementNode*>(parent)->getNsContext();
+
       // If we are copying the root of an xml subtree, or a node that does
       // not inherit ns bindings directly from its parent (but may inherit
       // from another ancestor).
@@ -1938,7 +2159,7 @@
 
     for (; ite != end; ++ite)
     {
-      AttributeNode* attr = static_cast<AttributeNode*>(*ite);
+      AttributeNode* attr = getAttr(ite);
 
       if (attr->isBaseUri())
       {
@@ -1994,7 +2215,16 @@
       if (child == rootCopy)
         continue;
 
-      child->copyInternal(rootParent, copyNode, 0, rootCopy, copymode);
+      if (child->isConnectorNode())
+      {
+        ZORBA_ASSERT(copymode.theNsPreserve == false);
+        static_cast<ConnectorNode*>(child)->getNode()->
+        copyInternal(rootParent, copyNode, 0, rootCopy, copymode);
+      }
+      else
+      {
+        child->copyInternal(rootParent, copyNode, 0, rootCopy, copymode);
+      }
     }
   }
   catch (...)
@@ -2108,7 +2338,7 @@
       if (textChild != NULL)
         return false;
 
-      textChild = static_cast<TextNode*>(*ite);
+      textChild = static_cast<TextNode*>(getChild(ite));
     }
 
     return (textChild && textChild->isTyped());
@@ -2137,7 +2367,7 @@
       if (textChild != NULL)
         ZORBA_ASSERT(false);
 
-      textChild = static_cast<TextNode*>(*ite);
+      textChild = static_cast<TextNode*>(getChild(ite));
     }
   }
 
@@ -2261,7 +2491,9 @@
 
       if (kind != store::StoreConsts::commentNode &&
           kind != store::StoreConsts::piNode)
+      {
         (*ite)->appendStringValue(val);
+      }
     }
   }
 }
@@ -2330,7 +2562,7 @@
 
   for (; ite != end; ++ite)
   {
-    AttributeNode* attr = static_cast<AttributeNode*>(*ite);
+    XmlNode* attr = *ite;
     if (ZSTREQ(attr->getNodeName()->getNamespace(), "xsi") &&
         ZSTREQ(attr->getNodeName()->getLocalName(), "nil"))
     {
@@ -2377,14 +2609,79 @@
   assert(bindings.empty());
   assert(theNsContext != NULL);
 
+  if (ns_scoping == store::StoreConsts::ONLY_LOCAL_NAMESPACES)
+  {
+    const zstring& prefix = theName->getPrefix();
+    zstring ns;
+
+    bool found = getNsContext()->findBinding(prefix, ns);
+
+    // binding may be absent only if the prefix was empty and there was no
+    // default namespace declaration in scope.
+    ZORBA_ASSERT(prefix.empty() || prefix == "xml" || found);
+
+    if (found)
+      bindings.push_back(std::pair<zstring, zstring>(prefix, ns));
+      
+    const_iterator ite = attrsBegin();
+    const_iterator end = attrsEnd();
+
+    for (; ite != end; ++ite)
+    {
+      const zstring& prefix = (*ite)->getNodeName()->getPrefix();
+
+      bool found = getNsContext()->findBinding(prefix, ns);
+
+      ZORBA_ASSERT(prefix.empty() || prefix == "xml" || found);
+
+      if (found)
+      {
+        store::NsBindings::const_iterator ite2 = bindings.begin();
+        store::NsBindings::const_iterator end2 = bindings.end();
+
+        for (; ite2 != end2; ++ite2)
+        {
+          if (ite2->second == ns && ite2->first == prefix)
+            break;
+        }
+
+        if (ite2 == end2)
+          bindings.push_back(std::pair<zstring, zstring>(prefix, ns));
+      }
+    }
+
+    if (haveLocalBindings())
+    {
+      store::NsBindings::const_iterator ite = getNsContext()->getBindings().begin();
+      store::NsBindings::const_iterator end = getNsContext()->getBindings().end();
+
+      for (; ite != end; ++ite)
+      {
+        const zstring& prefix = ite->first;
+        const zstring& ns = ite->second;
+
+        store::NsBindings::const_iterator ite2 = bindings.begin();
+        store::NsBindings::const_iterator end2 = bindings.end();
+
+        for (; ite2 != end2; ++ite2)
+        {
+          if (ite2->second == ns && ite2->first == prefix)
+            break;
+        }
+
+        if (ite2 == end2)
+          bindings.push_back(std::pair<zstring, zstring>(prefix, ns));
+      }
+    }
+
+    return;
+  }
+
   if (ns_scoping != store::StoreConsts::ONLY_PARENT_NAMESPACES)
   {
     bindings = theNsContext->getBindings();
   }
 
-  if (ns_scoping == store::StoreConsts::ONLY_LOCAL_NAMESPACES)
-    return;
-
   const NsBindingsContext* parentContext = theNsContext->getParent();
 
   while (parentContext != NULL)
@@ -2489,55 +2786,54 @@
   if (ns.empty() && isAttr)
     return false;
 
-  if (prefix != "xml")
-  {
-    zstring ns2;
-    bool found = findBinding(prefix, ns2);
-
-    if (!found)
-    {
-      if (!ns.empty())
-      {
-        addLocalBinding(prefix, ns);
-        return true;
-      }
-    }
-    else if (ns2 != ns)
-    {
-      if (ns2.empty())
-      {
-        if (!haveLocalBindings())
-        {
-          theNsContext = new NsBindingsContext(theNsContext.getp());
-        }
-
-        theNsContext->updateBinding(prefix, ns);
-      }
-
-      if (replacePrefix)
-      {
-        //std::cout << "Prefix: " << prefix << " ns: " << ns << " ns2: " << ns2 << " local: " << qname->getLocalName() << "\n";
-        ZORBA_FATAL(!ns.empty(), "");
-
-        zstring prefix("XXX");
-        zstring dummy;
-
-        while (findBinding(prefix, dummy))
-          prefix += "X";
-
-        GET_FACTORY().createQName(qname, ns, prefix, qname->getLocalName());
-        addLocalBinding(prefix, ns);
-        return true;
-      }
-      else
-      {
-        throw XQUERY_EXCEPTION(
-          err::XUDY0024, ERROR_PARAMS( qname->show(), prefix, ns2 )
-        );
-      }
-    }
-  }
-
+  if (prefix == "xml")
+    return false;
+
+  zstring ns2;
+  bool found = findBinding(prefix, ns2);
+
+  if (!found)
+  {
+    if (!ns.empty())
+    {
+      addLocalBinding(prefix, ns);
+      return true;
+    }
+  }
+  else if (ns2 != ns)
+  {
+    if (ns2.empty())
+    {
+      if (!haveLocalBindings())
+      {
+        theNsContext = new NsBindingsContext(theNsContext.getp());
+      }
+      
+      theNsContext->updateBinding(prefix, ns);
+    }
+    
+    if (replacePrefix)
+    {
+      //std::cout << "Prefix: " << prefix << " ns: " << ns << " ns2: "
+      //          << ns2 << " local: " << qname->getLocalName() << "\n";
+      ZORBA_FATAL(!ns.empty(), "");
+      
+      zstring prefix("XXX");
+      zstring dummy;
+      
+      while (findBinding(prefix, dummy))
+        prefix += "X";
+      
+      GET_FACTORY().createQName(qname, ns, prefix, qname->getLocalName());
+      addLocalBinding(prefix, ns);
+      return true;
+    }
+    else
+    {
+      throw XQUERY_EXCEPTION(err::XUDY0024, ERROR_PARAMS(qname->show(), prefix, ns2));
+    }
+  }
+  
   return false;
 }
 
@@ -2617,7 +2913,7 @@
   {
     if (theNsContext.getp() == rootNSCtx)
     {
-      theNsContext = new NsBindingsContext;
+      theNsContext = new NsBindingsContext(rootNSCtx);
     }
 
     zstring emptyStr;
@@ -2632,7 +2928,7 @@
   {
     if ((*ite)->getNodeKind() == store::StoreConsts::elementNode)
     {
-      static_cast<ElementNode*>((*ite))->uninheritBinding(rootNSCtx, prefix);
+      static_cast<ElementNode*>(getChild(ite))->uninheritBinding(rootNSCtx, prefix);
     }
   }
 }
@@ -2675,7 +2971,7 @@
 
   for (; ite != end; ++ite)
   {
-    AttributeNode* attr = static_cast<AttributeNode*>(*ite);
+    AttributeNode* attr = getAttr(ite);
     if (attr != NULL && !attr->isHidden() && attr->getNodeName()->equals(attrName))
     {
       throw XQUERY_EXCEPTION(err::XQDY0025, ERROR_PARAMS(attrName->getStringValue()));
@@ -2694,7 +2990,7 @@
 
   for (; ite != end; ++ite)
   {
-    AttributeNode* attr = static_cast<AttributeNode*>(*ite);
+    AttributeNode* attr = getAttr(ite);
 
     if (attr->isHidden())
       continue;
@@ -2705,7 +3001,7 @@
 
     for (; ite2 != end; ++ite2)
     {
-      AttributeNode* otherAttr = static_cast<AttributeNode*>(*ite2);
+      AttributeNode* otherAttr = getAttr(ite2);
 
       if (!otherAttr->isHidden() && otherAttr->getNodeName()->equals(attrName))
       {
@@ -2833,7 +3129,7 @@
 
   for (; ite != end; ++ite)
   {
-    AttributeNode* attr = static_cast<AttributeNode*>(*ite);
+    AttributeNode* attr = getAttr(ite);
 
     if (attr->isBaseUri() && attr->isHidden())
     {
@@ -2994,7 +3290,7 @@
 
           for (; ite != end; ++ite)
           {
-            AttributeNode* attr = static_cast<AttributeNode*>(*ite);
+            AttributeNode* attr = parent->getAttr(ite);
 
             if (attr->isBaseUri() && attr->isHidden())
             {
@@ -3233,9 +3529,9 @@
   if (haveListValue())
   {
     const ItemVector& values = getValueVector();
-    ulong numValues = values.size();
+    csize numValues = values.size();
 
-    for (ulong i = 0; i < numValues; ++i)
+    for (csize i = 0; i < numValues; ++i)
     {
       if (dynamic_cast<IDREFItem*>(values.getItem(i)) != NULL)
       {
@@ -3244,9 +3540,9 @@
       else if (dynamic_cast<UserTypedAtomicItem*>(values.getItem(i)) != NULL)
       {
         UserTypedAtomicItem* utai = dynamic_cast<UserTypedAtomicItem*>(values.getItem(i));
-        if ( utai->getTypeCode() == XS_IDREF )
+        if (utai->getTypeCode() == XS_IDREF)
           return true;
-        if ( (dynamic_cast<AtomicItem*>(utai->getBaseItem()))->getTypeCode() == XS_IDREF )
+        if ((dynamic_cast<AtomicItem*>(utai->getBaseItem()))->getTypeCode() == XS_IDREF)
           return true;
       }
     }
@@ -3258,9 +3554,9 @@
   else if (dynamic_cast<UserTypedAtomicItem*>(theTypedValue.getp()) != NULL)
   {
     UserTypedAtomicItem* utai = dynamic_cast<UserTypedAtomicItem*>(theTypedValue.getp());
-    if ( utai->getTypeCode() == XS_IDREF )
+    if (utai->getTypeCode() == XS_IDREF)
       return true;
-    if ( (dynamic_cast<AtomicItem*>(utai->getBaseItem()))->getTypeCode() == XS_IDREF )
+    if ((dynamic_cast<AtomicItem*>(utai->getBaseItem()))->getTypeCode() == XS_IDREF)
       return true;
   }
 
@@ -3285,7 +3581,7 @@
   {
     const std::vector<store::Item_t>& items = getValueVector().getItems();
 
-    ulong size = (ulong)items.size();
+    csize size = items.size();
 
     if (size == 1)
     {
@@ -3295,7 +3591,7 @@
     {
       items[0]->appendStringValue(val);
 
-      for (ulong i = 1; i < size; ++i)
+      for (csize i = 1; i < size; ++i)
       {
         val += " ";
         items[i]->appendStringValue(val);
@@ -3315,13 +3611,13 @@
   {
     const std::vector<store::Item_t>& items = getValueVector().getItems();
 
-    ulong size = (ulong)items.size();
+    csize size = items.size();
 
     if (size > 0)
     {
       items[0]->appendStringValue(buf);
 
-      for (ulong i = 1; i < size; i++)
+      for (csize i = 1; i < size; i++)
       {
         buf += " ";
         items[i]->appendStringValue(buf);
@@ -3458,7 +3754,7 @@
       {
         ZORBA_ASSERT(false);
       }
-    }    
+    }
   }
 
   ZORBA_ASSERT(p->haveTypedValue() && !p->haveEmptyTypedValue());
@@ -4341,7 +4637,8 @@
 
 
 inline XmlNodeTokenizerCallback::begin_type
-XmlNodeTokenizerCallback::beginTokenization() const {
+XmlNodeTokenizerCallback::beginTokenization() const 
+{
   return token_store_->getDocumentTokens().size();
 }
 
@@ -4353,12 +4650,16 @@
   token_store_->putRange(node, begin, token_store_->getDocumentTokens().size());
 }
 
-void XmlNodeTokenizerCallback::pop_lang() {
+
+void XmlNodeTokenizerCallback::pop_lang() 
+{
   lang_stack_.pop();
   ztd::pop_stack( tokenizer_stack_ )->destroy();
 }
 
-void XmlNodeTokenizerCallback::push_lang( iso639_1::type lang ) {
+
+void XmlNodeTokenizerCallback::push_lang( iso639_1::type lang ) 
+{
   lang_stack_.push( lang );
   Tokenizer::ptr t( provider_.getTokenizer( lang, numbers_ ) );
   ZORBA_ASSERT( t.get() );
@@ -4376,8 +4677,10 @@
   tokens_.push_back( t );
 }
 
+
 inline void XmlNodeTokenizerCallback::tokenize( char const *utf8_s,
-                                                size_t len ) {
+                                                size_t len ) 
+{
   tokenizer().tokenize(
     utf8_s, len, get_lang(), false, *this,
     element_stack_.empty() ? NULL : static_cast<void*>( get_element() )

=== modified file 'src/store/naive/node_items.h'
--- src/store/naive/node_items.h	2011-11-02 17:19:09 +0000
+++ src/store/naive/node_items.h	2011-11-29 22:22:26 +0000
@@ -284,6 +284,7 @@
   friend class TextNode;
   friend class PiNode;
   friend class CommentNode;
+  friend class ConnectorNode;
 
   friend class PULImpl;
   friend class CollectionPul;
@@ -352,13 +353,20 @@
 
     // For any kind of node. Set if an identifier has been generated for the node
     // (see SimpleStore::getNodeReference() method).
-    HaveReference         = 0x10000
+    HaveReference         = 0x10000,
+
+    IsConnectorNode       = 0x20000
   };
 
 protected:
   InternalNode    * theParent;
   uint32_t          theFlags;
 
+private:
+#ifndef TEXT_ORDPATH
+  static long compareInSameTree(const XmlNode* n1, const XmlNode* n2);
+#endif
+
 protected:
   XmlNode() : theParent(NULL)
   {
@@ -369,13 +377,34 @@
     theFlags = (uint32_t)k;
   }
 
-
   XmlNode(
       XmlTree* tree,
       InternalNode* parent,
       store::StoreConsts::NodeKind nodeKind);
 
+  virtual void getBaseURIInternal(zstring& uri, bool& local) const;
+
+  void attach(InternalNode* parent, csize pos);
+
+  void detach();
+
+  void destroy(bool removeType);
+
+  bool disconnect(csize& pos);
+
+  void connect(InternalNode* node, csize pos);
+
+#ifndef ZORBA_NO_FULL_TEXT
+  virtual void tokenize( XmlNodeTokenizerCallback& );
+#endif
+
+private:
+  void setTree(const XmlTree* t);
+
+  void destroyInternal(bool removeType);
+
 public:
+
 #ifndef NDEBUG
   virtual ~XmlNode();
 #else
@@ -401,10 +430,11 @@
 
   const store::Collection* getCollection() const
   {
+    assert(!isConnectorNode());
     return reinterpret_cast<const store::Collection*>(getTree()->getCollection());
   }
 
-  void getDocumentURI(zstring& uri) const
+  virtual void getDocumentURI(zstring& uri) const
   {
     ;
   }
@@ -419,11 +449,13 @@
       long timezone = 0,
       const XQPCollator* aCollation = 0) const
   {
+    assert(!isConnectorNode());
     return this == other;
   }
 
   uint32_t hash(long timezone = 0, const XQPCollator* aCollation = 0) const
   {
+    assert(!isConnectorNode());
     XmlNode* node = const_cast<XmlNode*>(this);
     return hashfun::h32((void*)(&node), sizeof(node), FNV_32_INIT);
   }
@@ -432,31 +464,42 @@
 
   void getBaseURI(zstring& uri) const
   {
+    assert(!isConnectorNode());
     bool local = false;
     getBaseURIInternal(uri, local);
   }
 
   store::Item_t getEBV() const;
 
-  store::Item* copy(
-      store::Item* parent,
-      const store::CopyMode& copymode) const;
-
-  store::Item* copy(
-      store::Item* parent,
-      csize pos,
-      const store::CopyMode& copymode) const;
-
-  virtual store::Item_t getNilled() const { return 0; }
-
-  virtual bool isId() const { return false; }
-
-  virtual bool isIdRefs() const { return false; }
-
-  bool isValidated() const { return getTree()->isValidated(); }
+  store::Item* copy(store::Item* parent, const store::CopyMode& copymode) const;
+
+  virtual store::Item_t getNilled() const 
+  {
+    assert(!isConnectorNode());
+    return 0; 
+  }
+
+  virtual bool isId() const 
+  {
+    assert(!isConnectorNode());
+    return false;
+  }
+
+  virtual bool isIdRefs() const 
+  {
+    assert(!isConnectorNode());
+    return false;
+  }
+
+  bool isValidated() const 
+  {
+    assert(!isConnectorNode());
+    return getTree()->isValidated();
+  }
 
   void markValidated()
   {
+    assert(!isConnectorNode());
     assert(theParent == NULL);
     getTree()->markValidated();
   }
@@ -475,10 +518,15 @@
 
   void setCollection(SimpleCollection* coll, ulong pos)
   {
+    assert(!isConnectorNode());
     getTree()->setCollection(coll, pos);
   }
 
-  ulong getCollectionId() const { return getTree()->getCollectionId(); }
+  ulong getCollectionId() const 
+  {
+    assert(!isConnectorNode());
+    return getTree()->getCollectionId(); 
+  }
 
   void setId(XmlTree* tree, const OrdPathStack* op);
 
@@ -515,6 +563,8 @@
 
   void resetHaveReference() { theFlags &= ~HaveReference; }
 
+  bool isConnectorNode() const { return theFlags & IsConnectorNode; }
+
 #ifndef ZORBA_NO_FULL_TEXT
   FTTokenIterator_t getTokens( 
       TokenizerProvider const&,
@@ -522,32 +572,46 @@
       locale::iso639_1::type,
       bool = false ) const;
 #endif /* ZORBA_NO_FULL_TEXT */
-
-protected:
-  virtual void getBaseURIInternal(zstring& uri, bool& local) const;
-
-  void attach(InternalNode* parent, csize pos);
-
-  void detach();
-
-  void destroy(bool removeType);
-
-  bool disconnect(csize& pos);
-
-  void connect(InternalNode* node, csize pos);
-
-#ifndef ZORBA_NO_FULL_TEXT
-  virtual void tokenize( XmlNodeTokenizerCallback& );
-#endif /* ZORBA_NO_FULL_TEXT */
-
-private:
-  void setTree(const XmlTree* t);
-
-#ifndef TEXT_ORDPATH
-  long compareInSameTree(const XmlNode* n1, const XmlNode* n2) const;
-#endif
-
-  void destroyInternal(bool removeType);
+};
+
+
+/******************************************************************************
+
+*******************************************************************************/
+class ConnectorNode : public XmlNode
+{
+  friend class XmlNode;
+
+protected:
+  XmlNode_t  theNode;
+
+protected:
+  ConnectorNode(
+      XmlTree* tree,
+      InternalNode* parent,
+      const XmlNode* child);
+
+public:
+  XmlNode* getNode() const { return theNode.getp(); }
+
+  store::Item* getNodeName() const { return theNode->getNodeName(); }
+
+  store::Item* getType() const { return theNode->getType(); }
+
+  zstring getStringValue() const { return theNode->getStringValue(); }
+
+  void getStringValue2(zstring& val) const { theNode->getStringValue2(val); }
+
+  void appendStringValue(zstring& buf) const { theNode->appendStringValue(buf); }
+
+  XmlNode* copyInternal(
+      InternalNode* rootParent,
+      InternalNode* parent,
+      csize pos,
+      const XmlNode* rootCopy,
+      const store::CopyMode& copyMode) const;
+
+  zstring show() const;
 };
 
 
@@ -629,7 +693,6 @@
 
   virtual store::Item_t
   leastCommonAncestor(const store::Item_t&) const;
-
 };
 
 
@@ -645,6 +708,7 @@
   friend class TextNode;
   friend class PiNode;
   friend class CommentNode;
+  friend class ConnectorNode;
   friend class UpdPut;
   friend class CollectionPul;
   friend class SimpleStore;
@@ -691,6 +755,7 @@
   // SimpleStore Methods
   //
 
+  // To be used by the loader ONLY!
   NodeVector& nodes() { return theNodes; }
 
   csize numChildren() const { return theNodes.size() - theNumAttrs; }
@@ -711,7 +776,23 @@
 
   const_reverse_iterator childrenREnd() const { return theNodes.rend() - theNumAttrs; }
 
-  XmlNode* getChild(csize i) const { return theNodes[theNumAttrs + i]; }
+  XmlNode* getChild(csize i) const 
+  {
+    XmlNode* child = theNodes[theNumAttrs + i];
+
+    if (child->isConnectorNode())
+      return static_cast<ConnectorNode*>(child)->getNode();
+
+    return child;
+  }
+
+  XmlNode* getChild(const_iterator& ite) const
+  {
+    if ((*ite)->isConnectorNode())
+      return static_cast<ConnectorNode*>(*ite)->getNode();
+
+    return *ite;
+  }
 
   csize numAttrs() const { return theNumAttrs; }
 
@@ -725,7 +806,24 @@
 
   AttributeNode* getAttr(csize i) const
   {
-    return reinterpret_cast<AttributeNode*>(theNodes[i]);
+    XmlNode* attr = theNodes[i];
+
+    if (attr && attr->isConnectorNode())
+    {
+      return reinterpret_cast<AttributeNode*>
+             (static_cast<ConnectorNode*>(attr)->getNode());
+    }
+    return reinterpret_cast<AttributeNode*>(attr);
+  }
+
+  AttributeNode* getAttr(const_iterator& ite) const
+  {
+    if ((*ite) && (*ite)->isConnectorNode())
+    {
+      return reinterpret_cast<AttributeNode*>
+             (static_cast<ConnectorNode*>(*ite)->getNode());
+    }
+    return reinterpret_cast<AttributeNode*>(*ite);
   }
 
   void deleteChild(UpdDelete& upd);
@@ -755,6 +853,8 @@
 
   void removeChildren(csize pos, csize numChildren);
 
+  void removeConnector(csize pos);
+
   csize findAttr(XmlNode* attr) const;
 
   void insertAttr(XmlNode* child, csize pos);

=== modified file 'src/store/naive/node_iterators.cpp'
--- src/store/naive/node_iterators.cpp	2011-06-14 17:26:33 +0000
+++ src/store/naive/node_iterators.cpp	2011-11-29 22:22:26 +0000
@@ -45,7 +45,14 @@
     return false;
   }
 
-  result = (*theIte);
+  if ((*theIte)->isConnectorNode())
+  {
+    result = static_cast<ConnectorNode*>(*theIte)->getNode();
+  }
+  else
+  {
+    result = (*theIte);
+  }
 
   ++theIte;
 
@@ -68,7 +75,14 @@
     return false;
   }
 
-  result = (*theIte);
+  if ((*theIte)->isConnectorNode())
+  {
+    result = static_cast<ConnectorNode*>(*theIte)->getNode();
+  }
+  else
+  {
+    result = (*theIte);
+  }
 
   ++theIte;
 
@@ -91,7 +105,13 @@
     return false;
   }
 
-  AttributeNode* attr = static_cast<AttributeNode*>(*theIte);
+  store::Item* node = ((*theIte)->isConnectorNode() ?
+                       static_cast<ConnectorNode*>(*theIte)->getNode() :
+                       (*theIte));
+
+  assert(node->getNodeKind() == store::StoreConsts::attributeNode);
+
+  AttributeNode* attr = static_cast<AttributeNode*>(node);
 
   while (attr->isHidden())
   {
@@ -103,7 +123,13 @@
       return false;
     }
 
-    attr = static_cast<AttributeNode*>(*theIte);
+    node = ((*theIte)->isConnectorNode() ?
+            static_cast<ConnectorNode*>(*theIte)->getNode() :
+            (*theIte));
+
+    assert(node->getNodeKind() == store::StoreConsts::attributeNode);
+
+    attr = static_cast<AttributeNode*>(node);
   }
 
   ++theIte;
@@ -140,7 +166,7 @@
     }
     else if (theCheckOnly)
     {
-      throw ZORBA_EXCEPTION( zerr::ZSTR0045_DUPLICATE_NODE_ERROR );
+      throw ZORBA_EXCEPTION(zerr::ZSTR0045_DUPLICATE_NODE_ERROR);
     }
   }
 }
@@ -285,8 +311,8 @@
   // Do not reset the input. This is done by the runtime NodeSortIterator,
   // which wraps this store iterator.
 
-  ulong numNodes = (ulong)theNodes.size();
-  for (ulong i = 0; i < numNodes; i++)
+  csize numNodes = theNodes.size();
+  for (csize i = 0; i < numNodes; i++)
   {
     XmlNode* n = theNodes[i];
     n->removeReference();
@@ -302,8 +328,8 @@
   // Do not close the input. This is done by the runtime NodeSortIterator,
   // which wraps this store iterator.
 
-  ulong numNodes = (ulong)theNodes.size();
-  for (ulong i = 0; i < numNodes; i++)
+  csize numNodes = theNodes.size();
+  for (csize i = 0; i < numNodes; i++)
   {
     XmlNode* n = theNodes[i];
     n->removeReference();

=== modified file 'src/store/naive/node_iterators.h'
--- src/store/naive/node_iterators.h	2011-06-14 17:26:33 +0000
+++ src/store/naive/node_iterators.h	2011-11-29 22:22:26 +0000
@@ -65,11 +65,17 @@
 
     if (child != NULL && theStart != theEnd)
     {
-      assert(child->getParent() == theParentNode);
+      XmlNode* myChild = ((*theStart)->isConnectorNode() ? 
+                          static_cast<ConnectorNode*>(*theStart)->getNode() :
+                          (*theStart));
 
       while ((*theStart) != child)
       {
         ++theStart;
+
+        myChild = ((*theStart)->isConnectorNode() ? 
+                   static_cast<ConnectorNode*>(*theStart)->getNode() :
+                   (*theStart));
       }
 
       ++theStart;
@@ -87,11 +93,17 @@
 
     if (child != NULL && theStart != theEnd)
     {
-      assert(child->getParent() == theParentNode);
+      XmlNode* myChild = ((*theStart)->isConnectorNode() ? 
+                          static_cast<ConnectorNode*>(*theStart)->getNode() :
+                          (*theStart));
 
-      while ((*theStart) != child)
+      while (myChild != child)
       {
         ++theStart;
+
+        myChild = ((*theStart)->isConnectorNode() ? 
+                   static_cast<ConnectorNode*>(*theStart)->getNode() :
+                   (*theStart));
       }
 
       ++theStart;
@@ -106,7 +118,16 @@
     if (theIte == theEnd)
       return NULL;
 
-    return *theIte++;
+    if ((*theIte)->isConnectorNode())
+    {
+      store::Item* res = static_cast<ConnectorNode*>(*theIte)->getNode();
+      ++theIte;
+      return res;
+    }
+    else
+    {
+      return *theIte++;
+    }
   }
 
 
@@ -158,11 +179,17 @@
 
     if (child != NULL && theStart != theEnd)
     {
-      assert(child->getParent() == theParentNode);
+      XmlNode* myChild = ((*theStart)->isConnectorNode() ? 
+                          static_cast<ConnectorNode*>(*theStart)->getNode() :
+                          (*theStart));
 
       while ((*theStart) != child)
       {
         ++theStart;
+
+        myChild = ((*theStart)->isConnectorNode() ? 
+                   static_cast<ConnectorNode*>(*theStart)->getNode() :
+                   (*theStart));
       }
 
       ++theStart;
@@ -180,11 +207,17 @@
 
     if (child != NULL && theStart != theEnd)
     {
-      assert(child->getParent() == theParentNode);
+      XmlNode* myChild = ((*theStart)->isConnectorNode() ? 
+                          static_cast<ConnectorNode*>(*theStart)->getNode() :
+                          (*theStart));
 
       while ((*theStart) != child)
       {
         ++theStart;
+
+        myChild = ((*theStart)->isConnectorNode() ? 
+                   static_cast<ConnectorNode*>(*theStart)->getNode() :
+                   (*theStart));
       }
 
       ++theStart;
@@ -199,7 +232,16 @@
     if (theIte == theEnd)
       return NULL;
 
-    return *theIte++;
+    if ((*theIte)->isConnectorNode())
+    {
+      store::Item* res = static_cast<ConnectorNode*>(*theIte)->getNode();
+      ++theIte;
+      return res;
+    }
+    else
+    {
+      return *theIte++;
+    }
   }
 
 
@@ -261,7 +303,13 @@
     if (theIte == theEnd)
       return NULL;
 
-    AttributeNode* attr = static_cast<AttributeNode*>(*theIte);
+    store::Item* node = ((*theIte)->isConnectorNode() ?
+                         static_cast<ConnectorNode*>(*theIte)->getNode() :
+                         (*theIte));
+
+    assert(node->getNodeKind() == store::StoreConsts::attributeNode);
+
+    AttributeNode* attr = static_cast<AttributeNode*>(node);
 
     while (attr->isHidden())
     {
@@ -270,7 +318,13 @@
       if (theIte == theEnd)
         return NULL;
 
-      attr = static_cast<AttributeNode*>(*theIte);
+      node = ((*theIte)->isConnectorNode() ?
+              static_cast<ConnectorNode*>(*theIte)->getNode() :
+              (*theIte));
+
+      assert(node->getNodeKind() == store::StoreConsts::attributeNode);
+
+      attr = static_cast<AttributeNode*>(node);
     }
 
     ++theIte;

=== modified file 'src/store/naive/nsbindings.cpp'
--- src/store/naive/nsbindings.cpp	2011-06-14 17:26:33 +0000
+++ src/store/naive/nsbindings.cpp	2011-11-29 22:22:26 +0000
@@ -43,7 +43,7 @@
 /*******************************************************************************
 
 ********************************************************************************/
-NsBindingsContext::NsBindingsContext(ulong numBindings)
+NsBindingsContext::NsBindingsContext(csize numBindings)
 {
   theBindings.resize(numBindings);
 #if 0
@@ -159,9 +159,9 @@
     const zstring& ns,
     bool soft)
 {
-  ulong numBindings = (ulong)theBindings.size();
+  csize numBindings = theBindings.size();
 
-  for (ulong i = 0; i < numBindings; ++i)
+  for (csize i = 0; i < numBindings; ++i)
   {
     if (theBindings[i].first == prefix)
     {

=== modified file 'src/store/naive/nsbindings.h'
--- src/store/naive/nsbindings.h	2011-11-16 04:09:54 +0000
+++ src/store/naive/nsbindings.h	2011-11-29 22:22:26 +0000
@@ -39,7 +39,7 @@
 
   NsBindingsContext(NsBindingsContext* parent);
 
-  NsBindingsContext(ulong numBindings);
+  NsBindingsContext(csize numBindings);
 
   NsBindingsContext(const store::NsBindings& bindings);
 

=== modified file 'src/system/zorba_properties.h'
--- src/system/zorba_properties.h	2011-06-14 21:31:37 +0000
+++ src/system/zorba_properties.h	2011-11-29 22:22:26 +0000
@@ -30,13 +30,20 @@
 
 #ifndef ZORBA_ZORBAPROPERTIES
 #define ZORBA_ZORBAPROPERTIES
-namespace zorba { 
-class ZORBA_DLL_PUBLIC ZorbaProperties : public ::zorba::PropertiesBase {
+namespace zorba 
+{ 
+
+class ZORBA_DLL_PUBLIC ZorbaProperties : public ::zorba::PropertiesBase 
+{
 protected:
-  const char **get_all_options () const {
-    static const char *result [] = { "--trace-parsing", "--trace-scanning", "--use-serializer", "--optimizer", "--result-file", "--debug-file", "--abort", "--query", "--print-query", "--print-time", "--print-ast", "--print-xqdoc", "--print-translated", "--print-normalized", "--print-optimized", "--print-iterator-tree", "--print-item-flow", "--print-static-types", "--dump-lib", "--stable-iterator-ids", "--no-tree-ids", "--print-intermediate-opt", "--print-locations", "--force-gflwor", "--reorder-globals", "--specialize-num", "--specialize-cmp", "--inline-udf", "--loop-hoisting", "--infer-joins", "--trace-translator", "--trace-codegen", "--trace-fulltext", "--debug", "--compile-only", "--tz", "--external-var", "--serializer-param", "--iter-plan-test", "--dot-plan-file", "--max-udf-call-depth", NULL };
+  const char** get_all_options() const 
+  {
+    static const char* result [] = 
+      { "--trace-parsing", "--trace-scanning", "--use-serializer", "--optimizer", "--result-file", "--debug-file", "--abort", "--query", "--print-query", "--print-time", "--print-ast", "--print-xqdoc", "--print-translated", "--print-normalized", "--print-optimized", "--print-iterator-tree", "--print-item-flow", "--print-static-types", "--dump-lib", "--stable-iterator-ids", "--no-tree-ids", "--print-intermediate-opt", "--print-locations", "--force-gflwor", "--reorder-globals", "--specialize-num", "--specialize-cmp", "--inline-udf", "--loop-hoisting", "--infer-joins", "--no-copy-optim", "--serialize-only-query", "--trace-translator", "--trace-codegen", "--trace-fulltext", "--debug", "--compile-only", "--tz", "--external-var", "--serializer-param", "--iter-plan-test", "--dot-plan-file", "--max-udf-call-depth", NULL };
+
     return result;
   }
+
   bool theTraceParsing;
   bool theTraceScanning;
   bool theUseSerializer;
@@ -67,6 +74,8 @@
   bool theInlineUdf;
   bool theLoopHoisting;
   bool theInferJoins;
+  bool theNoCopyOptim;
+  bool theSerializeOnlyQuery;
   bool theTraceTranslator;
   bool theTraceCodegen;
   bool theTraceFulltext;
@@ -79,7 +88,8 @@
   std::string theDotPlanFile;
   uint32_t theMaxUdfCallDepth;
 
-  void initialize () {
+  void initialize() 
+  {
     theTraceParsing = false;
     theTraceScanning = false;
     theUseSerializer = false;
@@ -107,6 +117,8 @@
     theInlineUdf = true;
     theLoopHoisting = true;
     theInferJoins = true;
+    theNoCopyOptim = true;
+    theSerializeOnlyQuery = true;
     theTraceTranslator = false;
     theTraceCodegen = false;
     theTraceFulltext = false;
@@ -115,6 +127,7 @@
     theIterPlanTest = false;
     theMaxUdfCallDepth = 1024;
   }
+
 public:
   const bool &traceParsing () const { return theTraceParsing; }
   const bool &traceScanning () const { return theTraceScanning; }
@@ -146,6 +159,8 @@
   const bool &inlineUdf () const { return theInlineUdf; }
   const bool &loopHoisting () const { return theLoopHoisting; }
   const bool &inferJoins () const { return theInferJoins; }
+  const bool &noCopyOptim() const { return theNoCopyOptim; }
+  const bool& serializeOnlyQuery() const { return theSerializeOnlyQuery; }
   const bool &traceTranslator () const { return theTraceTranslator; }
   const bool &traceCodegen () const { return theTraceCodegen; }
   const bool &traceFulltext () const { return theTraceFulltext; }
@@ -279,6 +294,21 @@
         if ((*argv) [1] == '-' || (*argv) [2] == '\0') { d = 0; ++argv; }
         if (*argv == NULL) { result = "No value given for --infer-joins option"; break; }        init_val (*argv, theInferJoins, d);
       }
+      else if (strcmp (*argv, "--no-copy-optim") == 0)
+      {
+        int d = 2;
+        if ((*argv) [1] == '-' || (*argv) [2] == '\0') { d = 0; ++argv; }
+        if (*argv == NULL) { result = "No value given for --no-copy-optim option"; break; }
+        init_val (*argv, theNoCopyOptim, d);
+      }
+      else if (strcmp (*argv, "--serialize-only-query") == 0)
+      {
+        int d = 2;
+        if ((*argv) [1] == '-' || (*argv) [2] == '\0') { d = 0; ++argv; }
+        if (*argv == NULL)
+        { result = "No value given for --serialize-only-query option"; break; }
+        init_val(*argv, theSerializeOnlyQuery, d);
+      }
 #ifndef NDEBUG
       else if (strcmp (*argv, "--trace-translator") == 0 || strncmp (*argv, "-l", 2) == 0) {
         theTraceTranslator = true;

=== modified file 'src/system/zorba_properties.txt'
--- src/system/zorba_properties.txt	2011-06-14 21:31:37 +0000
+++ src/system/zorba_properties.txt	2011-11-29 22:22:26 +0000
@@ -26,8 +26,10 @@
       ("specialize-num", po::value<bool> ()->default_value (true), "specialize numerics (1=enabled (default), 0=off)")
       ("specialize-cmp", po::value<bool> ()->default_value (true), "specialize generic comparisons (1=enabled (default), 0=off)")
       ("inline-udf", po::value<bool> ()->default_value (true), "inline functions (1=enabled (default), 0=off)")
-      ("loop-hoisting", po::value<bool> ()->default_value (true), "hoist expressions out of loops (1=enabled (default), 0=off)")
-      ("infer-joins", po::value<bool> ()->default_value (true), "infer joins (1=enabled (default), 0=off)")
+      ("loop-hoisting", po::value<bool>()->default_value (true), "hoist expressions out of loops (1=enabled (default), 0=off)")
+      ("infer-joins", po::value<bool>()->default_value (true), "infer joins (1=enabled (default), 0=off)")
+      ("no-copy-optim", po::value<bool>()->default_value(true), "no copy optim (1=enabled (default), 0=off)")
+      ("serialize-only-query", po::value<bool>()->default_value(false), "serialize-only query (1=true, 0=false (default))")
 #ifndef NDEBUG
       ("trace-translator,l", "trace the translator")
       ("trace-codegen,c", "trace the codegenerator")

=== modified file 'src/zorbamisc/ns_consts.h'
--- src/zorbamisc/ns_consts.h	2011-07-12 23:32:16 +0000
+++ src/zorbamisc/ns_consts.h	2011-11-29 22:22:26 +0000
@@ -46,15 +46,11 @@
 
 #define ZORBA_ERR_NS            ZORBA_NS "errors"
 #define ZORBA_WARN_NS           ZORBA_NS "warnings"
-#define ZORBA_OPTIONS_NS        ZORBA_NS "options"
+
 #define ZORBA_FEATURES_NS       ZORBA_NS "features"
 #define ZORBA_ANNOTATIONS_NS    ZORBA_NS "annotations"
 #define ZORBA_COLLATION_NS_BASE ZORBA_NS "collations/"
 
-#define ZORBA_OPTION_WARN_NS    ZORBA_OPTIONS_NS "/warnings"
-#define ZORBA_OPTION_FEATURE_NS ZORBA_OPTIONS_NS "/features"
-#define ZORBA_VERSIONING_NS     ZORBA_OPTIONS_NS "/versioning"
-
 // TODO these probably should not be in "ns_consts"
 #define ZORBA_OPTION_ENABLE_DTD "enable-dtd"
 #define ZORBA_OPTION_MODULE_VERSION "module-version"

=== modified file 'test/apitest.cpp'
--- test/apitest.cpp	2011-06-29 17:36:03 +0000
+++ test/apitest.cpp	2011-11-29 22:22:26 +0000
@@ -110,6 +110,13 @@
     chints.opt_level = ZORBA_OPT_LEVEL_O1;
   }
 
+  chints.for_serialization_only = false;
+
+  if (Properties::instance()->serializeOnlyQuery())
+  {
+    chints.for_serialization_only = true;
+  }
+
   // output file (either a file or the standard out if no file is specified)
   auto_ptr<ostream> outputFile (lProp->resultFile ().empty ()
                                 ? NULL : new ofstream (lProp->resultFile().c_str()));

=== modified file 'test/rbkt/ExpCompilerResults/IterPlan/iterscript.cmake'
--- test/rbkt/ExpCompilerResults/IterPlan/iterscript.cmake	2011-08-10 09:40:29 +0000
+++ test/rbkt/ExpCompilerResults/IterPlan/iterscript.cmake	2011-11-29 22:22:26 +0000
@@ -12,22 +12,26 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+#$TESTFILE is a filepath relative to the test/rbkt/ExpCompilerResults/IterPlan dir.
+
 STRING (LENGTH ${TESTFILE} testfile_length)
 MATH (EXPR testfile_length "${testfile_length} - 5")
-STRING (SUBSTRING ${TESTFILE} 0 ${testfile_length} test_file)
-    
-SET (APITEST_OUT_DIR ${CMAKE_ZORBA_BINARY_DIR}/test/rbkt/CompilerResults/IterPlan/${test_file}.spec)
-GET_FILENAME_COMPONENT (APITEST_OUT_PATH ${APITEST_OUT_DIR} PATH)
-    
-FILE (MAKE_DIRECTORY ${APITEST_OUT_PATH})
+STRING (SUBSTRING ${TESTFILE} 0 ${testfile_length} testname)
+    
+SET (APITEST_OUT_FILEPATH ${CMAKE_ZORBA_BINARY_DIR}/test/rbkt/CompilerResults/IterPlan/${testname}.spec)
+
+GET_FILENAME_COMPONENT (APITEST_OUT_DIRPATH ${APITEST_OUT_FILEPATH} PATH)
+    
+FILE (MAKE_DIRECTORY ${APITEST_OUT_DIRPATH})
     
 EXECUTE_PROCESS (
   COMMAND
     ${APITEST_PATH}
     --iter-plan-test
     --print-iterator-tree
-    --no-tree-ids ${CMAKE_ZORBA_SOURCE_DIR}/test/rbkt/Queries/${test_file}.xq
-  OUTPUT_FILE ${APITEST_OUT_DIR}
+    --no-tree-ids 
+    ${CMAKE_ZORBA_SOURCE_DIR}/test/rbkt/Queries/${testname}.xq
+  OUTPUT_FILE ${APITEST_OUT_FILEPATH}
 ) 
     
 FILE (TO_NATIVE_PATH ${CMAKE_ZORBA_BINARY_DIR}/test/rbkt/itertest.xq itertest_xq_path)
@@ -36,9 +40,9 @@
   COMMAND
     ${ZORBA_EXE}
     -f -q ${itertest_xq_path}
-    -e testfile:=${TESTFILE} 
     -e apitest-path:=${APITEST_PATH}
-    -e query-result:=${APITEST_OUT_DIR} 
+    -e testname:=${testname}
+    -e result-filepath:=${APITEST_OUT_FILEPATH} 
     -z method=text
   OUTPUT_VARIABLE out_var
 )

=== modified file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/idx5.iter'
--- test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/idx5.iter	2011-06-24 19:58:33 +0000
+++ test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/idx5.iter	2011-11-29 22:22:26 +0000
@@ -15,7 +15,7 @@
 Iterator tree for main query:
 <SequentialIterator>
   <CtxVarDeclareIterator varid="2" varname="tests">
-    <ElementIterator>
+    <ElementIterator copyInputNodes="false">
       <SingletonIterator value="xs:QName(,,tests)"/>
     </ElementIterator>
   </CtxVarDeclareIterator>

=== modified file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/misc/hoist4.iter'
--- test/rbkt/ExpCompilerResults/IterPlan/zorba/misc/hoist4.iter	2011-06-24 19:58:33 +0000
+++ test/rbkt/ExpCompilerResults/IterPlan/zorba/misc/hoist4.iter	2011-11-29 22:22:26 +0000
@@ -2,22 +2,22 @@
 <flwor::FLWORIterator>
   <ForVariable name="a">
     <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,foo)" typename="*" nill allowed="0">
-      <ElementIterator>
+      <ElementIterator copyInputNodes="false">
         <SingletonIterator value="xs:QName(,,root)"/>
         <FnConcatIterator>
-          <ElementIterator>
+          <ElementIterator copyInputNodes="false">
             <SingletonIterator value="xs:QName(,,foo)"/>
             <AttributeIterator qname="xs:QName(,,id)">
               <SingletonIterator value="xs:string(-1)"/>
             </AttributeIterator>
             <FnConcatIterator>
-              <ElementIterator>
+              <ElementIterator copyInputNodes="false">
                 <SingletonIterator value="xs:QName(,,boo)"/>
                 <AttributeIterator qname="xs:QName(,,id)">
                   <SingletonIterator value="xs:string(1)"/>
                 </AttributeIterator>
               </ElementIterator>
-              <ElementIterator>
+              <ElementIterator copyInputNodes="false">
                 <SingletonIterator value="xs:QName(,,boo)"/>
                 <AttributeIterator qname="xs:QName(,,id)">
                   <SingletonIterator value="xs:string(2)"/>
@@ -25,19 +25,19 @@
               </ElementIterator>
             </FnConcatIterator>
           </ElementIterator>
-          <ElementIterator>
+          <ElementIterator copyInputNodes="false">
             <SingletonIterator value="xs:QName(,,foo)"/>
             <AttributeIterator qname="xs:QName(,,id)">
               <SingletonIterator value="xs:string(-2)"/>
             </AttributeIterator>
             <FnConcatIterator>
-              <ElementIterator>
+              <ElementIterator copyInputNodes="false">
                 <SingletonIterator value="xs:QName(,,boo)"/>
                 <AttributeIterator qname="xs:QName(,,id)">
                   <SingletonIterator value="xs:string(3)"/>
                 </AttributeIterator>
               </ElementIterator>
-              <ElementIterator>
+              <ElementIterator copyInputNodes="false">
                 <SingletonIterator value="xs:QName(,,boo)"/>
                 <AttributeIterator qname="xs:QName(,,id)">
                   <SingletonIterator value="xs:string(4)"/>

=== modified file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/misc/inline_var1.iter'
--- test/rbkt/ExpCompilerResults/IterPlan/zorba/misc/inline_var1.iter	2011-06-24 19:58:33 +0000
+++ test/rbkt/ExpCompilerResults/IterPlan/zorba/misc/inline_var1.iter	2011-11-29 22:22:26 +0000
@@ -1,8 +1,8 @@
 Iterator tree for main query:
 <UDFunctionCallIterator>
-  <ElementIterator>
+  <ElementIterator copyInputNodes="false">
     <SingletonIterator value="xs:QName(,,a)"/>
-    <ElementIterator>
+    <ElementIterator copyInputNodes="false">
       <SingletonIterator value="xs:QName(,,b)"/>
       <FnConcatIterator>
         <AttributeIterator qname="xs:QName(,,att1)">

=== modified file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/paths/pred_order.iter'
--- test/rbkt/ExpCompilerResults/IterPlan/zorba/paths/pred_order.iter	2011-06-24 19:58:33 +0000
+++ test/rbkt/ExpCompilerResults/IterPlan/zorba/paths/pred_order.iter	2011-11-29 22:22:26 +0000
@@ -30,10 +30,10 @@
 <flwor::FLWORIterator>
   <LetVariable name="x" materialize="true">
     <FnConcatIterator>
-      <ElementIterator>
+      <ElementIterator copyInputNodes="false">
         <SingletonIterator value="xs:QName(,,a)"/>
       </ElementIterator>
-      <ElementIterator>
+      <ElementIterator copyInputNodes="false">
         <SingletonIterator value="xs:QName(,,b)"/>
       </ElementIterator>
     </FnConcatIterator>

=== modified file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/udf/udf1.iter'
--- test/rbkt/ExpCompilerResults/IterPlan/zorba/udf/udf1.iter	2011-06-24 19:58:33 +0000
+++ test/rbkt/ExpCompilerResults/IterPlan/zorba/udf/udf1.iter	2011-11-29 22:22:26 +0000
@@ -6,21 +6,21 @@
   <UDFunctionCallIterator>
     <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,price)" typename="*" nill allowed="0">
       <DescendantAxisIterator test kind="match_name_test" qname="xs:QName(,,book)" typename="*" nill allowed="0">
-        <ElementIterator>
+        <ElementIterator copyInputNodes="false">
           <SingletonIterator value="xs:QName(,,books)"/>
           <FnConcatIterator>
-            <ElementIterator>
+            <ElementIterator copyInputNodes="false">
               <SingletonIterator value="xs:QName(,,book)"/>
-              <ElementIterator>
+              <ElementIterator copyInputNodes="false">
                 <SingletonIterator value="xs:QName(,,price)"/>
                 <TextIterator>
                   <SingletonIterator value="xs:string(10)"/>
                 </TextIterator>
               </ElementIterator>
             </ElementIterator>
-            <ElementIterator>
+            <ElementIterator copyInputNodes="false">
               <SingletonIterator value="xs:QName(,,book)"/>
-              <ElementIterator>
+              <ElementIterator copyInputNodes="false">
                 <SingletonIterator value="xs:QName(,,price)"/>
                 <TextIterator>
                   <SingletonIterator value="xs:string(20)"/>

=== modified file 'test/rbkt/Queries/zorba/modules/libraryModule15.xqlib'
--- test/rbkt/Queries/zorba/modules/libraryModule15.xqlib	2011-06-24 19:58:33 +0000
+++ test/rbkt/Queries/zorba/modules/libraryModule15.xqlib	2011-11-29 22:22:26 +0000
@@ -4,9 +4,14 @@
 
 declare copy-namespaces no-preserve,no-inherit;
 
-declare variable $def:element1 := <element1 xmlns:namespace1="www.namespace1.com"></element1>;
-declare variable $def:element2 := <element2 xmlns:namespace2="www.namespace2.com">{$def:element1}</element2>;
-declare variable $def:element3 := <element3 xmlns:namespace3="www.namespace3.com">{$def:element2}</element3>;
+declare variable $def:element1 := 
+<element1 xmlns:namespace1="www.namespace1.com"></element1>;
+
+declare variable $def:element2 := 
+<element2 xmlns:namespace2="www.namespace2.com">{$def:element1}</element2>;
+
+declare variable $def:element3 := 
+<element3 xmlns:namespace3="www.namespace3.com">{$def:element2}</element3>;
 
 declare function def:init()
 {

=== modified file 'test/rbkt/Queries/zorba/xmark/q10.xq'
--- test/rbkt/Queries/zorba/xmark/q10.xq	2011-06-24 19:58:33 +0000
+++ test/rbkt/Queries/zorba/xmark/q10.xq	2011-11-29 22:22:26 +0000
@@ -1,10 +1,13 @@
 declare variable $input-context external;
-let $auction := doc($input-context) return
+
+let $auction := doc($input-context) 
+return
+
 for $i in distinct-values($auction/site/people/person/profile/interest/@category)
 let $p :=
-for $t in $auction/site/people/person
-where $t/profile/interest/@category = $i
-return
+  for $t in $auction/site/people/person
+  where $t/profile/interest/@category = $i
+  return
 <personne>
 <statistiques>
 <sexe>{$t/profile/gender/text()}</sexe>
@@ -24,5 +27,6 @@
 </coordonnees>
 <cartePaiement>{$t/creditcard/text()}</cartePaiement>
 </personne>
+
 return <categorie>{<id>{$i}</id>, $p}</categorie>
 

=== modified file 'test/rbkt/itertest.xq.in'
--- test/rbkt/itertest.xq.in	2011-08-05 02:21:55 +0000
+++ test/rbkt/itertest.xq.in	2011-11-29 22:22:26 +0000
@@ -18,50 +18,64 @@
 
 import schema namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";;
 
-declare variable $testfile external;  
-declare variable $apitest-path external;
-declare variable $query-result external;
 declare variable $source-dir := "@CMAKE_SOURCE_DIR@";
 declare variable $binary-dir := "@CMAKE_BINARY_DIR@";
 
-(: cut .iter ending :)
-let $cut-path := fn:substring($testfile, 1, fn:string-length($testfile) - 5)
-(: expected result file :)
-let $expected-file := fn:concat($source-dir, '/test/rbkt/ExpCompilerResults/IterPlan/', $cut-path, '.iter')
-let $result-file := fn:concat($binary-dir, '/test/rbkt/CompilerResults/IterPlan/', $cut-path, '.iter')
-(: query file :)
-let $query-file := fn:concat($source-dir, '/test/rbkt/Queries/', $cut-path, '.xq')
-let $apitest-path-normalized := file:path-to-native($apitest-path)
-let $expected-file-normalized := file:path-to-native($expected-file)
-let $result-file-normalized := file:path-to-native($result-file)
-let $query-file-normalized := file:path-to-native($query-file)
-let $query-result-normalized := file:path-to-native($query-result)
-
-return
-  if (file:exists($query-file-normalized)) 
-  then
-    {
-      variable $query-options := (
-        '--iter-plan-test',
-        '--print-iterator-tree',
-        '--no-tree-ids',
-        $query-file-normalized
-      );
-      variable $query-stdout as xs:string := file:read-text($query-result-normalized);
-      variable $expected-text as xs:string := file:read-text($expected-file-normalized);
-
-      {
-        (
-          (: compare generated iterator tree with expected result :)
-          if ($query-stdout eq $expected-text) then
-            "Passed!"
-          else
-            fn:concat(
-              "Failed! Generated iterator tree is not equal to the expected Result!",
-              "Command to generate iterator tree: ", $apitest-path, " ", fn:string-join($query-options," "), "",
-              "Expected Result: ", $expected-file, $expected-text)
-        )
-      }
-    }
-  else
-    fn:concat("Passed! But only because query file ", $query-file, " not found. Test was not executed!")
+declare variable $apitest-path external;
+
+declare variable $testname external; 
+ 
+declare variable $result-filepath external;
+
+variable $expected-filepath := 
+fn:concat($source-dir, '/test/rbkt/ExpCompilerResults/IterPlan/', $testname, '.iter');
+
+variable $query-filepath := 
+fn:concat($source-dir, '/test/rbkt/Queries/', $testname, '.xq');
+
+variable $expected-filepath-normalized := file:path-to-native($expected-filepath);
+
+variable $result-filepath-normalized := file:path-to-native($result-filepath);
+
+variable $query-filepath-normalized := file:path-to-native($query-filepath);
+
+variable $apitest-path-normalized := file:path-to-native($apitest-path);
+
+
+if (file:exists($query-filepath-normalized))
+then
+{
+  variable $query-options := (
+    '--iter-plan-test',
+    '--print-iterator-tree',
+    '--no-tree-ids',
+    $query-filepath-normalized
+  );
+
+  variable $result-text as xs:string := file:read-text($result-filepath-normalized);
+
+  variable $expected-text as xs:string := file:read-text($expected-filepath-normalized);
+
+  {
+    (
+      (: compare generated iterator tree with expected result :)
+      if ($result-text eq $expected-text) then
+        "Passed!"
+      else
+        fn:concat(
+          "Failed! Generated iterator tree is not equal to the expected Result!",
+          "Command to generate iterator tree: ", 
+           $apitest-path,
+           " ",
+           fn:string-join($query-options," "),
+           "",
+           "Expected Result: ",
+           $expected-filepath, 
+           $expected-text)
+    )
+  }
+}
+else
+    fn:concat("Passed! But only because query file ", 
+              $query-filepath,
+              " not found. Test was not executed!")

=== modified file 'test/rbkt/testdriver_common.cpp'
--- test/rbkt/testdriver_common.cpp	2011-10-19 16:19:45 +0000
+++ test/rbkt/testdriver_common.cpp	2011-11-29 22:22:26 +0000
@@ -25,7 +25,7 @@
 #include "testdriverconfig.h"
 #include "testdriver_common.h"
 #include "specification.h"
-
+#include "system/properties.h"
 
 static void set_var(
     DriverContext& driverCtx,
@@ -177,7 +177,8 @@
     lHints.opt_level = ZORBA_OPT_LEVEL_O0;
     //std::cout << "testdriver is using optimization level O0" << std::endl;
   }
-  else if ( lOptLevel != NULL && strcmp(lOptLevel, "O2") == 0) {
+  else if ( lOptLevel != NULL && strcmp(lOptLevel, "O2") == 0) 
+  {
     lHints.opt_level = ZORBA_OPT_LEVEL_O2;
     //std::cout << "testdriver is using optimization level O2" << std::endl;
   }
@@ -186,6 +187,14 @@
     lHints.opt_level = ZORBA_OPT_LEVEL_O1;
     //std::cout << "testdriver is using optimization level O1" << std::endl;
   }
+
+  lHints.for_serialization_only = false;
+
+  if (zorba::Properties::instance()->serializeOnlyQuery())
+  {
+    lHints.for_serialization_only = true;
+  }
+
   return lHints;
 }
 


Follow ups