← Back to team overview

zorba-coders team mailing list archive

[Merge] lp:~zorba-coders/zorba/csv2 into lp:zorba

 

Paul J. Lucas has proposed merging lp:~zorba-coders/zorba/csv2 into lp:zorba.

Commit message:
New CSV module for JSON.

Requested reviews:
  Paul J. Lucas (paul-lucas)
Related bugs:
  Bug #1189840 in Zorba: "Need JSONiq CSV module"
  https://bugs.launchpad.net/zorba/+bug/1189840

For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/csv2/+merge/182786

New CSV module for JSON.
-- 
https://code.launchpad.net/~zorba-coders/zorba/csv2/+merge/182786
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'ChangeLog'
--- ChangeLog	2013-08-21 10:25:42 +0000
+++ ChangeLog	2013-08-29 00:04:39 +0000
@@ -44,6 +44,7 @@
   * Fixed bug #1189636 (transcoding hexBinary streambuf)
   * Fixed bug in hoisting through try-catch expr
   * Fixed bug #1162631 (format-integer 'w' format of negative numbers)
+  * Fixed bug #1189840 (Need JSONiq CSV module)
   * Fixed bug #942171 (file module to allow for arbitrary encodings)
   * Fixed bug #1192285 (Have JSON token know number subtype)
   * Fixed bug #1210628 (file:last-modified returns wrong month)

=== modified file 'include/zorba/pregenerated/diagnostic_list.h'
--- include/zorba/pregenerated/diagnostic_list.h	2013-08-01 09:41:39 +0000
+++ include/zorba/pregenerated/diagnostic_list.h	2013-08-29 00:04:39 +0000
@@ -838,6 +838,12 @@
 
 extern ZORBA_DLL_PUBLIC ZorbaErrorCode XSST0010;
 
+extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZCSV0001_INVALID_OPTION;
+
+extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZCSV0002_MISSING_VALUE;
+
+extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZCSV0003_EXTRA_VALUE;
+
 extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZDTP0001_INVALID_SPECIFICATION;
 
 extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZDTP0002_INSUFFICIENT_BUFFER;

=== modified file 'modules/json/CMakeLists.txt'
--- modules/json/CMakeLists.txt	2013-07-10 09:41:45 +0000
+++ modules/json/CMakeLists.txt	2013-08-29 00:04:39 +0000
@@ -14,3 +14,8 @@
 
 DECLARE_ZORBA_MODULE(FILE json-xml.xq VERSION 1.0
   URI "http://zorba.io/modules/json-xml";)
+
+DECLARE_ZORBA_MODULE(FILE json-csv.jq VERSION 1.0
+  URI "http://zorba.io/modules/json-csv";)
+
+# vim:set et sw=2 ts=2:

=== added file 'modules/json/json-csv.jq'
--- modules/json/json-csv.jq	1970-01-01 00:00:00 +0000
+++ modules/json/json-csv.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,361 @@
+jsoniq version "1.0";
+
+(:
+ : Copyright 2006-2011 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.
+ :)
+
+(:===========================================================================:)
+
+(:~
+ : This module provides an API for parsing and serializing CSV (comma-separated
+ : values) files.
+ : See RFC 4180,
+ : "Common Format and MIME Type for Comma-Separated Values (CSV) Files."
+ : @project Zorba/CSV
+ :)
+
+module namespace csv = "http://zorba.io/modules/json-csv";;
+
+declare namespace err = "http://www.w3.org/2005/xqt-errors";;
+declare namespace zerr = "http://zorba.io/errors";;
+
+declare namespace ver = "http://zorba.io/options/versioning";;
+declare option ver:module-version "1.0";
+
+(:===========================================================================:)
+
+(:~
+ : Parses a CSV (comma-separated values) string using the given options.
+ : A newline (U+000A), optionally preceeded by a carriage-return (U+000D),
+ : terminates lines, aka, "records."
+ : <p/>
+ : Quoted values are always considered strings;
+ : unquoted values are attempted to be cast to other types, e.g., integer
+ : (unless the <code>cast-unquoted-values</code> option is <code>false</code>).
+ : Casting is attempted in the following order:
+ : integer, decimal, double, and boolean.
+ : If casting fails, the value is considered a string.
+ : Header field names are always considered strings even if unquoted.
+ : <p/>
+ : In addition to the "normal" values of
+ : <code>true</code> and <code>false</code> for boolean,
+ : <code>T</code> and <code>Y</code> are also considered "true"
+ : and <code>F</code> and <code>N</code> are also considered "false."
+ :
+ : @param $csv The CSV string to parse.
+ : @param $options The options to use:
+ :  <dl>
+ :    <dt><code>cast-unquoted-values</code></dt>
+ :      <dd>
+ :        Whether to attempt to cast unquoted values to
+ :        integer, decimal, double, or boolean;
+ :        default: <code>true</code>.
+ :      </dd>
+ :    <dt><code>extra-name</code></dt>
+ :      <dd>
+ :        The field name for extra values, if any;
+ :        default: none (error <code>zerr:ZCSV0003</code> is raised).
+ :        If this option is given and a line contains one or more extra values
+ :        (that is, values that have no corresponding field names),
+ :        then the extra values are assigned as the values
+ :        for fields having <code>extra-name</code> as their names.
+ :        <p/>
+ :        If <code>extra-name</code> contains a <code>#</code> (U+0023),
+ :        then the <code>#</code> is substituted with the field number
+ :        (where field numbers start at 1).
+ :        If <code>extra-name</code> does not contains a <code>#</code>,
+ :        then the field number is appended.
+ :      </dd>
+ :    <dt><code>field-names</code></dt>
+ :      <dd>
+ :        A JSON array of strings denoting field names;
+ :        default: none.
+ :        If this option is given, then the first CSV line is assumed not to be
+ :        a header line; if omitted, then the first CSV line is assumed to be a
+ :        header line and the field names are taken from this line.
+ :      </dd>
+ :    <dt><code>missing-value</code></dt>
+ :      <dd>
+ :        What should happen when a missing value is detected;
+ :        default: <code>"null"</code>.
+ :        A "missing" value is one of:
+ :        <ul>
+ :          <li>Two consecutive <code>separator</code> characters.</li>
+ :          <li>A <code>separator</code> character as either the first
+ :              or last character on a line.</li>
+ :          <li>Fewer values than the number of field names.</li>
+ :        </ul>
+ :        When a missing value is detected,
+ :        the value of this option determines what happens:
+ :        <dl>
+ :          <dt><code>"error"</code></dt>
+ :            <dd>Error <code>zerr:ZCSV0002</code> is raised.</dd>
+ :          <dt><code>"omit"</code></dt>
+ :            <dd>Both the value and its key are omitted from the result
+ :                object.</dd>
+ :          <dt><code>"null"</code></dt>
+ :            <dd>The value is set to <code>null</code>.</dd>
+ :        </dl>
+ :      </dd>
+ :    <dt><code>quote-char</code></dt>
+ :      <dd>
+ :        The single ASCII character that may be used to quote values;
+ :        default: <code>"</code> (U+0022).
+ :      </dd>
+ :    <dt><code>quote-escape</code></dt>
+ :      <dd>
+ :        The single ASCII character used to escape <code>quote-char</code>;
+ :        default: same as <code>quote-char</code>.
+ :        If <code>quote-escape</code> equals <code>quote-char</code>,
+ :        it means that <code>quote-char</code> must be doubled to escape it.
+ :        If <code>quote-escape</code> does not equal <code>quote-char</code>,
+ :        it means that <code>quote-escape</code> is used to escape
+ :        <code>quote-char</code>.
+ :        For example, a <code>quote-char</code> of <code>"</code> (U+0022)
+ :        and a <code>quote-escape</code> of <code>\</code> (U+005C) means that
+ :        quotes will be escaped by <code>\"</code>.
+ :      </dd>
+ :    <dt><code>separator</code></dt>
+ :      <dd>
+ :        The single ASCII character used to separate values;
+ :        default: <code>,</code> (U+002C).
+ :      </dd>
+ :  </dl>
+ : @return a sequence of zero or more JSON objects where each key is a field
+ : name and each value is a parsed value.
+ : @error zerr:ZCSV0001 if the <code>quote-char</code>,
+ : <code>quote-escape</code>, or <code>separator</code> option is given
+ : and it's not a single ASCII character.
+ : @error zerr:ZCSV0002 if a missing value is detected and the
+ : <code>missing-value</code> option is "<code>error</code>".
+ : @error zerr:ZCSV0003 if an extra value is detected and the
+ : <code>extra-name</code> option is not set.
+ :)
+declare function csv:parse( $csv as string, $options as object() )
+  as object()* external;
+
+(:~
+ : Parses a CSV (comma-separated values) string using the default options.
+ : A newline (U+000A), optionally preceeded by a carriage-return (U+000D),
+ : terminates lines, aka, "records."
+ : <p/>
+ : Quoted values are always considered strings;
+ : unquoted values are attempted to be cast to other types, e.g., integer
+ : (unless the <code>cast-unquoted-values</code> option is <code>false</code>).
+ : Casting is attempted in the following order:
+ : integer, decimal, double, and boolean.
+ : If casting fails, the value is considered a string.
+ : Header field names are always considered strings even if unquoted.
+ : <p/>
+ : In addition to the "normal" values of
+ : <code>true</code> and <code>false</code> for boolean,
+ : <code>T</code> and <code>Y</code> are also considered "true"
+ : and <code>F</code> and <code>N</code> are also considered "false."
+ : <p/>
+ : The default options are:
+ :  <dl>
+ :    <dt><code>cast-unquoted-values</code></dt>
+ :      <dd>
+ :        Whether to attempt to cast unquoted values to
+ :        integer, decimal, double, or boolean;
+ :        default: <code>true</code>.
+ :      </dd>
+ :    <dt><code>extra-name</code></dt>
+ :      <dd>
+ :        The field name for extra values, if any;
+ :        default: none (error <code>zerr:ZCSV0003</code> is raised).
+ :      </dd>
+ :    <dt><code>field-names</code></dt>
+ :      <dd>
+ :        A JSON array of strings denoting field names;
+ :        default: none.
+ :        The first CSV line is assumed to be a header line
+ :        and the field names are taken from this line.
+ :      </dd>
+ :    <dt><code>missing-value</code></dt>
+ :      <dd>
+ :        What should happen when a missing value is detected;
+ :        default: <code>"null"</code>.
+ :        A "missing" value is one of:
+ :        <ul>
+ :          <li>Two consecutive <code>quote-char</code> characters.</li>
+ :          <li>A <code>quote-char</code> character as either the first
+ :              or last character on a line.</li>
+ :          <li>Fewer values than the number of field names.</li>
+ :        </ul>
+ :        When a missing value is detected,
+ :        the value is set to <code>null</code>.
+ :      </dd>
+ :    <dt><code>quote-char</code></dt>
+ :      <dd>
+ :        The single ASCII character that may be used to quote values;
+ :        default: <code>"</code> (U+0022).
+ :      </dd>
+ :    <dt><code>quote-escape</code></dt>
+ :      <dd>
+ :        The single ASCII character used to escape <code>quote-char</code>;
+ :        default: same as <code>quote-char</code>.
+ :        This means that an escaped quote is doubled as <code>""</code>.
+ :      </dd>
+ :    <dt><code>separator</code></dt>
+ :      <dd>
+ :        The single ASCII character used to separate values;
+ :        default: <code>,</code> (U+002C).
+ :      </dd>
+ :  </dl>
+ :
+ : @param $csv The CSV string to parse.
+ : @return a sequence of zero or more JSON objects where each key is a field
+ : name and each value is a parsed value.
+ : @error zerr:ZCSV0003 if an extra value is detected.
+ :)
+declare function csv:parse( $csv as string )
+  as object()*
+{
+  csv:parse( $csv, {} )
+};
+
+(:~
+ : Serializes a sequence of JSON objects as CSV (comma-separated values) using
+ : the given options.
+ :
+ : @param $obj The sequence of JSON objects to serialize.
+ : @param $options The options to use:
+ :  <dl>
+ :    <dt><code>field-names</code></dt>
+ :      <dd>
+ :        A JSON array of strings denoting field names;
+ :        default: none.
+ :        If this option is not set,
+ :        the field names are taken from the first JSON object
+ :        and the order of the fields is implementation dependent.
+ :        If this option is set,
+ :        the fields are serielized in the order they are in the array.
+ :        In either case,
+ :        every JSON object must have the same keys as the first object.
+ :      </dd>
+ :    <dt><code>serialize-boolean-as</code></dt>
+ :      <dd>
+ :        What strings to serialize <code>true</code> and <code>false</code> as;
+ :        default: <code>true</code> and <code>false</code>.
+ :        This must be a sub-object with the two keys
+ :        <code>"true"</code> and <code>"false"</code>, e.g.:
+ :        <code>{ "true" : "Y", "false" : "N" }</code>.
+ :      </dd>
+ :    <dt><code>serialize-header</code></dt>
+ :      <dd>
+ :        Whether a header line is included;
+ :        default: <code>true</code>.
+ :        If <code>true</code>,
+ :        the first string result is the header line
+ :        comprised of all the objects' keys' names;
+ :        if <code>false</code>,
+ :        the heder line is not returned.
+ :      </dd>
+ :    <dt><code>serialize-null-as</code></dt>
+ :      <dd>
+ :        What string to serialize JSON <code>null</code> values as;
+ :        default: <code>null</code>.
+ :      </dd>
+ :    <dt><code>quote-char</code></dt>
+ :      <dd>
+ :        The single ASCII character that may be used to quote values;
+ :        default: <code>"</code> (U+0022).
+ :      </dd>
+ :    <dt><code>quote-escape</code></dt>
+ :      <dd>
+ :        The single ASCII character used to escape <code>quote-char</code>;
+ :        default: same as <code>quote-char</code>.
+ :        If <code>quote-escape</code> equals <code>quote-char</code>,
+ :        it means that <code>quote-char</code> must be doubled to escape it.
+ :        If <code>quote-escape</code> does not equal <code>quote-char</code>,
+ :        it means that <code>quote-escape</code> is used to escape
+ :        <code>quote-char</code>.
+ :        For example, a <code>quote-char</code> of <code>"</code> (U+0022)
+ :        and a <code>quote-escape</code> of <code>\</code> (U+005C) means that
+ :        quotes will be escaped by <code>\"</code>.
+ :      </dd>
+ :    <dt><code>separator</code></dt>
+ :      <dd>
+ :        The single ASCII character used to separate values;
+ :        default: <code>,</code> (U+002C).
+ :      </dd>
+ :  </dl>
+ : @return a sequence of strings where each string corresponds to a JSON
+ : object, aka, "record."
+ :)
+declare function csv:serialize( $obj as object()*, $options as object() )
+  as string* external;
+
+(:~
+ : Serializes a sequence of JSON objects as CSV (comma-separated values) using
+ : the default options.
+ : The default options are:
+ :  <dl>
+ :    <dt><code>field-names</code></dt>
+ :      <dd>
+ :        A JSON array of strings denoting field names;
+ :        default: none.
+ :        The field names are taken from the first JSON object
+ :        and the order of the fields is implementation dependent.
+ :      </dd>
+ :    <dt><code>serialize-boolean-as</code></dt>
+ :      <dd>
+ :        What strings to serialize <code>true</code> and <code>false</code> as;
+ :        default: <code>true</code> and <code>false</code>.
+ :      </dd>
+ :    <dt><code>serialize-header</code></dt>
+ :      <dd>
+ :        Whether a header line is included;
+ :        default: <code>true</code>.
+ :        The first string result is the header line
+ :        comprised of all the objects' keys' names.
+ :      </dd>
+ :    <dt><code>serialize-null-as</code></dt>
+ :      <dd>
+ :        What string to serialize JSON <code>null</code> values as;
+ :        default: <code>null</code>.
+ :      </dd>
+ :    <dt><code>quote-char</code></dt>
+ :      <dd>
+ :        The single ASCII character that may be used to quote values;
+ :        default: <code>"</code> (U+0022).
+ :      </dd>
+ :    <dt><code>quote-escape</code></dt>
+ :      <dd>
+ :        The single ASCII character used to escape <code>quote-char</code>;
+ :        default: same as <code>quote-char</code>.
+ :        This means that <code>quote-char</code> is doubled to escape it.
+ :      </dd>
+ :    <dt><code>separator</code></dt>
+ :      <dd>
+ :        The single ASCII character used to separate values;
+ :        default: <code>,</code> (U+002C).
+ :      </dd>
+ :  </dl>
+ :
+ : @param $obj The sequence of JSON objects to serialize.
+ : @return a sequence of strings where each string corresponds to a JSON
+ : object, aka, "record."
+ :)
+declare function csv:serialize( $obj as object()* )
+  as string*
+{
+  csv:serialize( $obj, {} )
+};
+
+(:===========================================================================:)
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== modified file 'modules/pregenerated/zorba-errors.xq'
--- modules/pregenerated/zorba-errors.xq	2013-08-07 05:28:39 +0000
+++ modules/pregenerated/zorba-errors.xq	2013-08-29 00:04:39 +0000
@@ -889,6 +889,18 @@
 
 (:~
 :)
+declare variable $zerr:ZCSV0001 as xs:QName := fn:QName($zerr:NS, "zerr:ZCSV0001");
+
+(:~
+:)
+declare variable $zerr:ZCSV0002 as xs:QName := fn:QName($zerr:NS, "zerr:ZCSV0002");
+
+(:~
+:)
+declare variable $zerr:ZCSV0003 as xs:QName := fn:QName($zerr:NS, "zerr:ZCSV0003");
+
+(:~
+:)
 declare variable $zerr:ZDTP0001 as xs:QName := fn:QName($zerr:NS, "zerr:ZDTP0001");
 
 (:~

=== modified file 'src/context/static_context.cpp'
--- src/context/static_context.cpp	2013-08-09 09:08:04 +0000
+++ src/context/static_context.cpp	2013-08-29 00:04:39 +0000
@@ -359,7 +359,11 @@
 "http://zorba.io/modules/base64";;
 
 const char*
-static_context::ZORBA_JSON_FN_NS =
+static_context::ZORBA_JSON_CSV_FN_NS =
+"http://zorba.io/modules/json-csv";;
+
+const char*
+static_context::ZORBA_JSON_XML_FN_NS =
 "http://zorba.io/modules/json-xml";;
 
 const char*
@@ -555,7 +559,8 @@
 
             ns == ZORBA_URI_FN_NS ||
 
-            ns == ZORBA_JSON_FN_NS ||
+            ns == ZORBA_JSON_CSV_FN_NS ||
+            ns == ZORBA_JSON_XML_FN_NS ||
             ns == ZORBA_FETCH_FN_NS ||
             ns == ZORBA_NODE_FN_NS ||
             ns == ZORBA_ITEM_FN_NS ||
@@ -616,7 +621,8 @@
   {
     return (ns == ZORBA_MATH_FN_NS ||
             ns == ZORBA_INTROSP_SCTX_FN_NS ||
-            ns == ZORBA_JSON_FN_NS ||
+            ns == ZORBA_JSON_CSV_FN_NS ||
+            ns == ZORBA_JSON_XML_FN_NS ||
             ns == ZORBA_XQDOC_FN_NS ||
             ns == ZORBA_URI_FN_NS ||
             ns == ZORBA_RANDOM_FN_NS ||

=== modified file 'src/context/static_context.h'
--- src/context/static_context.h	2013-07-26 20:43:25 +0000
+++ src/context/static_context.h	2013-08-29 00:04:39 +0000
@@ -520,7 +520,8 @@
   static const char* ZORBA_MATH_FN_NS;
   static const char* ZORBA_BASE64_FN_NS;
 
-  static const char* ZORBA_JSON_FN_NS;
+  static const char* ZORBA_JSON_CSV_FN_NS;
+  static const char* ZORBA_JSON_XML_FN_NS;
 
   static const char* ZORBA_REFERENCE_FN_NS;
   static const char* ZORBA_NODEPOS_FN_NS;

=== modified file 'src/diagnostics/diagnostic_en.xml'
--- src/diagnostics/diagnostic_en.xml	2013-08-16 21:24:42 +0000
+++ src/diagnostics/diagnostic_en.xml	2013-08-29 00:04:39 +0000
@@ -3170,6 +3170,38 @@
       <value>"continue loop" statement not inside while statement</value>
     </diagnostic>
 
+   <!--////////// CSV Module Errors ////////////////////////////////////////-->
+
+    <diagnostic code="ZCSV0001" name="INVALID_OPTION">
+      <value>${"1": }invalid value for "$2" option${; 3}</value>
+      <entry key="MustBeASCIIChar">
+        <value>must be single ASCII character</value>
+      </entry>
+      <entry key="MustBeTrueFalse">
+        <value>must be sub-object with "true" and "false" keys</value>
+      </entry>
+      <entry key="MustBeBoolean">
+        <value>must be boolean</value>
+      </entry>
+      <entry key="MustBeString">
+        <value>must be string</value>
+      </entry>
+    </diagnostic>
+
+    <diagnostic code="ZCSV0002" name="MISSING_VALUE">
+      <value>$1</value>
+      <entry key="EmptyHeaderValue">
+        <value>empty header value detected on line 1</value>
+      </entry>
+      <entry key="MissingValue">
+        <value>"$2": missing value detected for this field on line $3</value>
+      </entry>
+    </diagnostic>
+
+    <diagnostic code="ZCSV0003" name="EXTRA_VALUE">
+      <value>"$1": extra value detected on line $2</value>
+    </diagnostic>
+
    <!--////////// dateTime Parse Errors ////////////////////////////////////-->
 
     <diagnostic code="ZDTP0001" name="INVALID_SPECIFICATION">

=== modified file 'src/diagnostics/pregenerated/diagnostic_list.cpp'
--- src/diagnostics/pregenerated/diagnostic_list.cpp	2013-08-01 09:41:39 +0000
+++ src/diagnostics/pregenerated/diagnostic_list.cpp	2013-08-29 00:04:39 +0000
@@ -1235,6 +1235,15 @@
 ZorbaErrorCode XSST0010( "XSST0010" );
 
 
+ZorbaErrorCode ZCSV0001_INVALID_OPTION( "ZCSV0001" );
+
+
+ZorbaErrorCode ZCSV0002_MISSING_VALUE( "ZCSV0002" );
+
+
+ZorbaErrorCode ZCSV0003_EXTRA_VALUE( "ZCSV0003" );
+
+
 ZorbaErrorCode ZDTP0001_INVALID_SPECIFICATION( "ZDTP0001" );
 
 

=== modified file 'src/diagnostics/pregenerated/dict_en.cpp'
--- src/diagnostics/pregenerated/dict_en.cpp	2013-08-16 21:24:42 +0000
+++ src/diagnostics/pregenerated/dict_en.cpp	2013-08-29 00:04:39 +0000
@@ -316,6 +316,9 @@
   { "ZCSE0015", "cannot load execution plan: incompatible between 32/64 bits or little/big-endian" },
   { "ZCSE0016", "cannot load execution plan saved from release mode Zorba into debug mode Zorba" },
   { "ZCSE0017", "cannot load execution plan saved from debug mode Zorba into release mode Zorba" },
+  { "ZCSV0001", "${\"1\": }invalid value for \"$2\" option${; 3}" },
+  { "ZCSV0002", "$1" },
+  { "ZCSV0003", "\"$1\": extra value detected on line $2" },
   { "ZDDY0001", "\"$1\": collection not declared" },
   { "ZDDY0002", "\"$1\": collection already exists" },
   { "ZDDY0003", "\"$1\": collection does not exist" },
@@ -967,6 +970,12 @@
   { "~XUST0001_UDF_2", "\"$2\": function declared simple but body is updating" },
   { "~XUST0002_Transform", "transform expression witn non-updating or vacuous modify clause" },
   { "~XUST0002_UDF_2", "\"$2\": function declared updating but body is not updating or vacuous" },
+  { "~ZCSV0001_MustBeASCIIChar", "must be single ASCII character" },
+  { "~ZCSV0001_MustBeBoolean", "must be boolean" },
+  { "~ZCSV0001_MustBeString", "must be string" },
+  { "~ZCSV0001_MustBeTrueFalse", "must be sub-object with \"true\" and \"false\" keys" },
+  { "~ZCSV0002_EmptyHeaderValue", "empty header value detected on line 1" },
+  { "~ZCSV0002_MissingValue", "\"$2\": missing value detected for this field on line $3" },
   { "~ZDST0027_MULTI_VALUED_KEY_TYPE_DECL", "value index can not have a key type declaration with * or + quantifier" },
   { "~ZDST0027_NON_ATOMIC_KEY_TYPE", "index has non-atomic key type declaration" },
   { "~ZDST0027_NON_ORDERED_KEY_TYPE", "range index can not have type $3 in key type declaration" },

=== modified file 'src/diagnostics/pregenerated/dict_zed_keys.h'
--- src/diagnostics/pregenerated/dict_zed_keys.h	2013-08-14 02:10:00 +0000
+++ src/diagnostics/pregenerated/dict_zed_keys.h	2013-08-29 00:04:39 +0000
@@ -168,6 +168,12 @@
 #define ZED_ZDST0060_unknown_localname "~ZDST0060_unknown_localname"
 #define ZED_ZSTR0060_ForCollection_3 "~ZSTR0060_ForCollection_3"
 #define ZED_ZSTR0060_ForSequence "~ZSTR0060_ForSequence"
+#define ZED_ZCSV0001_MustBeASCIIChar "~ZCSV0001_MustBeASCIIChar"
+#define ZED_ZCSV0001_MustBeTrueFalse "~ZCSV0001_MustBeTrueFalse"
+#define ZED_ZCSV0001_MustBeBoolean "~ZCSV0001_MustBeBoolean"
+#define ZED_ZCSV0001_MustBeString "~ZCSV0001_MustBeString"
+#define ZED_ZCSV0002_EmptyHeaderValue "~ZCSV0002_EmptyHeaderValue"
+#define ZED_ZCSV0002_MissingValue "~ZCSV0002_MissingValue"
 #define ZED_ZJ2X0001_ArrayRequired "~ZJ2X0001_ArrayRequired"
 #define ZED_ZJ2X0001_EmptyArray "~ZJ2X0001_EmptyArray"
 #define ZED_ZJ2X0001_Bad1stElement "~ZJ2X0001_Bad1stElement"

=== modified file 'src/functions/library.cpp'
--- src/functions/library.cpp	2013-07-02 21:32:23 +0000
+++ src/functions/library.cpp	2013-08-29 00:04:39 +0000
@@ -34,6 +34,7 @@
 #include "functions/func_booleans_impl.h"
 #include "functions/func_collections.h"
 #include "functions/func_context.h"
+#include "functions/func_csv.h"
 #include "functions/func_datetime.h"
 #include "functions/func_documents.h"
 #include "functions/func_durations_dates_times.h"
@@ -119,6 +120,7 @@
   populate_context_booleans_impl(sctx);
   populate_context_collections(sctx);
   populate_context_context(sctx);
+  populate_context_csv(sctx);
   populate_context_datetime(sctx);
   populate_context_durations_dates_times(sctx);
   populate_context_durations_dates_times_impl(sctx);

=== added file 'src/functions/pregenerated/func_csv.cpp'
--- src/functions/pregenerated/func_csv.cpp	1970-01-01 00:00:00 +0000
+++ src/functions/pregenerated/func_csv.cpp	2013-08-29 00:04:39 +0000
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2006-2012 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.
+ */
+ 
+// ******************************************
+// *                                        *
+// * THIS IS A GENERATED FILE. DO NOT EDIT! *
+// * SEE .xml FILE WITH SAME NAME           *
+// *                                        *
+// ******************************************
+
+
+#include "stdafx.h"
+#include "runtime/csv/csv.h"
+#include "functions/func_csv.h"
+
+
+namespace zorba{
+
+
+
+PlanIter_t fn_zorba_csv_parse::codegen(
+  CompilerCB*,
+  static_context* sctx,
+  const QueryLoc& loc,
+  std::vector<PlanIter_t>& argv,
+  expr& ann) const
+{
+  return new CsvParseIterator(sctx, loc, argv);
+}
+
+PlanIter_t fn_zorba_csv_serialize::codegen(
+  CompilerCB*,
+  static_context* sctx,
+  const QueryLoc& loc,
+  std::vector<PlanIter_t>& argv,
+  expr& ann) const
+{
+  return new CsvSerializeIterator(sctx, loc, argv);
+}
+
+void populate_context_csv(static_context* sctx)
+{
+
+
+      {
+    DECL_WITH_KIND(sctx, fn_zorba_csv_parse,
+        (createQName("http://zorba.io/modules/json-csv","","parse";), 
+        GENV_TYPESYSTEM.STRING_TYPE_ONE, 
+        GENV_TYPESYSTEM.JSON_OBJECT_TYPE_ONE, 
+        GENV_TYPESYSTEM.JSON_OBJECT_TYPE_STAR),
+        FunctionConsts::FN_ZORBA_CSV_PARSE_2);
+
+  }
+
+
+
+
+      {
+    DECL_WITH_KIND(sctx, fn_zorba_csv_serialize,
+        (createQName("http://zorba.io/modules/json-csv","","serialize";), 
+        GENV_TYPESYSTEM.JSON_OBJECT_TYPE_STAR, 
+        GENV_TYPESYSTEM.JSON_OBJECT_TYPE_ONE, 
+        GENV_TYPESYSTEM.STRING_TYPE_STAR),
+        FunctionConsts::FN_ZORBA_CSV_SERIALIZE_2);
+
+  }
+
+}
+
+
+}
+
+
+

=== added file 'src/functions/pregenerated/func_csv.h'
--- src/functions/pregenerated/func_csv.h	1970-01-01 00:00:00 +0000
+++ src/functions/pregenerated/func_csv.h	2013-08-29 00:04:39 +0000
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2006-2012 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.
+ */
+ 
+// ******************************************
+// *                                        *
+// * THIS IS A GENERATED FILE. DO NOT EDIT! *
+// * SEE .xml FILE WITH SAME NAME           *
+// *                                        *
+// ******************************************
+
+
+#ifndef ZORBA_FUNCTIONS_CSV_H
+#define ZORBA_FUNCTIONS_CSV_H
+
+
+#include "common/shared_types.h"
+#include "functions/function_impl.h"
+
+
+namespace zorba {
+
+
+void populate_context_csv(static_context* sctx);
+
+
+
+
+//fn-zorba-csv:parse
+class fn_zorba_csv_parse : public function
+{
+public:
+  fn_zorba_csv_parse(const signature& sig, FunctionConsts::FunctionKind kind)
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  CODEGEN_DECL();
+};
+
+
+//fn-zorba-csv:serialize
+class fn_zorba_csv_serialize : public function
+{
+public:
+  fn_zorba_csv_serialize(const signature& sig, FunctionConsts::FunctionKind kind)
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  CODEGEN_DECL();
+};
+
+
+} //namespace zorba
+
+
+#endif
+/*
+ * Local variables:
+ * mode: c++
+ * End:
+ */ 

=== modified file 'src/functions/pregenerated/function_enum.h'
--- src/functions/pregenerated/function_enum.h	2013-08-16 13:00:06 +0000
+++ src/functions/pregenerated/function_enum.h	2013-08-29 00:04:39 +0000
@@ -143,6 +143,8 @@
   FN_POSITION_0,
   FN_LAST_0,
   FN_STATIC_BASE_URI_0,
+  FN_ZORBA_CSV_PARSE_2,
+  FN_ZORBA_CSV_SERIALIZE_2,
   FN_ZORBA_DATETIME_CURRENT_DATE_0,
   FN_ZORBA_DATETIME_CURRENT_DATETIME_0,
   FN_ZORBA_DATETIME_CURRENT_TIME_0,

=== modified file 'src/runtime/CMakeLists.txt'
--- src/runtime/CMakeLists.txt	2013-06-15 02:57:08 +0000
+++ src/runtime/CMakeLists.txt	2013-08-29 00:04:39 +0000
@@ -152,6 +152,8 @@
   json/json_loader.cpp
 )
 
+ADD_SRC_SUBFOLDER(RUNTIME_SRCS csv CSV_SRCS)
+
 IF(NOT ZORBA_NO_FULL_TEXT)
   ADD_SRC_SUBFOLDER(RUNTIME_SRCS full_text FULLTEXT_SRCS)
 ENDIF(NOT ZORBA_NO_FULL_TEXT)

=== added directory 'src/runtime/csv'
=== added file 'src/runtime/csv/CMakeLists.txt'
--- src/runtime/csv/CMakeLists.txt	1970-01-01 00:00:00 +0000
+++ src/runtime/csv/CMakeLists.txt	2013-08-29 00:04:39 +0000
@@ -0,0 +1,19 @@
+# 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.
+
+SET(CSV_SRCS
+    csv_impl.cpp
+    )
+
+# vim:set et sw=2 ts=2:

=== added file 'src/runtime/csv/csv_impl.cpp'
--- src/runtime/csv/csv_impl.cpp	1970-01-01 00:00:00 +0000
+++ src/runtime/csv/csv_impl.cpp	2013-08-29 00:04:39 +0000
@@ -0,0 +1,615 @@
+/*
+ * Copyright 2006-2008 The FLWOR Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "stdafx.h"
+
+#include <algorithm>
+#include <iterator>
+#include <set>
+#include <sstream>
+
+#include <zorba/config.h>
+#include <zorba/internal/cxx_util.h>
+#include <zorba/diagnostic_list.h>
+#include <zorba/store_consts.h>
+
+#include "runtime/csv/csv.h"
+#include "store/api/item_factory.h"
+#include "system/globalenv.h"
+#include "types/casting.h"
+#include "types/root_typemanager.h"
+#include "types/typeops.h"
+#include "util/ascii_util.h"
+#include "util/json_parser.h"
+#include "util/stl_util.h"
+#include "zorbatypes/decimal.h"
+#include "zorbatypes/float.h"
+#include "zorbatypes/integer.h"
+
+#include "csv_util.h"
+
+using namespace std;
+
+namespace zorba {
+
+///////////////////////////////////////////////////////////////////////////////
+
+#define IS_ATOMIC_TYPE(ITEM,TYPE) \
+  ( (ITEM)->isAtomic() && TypeOps::is_subtype( (ITEM)->getTypeCode(), store::TYPE ) )
+
+#define IS_JSON_NULL(ITEM) \
+  ( (ITEM)->isAtomic() && (ITEM)->getTypeCode() == store::JS_NULL )
+
+static bool get_opt( store::Item_t const &object, char const *opt_name,
+                     store::Item_t *result ) {
+  store::Item_t key_item;
+  zstring s( opt_name );
+  GENV_ITEMFACTORY->createString( key_item, s );
+  *result = object->getObjectValue( key_item );
+  return !result->isNull();
+}
+
+static bool get_bool_opt( store::Item_t const &object,
+                          char const *opt_name, bool *result,
+                          QueryLoc const &loc ) {
+  store::Item_t opt_item;
+  if ( get_opt( object, opt_name, &opt_item ) ) {
+    if ( !IS_ATOMIC_TYPE( opt_item, XS_BOOLEAN ) )
+      throw XQUERY_EXCEPTION(
+        zerr::ZCSV0001_INVALID_OPTION,
+        ERROR_PARAMS(
+          opt_item->getStringValue(), opt_name, ZED( ZCSV0001_MustBeBoolean )
+        ),
+        ERROR_LOC( loc )
+      );
+    *result = opt_item->getBooleanValue();
+    return true;
+  }
+  return false;
+}
+
+static bool get_char_opt( store::Item_t const &object,
+                          char const *opt_name, char *result,
+                          QueryLoc const &loc ) {
+  store::Item_t opt_item;
+  if ( get_opt( object, opt_name, &opt_item ) ) {
+    zstring const value( opt_item->getStringValue() );
+    if ( !IS_ATOMIC_TYPE( opt_item, XS_STRING ) ||
+         value.size() != 1 || !ascii::is_ascii( value[0] ) ) {
+      throw XQUERY_EXCEPTION(
+        zerr::ZCSV0001_INVALID_OPTION,
+        ERROR_PARAMS( value, opt_name, ZED( ZCSV0001_MustBeASCIIChar ) ),
+        ERROR_LOC( loc )
+      );
+    }
+    *result = value[0];
+    return true;
+  }
+  return false;
+}
+
+static bool get_string_opt( store::Item_t const &object,
+                            char const *opt_name, zstring *result,
+                            QueryLoc const &loc ) {
+  store::Item_t opt_item;
+  if ( get_opt( object, opt_name, &opt_item ) ) {
+    if ( !IS_ATOMIC_TYPE( opt_item, XS_STRING ) )
+      throw XQUERY_EXCEPTION(
+        zerr::ZCSV0001_INVALID_OPTION,
+        ERROR_PARAMS(
+          opt_item->getStringValue(), opt_name, ZED( ZCSV0001_MustBeString )
+        ),
+        ERROR_LOC( loc )
+      );
+    opt_item->getStringValue2( *result );
+    return true;
+  }
+  return false;
+}
+
+static json::type parse_json( zstring const &s, json::token *ptoken ) {
+  mem_streambuf buf( (char*)s.data(), s.size() );
+  istringstream iss;
+  iss.ios::rdbuf( &buf );
+  json::lexer lex( iss );
+  try {
+    if ( lex.next( ptoken ) )
+      return json::map_type( ptoken->get_type() );
+  }
+  catch ( json::exception const& ) {
+    // ignore
+  }
+  return json::none;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void CsvParseIterator::set_input( store::Item_t const &item,
+                                  CsvParseIteratorState *state ) const {
+  if ( item->isStreamable() )
+    state->csv_.set_stream( item->getStream() );
+  else {
+    item->getStringValue2( state->string_ );
+    state->mem_streambuf_.set( state->string_.data(), state->string_.size() );
+    state->iss_.ios::rdbuf( &state->mem_streambuf_ );
+    state->csv_.set_stream( state->iss_ );
+  }
+}
+
+void CsvParseIterator::set_options( store::Item_t const &item,
+                                    CsvParseIteratorState *state ) const {
+  store::Item_t opt_item;
+  char opt_char;
+  zstring value;
+
+  get_bool_opt( item, "cast-unquoted-values", &state->cast_unquoted_, loc );
+  get_string_opt( item, "extra-name", &state->extra_name_, loc );
+  if ( get_opt( item, "field-names", &opt_item ) ) {
+    store::Iterator_t i( opt_item->getArrayValues() );
+    i->open();
+    store::Item_t name_item;
+    while ( i->next( name_item ) )
+      state->keys_.push_back( name_item );
+    i->close();
+  }
+  if ( get_string_opt( item, "missing-value", &value, loc ) ) {
+    if ( value == "error" )
+      state->missing_ = missing::error;
+    else if ( value == "omit" )
+      state->missing_ = missing::omit;
+    else if ( value == "null" )
+      state->missing_ = missing::null;
+    else
+      ZORBA_ASSERT( false );            // should be caught by JSON schema
+  }
+  if ( get_char_opt( item, "quote-char", &opt_char, loc ) ) {
+    state->csv_.set_quote( opt_char );
+    state->csv_.set_quote_esc( opt_char );
+  }
+  if ( get_char_opt( item, "quote-escape", &opt_char, loc ) )
+    state->csv_.set_quote_esc( opt_char );
+  if ( get_char_opt( item, "separator", &opt_char, loc ) )
+    state->csv_.set_separator( opt_char );
+}
+
+bool CsvParseIterator::count( store::Item_t &result,
+                              PlanState &plan_state ) const {
+  unsigned long count = 0;
+  bool eol;
+  store::Item_t item;
+  zstring value;
+
+  CsvParseIteratorState *state;
+  DEFAULT_STACK_INIT( CsvParseIteratorState, state, plan_state );
+
+  // $csv as string
+  consumeNext( item, theChildren[0], plan_state );
+  set_input( item, state );
+
+  // $options as object()
+  consumeNext( item, theChildren[1], plan_state );
+  set_options( item, state );
+
+  while ( state->csv_.next_value( &value, &eol ) )
+    if ( eol )
+      ++count;
+
+  if ( state->keys_.empty() && count )
+    --count;
+
+  STACK_PUSH(
+    GENV_ITEMFACTORY->createInteger( result, xs_integer( count ) ),
+    state
+  );
+  STACK_END( state );
+}
+
+bool CsvParseIterator::skip( int64_t count, PlanState &plan_state ) const {
+  bool eol;
+  store::Item_t item;
+  vector<store::Item_t> keys;
+  zstring value;
+
+  CsvParseIteratorState *const state = StateTraitsImpl<CsvParseIteratorState>::
+    getState( plan_state, theStateOffset );
+
+  // $csv as string
+  consumeNext( item, theChildren[0], plan_state );
+  set_input( item, state );
+
+  // $options as object()
+  consumeNext( item, theChildren[1], plan_state );
+  set_options( item, state );
+
+  if ( state->keys_.empty() ) {
+    //
+    // If keys_ is empty, it means that the "field-names" option wasn't
+    // specified; hence, the first line of the file is assumed to be a header
+    // line.  A header line shouldn't count as a real record to be skipped, so
+    // bump up the count by 1 to compensate.
+    //
+    ++count;
+  }
+
+  //
+  // Since we called consumeNext() here and consumed the arguments, we have to
+  // use the already-consumed arguments (stored in the iterator's state) in
+  // nextImpl() and not call consumeNext() there.  Set a flag to indicate this.
+  //
+  state->skip_called_ = true;
+
+  while ( count-- > 0 ) {
+    while ( true ) {
+      if ( !state->csv_.next_value( &value, &eol ) )
+        return false;
+      if ( state->keys_.empty() ) {
+        if ( value.empty() ) {
+          //
+          // Header field names can never be empty.
+          //
+          throw XQUERY_EXCEPTION(
+            zerr::ZCSV0002_MISSING_VALUE,
+            ERROR_PARAMS( ZED( ZCSV0002_EmptyHeaderValue ) ),
+            ERROR_LOC( loc )
+          );
+        }
+        GENV_ITEMFACTORY->createString( item, value );
+        keys.push_back( item );
+      }
+      if ( eol ) {
+        if ( state->keys_.empty() ) {
+          //
+          // The first line of values are taken to be the header field names.
+          //
+          state->keys_.swap( keys );
+        }
+        break;
+      }
+    } // while ( true )
+  } // while ( count-- > 0 )
+  return true;
+}
+
+bool CsvParseIterator::nextImpl( store::Item_t &result,
+                                 PlanState &plan_state ) const {
+  unsigned field_no = 0;
+  store::Item_t item;
+  vector<store::Item_t> keys_copy, values;
+  set<unsigned> keys_omit;
+  zstring value;
+  bool eol, quoted, swap_keys = false;
+
+  CsvParseIteratorState *state;
+  DEFAULT_STACK_INIT( CsvParseIteratorState, state, plan_state );
+
+  if ( !state->skip_called_ ) {
+    // $csv as string
+    consumeNext( item, theChildren[0], plan_state );
+    set_input( item, state );
+
+    // $options as object()
+    consumeNext( item, theChildren[1], plan_state );
+    set_options( item, state );
+  }
+
+  while ( state->csv_.next_value( &value, &eol, &quoted ) ) {
+    if ( state->keys_.size() && values.size() == state->keys_.size() &&
+         state->extra_name_.empty() ) {
+      //
+      // We've already max'd out on the number of values for a record and the
+      // "extra-name" option wasn't specified.
+      //
+      throw XQUERY_EXCEPTION(
+        zerr::ZCSV0003_EXTRA_VALUE,
+        ERROR_PARAMS( value, state->line_no_ ),
+        ERROR_LOC( loc )
+      );
+    }
+
+    item = nullptr;
+    if ( value.empty() ) {
+      if ( state->keys_.empty() ) {
+        //
+        // Header field names can never be empty.
+        //
+        throw XQUERY_EXCEPTION(
+          zerr::ZCSV0002_MISSING_VALUE,
+          ERROR_PARAMS( ZED( ZCSV0002_EmptyHeaderValue ) ),
+          ERROR_LOC( loc )
+        );
+      }
+      if ( quoted )
+        GENV_ITEMFACTORY->createString( item, value );
+      else
+        switch ( state->missing_ ) {
+          case missing::error:
+            goto missing_error;
+          case missing::null:
+            GENV_ITEMFACTORY->createJSONNull( item );
+            break;
+          case missing::omit:
+            keys_omit.insert( field_no );
+            break;
+        }
+    } else if ( state->cast_unquoted_ && !quoted && !state->keys_.empty() ) {
+      if ( value == "T" || value == "Y" )
+        GENV_ITEMFACTORY->createBoolean( item, true );
+      else if ( value == "F" || value == "N" )
+        GENV_ITEMFACTORY->createBoolean( item, false );
+      else {
+        json::token t;
+        switch ( parse_json( value, &t ) ) {
+          case json::boolean:
+            GENV_ITEMFACTORY->createBoolean( item, value[0] == 't' );
+            break;
+          case json::null:
+            GENV_ITEMFACTORY->createJSONNull( item );
+            break;
+          case json::number:
+            switch ( t.get_numeric_type() ) {
+              case json::token::integer:
+                GENV_ITEMFACTORY->createInteger( item, xs_integer( value ) );
+                break;
+              case json::token::decimal:
+                GENV_ITEMFACTORY->createDecimal( item, xs_decimal( value ) );
+                break;
+              case json::token::floating_point:
+                GENV_ITEMFACTORY->createDouble( item, xs_double( value ) );
+                break;
+              default:
+                ZORBA_ASSERT( false );
+            }
+            break;
+          default:
+            GENV_ITEMFACTORY->createString( item, value );
+        } // switch
+      } // else
+    } else {
+      GENV_ITEMFACTORY->createString( item, value );
+    }
+
+    if ( !item.isNull() )
+      values.push_back( item );
+
+    if ( eol ) {
+      if ( state->keys_.empty() ) {
+        //
+        // The first line of values are taken to be the header field names.
+        //
+        state->keys_.swap( values );
+      } else {
+        if ( values.size() < state->keys_.size() ) {
+          //
+          // At least one value is missing.
+          //
+          switch ( state->missing_ ) {
+            case missing::error:
+              //
+              // We don't actually know which field is missing; we know only
+              // that there's at least one less field than there should be.
+              //
+              field_no = values.size();
+              goto missing_error;
+            case missing::null:
+              GENV_ITEMFACTORY->createJSONNull( item );
+              while ( values.size() < state->keys_.size() )
+                values.push_back( item );
+              break;
+            case missing::omit:
+              //
+              // We have to remove the keys for those fields that should be
+              // omitted temporarily.
+              //
+              if ( keys_omit.empty() ) {
+                //
+                // The last field is the one that's missing and there's no
+                // trailing ',' (which is why keys_omit is empty).
+                //
+                keys_copy = state->keys_;
+                state->keys_.pop_back();
+              } else {
+                for ( unsigned i = 0; i < state->keys_.size(); ++i )
+                  if ( !ztd::contains( keys_omit, i ) )
+                    keys_copy.push_back( state->keys_[i] );
+                keys_copy.swap( state->keys_ );
+              }
+              swap_keys = true;
+              break;
+          }
+        } else if ( values.size() > state->keys_.size() ) {
+          //
+          // There's at least one extra value: add in extra fields for keys
+          // temporarily.
+          //
+          keys_copy = state->keys_;
+          zstring::size_type const num_pos = state->extra_name_.find( '#' );
+          for ( unsigned f = state->keys_.size() +1; f <= values.size(); ++f ) {
+            ascii::itoa_buf_type buf;
+            ascii::itoa( f, buf );
+            zstring extra_name( state->extra_name_ );
+            if ( num_pos != zstring::npos )
+              extra_name.replace( num_pos, 1, buf );
+            else
+              extra_name += buf;
+            GENV_ITEMFACTORY->createString( item, extra_name );
+            state->keys_.push_back( item );
+          }
+          swap_keys = true;
+        }
+
+        GENV_ITEMFACTORY->createJSONObject( result, state->keys_, values );
+        if ( swap_keys ) {
+          //
+          // Put the original set of field names (keys) back the way it was.
+          //
+          keys_copy.swap( state->keys_ );
+        }
+        STACK_PUSH( true, state );
+      } // else
+      ++state->line_no_, field_no = 0;
+      continue;
+    } // if ( eol )
+    ++field_no;
+  } // while
+
+  STACK_END( state );
+
+missing_error:
+  throw XQUERY_EXCEPTION(
+    zerr::ZCSV0002_MISSING_VALUE,
+    ERROR_PARAMS(
+      ZED( ZCSV0002_MissingValue ),
+      state->keys_[ field_no ]->getStringValue(),
+      state->line_no_
+    ),
+    ERROR_LOC( loc )
+  );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool CsvSerializeIterator::nextImpl( store::Item_t &result,
+                                     PlanState &plan_state ) const {
+  char char_opt;
+  bool do_header, separator;
+  store::Item_t item, opt_item;
+  zstring line, value;
+
+  CsvSerializeIteratorState *state;
+  DEFAULT_STACK_INIT( CsvSerializeIteratorState, state, plan_state );
+
+  // $options as object()
+  consumeNext( item, theChildren[1], plan_state );
+  if ( get_opt( item, "field-names", &opt_item ) ) {
+    store::Iterator_t i( opt_item->getArrayValues() );
+    i->open();
+    store::Item_t name_item;
+    while ( i->next( name_item ) )
+      state->keys_.push_back( name_item );
+    i->close();
+  }
+  if ( !get_char_opt( item, "quote-char", &state->quote_, loc ) )
+    state->quote_ = '"';
+  if ( get_char_opt( item, "quote-escape", &char_opt, loc ) ) {
+    state->quote_esc_ = char_opt;
+    state->quote_esc_ += state->quote_;
+  } else
+    state->quote_esc_.assign( 2, state->quote_ );
+  if ( !get_bool_opt( item, "serialize-header", &do_header, loc ) )
+    do_header = true;
+  if ( !get_char_opt( item, "separator", &state->separator_, loc ) )
+    state->separator_ = ',';
+  if ( !get_string_opt( item, "serialize-null-as", &state->null_string_, loc ) )
+    state->null_string_ = "null";
+  if ( get_opt( item, "serialize-boolean-as", &opt_item ) ) {
+    if ( !get_string_opt( opt_item, "false", &state->boolean_string_[0], loc )
+      || !get_string_opt( opt_item, "true", &state->boolean_string_[1], loc ) )
+      throw XQUERY_EXCEPTION(
+        zerr::ZCSV0001_INVALID_OPTION,
+        ERROR_PARAMS(
+          "", "serialize-boolea-as",
+          ZED( ZCSV0001_MustBeTrueFalse )
+        ),
+        ERROR_LOC( loc )
+      );
+  } else
+    state->boolean_string_[0] = "false", state->boolean_string_[1] = "true";
+
+  state->must_quote_ = state->separator_;
+  state->must_quote_ += state->quote_;
+  state->must_quote_ += "\r\n";
+
+  if ( state->keys_.empty() ) {
+    //
+    // We have to take the header field names from the first item, but we have
+    // to save the first item to return its values later.
+    //
+    if ( consumeNext( state->header_item_, theChildren[0], plan_state ) ) {
+      store::Iterator_t i( state->header_item_->getObjectKeys() );
+      i->open();
+      while ( i->next( item ) )
+        state->keys_.push_back( item );
+      i->close();
+    }
+  }
+
+  if ( do_header ) {
+    separator = false;
+    FOR_EACH( vector<store::Item_t>, key, state->keys_ ) {
+      if ( separator )
+        line += state->separator_;
+      else
+        separator = true;
+      line += (*key)->getStringValue();
+    }
+    line += "\r\n";
+    GENV_ITEMFACTORY->createString( result, line );
+    STACK_PUSH( true, state );
+  }
+
+  if ( !state->header_item_.isNull() ) {
+    //
+    // We consumed the first item above to get the field names for the header
+    // since they weren't given.  However, we must still return the first
+    // item's values as the first "real" result, so set "item" to
+    // "header_item_" and jump into the while loop below but skipping the call
+    // to consumeNext().
+    //
+    item = state->header_item_;
+    goto skip_consumeNext;
+  }
+
+  while ( consumeNext( item, theChildren[0], plan_state ) ) {
+skip_consumeNext:
+    line.clear();
+    separator = false;
+    FOR_EACH( vector<store::Item_t>, key, state->keys_ ) {
+      if ( separator )
+        line += state->separator_;
+      else
+        separator = true;
+      store::Item_t const value_item( item->getObjectValue( *key ) );
+      if ( !value_item.isNull() ) {
+        if ( IS_ATOMIC_TYPE( value_item, XS_BOOLEAN ) )
+          line += state->boolean_string_[ value_item->getBooleanValue() ];
+        else if ( IS_JSON_NULL( value_item ) )
+          line += state->null_string_;
+        else {
+          value_item->getStringValue2( value );
+          bool const quote =
+            value.find_first_of( state->must_quote_ ) != zstring::npos;
+          if ( quote )
+            line += state->quote_;
+          ascii::replace_all( value, state->quote_, state->quote_esc_ );
+          line += value;
+          if ( quote )
+            line += state->quote_;
+        }
+      }
+    } // for
+    line += "\r\n";
+    GENV_ITEMFACTORY->createString( result, line );
+    STACK_PUSH( true, state );
+  } // while
+
+  STACK_END( state );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+} // namespace zorba
+
+/* vim:set et sw=2 ts=2: */

=== added file 'src/runtime/csv/csv_util.h'
--- src/runtime/csv/csv_util.h	1970-01-01 00:00:00 +0000
+++ src/runtime/csv/csv_util.h	2013-08-29 00:04:39 +0000
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+#ifndef ZORBA_CSV_UTIL_H
+#define ZORBA_CSV_UTIL_H
+
+namespace zorba {
+
+///////////////////////////////////////////////////////////////////////////////
+
+namespace missing {
+  enum type {
+    null,
+    omit,
+    error
+  };
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+} // namespace zorba
+#endif /* ZORBA_CSV_UTIL_H */
+/* vim:set et sw=2 ts=2: */

=== added directory 'src/runtime/csv/pregenerated'
=== added file 'src/runtime/csv/pregenerated/csv.cpp'
--- src/runtime/csv/pregenerated/csv.cpp	1970-01-01 00:00:00 +0000
+++ src/runtime/csv/pregenerated/csv.cpp	2013-08-29 00:04:39 +0000
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2006-2012 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.
+ */
+ 
+// ******************************************
+// *                                        *
+// * THIS IS A GENERATED FILE. DO NOT EDIT! *
+// * SEE .xml FILE WITH SAME NAME           *
+// *                                        *
+// ******************************************
+
+#include "stdafx.h"
+#include "zorbatypes/rchandle.h"
+#include "zorbatypes/zstring.h"
+#include "runtime/visitors/planiter_visitor.h"
+#include "runtime/csv/csv.h"
+#include "system/globalenv.h"
+
+
+#include "store/api/iterator.h"
+
+namespace zorba {
+
+// <CsvParseIterator>
+SERIALIZABLE_CLASS_VERSIONS(CsvParseIterator)
+
+void CsvParseIterator::serialize(::zorba::serialization::Archiver& ar)
+{
+  serialize_baseclass(ar,
+  (NaryBaseIterator<CsvParseIterator, CsvParseIteratorState>*)this);
+}
+
+
+void CsvParseIterator::accept(PlanIterVisitor& v) const
+{
+  v.beginVisit(*this);
+
+  std::vector<PlanIter_t>::const_iterator lIter = theChildren.begin();
+  std::vector<PlanIter_t>::const_iterator lEnd = theChildren.end();
+  for ( ; lIter != lEnd; ++lIter ){
+    (*lIter)->accept(v);
+  }
+
+  v.endVisit(*this);
+}
+
+CsvParseIterator::~CsvParseIterator() {}
+
+CsvParseIteratorState::CsvParseIteratorState() {}
+
+CsvParseIteratorState::~CsvParseIteratorState() {}
+
+
+void CsvParseIteratorState::init(PlanState& planState) {
+  PlanIteratorState::init(planState);
+  cast_unquoted_ = true;
+  line_no_ = 1;
+  missing_ = missing::null;
+  skip_called_ = false;
+}
+
+void CsvParseIteratorState::reset(PlanState& planState) {
+  PlanIteratorState::reset(planState);
+  cast_unquoted_ = true;
+  line_no_ = 1;
+  missing_ = missing::null;
+  skip_called_ = false;
+}
+// </CsvParseIterator>
+
+
+// <CsvSerializeIterator>
+SERIALIZABLE_CLASS_VERSIONS(CsvSerializeIterator)
+
+void CsvSerializeIterator::serialize(::zorba::serialization::Archiver& ar)
+{
+  serialize_baseclass(ar,
+  (NaryBaseIterator<CsvSerializeIterator, CsvSerializeIteratorState>*)this);
+}
+
+
+void CsvSerializeIterator::accept(PlanIterVisitor& v) const
+{
+  v.beginVisit(*this);
+
+  std::vector<PlanIter_t>::const_iterator lIter = theChildren.begin();
+  std::vector<PlanIter_t>::const_iterator lEnd = theChildren.end();
+  for ( ; lIter != lEnd; ++lIter ){
+    (*lIter)->accept(v);
+  }
+
+  v.endVisit(*this);
+}
+
+CsvSerializeIterator::~CsvSerializeIterator() {}
+
+CsvSerializeIteratorState::CsvSerializeIteratorState() {}
+
+CsvSerializeIteratorState::~CsvSerializeIteratorState() {}
+
+
+void CsvSerializeIteratorState::reset(PlanState& planState) {
+  PlanIteratorState::reset(planState);
+}
+// </CsvSerializeIterator>
+
+
+
+}
+
+

=== added file 'src/runtime/csv/pregenerated/csv.h'
--- src/runtime/csv/pregenerated/csv.h	1970-01-01 00:00:00 +0000
+++ src/runtime/csv/pregenerated/csv.h	2013-08-29 00:04:39 +0000
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2006-2012 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.
+ */
+ 
+// ******************************************
+// *                                        *
+// * THIS IS A GENERATED FILE. DO NOT EDIT! *
+// * SEE .xml FILE WITH SAME NAME           *
+// *                                        *
+// ******************************************
+#ifndef ZORBA_RUNTIME_CSV_CSV_H
+#define ZORBA_RUNTIME_CSV_CSV_H
+
+
+#include "common/shared_types.h"
+
+
+
+#include "runtime/base/narybase.h"
+#include <sstream>
+#include <vector>
+#include "runtime/csv/csv_util.h"
+#include "util/csv_parser.h"
+#include "util/mem_streambuf.h"
+#include "zorbatypes/zstring.h"
+
+
+namespace zorba {
+
+/**
+ * 
+ * Author: 
+ */
+class CsvParseIteratorState : public PlanIteratorState
+{
+public:
+  bool cast_unquoted_; //
+  csv_parser csv_; //
+  zstring extra_name_; //
+  std::istringstream iss_; //
+  std::vector<store::Item_t> keys_; //
+  unsigned line_no_; //
+  mem_streambuf mem_streambuf_; //
+  missing::type missing_; //
+  bool skip_called_; //
+  zstring string_; //
+
+  CsvParseIteratorState();
+
+  ~CsvParseIteratorState();
+
+  void init(PlanState&);
+  void reset(PlanState&);
+};
+
+class CsvParseIterator : public NaryBaseIterator<CsvParseIterator, CsvParseIteratorState>
+{ 
+public:
+  SERIALIZABLE_CLASS(CsvParseIterator);
+
+  SERIALIZABLE_CLASS_CONSTRUCTOR2T(CsvParseIterator,
+    NaryBaseIterator<CsvParseIterator, CsvParseIteratorState>);
+
+  void serialize( ::zorba::serialization::Archiver& ar);
+
+  CsvParseIterator(
+    static_context* sctx,
+    const QueryLoc& loc,
+    std::vector<PlanIter_t>& children)
+    : 
+    NaryBaseIterator<CsvParseIterator, CsvParseIteratorState>(sctx, loc, children)
+  {}
+
+  virtual ~CsvParseIterator();
+
+public:
+  bool count(store::Item_t& result, PlanState& planState) const;
+  bool skip(int64_t count, PlanState& planState) const;
+  void set_input(store::Item_t const& item, CsvParseIteratorState* state) const;
+  void set_options(store::Item_t const& item, CsvParseIteratorState* state) const;
+  void accept(PlanIterVisitor& v) const;
+
+  bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
+};
+
+
+/**
+ * 
+ * Author: 
+ */
+class CsvSerializeIteratorState : public PlanIteratorState
+{
+public:
+  zstring boolean_string_[2]; //
+  store::Item_t header_item_; //
+  std::vector<store::Item_t> keys_; //
+  zstring must_quote_; //
+  zstring null_string_; //
+  char quote_; //
+  zstring quote_esc_; //
+  char separator_; //
+
+  CsvSerializeIteratorState();
+
+  ~CsvSerializeIteratorState();
+
+  void reset(PlanState&);
+};
+
+class CsvSerializeIterator : public NaryBaseIterator<CsvSerializeIterator, CsvSerializeIteratorState>
+{ 
+public:
+  SERIALIZABLE_CLASS(CsvSerializeIterator);
+
+  SERIALIZABLE_CLASS_CONSTRUCTOR2T(CsvSerializeIterator,
+    NaryBaseIterator<CsvSerializeIterator, CsvSerializeIteratorState>);
+
+  void serialize( ::zorba::serialization::Archiver& ar);
+
+  CsvSerializeIterator(
+    static_context* sctx,
+    const QueryLoc& loc,
+    std::vector<PlanIter_t>& children)
+    : 
+    NaryBaseIterator<CsvSerializeIterator, CsvSerializeIteratorState>(sctx, loc, children)
+  {}
+
+  virtual ~CsvSerializeIterator();
+
+  void accept(PlanIterVisitor& v) const;
+
+  bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
+};
+
+
+}
+#endif
+/*
+ * Local variables:
+ * mode: c++
+ * End:
+ */ 

=== modified file 'src/runtime/errors_and_diagnostics/other_diagnostics_impl.cpp'
--- src/runtime/errors_and_diagnostics/other_diagnostics_impl.cpp	2013-02-07 17:24:36 +0000
+++ src/runtime/errors_and_diagnostics/other_diagnostics_impl.cpp	2013-08-29 00:04:39 +0000
@@ -84,6 +84,19 @@
   theFunctionArity = arity;
 }
 
+bool
+FunctionTraceIterator::count(store::Item_t &result, PlanState &plan_state) const
+{
+  return theChildren[0]->count(result, plan_state);
+}
+
+bool
+FunctionTraceIterator::skip( int64_t count, PlanState &plan_state ) const
+{
+  return theChildren[0]->skip(count, plan_state);
+}
+
+
 /*******************************************************************************
   Diagnostics iterators: read-line
 ********************************************************************************/

=== modified file 'src/runtime/errors_and_diagnostics/pregenerated/other_diagnostics.h'
--- src/runtime/errors_and_diagnostics/pregenerated/other_diagnostics.h	2013-03-05 23:11:50 +0000
+++ src/runtime/errors_and_diagnostics/pregenerated/other_diagnostics.h	2013-08-29 00:04:39 +0000
@@ -140,6 +140,8 @@
   void setFunctionCallLocation(const QueryLoc& aFunctionLocation);
   void setFunctionLocation(const QueryLoc& aFunctionLocation);
   void setFunctionArity(unsigned int arity);
+  bool count(store::Item_t& result, PlanState& planState) const;
+  bool skip(int64_t count, PlanState& planState) const;
   void accept(PlanIterVisitor& v) const;
 
   bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;

=== modified file 'src/runtime/json/jsonml_array.cpp'
--- src/runtime/json/jsonml_array.cpp	2013-07-29 23:56:38 +0000
+++ src/runtime/json/jsonml_array.cpp	2013-08-29 00:04:39 +0000
@@ -19,6 +19,7 @@
 
 #include <zorba/diagnostic_list.h>
 #include <zorba/internal/cxx_util.h>
+#include <zorba/store_consts.h>
 
 #include "runtime/json/json.h"
 #include "store/api/item_factory.h"

=== modified file 'src/runtime/json/snelson.cpp'
--- src/runtime/json/snelson.cpp	2013-08-16 22:10:33 +0000
+++ src/runtime/json/snelson.cpp	2013-08-29 00:04:39 +0000
@@ -20,6 +20,7 @@
 
 #include <zorba/diagnostic_list.h>
 #include <zorba/internal/cxx_util.h>
+#include <zorba/store_consts.h>
 
 #include "runtime/json/json.h"
 #include "store/api/item_factory.h"

=== modified file 'src/runtime/numerics/format_number.cpp'
--- src/runtime/numerics/format_number.cpp	2013-06-18 02:28:10 +0000
+++ src/runtime/numerics/format_number.cpp	2013-08-29 00:04:39 +0000
@@ -28,7 +28,6 @@
 #include "store/api/item_factory.h"
 #include "system/globalenv.h"
 #include "types/casting.h"
-#include "types/typeconstants.h"
 #include "types/typeops.h"
 #include "util/xml_util.h"
 #include "zorbatypes/float.h"

=== modified file 'src/runtime/pregenerated/iterator_enum.h'
--- src/runtime/pregenerated/iterator_enum.h	2013-08-16 13:00:06 +0000
+++ src/runtime/pregenerated/iterator_enum.h	2013-08-29 00:04:39 +0000
@@ -72,6 +72,8 @@
   TYPE_CurrentTimeIterator,
   TYPE_ImplicitTimezoneIterator,
   TYPE_DefaultCollationIterator,
+  TYPE_CsvParseIterator,
+  TYPE_CsvSerializeIterator,
   TYPE_CurrentDate,
   TYPE_CurrentDateTime,
   TYPE_CurrentTime,

=== added directory 'src/runtime/spec/csv'
=== added file 'src/runtime/spec/csv/csv.xml'
--- src/runtime/spec/csv/csv.xml	1970-01-01 00:00:00 +0000
+++ src/runtime/spec/csv/csv.xml	2013-08-29 00:04:39 +0000
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<zorba:iterators
+  xmlns:zorba="http://www.zorba-xquery.com";
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+  xsi:schemaLocation="http://www.zorba-xquery.com ../runtime.xsd">
+
+<zorba:header>
+  <zorba:include form="Angle-bracket">sstream</zorba:include>
+  <zorba:include form="Angle-bracket">vector</zorba:include>
+  <zorba:include form="Quoted">runtime/csv/csv_util.h</zorba:include>
+  <zorba:include form="Quoted">util/csv_parser.h</zorba:include>
+  <zorba:include form="Quoted">util/mem_streambuf.h</zorba:include>
+  <zorba:include form="Quoted">zorbatypes/zstring.h</zorba:include>
+</zorba:header>
+
+<zorba:source>
+  <zorba:include form="Quoted">store/api/iterator.h</zorba:include>
+</zorba:source>
+
+<!--========================================================================-->
+
+<zorba:iterator name="CsvParseIterator" arity="nary">
+  <zorba:function>
+    <zorba:signature localname="parse" prefix="fn-zorba-csv">
+      <zorba:param>xs:string</zorba:param>
+      <zorba:param>object()</zorba:param>
+      <zorba:output>object()*</zorba:output>
+    </zorba:signature>
+  </zorba:function>
+  <zorba:state generateInit="true" generateReset="true">
+    <zorba:member type="bool" name="cast_unquoted_" defaultValue="true"/>
+    <zorba:member type="csv_parser" name="csv_"/>
+    <zorba:member type="zstring" name="extra_name_"/>
+    <zorba:member type="std::istringstream" name="iss_"/>
+    <zorba:member type="std::vector&lt;store::Item_t&gt;" name="keys_"/>
+    <zorba:member type="unsigned" name="line_no_" defaultValue="1"/>
+    <zorba:member type="mem_streambuf" name="mem_streambuf_"/>
+    <zorba:member type="missing::type" name="missing_" defaultValue="missing::null"/>
+    <zorba:member type="bool" name="skip_called_" defaultValue="false"/>
+    <zorba:member type="zstring" name="string_"/>
+  </zorba:state>
+  <zorba:method name="count" const="true" return="bool">
+    <zorba:param name="result" type="store::Item_t&amp;"/>
+    <zorba:param name="planState" type="PlanState&amp;"/>
+  </zorba:method>
+  <zorba:method name="skip" const="true" return="bool">
+    <zorba:param name="count" type="int64_t"/>
+    <zorba:param name="planState" type="PlanState&amp;"/>
+  </zorba:method>
+  <zorba:method name="set_input" return="void" const="true">
+    <zorba:param type="store::Item_t const&amp;" name="item"/>
+    <zorba:param type="CsvParseIteratorState*" name="state"/>
+  </zorba:method>
+  <zorba:method name="set_options" return="void" const="true">
+    <zorba:param type="store::Item_t const&amp;" name="item"/>
+    <zorba:param type="CsvParseIteratorState*" name="state"/>
+  </zorba:method>
+</zorba:iterator>
+
+<!--========================================================================-->
+
+<zorba:iterator name="CsvSerializeIterator" arity="nary">
+  <zorba:function>
+    <zorba:signature localname="serialize" prefix="fn-zorba-csv">
+      <zorba:param>object()*</zorba:param>
+      <zorba:param>object()</zorba:param>
+      <zorba:output>xs:string*</zorba:output>
+    </zorba:signature>
+  </zorba:function>
+  <zorba:state generateInit="use-default">
+    <zorba:member type="zstring" name="boolean_string_[2]"/>
+    <zorba:member type="store::Item_t" name="header_item_"/>
+    <zorba:member type="std::vector&lt;store::Item_t&gt;" name="keys_"/>
+    <zorba:member type="zstring" name="must_quote_"/>
+    <zorba:member type="zstring" name="null_string_"/>
+    <zorba:member type="char" name="quote_"/>
+    <zorba:member type="zstring" name="quote_esc_"/>
+    <zorba:member type="char" name="separator_"/>
+  </zorba:state>
+</zorba:iterator>
+
+<!--========================================================================-->
+
+</zorba:iterators>
+<!-- vim:set et sw=2 ts=2: -->

=== modified file 'src/runtime/spec/errors_and_diagnostics/other_diagnostics.xml'
--- src/runtime/spec/errors_and_diagnostics/other_diagnostics.xml	2013-02-07 17:24:36 +0000
+++ src/runtime/spec/errors_and_diagnostics/other_diagnostics.xml	2013-08-29 00:04:39 +0000
@@ -109,6 +109,17 @@
       <zorba:param type="unsigned int" name="arity" />
     </zorba:method>
 
+    <zorba:method name="count" const="true" return="bool">
+      <zorba:param name="result" type="store::Item_t&amp;"/>
+      <zorba:param name="planState" type="PlanState&amp;"/>
+    </zorba:method>
+
+    <zorba:method name="skip" const="true" return="bool">
+      <zorba:param name="count" type="int64_t"/>
+      <zorba:param name="planState" type="PlanState&amp;"/>
+    </zorba:method>
+
+
   </zorba:iterator>
 
 </zorba:iterators>

=== modified file 'src/runtime/spec/mappings.xml'
--- src/runtime/spec/mappings.xml	2013-08-09 09:20:54 +0000
+++ src/runtime/spec/mappings.xml	2013-08-29 00:04:39 +0000
@@ -114,8 +114,12 @@
                      define="ZORBA_URI_FN_NS" 
                      prefix="fn-zorba-uri"/>
 
+    <zorba:namespace uri="http://zorba.io/modules/json-csv";
+                     define="ZORBA_JSON_CSV_FN_NS" 
+                     prefix="fn-zorba-csv"/>
+
     <zorba:namespace uri="http://zorba.io/modules/json-xml";
-                     define="ZORBA_JSON_FN_NS" 
+                     define="ZORBA_JSON_XML_FN_NS" 
                      prefix="fn-zorba-json"/>
 
     <zorba:namespace uri="http://www.zorba-xquery.com/modules/fetch";

=== modified file 'src/runtime/visitors/pregenerated/planiter_visitor.h'
--- src/runtime/visitors/pregenerated/planiter_visitor.h	2013-08-16 13:00:06 +0000
+++ src/runtime/visitors/pregenerated/planiter_visitor.h	2013-08-29 00:04:39 +0000
@@ -134,6 +134,10 @@
 
     class DefaultCollationIterator;
 
+    class CsvParseIterator;
+
+    class CsvSerializeIterator;
+
     class CurrentDate;
 
     class CurrentDateTime;
@@ -915,6 +919,12 @@
     virtual void beginVisit ( const DefaultCollationIterator& ) = 0;
     virtual void endVisit   ( const DefaultCollationIterator& ) = 0;
 
+    virtual void beginVisit ( const CsvParseIterator& ) = 0;
+    virtual void endVisit   ( const CsvParseIterator& ) = 0;
+
+    virtual void beginVisit ( const CsvSerializeIterator& ) = 0;
+    virtual void endVisit   ( const CsvSerializeIterator& ) = 0;
+
     virtual void beginVisit ( const CurrentDate& ) = 0;
     virtual void endVisit   ( const CurrentDate& ) = 0;
 

=== modified file 'src/runtime/visitors/pregenerated/printer_visitor.cpp'
--- src/runtime/visitors/pregenerated/printer_visitor.cpp	2013-08-16 13:00:06 +0000
+++ src/runtime/visitors/pregenerated/printer_visitor.cpp	2013-08-29 00:04:39 +0000
@@ -41,6 +41,7 @@
 #include "runtime/booleans/booleans.h"
 #include "runtime/collections/collections.h"
 #include "runtime/context/context.h"
+#include "runtime/csv/csv.h"
 #include "runtime/datetime/datetime.h"
 #include "runtime/debug/debug_iterator.h"
 #include "runtime/durations_dates_times/durations_dates_times.h"
@@ -706,6 +707,34 @@
 // </DefaultCollationIterator>
 
 
+// <CsvParseIterator>
+void PrinterVisitor::beginVisit ( const CsvParseIterator& a) {
+  thePrinter.startBeginVisit("CsvParseIterator", ++theId);
+  printCommons( &a, theId );
+  thePrinter.endBeginVisit( theId );
+}
+
+void PrinterVisitor::endVisit ( const CsvParseIterator& ) {
+  thePrinter.startEndVisit();
+  thePrinter.endEndVisit();
+}
+// </CsvParseIterator>
+
+
+// <CsvSerializeIterator>
+void PrinterVisitor::beginVisit ( const CsvSerializeIterator& a) {
+  thePrinter.startBeginVisit("CsvSerializeIterator", ++theId);
+  printCommons( &a, theId );
+  thePrinter.endBeginVisit( theId );
+}
+
+void PrinterVisitor::endVisit ( const CsvSerializeIterator& ) {
+  thePrinter.startEndVisit();
+  thePrinter.endEndVisit();
+}
+// </CsvSerializeIterator>
+
+
 // <CurrentDate>
 void PrinterVisitor::beginVisit ( const CurrentDate& a) {
   thePrinter.startBeginVisit("CurrentDate", ++theId);

=== modified file 'src/runtime/visitors/pregenerated/printer_visitor.h'
--- src/runtime/visitors/pregenerated/printer_visitor.h	2013-08-16 13:00:06 +0000
+++ src/runtime/visitors/pregenerated/printer_visitor.h	2013-08-29 00:04:39 +0000
@@ -203,6 +203,12 @@
     void beginVisit( const DefaultCollationIterator& );
     void endVisit  ( const DefaultCollationIterator& );
 
+    void beginVisit( const CsvParseIterator& );
+    void endVisit  ( const CsvParseIterator& );
+
+    void beginVisit( const CsvSerializeIterator& );
+    void endVisit  ( const CsvSerializeIterator& );
+
     void beginVisit( const CurrentDate& );
     void endVisit  ( const CurrentDate& );
 

=== modified file 'src/util/CMakeLists.txt'
--- src/util/CMakeLists.txt	2013-08-02 14:55:29 +0000
+++ src/util/CMakeLists.txt	2013-08-29 00:04:39 +0000
@@ -14,6 +14,7 @@
 
 SET(UTIL_SRCS
   ascii_util.cpp
+  csv_parser.cpp
   dynamic_bitset.cpp
   error_util.cpp
   fs_util.cpp

=== modified file 'src/util/ascii_util.h'
--- src/util/ascii_util.h	2013-05-09 00:48:27 +0000
+++ src/util/ascii_util.h	2013-08-29 00:04:39 +0000
@@ -677,6 +677,43 @@
  * @tparam StringType The string type.
  * @param s The string to modify.
  * @param from The substring to replace.
+ * @param from_len The length of \a from.
+ * @param to The substring to replace with.
+ * @return Returns \c true only if at least one replacement is performed.
+ */
+template<class StringType,class ToStringType> inline
+typename std::enable_if<ZORBA_IS_STRING(StringType)
+                     && ZORBA_IS_STRING(ToStringType),
+                        bool>::type
+replace_all( StringType &s,
+             char const *from, typename StringType::size_type from_len,
+             ToStringType const &to ) {
+  return replace_all( s, from, from_len, to.data(), to.size() );
+}
+
+/**
+ * Replaces all occurrences of a character with a string.
+ *
+ * @tparam StringType The string type.
+ * @param s The string to modify.
+ * @param from The character to replace.
+ * @param to The substring to replace with.
+ * @return Returns \c true only if at least one replacement is performed.
+ */
+template<class StringType,class ToStringType> inline
+typename std::enable_if<ZORBA_IS_STRING(StringType)
+                     && ZORBA_IS_STRING(ToStringType),
+                        bool>::type
+replace_all( StringType &s, char from, ToStringType const &to ) {
+  return replace_all( s, &from, 1, to.data(), to.size() );
+}
+
+/**
+ * Replaces all occurrences of one substring with another.
+ *
+ * @tparam StringType The string type.
+ * @param s The string to modify.
+ * @param from The substring to replace.
  * @param to The substring to replace with.
  * @return Returns \c true only if at least one replacement is performed.
  */

=== added file 'src/util/csv_parser.cpp'
--- src/util/csv_parser.cpp	1970-01-01 00:00:00 +0000
+++ src/util/csv_parser.cpp	2013-08-29 00:04:39 +0000
@@ -0,0 +1,85 @@
+/*
+ * 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 "csv_parser.h"
+
+namespace zorba {
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool csv_parser::next_value( zstring *value, bool *eol, bool *quoted ) const {
+  value->clear();
+  char c;
+  bool in_quote = false;
+  bool is_quoted = false;
+
+  while ( is_->get( c ) ) {
+    if ( in_quote ) {
+      if ( quote_esc_ == quote_ ) {     // ""
+        if ( c == quote_ ) {
+          c = is_->peek();
+          if ( is_->good() ) {
+            if ( c != quote_ ) {
+              in_quote = false;
+              continue;
+            }
+            is_->get();
+          }
+        }
+      } else {                          // \"
+        if ( c == quote_ ) {
+          in_quote = false;
+          continue;
+        }
+        if ( c == quote_esc_ && !is_->get( c ) )
+          break;
+      }
+    } else {
+      if ( c == quote_ ) {
+        in_quote = is_quoted = true;
+        continue;
+      }
+      if ( c == sep_ ) {
+        *eol = false;
+        goto return_true;
+      }
+      switch ( c ) {
+        case '\r':
+          if ( ((c = is_->peek()), is_->good()) && c == '\n' )
+            is_->get();
+          // no break;
+        case '\n':
+          *eol = true;
+          goto return_true;
+      } // switch
+    } // else
+    *value += c;
+  } // while
+
+  if ( value->empty() )
+    return false;
+
+  *eol = true;
+return_true:
+  if ( quoted )
+    *quoted = is_quoted;
+  return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+} // namespace zorba
+/* vim:set et sw=2 ts=2: */

=== added file 'src/util/csv_parser.h'
--- src/util/csv_parser.h	1970-01-01 00:00:00 +0000
+++ src/util/csv_parser.h	2013-08-29 00:04:39 +0000
@@ -0,0 +1,154 @@
+/*
+ * 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.
+ */
+
+#ifndef ZORBA_CSV_H
+#define ZORBA_CSV_H
+
+#include <zorba/internal/cxx_util.h>
+
+#include "zorbatypes/zstring.h"
+
+namespace zorba {
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Parses a CSV (Comma-Separated Values) stream.
+ * See RFC 4180: "Common Format and MIME Type for Comma-Separated Values (CSV)
+ * Files."
+ */
+class csv_parser {
+public:
+  /**
+   * Constructs a %csv_parser.
+   *
+   * @param sep The value separator to use.
+   * @param quote The quote character to use.  (The quote escape is a doubling
+   * of this character.)
+   */
+  csv_parser( char sep = ',', char quote = '"' ) {
+    is_ = 0;
+    sep_ = sep;
+    quote_ = quote_esc_ = quote;
+  }
+
+  /**
+   * Constructs a %csv_parser.
+   *
+   * @param sep The value separator to use.
+   * @param quote The quote character to use.
+   * @param quote_esc The quote-escape character to use.  If it matches
+   * \a quote, then a quote is escaped by doubling it.
+   */
+  csv_parser( char sep, char quote, char quote_esc ) {
+    is_ = 0;
+    sep_ = sep;
+    quote_ = quote;
+    quote_esc_ = quote_esc;
+  }
+
+  /**
+   * Constructs a %csv_parser.
+   *
+   * @param is The istream to read from.
+   * @param sep The value separator to use.
+   * @param quote The quote character to use.  (The quote escape is a doubling
+   * of this character.)
+   */
+  csv_parser( std::istream &is, char sep = ',', char quote = '"' ) {
+    is_ = &is;
+    sep_ = sep;
+    quote_ = quote_esc_ = quote;
+  }
+
+  /**
+   * Constructs a %csv_parser.
+   *
+   * @param is The istream to read from.
+   * @param sep The value separator to use.
+   * @param quote The quote character to use.
+   * @param quote_esc The quote-escape character to use.  If it matches
+   * \a quote, then a quote is escaped by doubling it.
+   */
+  csv_parser( std::istream &is, char sep, char quote, char quote_esc ) {
+    is_ = &is;
+    sep_ = sep;
+    quote_ = quote;
+    quote_esc_ = quote_esc;
+  }
+
+  /**
+   * Parses the next value.
+   *
+   * @param value A pointer to the string to receive the next value.
+   * @param eol Set to \c true only when \a value is set to the last value on a
+   * line.
+   * @param quoted If not \c null, set to \c true only when \a value was
+   * quoted.
+   * @return Returns \c true only if a value was parsed; \c false otherwise.
+   */
+  bool next_value( zstring *value, bool *eol, bool *quoted = nullptr ) const;
+
+  /**
+   * Sets the quote character to use.
+   *
+   * @param quote The quote character to use.
+   */
+  void set_quote( char quote ) {
+    quote_ = quote;
+  }
+
+  /**
+   * Sets the quote-escape character to use.  If it matches the quote
+   * character, en a quote is escaped by doubling it.
+   *
+   * @param quote_esc The quote-escape character to use.
+   */
+  void set_quote_esc( char quote_esc ) {
+    quote_esc_ = quote_esc;
+  }
+
+  /**
+   * Sets the value-separator character to use.
+   *
+   * @param sep The value separator character to use.
+   */
+  void set_separator( char sep ) {
+    sep_ = sep;
+  }
+
+  /**
+   * Sets the istream to read from.
+   *
+   * @param is The istream to read from.
+   */
+  void set_stream( std::istream &is ) {
+    is_ = &is;
+  }
+
+private:
+  std::istream *is_;
+  char quote_;
+  char quote_esc_;
+  char sep_;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+} // namespace std
+
+#endif /* ZORBA_CSV_H */
+/* vim:set et sw=2 ts=2: */

=== modified file 'src/util/json_parser.cpp'
--- src/util/json_parser.cpp	2013-07-15 15:09:19 +0000
+++ src/util/json_parser.cpp	2013-08-29 00:04:39 +0000
@@ -396,6 +396,8 @@
   if ( c == '0' ) {
     if ( !peek_char( &c ) )
       goto done;
+    if ( ascii::is_alnum( c ) )
+      throw illegal_number( set_cur_loc_end( false ) );
   } else {
     while ( true ) {
       if ( !peek_char( &c ) )

=== added directory 'test/rbkt/ExpQueryResults/zorba/csv'
=== added file 'test/rbkt/ExpQueryResults/zorba/csv/csv-parse-01.xml.res'
--- test/rbkt/ExpQueryResults/zorba/csv/csv-parse-01.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/csv/csv-parse-01.xml.res	2013-08-29 00:04:39 +0000
@@ -0,0 +1,17 @@
+{
+  "first" : "one", 
+  "second" : "two", 
+  "third" : "three"
+}{
+  "first" : "quoted", 
+  "second" : "embedded \" quote", 
+  "third" : "embedded\r\nnewline"
+}{
+  "first" : "\" leading quote", 
+  "second" : "", 
+  "third" : "trailing quote \""
+}{
+  "first" : "last", 
+  "second" : "three", 
+  "third" : "fields"
+}

=== added file 'test/rbkt/ExpQueryResults/zorba/csv/csv-parse-cast-01.xml.res'
--- test/rbkt/ExpQueryResults/zorba/csv/csv-parse-cast-01.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/csv/csv-parse-cast-01.xml.res	2013-08-29 00:04:39 +0000
@@ -0,0 +1,8 @@
+{
+  "string" : "foo", 
+  "integer" : 42, 
+  "decimal" : 98.6, 
+  "double" : 10000, 
+  "boolean" : false, 
+  "null" : null
+}

=== added file 'test/rbkt/ExpQueryResults/zorba/csv/csv-parse-cast-unquoted-01.xml.res'
--- test/rbkt/ExpQueryResults/zorba/csv/csv-parse-cast-unquoted-01.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/csv/csv-parse-cast-unquoted-01.xml.res	2013-08-29 00:04:39 +0000
@@ -0,0 +1,8 @@
+{
+  "string" : "foo", 
+  "integer" : "42", 
+  "decimal" : "98.6", 
+  "double" : "1E4", 
+  "boolean" : "false", 
+  "null" : "null"
+}

=== added file 'test/rbkt/ExpQueryResults/zorba/csv/csv-parse-count-01.xml.res'
--- test/rbkt/ExpQueryResults/zorba/csv/csv-parse-count-01.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/csv/csv-parse-count-01.xml.res	2013-08-29 00:04:39 +0000
@@ -0,0 +1,1 @@
+4

=== added file 'test/rbkt/ExpQueryResults/zorba/csv/csv-parse-count-02.xml.res'
--- test/rbkt/ExpQueryResults/zorba/csv/csv-parse-count-02.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/csv/csv-parse-count-02.xml.res	2013-08-29 00:04:39 +0000
@@ -0,0 +1,1 @@
+4

=== added file 'test/rbkt/ExpQueryResults/zorba/csv/csv-parse-extra-name-01.xml.res'
--- test/rbkt/ExpQueryResults/zorba/csv/csv-parse-extra-name-01.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/csv/csv-parse-extra-name-01.xml.res	2013-08-29 00:04:39 +0000
@@ -0,0 +1,10 @@
+{
+  "first" : "one", 
+  "second" : "two", 
+  "third" : "three", 
+  "field4" : "four"
+}{
+  "first" : "last", 
+  "second" : "three", 
+  "third" : "fields"
+}

=== added file 'test/rbkt/ExpQueryResults/zorba/csv/csv-parse-extra-name-02.xml.res'
--- test/rbkt/ExpQueryResults/zorba/csv/csv-parse-extra-name-02.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/csv/csv-parse-extra-name-02.xml.res	2013-08-29 00:04:39 +0000
@@ -0,0 +1,10 @@
+{
+  "first" : "one", 
+  "second" : "two", 
+  "third" : "three", 
+  "field-4" : "four"
+}{
+  "first" : "last", 
+  "second" : "three", 
+  "third" : "fields"
+}

=== added file 'test/rbkt/ExpQueryResults/zorba/csv/csv-parse-field-names-01.xml.res'
--- test/rbkt/ExpQueryResults/zorba/csv/csv-parse-field-names-01.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/csv/csv-parse-field-names-01.xml.res	2013-08-29 00:04:39 +0000
@@ -0,0 +1,17 @@
+{
+  "first" : "one", 
+  "second" : "two", 
+  "third" : "three"
+}{
+  "first" : "quoted", 
+  "second" : "embedded \" quote", 
+  "third" : "embedded\r\nnewline"
+}{
+  "first" : "\" leading quote", 
+  "second" : "", 
+  "third" : "trailing quote \""
+}{
+  "first" : "last", 
+  "second" : "three", 
+  "third" : "fields"
+}

=== added file 'test/rbkt/ExpQueryResults/zorba/csv/csv-parse-missing-omit-01.xml.res'
--- test/rbkt/ExpQueryResults/zorba/csv/csv-parse-missing-omit-01.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/csv/csv-parse-missing-omit-01.xml.res	2013-08-29 00:04:39 +0000
@@ -0,0 +1,8 @@
+{
+  "second" : "two", 
+  "third" : "three"
+}{
+  "first" : "last", 
+  "second" : "three", 
+  "third" : "fields"
+}

=== added file 'test/rbkt/ExpQueryResults/zorba/csv/csv-parse-missing-omit-02.xml.res'
--- test/rbkt/ExpQueryResults/zorba/csv/csv-parse-missing-omit-02.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/csv/csv-parse-missing-omit-02.xml.res	2013-08-29 00:04:39 +0000
@@ -0,0 +1,8 @@
+{
+  "first" : "one", 
+  "third" : "three"
+}{
+  "first" : "last", 
+  "second" : "three", 
+  "third" : "fields"
+}

=== added file 'test/rbkt/ExpQueryResults/zorba/csv/csv-parse-missing-omit-03.xml.res'
--- test/rbkt/ExpQueryResults/zorba/csv/csv-parse-missing-omit-03.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/csv/csv-parse-missing-omit-03.xml.res	2013-08-29 00:04:39 +0000
@@ -0,0 +1,8 @@
+{
+  "first" : "one", 
+  "second" : "two"
+}{
+  "first" : "last", 
+  "second" : "three", 
+  "third" : "fields"
+}

=== added file 'test/rbkt/ExpQueryResults/zorba/csv/csv-parse-missing-omit-04.xml.res'
--- test/rbkt/ExpQueryResults/zorba/csv/csv-parse-missing-omit-04.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/csv/csv-parse-missing-omit-04.xml.res	2013-08-29 00:04:39 +0000
@@ -0,0 +1,8 @@
+{
+  "first" : "one", 
+  "second" : "two"
+}{
+  "first" : "last", 
+  "second" : "three", 
+  "third" : "fields"
+}

=== added file 'test/rbkt/ExpQueryResults/zorba/csv/csv-parse-quote-char-01.xml.res'
--- test/rbkt/ExpQueryResults/zorba/csv/csv-parse-quote-char-01.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/csv/csv-parse-quote-char-01.xml.res	2013-08-29 00:04:39 +0000
@@ -0,0 +1,17 @@
+{
+  "first" : "one", 
+  "second" : "two", 
+  "third" : "three"
+}{
+  "first" : "quoted", 
+  "second" : "embedded ' quote", 
+  "third" : "embedded\r\nnewline"
+}{
+  "first" : "' leading quote", 
+  "second" : "", 
+  "third" : "trailing quote '"
+}{
+  "first" : "last", 
+  "second" : "three", 
+  "third" : "fields"
+}

=== added file 'test/rbkt/ExpQueryResults/zorba/csv/csv-parse-quote-escape-01.xml.res'
--- test/rbkt/ExpQueryResults/zorba/csv/csv-parse-quote-escape-01.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/csv/csv-parse-quote-escape-01.xml.res	2013-08-29 00:04:39 +0000
@@ -0,0 +1,17 @@
+{
+  "first" : "one", 
+  "second" : "two", 
+  "third" : "three"
+}{
+  "first" : "quoted", 
+  "second" : "embedded \" quote", 
+  "third" : "embedded\r\nnewline"
+}{
+  "first" : "\" leading quote", 
+  "second" : "", 
+  "third" : "trailing quote \""
+}{
+  "first" : "last", 
+  "second" : "three", 
+  "third" : "fields"
+}

=== added file 'test/rbkt/ExpQueryResults/zorba/csv/csv-parse-separator-01.xml.res'
--- test/rbkt/ExpQueryResults/zorba/csv/csv-parse-separator-01.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/csv/csv-parse-separator-01.xml.res	2013-08-29 00:04:39 +0000
@@ -0,0 +1,17 @@
+{
+  "first" : "one", 
+  "second" : "two", 
+  "third" : "three"
+}{
+  "first" : "quoted", 
+  "second" : "embedded \" quote", 
+  "third" : "embedded\r\nnewline"
+}{
+  "first" : "\" leading quote", 
+  "second" : "", 
+  "third" : "trailing quote \""
+}{
+  "first" : "last", 
+  "second" : "three", 
+  "third" : "fields"
+}

=== added file 'test/rbkt/ExpQueryResults/zorba/csv/csv-parse-skip-01.xml.res'
--- test/rbkt/ExpQueryResults/zorba/csv/csv-parse-skip-01.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/csv/csv-parse-skip-01.xml.res	2013-08-29 00:04:39 +0000
@@ -0,0 +1,13 @@
+{
+  "first" : "quoted", 
+  "second" : "embedded \" quote", 
+  "third" : "embedded\r\nnewline"
+}{
+  "first" : "\" leading quote", 
+  "second" : "", 
+  "third" : "trailing quote \""
+}{
+  "first" : "last", 
+  "second" : "three", 
+  "third" : "fields"
+}

=== added file 'test/rbkt/ExpQueryResults/zorba/csv/csv-parse-skip-02.xml.res'
--- test/rbkt/ExpQueryResults/zorba/csv/csv-parse-skip-02.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/csv/csv-parse-skip-02.xml.res	2013-08-29 00:04:39 +0000
@@ -0,0 +1,9 @@
+{
+  "first" : "\" leading quote", 
+  "second" : "", 
+  "third" : "trailing quote \""
+}{
+  "first" : "last", 
+  "second" : "three", 
+  "third" : "fields"
+}

=== added file 'test/rbkt/ExpQueryResults/zorba/csv/csv-parse-skip-03.xml.res'
--- test/rbkt/ExpQueryResults/zorba/csv/csv-parse-skip-03.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/csv/csv-parse-skip-03.xml.res	2013-08-29 00:04:39 +0000
@@ -0,0 +1,5 @@
+{
+  "first" : "\" leading quote", 
+  "second" : "", 
+  "third" : "trailing quote \""
+}

=== added file 'test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-01.xml.res'
--- test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-01.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-01.xml.res	2013-08-29 00:04:39 +0000
@@ -0,0 +1,4 @@
+first,second,third
+one,two,three
+four,"embedded "" quote","embedded
+newline"

=== added file 'test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-boolean-01.xml.res'
--- test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-boolean-01.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-boolean-01.xml.res	2013-08-29 00:04:39 +0000
@@ -0,0 +1,2 @@
+b1,b2

+T,F


=== added file 'test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-header-01.xml.res'
--- test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-header-01.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-header-01.xml.res	2013-08-29 00:04:39 +0000
@@ -0,0 +1,2 @@
+one
+two

=== added file 'test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-null-01.xml.res'
--- test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-null-01.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-null-01.xml.res	2013-08-29 00:04:39 +0000
@@ -0,0 +1,2 @@
+foo,bar,baz
+f,null,b

=== added file 'test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-null-02.xml.res'
--- test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-null-02.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-null-02.xml.res	2013-08-29 00:04:39 +0000
@@ -0,0 +1,2 @@
+bar

+null


=== added file 'test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-null-03.xml.res'
--- test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-null-03.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-null-03.xml.res	2013-08-29 00:04:39 +0000
@@ -0,0 +1,2 @@
+foo,bar,baz

+f,,b


=== added file 'test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-null-04.xml.res'
--- test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-null-04.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-null-04.xml.res	2013-08-29 00:04:39 +0000
@@ -0,0 +1,2 @@
+bar

+


=== added file 'test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-quote-char-01.xml.res'
--- test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-quote-char-01.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-quote-char-01.xml.res	2013-08-29 00:04:39 +0000
@@ -0,0 +1,2 @@
+field

+'embedded , comma'


=== added file 'test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-quote-char-02.xml.res'
--- test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-quote-char-02.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-quote-char-02.xml.res	2013-08-29 00:04:39 +0000
@@ -0,0 +1,2 @@
+field

+'embedded '' quote'


=== added file 'test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-quote-escape-01.xml.res'
--- test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-quote-escape-01.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-quote-escape-01.xml.res	2013-08-29 00:04:39 +0000
@@ -0,0 +1,2 @@
+field

+'embedded \' quote'


=== added file 'test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-separator-01.xml.res'
--- test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-separator-01.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/csv/csv-serialize-separator-01.xml.res	2013-08-29 00:04:39 +0000
@@ -0,0 +1,4 @@
+first|second|third

+one|two|three

+four|"embedded "" quote"|"embedded
+newline"


=== added directory 'test/rbkt/Queries/zorba/csv'
=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-01.jq'
--- test/rbkt/Queries/zorba/csv/csv-parse-01.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-01.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,10 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+import module namespace file = "http://expath.org/ns/file";;
+
+declare variable $rbktPath as xs:string external;
+
+let $file := concat( $rbktPath, "/Queries/zorba/csv/sample_files/csv-01.txt" )
+let $values := file:read-text( $file )
+return csv:parse( $values )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-01.spec'
--- test/rbkt/Queries/zorba/csv/csv-parse-01.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-01.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,4 @@
+Serialization: indent=yes
+Args:
+-x
+rbktPath:=xs:string($RBKT_SRC_DIR)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-ZCSV0001-01.jq'
--- test/rbkt/Queries/zorba/csv/csv-parse-ZCSV0001-01.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-ZCSV0001-01.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,13 @@
+(: Test "quote-char" with a string > 1 character in length. :)
+
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+import module namespace file = "http://expath.org/ns/file";;
+
+declare variable $rbktPath as xs:string external;
+
+let $file := concat( $rbktPath, "/Queries/zorba/csv/sample_files/csv-quote-char-01.txt" )
+let $values := file:read-text( $file )
+let $options := { "quote-char" : "''" }
+return csv:parse( $values, $options )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-ZCSV0001-01.spec'
--- test/rbkt/Queries/zorba/csv/csv-parse-ZCSV0001-01.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-ZCSV0001-01.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,5 @@
+Error: http://zorba.io/errors:ZCSV0001
+Serialization: indent=yes
+Args:
+-x
+rbktPath:=xs:string($RBKT_SRC_DIR)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-ZCSV0001-02.jq'
--- test/rbkt/Queries/zorba/csv/csv-parse-ZCSV0001-02.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-ZCSV0001-02.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,13 @@
+(: Test "quote-char" with an ISO 8859-1 character. :)
+
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+import module namespace file = "http://expath.org/ns/file";;
+
+declare variable $rbktPath as xs:string external;
+
+let $file := concat( $rbktPath, "/Queries/zorba/csv/sample_files/csv-quote-char-01.txt" )
+let $values := file:read-text( $file )
+let $options := { "quote-char" : "�" }
+return csv:parse( $values, $options )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-ZCSV0001-02.spec'
--- test/rbkt/Queries/zorba/csv/csv-parse-ZCSV0001-02.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-ZCSV0001-02.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,5 @@
+Error: http://zorba.io/errors:ZCSV0001
+Serialization: indent=yes
+Args:
+-x
+rbktPath:=xs:string($RBKT_SRC_DIR)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-ZCSV0001-03.jq'
--- test/rbkt/Queries/zorba/csv/csv-parse-ZCSV0001-03.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-ZCSV0001-03.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,13 @@
+(: Test "quote-char" with a UTF-8 character. :)
+
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+import module namespace file = "http://expath.org/ns/file";;
+
+declare variable $rbktPath as xs:string external;
+
+let $file := concat( $rbktPath, "/Queries/zorba/csv/sample_files/csv-quote-char-01.txt" )
+let $values := file:read-text( $file )
+let $options := { "quote-char" : "¦" }
+return csv:parse( $values, $options )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-ZCSV0001-03.spec'
--- test/rbkt/Queries/zorba/csv/csv-parse-ZCSV0001-03.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-ZCSV0001-03.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,5 @@
+Error: http://zorba.io/errors:ZCSV0001
+Serialization: indent=yes
+Args:
+-x
+rbktPath:=xs:string($RBKT_SRC_DIR)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-ZCSV0001-04.jq'
--- test/rbkt/Queries/zorba/csv/csv-parse-ZCSV0001-04.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-ZCSV0001-04.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,13 @@
+(: Test a boolean option with a non-boolean value. :)
+
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+import module namespace file = "http://expath.org/ns/file";;
+
+declare variable $rbktPath as xs:string external;
+
+let $file := concat( $rbktPath, "/Queries/zorba/csv/sample_files/csv-quote-char-01.txt" )
+let $values := file:read-text( $file )
+let $options := { "cast-unquoted-values" : 1 }
+return csv:parse( $values, $options )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-ZCSV0001-04.spec'
--- test/rbkt/Queries/zorba/csv/csv-parse-ZCSV0001-04.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-ZCSV0001-04.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,5 @@
+Error: http://zorba.io/errors:ZCSV0001
+Serialization: indent=yes
+Args:
+-x
+rbktPath:=xs:string($RBKT_SRC_DIR)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-cast-01.jq'
--- test/rbkt/Queries/zorba/csv/csv-parse-cast-01.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-cast-01.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,10 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+import module namespace file = "http://expath.org/ns/file";;
+
+declare variable $rbktPath as xs:string external;
+
+let $file := concat( $rbktPath, "/Queries/zorba/csv/sample_files/csv-cast-01.txt" )
+let $values := file:read-text( $file )
+return csv:parse( $values )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-cast-01.spec'
--- test/rbkt/Queries/zorba/csv/csv-parse-cast-01.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-cast-01.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,4 @@
+Serialization: indent=yes
+Args:
+-x
+rbktPath:=xs:string($RBKT_SRC_DIR)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-cast-unquoted-01.jq'
--- test/rbkt/Queries/zorba/csv/csv-parse-cast-unquoted-01.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-cast-unquoted-01.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,11 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+import module namespace file = "http://expath.org/ns/file";;
+
+declare variable $rbktPath as xs:string external;
+
+let $file := concat( $rbktPath, "/Queries/zorba/csv/sample_files/csv-cast-01.txt" )
+let $values := file:read-text( $file )
+let $options := { "cast-unquoted-values" : false }
+return csv:parse( $values, $options )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-cast-unquoted-01.spec'
--- test/rbkt/Queries/zorba/csv/csv-parse-cast-unquoted-01.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-cast-unquoted-01.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,4 @@
+Serialization: indent=yes
+Args:
+-x
+rbktPath:=xs:string($RBKT_SRC_DIR)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-count-01.jq'
--- test/rbkt/Queries/zorba/csv/csv-parse-count-01.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-count-01.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,10 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+import module namespace file = "http://expath.org/ns/file";;
+
+declare variable $rbktPath as xs:string external;
+
+let $file := concat( $rbktPath, "/Queries/zorba/csv/sample_files/csv-01.txt" )
+let $values := file:read-text( $file )
+return count( csv:parse( $values ) )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-count-01.spec'
--- test/rbkt/Queries/zorba/csv/csv-parse-count-01.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-count-01.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,3 @@
+Args:
+-x
+rbktPath:=xs:string($RBKT_SRC_DIR)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-count-02.jq'
--- test/rbkt/Queries/zorba/csv/csv-parse-count-02.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-count-02.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,11 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+import module namespace file = "http://expath.org/ns/file";;
+
+declare variable $rbktPath as xs:string external;
+
+let $file := concat( $rbktPath, "/Queries/zorba/csv/sample_files/csv-no-field-names-01.txt" )
+let $values := file:read-text( $file )
+let $options := { "field-names" : [ "first", "second", "third" ] }
+return count( csv:parse( $values, $options ) )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-count-02.spec'
--- test/rbkt/Queries/zorba/csv/csv-parse-count-02.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-count-02.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,3 @@
+Args:
+-x
+rbktPath:=xs:string($RBKT_SRC_DIR)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-extra-name-01.jq'
--- test/rbkt/Queries/zorba/csv/csv-parse-extra-name-01.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-extra-name-01.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,11 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+import module namespace file = "http://expath.org/ns/file";;
+
+declare variable $rbktPath as xs:string external;
+
+let $file := concat( $rbktPath, "/Queries/zorba/csv/sample_files/csv-extra-01.txt" )
+let $values := file:read-text( $file )
+let $options := { "extra-name" : "field" }
+return csv:parse( $values, $options )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-extra-name-01.spec'
--- test/rbkt/Queries/zorba/csv/csv-parse-extra-name-01.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-extra-name-01.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,4 @@
+Serialization: indent=yes
+Args:
+-x
+rbktPath:=xs:string($RBKT_SRC_DIR)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-extra-name-02.jq'
--- test/rbkt/Queries/zorba/csv/csv-parse-extra-name-02.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-extra-name-02.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,11 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+import module namespace file = "http://expath.org/ns/file";;
+
+declare variable $rbktPath as xs:string external;
+
+let $file := concat( $rbktPath, "/Queries/zorba/csv/sample_files/csv-extra-01.txt" )
+let $values := file:read-text( $file )
+let $options := { "extra-name" : "field-#" }
+return csv:parse( $values, $options )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-extra-name-02.spec'
--- test/rbkt/Queries/zorba/csv/csv-parse-extra-name-02.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-extra-name-02.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,4 @@
+Serialization: indent=yes
+Args:
+-x
+rbktPath:=xs:string($RBKT_SRC_DIR)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-extra-name-03.jq'
--- test/rbkt/Queries/zorba/csv/csv-parse-extra-name-03.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-extra-name-03.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,10 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+import module namespace file = "http://expath.org/ns/file";;
+
+declare variable $rbktPath as xs:string external;
+
+let $file := concat( $rbktPath, "/Queries/zorba/csv/sample_files/csv-extra-01.txt" )
+let $values := file:read-text( $file )
+return csv:parse( $values )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-extra-name-03.spec'
--- test/rbkt/Queries/zorba/csv/csv-parse-extra-name-03.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-extra-name-03.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,5 @@
+Error: http://zorba.io/errors:ZCSV0003
+Serialization: indent=yes
+Args:
+-x
+rbktPath:=xs:string($RBKT_SRC_DIR)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-field-names-01.jq'
--- test/rbkt/Queries/zorba/csv/csv-parse-field-names-01.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-field-names-01.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,11 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+import module namespace file = "http://expath.org/ns/file";;
+
+declare variable $rbktPath as xs:string external;
+
+let $file := concat( $rbktPath, "/Queries/zorba/csv/sample_files/csv-no-field-names-01.txt" )
+let $values := file:read-text( $file )
+let $options := { "field-names" : [ "first", "second", "third" ] }
+return csv:parse( $values, $options )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-field-names-01.spec'
--- test/rbkt/Queries/zorba/csv/csv-parse-field-names-01.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-field-names-01.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,4 @@
+Serialization: indent=yes
+Args:
+-x
+rbktPath:=xs:string($RBKT_SRC_DIR)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-missing-error-01.jq'
--- test/rbkt/Queries/zorba/csv/csv-parse-missing-error-01.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-missing-error-01.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,11 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+import module namespace file = "http://expath.org/ns/file";;
+
+declare variable $rbktPath as xs:string external;
+
+let $file := concat( $rbktPath, "/Queries/zorba/csv/sample_files/csv-missing-01.txt" )
+let $values := file:read-text( $file )
+let $options := { "missing-value" : "error" }
+return csv:parse( $values, $options )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-missing-error-01.spec'
--- test/rbkt/Queries/zorba/csv/csv-parse-missing-error-01.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-missing-error-01.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,5 @@
+Error: http://zorba.io/errors:ZCSV0002
+Serialization: indent=yes
+Args:
+-x
+rbktPath:=xs:string($RBKT_SRC_DIR)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-missing-error-02.jq'
--- test/rbkt/Queries/zorba/csv/csv-parse-missing-error-02.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-missing-error-02.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,11 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+import module namespace file = "http://expath.org/ns/file";;
+
+declare variable $rbktPath as xs:string external;
+
+let $file := concat( $rbktPath, "/Queries/zorba/csv/sample_files/csv-missing-02.txt" )
+let $values := file:read-text( $file )
+let $options := { "missing-value" : "error" }
+return csv:parse( $values, $options )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-missing-error-02.spec'
--- test/rbkt/Queries/zorba/csv/csv-parse-missing-error-02.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-missing-error-02.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,5 @@
+Error: http://zorba.io/errors:ZCSV0002
+Serialization: indent=yes
+Args:
+-x
+rbktPath:=xs:string($RBKT_SRC_DIR)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-missing-error-03.jq'
--- test/rbkt/Queries/zorba/csv/csv-parse-missing-error-03.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-missing-error-03.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,11 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+import module namespace file = "http://expath.org/ns/file";;
+
+declare variable $rbktPath as xs:string external;
+
+let $file := concat( $rbktPath, "/Queries/zorba/csv/sample_files/csv-missing-03.txt" )
+let $values := file:read-text( $file )
+let $options := { "missing-value" : "error" }
+return csv:parse( $values, $options )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-missing-error-03.spec'
--- test/rbkt/Queries/zorba/csv/csv-parse-missing-error-03.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-missing-error-03.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,5 @@
+Error: http://zorba.io/errors:ZCSV0002
+Serialization: indent=yes
+Args:
+-x
+rbktPath:=xs:string($RBKT_SRC_DIR)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-missing-error-04.jq'
--- test/rbkt/Queries/zorba/csv/csv-parse-missing-error-04.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-missing-error-04.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,11 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+import module namespace file = "http://expath.org/ns/file";;
+
+declare variable $rbktPath as xs:string external;
+
+let $file := concat( $rbktPath, "/Queries/zorba/csv/sample_files/csv-missing-04.txt" )
+let $values := file:read-text( $file )
+let $options := { "missing-value" : "error" }
+return csv:parse( $values, $options )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-missing-error-04.spec'
--- test/rbkt/Queries/zorba/csv/csv-parse-missing-error-04.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-missing-error-04.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,5 @@
+Error: http://zorba.io/errors:ZCSV0002
+Serialization: indent=yes
+Args:
+-x
+rbktPath:=xs:string($RBKT_SRC_DIR)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-missing-omit-01.jq'
--- test/rbkt/Queries/zorba/csv/csv-parse-missing-omit-01.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-missing-omit-01.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,11 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+import module namespace file = "http://expath.org/ns/file";;
+
+declare variable $rbktPath as xs:string external;
+
+let $file := concat( $rbktPath, "/Queries/zorba/csv/sample_files/csv-missing-01.txt" )
+let $values := file:read-text( $file )
+let $options := { "missing-value" : "omit" }
+return csv:parse( $values, $options )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-missing-omit-01.spec'
--- test/rbkt/Queries/zorba/csv/csv-parse-missing-omit-01.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-missing-omit-01.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,4 @@
+Serialization: indent=yes
+Args:
+-x
+rbktPath:=xs:string($RBKT_SRC_DIR)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-missing-omit-02.jq'
--- test/rbkt/Queries/zorba/csv/csv-parse-missing-omit-02.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-missing-omit-02.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,11 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+import module namespace file = "http://expath.org/ns/file";;
+
+declare variable $rbktPath as xs:string external;
+
+let $file := concat( $rbktPath, "/Queries/zorba/csv/sample_files/csv-missing-02.txt" )
+let $values := file:read-text( $file )
+let $options := { "missing-value" : "omit" }
+return csv:parse( $values, $options )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-missing-omit-02.spec'
--- test/rbkt/Queries/zorba/csv/csv-parse-missing-omit-02.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-missing-omit-02.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,4 @@
+Serialization: indent=yes
+Args:
+-x
+rbktPath:=xs:string($RBKT_SRC_DIR)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-missing-omit-03.jq'
--- test/rbkt/Queries/zorba/csv/csv-parse-missing-omit-03.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-missing-omit-03.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,11 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+import module namespace file = "http://expath.org/ns/file";;
+
+declare variable $rbktPath as xs:string external;
+
+let $file := concat( $rbktPath, "/Queries/zorba/csv/sample_files/csv-missing-03.txt" )
+let $values := file:read-text( $file )
+let $options := { "missing-value" : "omit" }
+return csv:parse( $values, $options )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-missing-omit-03.spec'
--- test/rbkt/Queries/zorba/csv/csv-parse-missing-omit-03.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-missing-omit-03.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,4 @@
+Serialization: indent=yes
+Args:
+-x
+rbktPath:=xs:string($RBKT_SRC_DIR)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-missing-omit-04.jq'
--- test/rbkt/Queries/zorba/csv/csv-parse-missing-omit-04.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-missing-omit-04.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,11 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+import module namespace file = "http://expath.org/ns/file";;
+
+declare variable $rbktPath as xs:string external;
+
+let $file := concat( $rbktPath, "/Queries/zorba/csv/sample_files/csv-missing-04.txt" )
+let $values := file:read-text( $file )
+let $options := { "missing-value" : "omit" }
+return csv:parse( $values, $options )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-missing-omit-04.spec'
--- test/rbkt/Queries/zorba/csv/csv-parse-missing-omit-04.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-missing-omit-04.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,4 @@
+Serialization: indent=yes
+Args:
+-x
+rbktPath:=xs:string($RBKT_SRC_DIR)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-quote-char-01.jq'
--- test/rbkt/Queries/zorba/csv/csv-parse-quote-char-01.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-quote-char-01.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,11 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+import module namespace file = "http://expath.org/ns/file";;
+
+declare variable $rbktPath as xs:string external;
+
+let $file := concat( $rbktPath, "/Queries/zorba/csv/sample_files/csv-quote-char-01.txt" )
+let $values := file:read-text( $file )
+let $options := { "quote-char" : "'" }
+return csv:parse( $values, $options )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-quote-char-01.spec'
--- test/rbkt/Queries/zorba/csv/csv-parse-quote-char-01.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-quote-char-01.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,4 @@
+Serialization: indent=yes
+Args:
+-x
+rbktPath:=xs:string($RBKT_SRC_DIR)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-quote-escape-01.jq'
--- test/rbkt/Queries/zorba/csv/csv-parse-quote-escape-01.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-quote-escape-01.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,11 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+import module namespace file = "http://expath.org/ns/file";;
+
+declare variable $rbktPath as xs:string external;
+
+let $file := concat( $rbktPath, "/Queries/zorba/csv/sample_files/csv-quote-escape-01.txt" )
+let $values := file:read-text( $file )
+let $options := { "quote-escape" : "\\" }
+return csv:parse( $values, $options )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-quote-escape-01.spec'
--- test/rbkt/Queries/zorba/csv/csv-parse-quote-escape-01.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-quote-escape-01.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,4 @@
+Serialization: indent=yes
+Args:
+-x
+rbktPath:=xs:string($RBKT_SRC_DIR)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-separator-01.jq'
--- test/rbkt/Queries/zorba/csv/csv-parse-separator-01.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-separator-01.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,11 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+import module namespace file = "http://expath.org/ns/file";;
+
+declare variable $rbktPath as xs:string external;
+
+let $file := concat( $rbktPath, "/Queries/zorba/csv/sample_files/csv-separator-01.txt" )
+let $values := file:read-text( $file )
+let $options := { "separator" : "|" }
+return csv:parse( $values, $options )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-separator-01.spec'
--- test/rbkt/Queries/zorba/csv/csv-parse-separator-01.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-separator-01.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,4 @@
+Serialization: indent=yes
+Args:
+-x
+rbktPath:=xs:string($RBKT_SRC_DIR)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-skip-01.jq'
--- test/rbkt/Queries/zorba/csv/csv-parse-skip-01.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-skip-01.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,10 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+import module namespace file = "http://expath.org/ns/file";;
+
+declare variable $rbktPath as xs:string external;
+
+let $file := concat( $rbktPath, "/Queries/zorba/csv/sample_files/csv-01.txt" )
+let $values := file:read-text( $file )
+return subsequence( csv:parse( $values ), 2 )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-skip-01.spec'
--- test/rbkt/Queries/zorba/csv/csv-parse-skip-01.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-skip-01.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,4 @@
+Serialization: indent=yes
+Args:
+-x
+rbktPath:=xs:string($RBKT_SRC_DIR)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-skip-02.jq'
--- test/rbkt/Queries/zorba/csv/csv-parse-skip-02.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-skip-02.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,10 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+import module namespace file = "http://expath.org/ns/file";;
+
+declare variable $rbktPath as xs:string external;
+
+let $file := concat( $rbktPath, "/Queries/zorba/csv/sample_files/csv-01.txt" )
+let $values := file:read-text( $file )
+return subsequence( csv:parse( $values ), 3 )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-skip-02.spec'
--- test/rbkt/Queries/zorba/csv/csv-parse-skip-02.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-skip-02.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,4 @@
+Serialization: indent=yes
+Args:
+-x
+rbktPath:=xs:string($RBKT_SRC_DIR)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-skip-03.jq'
--- test/rbkt/Queries/zorba/csv/csv-parse-skip-03.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-skip-03.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,10 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+import module namespace file = "http://expath.org/ns/file";;
+
+declare variable $rbktPath as xs:string external;
+
+let $file := concat( $rbktPath, "/Queries/zorba/csv/sample_files/csv-01.txt" )
+let $values := file:read-text( $file )
+return subsequence( csv:parse( $values ), 3, 1 )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-parse-skip-03.spec'
--- test/rbkt/Queries/zorba/csv/csv-parse-skip-03.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-parse-skip-03.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,4 @@
+Serialization: indent=yes
+Args:
+-x
+rbktPath:=xs:string($RBKT_SRC_DIR)

=== added file 'test/rbkt/Queries/zorba/csv/csv-serialize-01.jq'
--- test/rbkt/Queries/zorba/csv/csv-serialize-01.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-serialize-01.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,18 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+
+let $values := (
+  {
+    "first" : "one",
+    "second" : "two",
+    "third" : "three"
+  },
+  {
+    "first" : "four",
+    "second" : "embedded \" quote",
+    "third" : "embedded\r\nnewline"
+  }
+)
+let $options := { "field-names" : [ "first", "second", "third" ] }
+return string-join( csv:serialize( $values, $options ), "" )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-serialize-01.spec'
--- test/rbkt/Queries/zorba/csv/csv-serialize-01.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-serialize-01.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,1 @@
+Serialization: method=text

=== added file 'test/rbkt/Queries/zorba/csv/csv-serialize-boolean-01.jq'
--- test/rbkt/Queries/zorba/csv/csv-serialize-boolean-01.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-serialize-boolean-01.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,15 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+
+let $values := (
+  {
+    "b1" : true,
+    "b2" : false
+  }
+)
+let $options := {
+  "field-names" : [ "b1", "b2" ],
+  "serialize-boolean-as" : { "true" : "T", "false" : "F" }
+}
+return string-join( csv:serialize( $values, $options ), "" )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-serialize-boolean-01.spec'
--- test/rbkt/Queries/zorba/csv/csv-serialize-boolean-01.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-serialize-boolean-01.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,1 @@
+Serialization: method=text

=== added file 'test/rbkt/Queries/zorba/csv/csv-serialize-header-01.jq'
--- test/rbkt/Queries/zorba/csv/csv-serialize-header-01.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-serialize-header-01.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,10 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+
+let $values := (
+  { "field" : "one" },
+  { "field" : "two" }
+)
+let $options := { "serialize-header" : false }
+return string-join( csv:serialize( $values, $options ), "" )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-serialize-header-01.spec'
--- test/rbkt/Queries/zorba/csv/csv-serialize-header-01.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-serialize-header-01.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,1 @@
+Serialization: method=text

=== added file 'test/rbkt/Queries/zorba/csv/csv-serialize-null-01.jq'
--- test/rbkt/Queries/zorba/csv/csv-serialize-null-01.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-serialize-null-01.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,16 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+
+let $values := (
+  {
+    "foo" : "f",
+    "bar" : null,
+    "baz" : "b"
+  }
+)
+let $options := {
+  "field-names" : [ "foo", "bar", "baz" ],
+  "serialize-null-as" : "null"
+}
+return string-join( csv:serialize( $values, $options ), "" )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-serialize-null-01.spec'
--- test/rbkt/Queries/zorba/csv/csv-serialize-null-01.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-serialize-null-01.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,1 @@
+Serialization: method=text

=== added file 'test/rbkt/Queries/zorba/csv/csv-serialize-null-02.jq'
--- test/rbkt/Queries/zorba/csv/csv-serialize-null-02.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-serialize-null-02.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,13 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+
+let $values := (
+  {
+    "bar" : null
+  }
+)
+let $options := {
+  "serialize-null-as" : "null"
+}
+return string-join( csv:serialize( $values, $options ), "" )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-serialize-null-02.spec'
--- test/rbkt/Queries/zorba/csv/csv-serialize-null-02.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-serialize-null-02.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,1 @@
+Serialization: method=text

=== added file 'test/rbkt/Queries/zorba/csv/csv-serialize-null-03.jq'
--- test/rbkt/Queries/zorba/csv/csv-serialize-null-03.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-serialize-null-03.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,16 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+
+let $values := (
+  {
+    "foo" : "f",
+    "bar" : null,
+    "baz" : "b"
+  }
+)
+let $options := {
+  "field-names" : [ "foo", "bar", "baz" ],
+  "serialize-null-as" : ""
+}
+return string-join( csv:serialize( $values, $options ), "" )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-serialize-null-03.spec'
--- test/rbkt/Queries/zorba/csv/csv-serialize-null-03.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-serialize-null-03.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,1 @@
+Serialization: method=text

=== added file 'test/rbkt/Queries/zorba/csv/csv-serialize-null-04.jq'
--- test/rbkt/Queries/zorba/csv/csv-serialize-null-04.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-serialize-null-04.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,13 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+
+let $values := (
+  {
+    "bar" : null
+  }
+)
+let $options := {
+  "serialize-null-as" : ""
+}
+return string-join( csv:serialize( $values, $options ), "" )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-serialize-null-04.spec'
--- test/rbkt/Queries/zorba/csv/csv-serialize-null-04.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-serialize-null-04.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,1 @@
+Serialization: method=text

=== added file 'test/rbkt/Queries/zorba/csv/csv-serialize-quote-char-01.jq'
--- test/rbkt/Queries/zorba/csv/csv-serialize-quote-char-01.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-serialize-quote-char-01.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,9 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+
+let $values := (
+  { "field" : "embedded , comma" }
+)
+let $options := { "quote-char" : "'" }
+return string-join( csv:serialize( $values, $options ), "" )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-serialize-quote-char-01.spec'
--- test/rbkt/Queries/zorba/csv/csv-serialize-quote-char-01.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-serialize-quote-char-01.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,1 @@
+Serialization: method=text

=== added file 'test/rbkt/Queries/zorba/csv/csv-serialize-quote-char-02.jq'
--- test/rbkt/Queries/zorba/csv/csv-serialize-quote-char-02.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-serialize-quote-char-02.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,9 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+
+let $values := (
+  { "field" : "embedded ' quote" }
+)
+let $options := { "quote-char" : "'" }
+return string-join( csv:serialize( $values, $options ), "" )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-serialize-quote-char-02.spec'
--- test/rbkt/Queries/zorba/csv/csv-serialize-quote-char-02.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-serialize-quote-char-02.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,1 @@
+Serialization: method=text

=== added file 'test/rbkt/Queries/zorba/csv/csv-serialize-quote-escape-01.jq'
--- test/rbkt/Queries/zorba/csv/csv-serialize-quote-escape-01.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-serialize-quote-escape-01.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,9 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+
+let $values := (
+  { "field" : "embedded ' quote" }
+)
+let $options := { "quote-char" : "'", "quote-escape" : "\\" }
+return string-join( csv:serialize( $values, $options ), "" )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-serialize-quote-escape-01.spec'
--- test/rbkt/Queries/zorba/csv/csv-serialize-quote-escape-01.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-serialize-quote-escape-01.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,1 @@
+Serialization: method=text

=== added file 'test/rbkt/Queries/zorba/csv/csv-serialize-separator-01.jq'
--- test/rbkt/Queries/zorba/csv/csv-serialize-separator-01.jq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-serialize-separator-01.jq	2013-08-29 00:04:39 +0000
@@ -0,0 +1,21 @@
+import module namespace csv = "http://zorba.io/modules/json-csv";;
+
+let $values := (
+  {
+    "first" : "one",
+    "second" : "two",
+    "third" : "three"
+  },
+  {
+    "first" : "four",
+    "second" : "embedded \" quote",
+    "third" : "embedded\r\nnewline"
+  }
+)
+let $options := {
+  "field-names" : [ "first", "second", "third" ],
+  "separator" : "|"
+}
+return string-join( csv:serialize( $values, $options ), "" )
+
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== added file 'test/rbkt/Queries/zorba/csv/csv-serialize-separator-01.spec'
--- test/rbkt/Queries/zorba/csv/csv-serialize-separator-01.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/csv-serialize-separator-01.spec	2013-08-29 00:04:39 +0000
@@ -0,0 +1,1 @@
+Serialization: method=text

=== added directory 'test/rbkt/Queries/zorba/csv/sample_files'
=== added file 'test/rbkt/Queries/zorba/csv/sample_files/csv-01.txt'
--- test/rbkt/Queries/zorba/csv/sample_files/csv-01.txt	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/sample_files/csv-01.txt	2013-08-29 00:04:39 +0000
@@ -0,0 +1,6 @@
+first,second,third
+one,two,three
+"quoted","embedded "" quote","embedded
+newline"
+""" leading quote","","trailing quote """
+last,three,fields

=== added file 'test/rbkt/Queries/zorba/csv/sample_files/csv-cast-01.txt'
--- test/rbkt/Queries/zorba/csv/sample_files/csv-cast-01.txt	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/sample_files/csv-cast-01.txt	2013-08-29 00:04:39 +0000
@@ -0,0 +1,2 @@
+string,integer,decimal,double,boolean,null
+foo,42,98.6,1E4,false,null

=== added file 'test/rbkt/Queries/zorba/csv/sample_files/csv-extra-01.txt'
--- test/rbkt/Queries/zorba/csv/sample_files/csv-extra-01.txt	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/sample_files/csv-extra-01.txt	2013-08-29 00:04:39 +0000
@@ -0,0 +1,3 @@
+first,second,third
+one,two,three,four
+last,three,fields

=== added file 'test/rbkt/Queries/zorba/csv/sample_files/csv-missing-01.txt'
--- test/rbkt/Queries/zorba/csv/sample_files/csv-missing-01.txt	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/sample_files/csv-missing-01.txt	2013-08-29 00:04:39 +0000
@@ -0,0 +1,3 @@
+first,second,third
+,two,three
+last,three,fields

=== added file 'test/rbkt/Queries/zorba/csv/sample_files/csv-missing-02.txt'
--- test/rbkt/Queries/zorba/csv/sample_files/csv-missing-02.txt	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/sample_files/csv-missing-02.txt	2013-08-29 00:04:39 +0000
@@ -0,0 +1,3 @@
+first,second,third
+one,,three
+last,three,fields

=== added file 'test/rbkt/Queries/zorba/csv/sample_files/csv-missing-03.txt'
--- test/rbkt/Queries/zorba/csv/sample_files/csv-missing-03.txt	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/sample_files/csv-missing-03.txt	2013-08-29 00:04:39 +0000
@@ -0,0 +1,3 @@
+first,second,third
+one,two,
+last,three,fields

=== added file 'test/rbkt/Queries/zorba/csv/sample_files/csv-missing-04.txt'
--- test/rbkt/Queries/zorba/csv/sample_files/csv-missing-04.txt	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/sample_files/csv-missing-04.txt	2013-08-29 00:04:39 +0000
@@ -0,0 +1,3 @@
+first,second,third
+one,two
+last,three,fields

=== added file 'test/rbkt/Queries/zorba/csv/sample_files/csv-no-field-names-01.txt'
--- test/rbkt/Queries/zorba/csv/sample_files/csv-no-field-names-01.txt	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/sample_files/csv-no-field-names-01.txt	2013-08-29 00:04:39 +0000
@@ -0,0 +1,5 @@
+one,two,three
+"quoted","embedded "" quote","embedded
+newline"
+""" leading quote","","trailing quote """
+last,three,fields

=== added file 'test/rbkt/Queries/zorba/csv/sample_files/csv-quote-char-01.txt'
--- test/rbkt/Queries/zorba/csv/sample_files/csv-quote-char-01.txt	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/sample_files/csv-quote-char-01.txt	2013-08-29 00:04:39 +0000
@@ -0,0 +1,6 @@
+first,second,third
+one,two,three
+'quoted','embedded '' quote','embedded
+newline'
+''' leading quote','','trailing quote '''
+last,three,fields

=== added file 'test/rbkt/Queries/zorba/csv/sample_files/csv-quote-escape-01.txt'
--- test/rbkt/Queries/zorba/csv/sample_files/csv-quote-escape-01.txt	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/sample_files/csv-quote-escape-01.txt	2013-08-29 00:04:39 +0000
@@ -0,0 +1,6 @@
+first,second,third
+one,two,three
+"quoted","embedded \" quote","embedded
+newline"
+"\" leading quote","","trailing quote \""
+last,three,fields

=== added file 'test/rbkt/Queries/zorba/csv/sample_files/csv-separator-01.txt'
--- test/rbkt/Queries/zorba/csv/sample_files/csv-separator-01.txt	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/csv/sample_files/csv-separator-01.txt	2013-08-29 00:04:39 +0000
@@ -0,0 +1,6 @@
+first|second|third
+one|two|three
+"quoted"|"embedded "" quote"|"embedded
+newline"
+""" leading quote"|""|"trailing quote """
+last|three|fields


Follow ups