JSONiq object parser, constructor, and printer with test cases.
diff --git a/pom.xml b/pom.xml
index a082505..0d06a71 100644
--- a/pom.xml
+++ b/pom.xml
@@ -573,6 +573,7 @@
                         <exclude>.basex</exclude>
                         <exclude>**/ExpectedTestResults/**</exclude>
                         <exclude>**/xqts.txt</exclude>
+                        <exclude>test-suite*/**/*</exclude>
                     </excludes>
                 </configuration>
             </plugin>
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/datamodel/accessors/PointablePoolFactory.java b/vxquery-core/src/main/java/org/apache/vxquery/datamodel/accessors/PointablePoolFactory.java
index 9f440d4..3db4c3b 100644
--- a/vxquery-core/src/main/java/org/apache/vxquery/datamodel/accessors/PointablePoolFactory.java
+++ b/vxquery-core/src/main/java/org/apache/vxquery/datamodel/accessors/PointablePoolFactory.java
@@ -24,6 +24,7 @@
 import org.apache.vxquery.datamodel.accessors.atomic.XSDurationPointable;
 import org.apache.vxquery.datamodel.accessors.atomic.XSQNamePointable;
 import org.apache.vxquery.datamodel.accessors.atomic.XSTimePointable;
+import org.apache.vxquery.datamodel.accessors.jsonitem.ObjectPointable;
 import org.apache.vxquery.datamodel.accessors.jsonitem.ArrayPointable;
 import org.apache.vxquery.datamodel.accessors.nodes.AttributeNodePointable;
 import org.apache.vxquery.datamodel.accessors.nodes.DocumentNodePointable;
@@ -74,11 +75,13 @@
         pp.register(NodeTreePointable.class, NodeTreePointable.FACTORY);
         pp.register(DocumentNodePointable.class, DocumentNodePointable.FACTORY);
         pp.register(ElementNodePointable.class, ElementNodePointable.FACTORY);
-        pp.register(ArrayPointable.class, ArrayPointable.FACTORY);
         pp.register(AttributeNodePointable.class, AttributeNodePointable.FACTORY);
         pp.register(TextOrCommentNodePointable.class, TextOrCommentNodePointable.FACTORY);
         pp.register(PINodePointable.class, PINodePointable.FACTORY);
 
+        pp.register(ArrayPointable.class, ArrayPointable.FACTORY);
+        pp.register(ObjectPointable.class, ObjectPointable.FACTORY);
+
         return pp;
     }
 }
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/datamodel/accessors/jsonitem/ObjectPointable.java b/vxquery-core/src/main/java/org/apache/vxquery/datamodel/accessors/jsonitem/ObjectPointable.java
index 9c714ec..720f438 100644
--- a/vxquery-core/src/main/java/org/apache/vxquery/datamodel/accessors/jsonitem/ObjectPointable.java
+++ b/vxquery-core/src/main/java/org/apache/vxquery/datamodel/accessors/jsonitem/ObjectPointable.java
@@ -93,6 +93,7 @@
         result.set(abvs);
     }
 
+    //here the UTF8StringPointable of key is without the tag
     public boolean getValue(UTF8StringPointable key, IPointable result) {
         int dataAreaOffset = getDataAreaOffset(bytes, start);
         int entryCount = getEntryCount();
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/exceptions/ErrorCode.java b/vxquery-core/src/main/java/org/apache/vxquery/exceptions/ErrorCode.java
index 302ba9e..a10db97 100644
--- a/vxquery-core/src/main/java/org/apache/vxquery/exceptions/ErrorCode.java
+++ b/vxquery-core/src/main/java/org/apache/vxquery/exceptions/ErrorCode.java
@@ -16,10 +16,10 @@
  */
 package org.apache.vxquery.exceptions;
 
-import javax.xml.namespace.QName;
-
 import org.apache.vxquery.xmlquery.query.XQueryConstants;
 
+import javax.xml.namespace.QName;
+
 public enum ErrorCode {
     XPST0001(new QName(XQueryConstants.ERR_NSURI, "XPST0001"), ErrorMessages.ERR_XPST0001_DESCRIPTION),
     XPDY0002(new QName(XQueryConstants.ERR_NSURI, "XPDY0002"), ErrorMessages.ERR_XPDY0002_DESCRIPTION),
@@ -149,10 +149,31 @@
     FORX0004(new QName(XQueryConstants.ERR_NSURI, "FORX0004"), ErrorMessages.ERR_FORX0004_DESCRIPTION),
     FOTY0012(new QName(XQueryConstants.ERR_NSURI, "FOTY0012"), ErrorMessages.ERR_FOTY0012_DESCRIPTION),
 
+    JNDY0003(new QName(XQueryConstants.ERR_NSURI, "JNDY0003"), ErrorMessages.ERR_JNDY0003_DESCRIPTION),
+    JNTY0004(new QName(XQueryConstants.ERR_NSURI, "JNTY0004"), ErrorMessages.ERR_JNTY0004_DESCRIPTION),
+    JNUP0005(new QName(XQueryConstants.ERR_NSURI, "JNUP0005"), ErrorMessages.ERR_JNUP0005_DESCRIPTION),
+    JNUP0006(new QName(XQueryConstants.ERR_NSURI, "JNUP0006"), ErrorMessages.ERR_JNUP0006_DESCRIPTION),
+    JNUP0007(new QName(XQueryConstants.ERR_NSURI, "JNUP0007"), ErrorMessages.ERR_JNUP0007_DESCRIPTION),
+    JNUP0008(new QName(XQueryConstants.ERR_NSURI, "JNUP0008"), ErrorMessages.ERR_JNUP0008_DESCRIPTION),
+    JNUP0009(new QName(XQueryConstants.ERR_NSURI, "JNUP0009"), ErrorMessages.ERR_JNUP0009_DESCRIPTION),
+    JNUP0010(new QName(XQueryConstants.ERR_NSURI, "JNUP0010"), ErrorMessages.ERR_JNUP0010_DESCRIPTION),
+    JNTY0011(new QName(XQueryConstants.ERR_NSURI, "JNTY0011"), ErrorMessages.ERR_JNTY0011_DESCRIPTION),
+    JNSE0012(new QName(XQueryConstants.ERR_NSURI, "JNSE0012"), ErrorMessages.ERR_JNSE0012_DESCRIPTION),
+    JNSE0014(new QName(XQueryConstants.ERR_NSURI, "JNSE0014"), ErrorMessages.ERR_JNSE0014_DESCRIPTION),
+    JNSE0015(new QName(XQueryConstants.ERR_NSURI, "JNSE0015"), ErrorMessages.ERR_JNSE0015_DESCRIPTION),
+    JNUP0016(new QName(XQueryConstants.ERR_NSURI, "JNUP0016"), ErrorMessages.ERR_JNUP0016_DESCRIPTION),
+    JNTY0018(new QName(XQueryConstants.ERR_NSURI, "JNTY0018"), ErrorMessages.ERR_JNTY0018_DESCRIPTION),
+    JNUP0019(new QName(XQueryConstants.ERR_NSURI, "JNUP0019"), ErrorMessages.ERR_JNUP0019_DESCRIPTION),
+    JNTY0020(new QName(XQueryConstants.ERR_NSURI, "JNTY0020"), ErrorMessages.ERR_JNTY0020_DESCRIPTION),
+    JNDY0021(new QName(XQueryConstants.ERR_NSURI, "JNDY0021"), ErrorMessages.ERR_JNDY0021_DESCRIPTION),
+    JNSE0022(new QName(XQueryConstants.ERR_NSURI, "JNSE0022"), ErrorMessages.ERR_JNSE0022_DESCRIPTION),
+    JNTY0023(new QName(XQueryConstants.ERR_NSURI, "JNTY0023"), ErrorMessages.ERR_JNTY0023_DESCRIPTION),
+    JNTY0024(new QName(XQueryConstants.ERR_NSURI, "JNDY0024"), ErrorMessages.ERR_JNTY0024_DESCRIPTION),
+
     SYSE0001(new QName(XQueryConstants.ERR_NSURI, "SYSE0001"), ErrorMessages.ERR_SYSE0001_DESCRIPTION),
     TODO(new QName(XQueryConstants.ERR_NSURI, "TODO"), ErrorMessages.ERR_TODO_DESCRIPTION),
     ;
-    
+
     private QName qname;
     private String description;
 
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/exceptions/ErrorMessages.java b/vxquery-core/src/main/java/org/apache/vxquery/exceptions/ErrorMessages.java
index 8b9fe97..42242e7 100644
--- a/vxquery-core/src/main/java/org/apache/vxquery/exceptions/ErrorMessages.java
+++ b/vxquery-core/src/main/java/org/apache/vxquery/exceptions/ErrorMessages.java
@@ -181,6 +181,27 @@
     public static String ERR_FORX0004_DESCRIPTION;
     public static String ERR_FOTY0012_DESCRIPTION;
 
+    public static String ERR_JNDY0003_DESCRIPTION;
+    public static String ERR_JNTY0004_DESCRIPTION;
+    public static String ERR_JNUP0005_DESCRIPTION;
+    public static String ERR_JNUP0006_DESCRIPTION;
+    public static String ERR_JNUP0007_DESCRIPTION;
+    public static String ERR_JNUP0008_DESCRIPTION;
+    public static String ERR_JNUP0009_DESCRIPTION;
+    public static String ERR_JNUP0010_DESCRIPTION;
+    public static String ERR_JNTY0011_DESCRIPTION;
+    public static String ERR_JNSE0012_DESCRIPTION;
+    public static String ERR_JNSE0014_DESCRIPTION;
+    public static String ERR_JNSE0015_DESCRIPTION;
+    public static String ERR_JNUP0016_DESCRIPTION;
+    public static String ERR_JNTY0018_DESCRIPTION;
+    public static String ERR_JNUP0019_DESCRIPTION;
+    public static String ERR_JNTY0020_DESCRIPTION;
+    public static String ERR_JNDY0021_DESCRIPTION;
+    public static String ERR_JNSE0022_DESCRIPTION;
+    public static String ERR_JNTY0023_DESCRIPTION;
+    public static String ERR_JNTY0024_DESCRIPTION;
+
     public static String ERR_SYSE0001_DESCRIPTION;
     public static String ERR_TODO_DESCRIPTION;
 }
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/functions/builtin-operators.xml b/vxquery-core/src/main/java/org/apache/vxquery/functions/builtin-operators.xml
index 05582e8..e89d619 100644
--- a/vxquery-core/src/main/java/org/apache/vxquery/functions/builtin-operators.xml
+++ b/vxquery-core/src/main/java/org/apache/vxquery/functions/builtin-operators.xml
@@ -731,7 +731,7 @@
             <argument value="0"/>
         </property>
     </operator>
-    
+
     <!-- opext:sort-distinct-nodes-asc-or-atomics($arg as item()*) as item()* -->
     <operator name="opext:sort-distinct-nodes-asc-or-atomics">
         <param name="arg" type="item()*"/>
@@ -852,12 +852,19 @@
         <param name="content" type="node()"/>
         <return type="node()"/>
     </operator>
-    
-    <!-- opext:array-constructor($expression as node()) as node() -->
+
+    <!-- opext:array-constructor($expression as item()*) as array() -->
     <operator name="opext:array-constructor">
-        <param name="expession" type="node()"/>
+        <param name="expression" type="item()*"/>
         <return type="item()"/>
-        <runtime type="scalar" class="org.apache.vxquery.runtime.functions.node.ArrayConstructorScalarEvaluatorFactory"/>
+        <runtime type="scalar" class="org.apache.vxquery.runtime.functions.jsonitem.ArrayConstructorScalarEvaluatorFactory"/>
+    </operator>
+
+    <!-- opext:object-constructor($expression as item()*) as object() -->
+    <operator name="opext:object-constructor">
+        <param name="expression" type="item()*"/>
+        <return type="item()"/>
+        <runtime type="scalar" class="org.apache.vxquery.runtime.functions.jsonitem.ObjectConstructorScalarEvaluatorFactory"/>
     </operator>
 
     <!-- opext:if-then-else($condition as xs:boolean, $then as item()*, $else as item()*) as item()* -->
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/ArrayConstructorScalarEvaluator.java b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/jsonitem/ArrayConstructorScalarEvaluator.java
similarity index 97%
rename from vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/ArrayConstructorScalarEvaluator.java
rename to vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/jsonitem/ArrayConstructorScalarEvaluator.java
index 7386ce9..541a44c 100644
--- a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/ArrayConstructorScalarEvaluator.java
+++ b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/jsonitem/ArrayConstructorScalarEvaluator.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.vxquery.runtime.functions.node;
+package org.apache.vxquery.runtime.functions.jsonitem;
 
 import java.io.IOException;
 
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/ArrayConstructorScalarEvaluatorFactory.java b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/jsonitem/ArrayConstructorScalarEvaluatorFactory.java
similarity index 96%
rename from vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/ArrayConstructorScalarEvaluatorFactory.java
rename to vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/jsonitem/ArrayConstructorScalarEvaluatorFactory.java
index c70a8e2..7b0b379 100644
--- a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/ArrayConstructorScalarEvaluatorFactory.java
+++ b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/jsonitem/ArrayConstructorScalarEvaluatorFactory.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.vxquery.runtime.functions.node;
+package org.apache.vxquery.runtime.functions.jsonitem;
 
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/jsonitem/ObjectConstructorScalarEvaluator.java b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/jsonitem/ObjectConstructorScalarEvaluator.java
new file mode 100644
index 0000000..edfa883
--- /dev/null
+++ b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/jsonitem/ObjectConstructorScalarEvaluator.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.vxquery.runtime.functions.jsonitem;
+
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
+import org.apache.hyracks.data.std.primitive.VoidPointable;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
+import org.apache.vxquery.datamodel.accessors.SequencePointable;
+import org.apache.vxquery.datamodel.accessors.TaggedValuePointable;
+import org.apache.vxquery.datamodel.builders.jsonitem.ObjectBuilder;
+import org.apache.vxquery.datamodel.values.ValueTag;
+import org.apache.vxquery.exceptions.ErrorCode;
+import org.apache.vxquery.exceptions.SystemException;
+import org.apache.vxquery.runtime.functions.base.AbstractTaggedValueArgumentScalarEvaluator;
+import org.apache.vxquery.runtime.functions.util.FunctionHelper;
+
+import java.io.IOException;
+
+public class ObjectConstructorScalarEvaluator extends AbstractTaggedValueArgumentScalarEvaluator {
+    private ObjectBuilder ob;
+    private TaggedValuePointable[] pointables;
+    private IPointable vp;
+    private UTF8StringPointable sp;
+    private SequencePointable seqp;
+    protected final IHyracksTaskContext ctx;
+    private final ArrayBackedValueStorage abvs;
+
+    public ObjectConstructorScalarEvaluator(IHyracksTaskContext ctx, IScalarEvaluator[] args) {
+        super(args);
+        this.ctx = ctx;
+        abvs = new ArrayBackedValueStorage();
+        ob = new ObjectBuilder();
+        vp = VoidPointable.FACTORY.createPointable();
+        sp = (UTF8StringPointable) UTF8StringPointable.FACTORY.createPointable();
+        seqp = (SequencePointable) SequencePointable.FACTORY.createPointable();
+    }
+
+    private boolean isDuplicate(TaggedValuePointable tempKey) {
+        for (TaggedValuePointable tvp : pointables) {
+            tempKey.getValue(vp);
+            if (tvp != null && FunctionHelper.arraysEqual(tvp, vp)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    protected void evaluate(TaggedValuePointable[] args, IPointable result) throws SystemException {
+        TaggedValuePointable tvp;
+        TaggedValuePointable tempKey = ppool.takeOne(TaggedValuePointable.class);
+        TaggedValuePointable tempValue = ppool.takeOne(TaggedValuePointable.class);
+        try {
+            ob.reset(abvs);
+
+            tvp = args[0];
+            if (tvp.getTag() == ValueTag.SEQUENCE_TAG) {
+                tvp.getValue(seqp);
+                int len = seqp.getEntryCount();
+                pointables = new TaggedValuePointable[len / 2];
+                for (int i = 0; i < len; i += 2) {
+                    seqp.getEntry(i, tempKey);
+                    seqp.getEntry(i + 1, tempValue);
+                    if (!isDuplicate(tempKey)) {
+                        pointables[i / 2] = (TaggedValuePointable) TaggedValuePointable.FACTORY.createPointable();
+                        tempKey.getValue(pointables[i / 2]);
+                        sp.set(vp);
+                        ob.addItem(sp, tempValue);
+                    } else {
+                        throw new SystemException(ErrorCode.JNDY0003);
+                    }
+                }
+            }
+            ob.finish();
+            result.set(abvs);
+        } catch (IOException e) {
+            throw new SystemException(ErrorCode.SYSE0001, e);
+        } finally {
+            ppool.giveBack(tempKey);
+            ppool.giveBack(tempValue);
+        }
+    }
+}
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/ArrayConstructorScalarEvaluatorFactory.java b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/jsonitem/ObjectConstructorScalarEvaluatorFactory.java
similarity index 78%
copy from vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/ArrayConstructorScalarEvaluatorFactory.java
copy to vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/jsonitem/ObjectConstructorScalarEvaluatorFactory.java
index c70a8e2..a030736 100644
--- a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/ArrayConstructorScalarEvaluatorFactory.java
+++ b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/jsonitem/ObjectConstructorScalarEvaluatorFactory.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.vxquery.runtime.functions.node;
+package org.apache.vxquery.runtime.functions.jsonitem;
 
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
@@ -22,16 +22,15 @@
 import org.apache.hyracks.api.context.IHyracksTaskContext;
 import org.apache.vxquery.runtime.functions.base.AbstractTaggedValueArgumentScalarEvaluatorFactory;
 
-public class ArrayConstructorScalarEvaluatorFactory extends AbstractTaggedValueArgumentScalarEvaluatorFactory {
-    private static final long serialVersionUID = 1L;
+public class ObjectConstructorScalarEvaluatorFactory extends AbstractTaggedValueArgumentScalarEvaluatorFactory {
 
-    public ArrayConstructorScalarEvaluatorFactory(IScalarEvaluatorFactory[] args) {
+    public ObjectConstructorScalarEvaluatorFactory(IScalarEvaluatorFactory[] args) {
         super(args);
     }
 
     @Override
     protected IScalarEvaluator createEvaluator(IHyracksTaskContext ctx, IScalarEvaluator[] args)
             throws AlgebricksException {
-        return new ArrayConstructorScalarEvaluator(ctx, args);
+        return new ObjectConstructorScalarEvaluator(ctx, args);
     }
 }
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/serializer/XMLSerializer.java b/vxquery-core/src/main/java/org/apache/vxquery/serializer/XMLSerializer.java
index 8b83995..651572a 100644
--- a/vxquery-core/src/main/java/org/apache/vxquery/serializer/XMLSerializer.java
+++ b/vxquery-core/src/main/java/org/apache/vxquery/serializer/XMLSerializer.java
@@ -33,6 +33,7 @@
 import org.apache.vxquery.datamodel.accessors.atomic.XSQNamePointable;
 import org.apache.vxquery.datamodel.accessors.atomic.XSTimePointable;
 import org.apache.vxquery.datamodel.accessors.jsonitem.ArrayPointable;
+import org.apache.vxquery.datamodel.accessors.jsonitem.ObjectPointable;
 import org.apache.vxquery.datamodel.accessors.nodes.AttributeNodePointable;
 import org.apache.vxquery.datamodel.accessors.nodes.DocumentNodePointable;
 import org.apache.vxquery.datamodel.accessors.nodes.ElementNodePointable;
@@ -241,11 +242,22 @@
                 printPINode(ps, tvp);
                 break;
 
+            case ValueTag.OBJECT_TAG:
+                printObject(ps, tvp);
+                break;
+
+            case ValueTag.JS_NULL_TAG:
+                printNull(ps, tvp);
+                break;
             default:
                 throw new UnsupportedOperationException("Encountered tag: " + tvp.getTag());
         }
     }
 
+    private void printNull(PrintStream ps, TaggedValuePointable tvp) {
+        ps.append("null");
+    }
+
     private void printDecimal(PrintStream ps, TaggedValuePointable tvp) {
         XSDecimalPointable dp = pp.takeOne(XSDecimalPointable.class);
         try {
@@ -346,6 +358,94 @@
         }
     }
 
+    private void printObject(PrintStream ps, TaggedValuePointable tvp) {
+        ObjectPointable op = pp.takeOne(ObjectPointable.class);
+        TaggedValuePointable keys = pp.takeOne(TaggedValuePointable.class);
+        tvp.getValue(op);
+        try {
+            op.getKeys(keys);
+            ps.append('{');
+            if (keys.getTag() == ValueTag.SEQUENCE_TAG) {
+                printObjectPairs(ps, keys, op);
+            } else {
+                printObjectPair(ps, keys, op);
+            }
+            ps.append('}');
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            pp.giveBack(keys);
+            pp.giveBack(op);
+        }
+    }
+
+    private void printObjectPairs(PrintStream ps, TaggedValuePointable keys, ObjectPointable op) {
+        SequencePointable seqp = pp.takeOne(SequencePointable.class);
+        TaggedValuePointable tvp = pp.takeOne(TaggedValuePointable.class);
+        try {
+            keys.getValue(seqp);
+            int len = seqp.getEntryCount();
+            for (int i = 0; i < len; i++) {
+                seqp.getEntry(i, tvp);
+                printObjectPair(ps, tvp, op);
+                if (i != len - 1) {
+                    ps.append(',');
+                }
+            }
+        } finally {
+            pp.giveBack(seqp);
+            pp.giveBack(tvp);
+        }
+    }
+
+    private void printObjectPair(PrintStream ps, TaggedValuePointable key, ObjectPointable op) {
+        UTF8StringPointable utf8sp = pp.takeOne(UTF8StringPointable.class);
+        TaggedValuePointable tvp = pp.takeOne(TaggedValuePointable.class);
+        try {
+            printQuotedString(ps, key);
+            key.getValue(utf8sp);
+            ps.append(":");
+            op.getValue(utf8sp, tvp);
+            printJsonValue(ps, tvp);
+        } finally {
+            pp.giveBack(tvp);
+            pp.giveBack(utf8sp);
+        }
+    }
+
+    private void printArray(PrintStream ps, TaggedValuePointable tvp) {
+        ArrayPointable ap = pp.takeOne(ArrayPointable.class);
+        try {
+            tvp.getValue(ap);
+            int len = ap.getEntryCount();
+            ps.append('[');
+            for (int i = 0; i < len; i++) {
+                ap.getEntry(i, tvp);
+                printJsonValue(ps, tvp);
+                if (i != len - 1) {
+                    ps.append(',');
+                }
+            }
+            ps.append(']');
+        } finally {
+            pp.giveBack(ap);
+        }
+    }
+
+    private void printJsonValue(PrintStream ps, TaggedValuePointable tvp) {
+        if (tvp.getTag() == ValueTag.XS_STRING_TAG) {
+            printQuotedString(ps, tvp);
+        } else {
+            printTaggedValuePointable(ps, tvp);
+        }
+    }
+
+    private void printQuotedString(PrintStream ps, TaggedValuePointable tvp) {
+        ps.append('\"');
+        printString(ps, tvp);
+        ps.append('\"');
+    }
+
     private void printElementNode(PrintStream ps, TaggedValuePointable tvp) {
         ElementNodePointable enp = pp.takeOne(ElementNodePointable.class);
         CodedQNamePointable cqp = pp.takeOne(CodedQNamePointable.class);
@@ -446,28 +546,6 @@
         }
     }
 
-    private void printArray(PrintStream ps, TaggedValuePointable tvp) {
-        ArrayPointable ap = pp.takeOne(ArrayPointable.class);
-        try {
-            tvp.getValue(ap);
-            int len = ap.getEntryCount();
-            ps.append('[');
-            ps.append(' ');
-            for (int i = 0; i < len; i++) {
-                ap.getEntry(i, tvp);
-                print(tvp.getByteArray(), tvp.getStartOffset(), tvp.getLength(), ps);
-                if (i != len - 1) {
-                    ps.append(',');
-                }
-                ps.append(' ');
-            }
-            ps.append(']');
-        } finally {
-            pp.giveBack(ap);
-            pp.giveBack(tvp);
-        }
-    }
-
     private void printBase64Binary(PrintStream ps, TaggedValuePointable tvp) {
         XSBinaryPointable bp = pp.takeOne(XSBinaryPointable.class);
         try {
@@ -832,5 +910,6 @@
 
     @Override
     public void init() throws AlgebricksException {
+
     }
 }
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/types/BuiltinTypeRegistry.java b/vxquery-core/src/main/java/org/apache/vxquery/types/BuiltinTypeRegistry.java
index 7cfcb5c..29bb5e2 100644
--- a/vxquery-core/src/main/java/org/apache/vxquery/types/BuiltinTypeRegistry.java
+++ b/vxquery-core/src/main/java/org/apache/vxquery/types/BuiltinTypeRegistry.java
@@ -161,6 +161,9 @@
     public static final BuiltinAtomicType XS_NOTATION = new BuiltinAtomicType(BuiltinTypeConstants.XS_NOTATION_TYPE_ID,
             XS_ANY_ATOMIC, DerivationProcess.RESTRICTION);
 
+    public static final BuiltinAtomicType JS_NULL = new BuiltinAtomicType(BuiltinTypeConstants.JS_NULL_TYPE_ID,
+            XS_ANY_ATOMIC, DerivationProcess.RESTRICTION);
+
     public static final BuiltinTypeRegistry INSTANCE = new BuiltinTypeRegistry();
 
     private final SchemaType[] types;
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/ast/ASTTag.java b/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/ast/ASTTag.java
index cd3f223..3a91e80 100644
--- a/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/ast/ASTTag.java
+++ b/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/ast/ASTTag.java
@@ -87,7 +87,6 @@
     ORDERED_EXPRESSION,
     UNORDERED_EXPRESSION,
     FUNCTION_EXPRESSION,
-    ARRAY_CONSTRUCTOR,
     DIRECT_ELEMENT_CONSTRUCTOR,
     DIRECT_ATTRIBUTE_CONSTRUCTOR,
     DQUOTED_ATTRIBUTE_CONTENT,
@@ -107,6 +106,8 @@
     NCNAME,
     CONTENT_CHARS,
     NAMESPACE_DECLARATION,
-    SINGLE_TYPE
-
+    SINGLE_TYPE,
+    ARRAY_CONSTRUCTOR,
+    OBJECT_CONSTRUCTOR,
+    PAIR_CONSTRUCTOR
 }
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/ast/LiteralNode.java b/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/ast/LiteralNode.java
index 774e38a..0d7cb38 100644
--- a/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/ast/LiteralNode.java
+++ b/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/ast/LiteralNode.java
@@ -35,7 +35,8 @@
         INTEGER,
         DECIMAL,
         DOUBLE,
-        STRING
+        STRING,
+        NULL
     }
 
     public String getImage() {
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/ast/ObjectConstructor.java b/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/ast/ObjectConstructor.java
new file mode 100644
index 0000000..0d66dfb
--- /dev/null
+++ b/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/ast/ObjectConstructor.java
@@ -0,0 +1,42 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.apache.vxquery.xmlquery.ast;
+
+import java.util.List;
+
+import org.apache.vxquery.util.SourceLocation;
+
+public class ObjectConstructor extends ASTNode {
+    private List<ASTNode> content;
+
+    public ObjectConstructor(SourceLocation loc) {
+        super(loc);
+    }
+
+    @Override
+    public ASTTag getTag() {
+        return ASTTag.OBJECT_CONSTRUCTOR;
+    }
+
+    public List<ASTNode> getContent() {
+        return content;
+    }
+
+    public void setContent(List<ASTNode> content) {
+        this.content = content;
+    }
+}
\ No newline at end of file
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/ast/PairConstructor.java b/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/ast/PairConstructor.java
new file mode 100644
index 0000000..082802b
--- /dev/null
+++ b/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/ast/PairConstructor.java
@@ -0,0 +1,48 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.apache.vxquery.xmlquery.ast;
+
+import org.apache.vxquery.util.SourceLocation;
+
+public class PairConstructor extends ASTNode{
+    private String key;
+    private ASTNode value;
+    public PairConstructor(SourceLocation loc) {
+        super(loc);
+    }
+
+    @Override
+    public ASTTag getTag() {
+        return ASTTag.PAIR_CONSTRUCTOR;
+    }
+
+    public String getKey() {
+        return key;
+    }
+
+    public void setKey(String key) {
+        this.key = key;
+    }
+
+    public ASTNode getValue() {
+        return value;
+    }
+
+    public void setValue(ASTNode value) {
+        this.value = value;
+    }
+}
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/translator/XMLQueryTranslator.java b/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/translator/XMLQueryTranslator.java
index 047ffc8..5f44fea 100644
--- a/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/translator/XMLQueryTranslator.java
+++ b/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/translator/XMLQueryTranslator.java
@@ -147,12 +147,14 @@
 import org.apache.vxquery.xmlquery.ast.NCNameNode;
 import org.apache.vxquery.xmlquery.ast.NameTestNode;
 import org.apache.vxquery.xmlquery.ast.NamespaceDeclNode;
+import org.apache.vxquery.xmlquery.ast.ObjectConstructor;
 import org.apache.vxquery.xmlquery.ast.OptionDeclNode;
 import org.apache.vxquery.xmlquery.ast.OrderSpecNode;
 import org.apache.vxquery.xmlquery.ast.OrderbyClauseNode;
 import org.apache.vxquery.xmlquery.ast.OrderedExprNode;
 import org.apache.vxquery.xmlquery.ast.OrderingModeDeclNode;
 import org.apache.vxquery.xmlquery.ast.PITestNode;
+import org.apache.vxquery.xmlquery.ast.PairConstructor;
 import org.apache.vxquery.xmlquery.ast.ParamNode;
 import org.apache.vxquery.xmlquery.ast.ParenthesizedExprNode;
 import org.apache.vxquery.xmlquery.ast.PathExprNode;
@@ -829,6 +831,11 @@
                 return translateComputedAttributeConstructorNode(tCtx, cNode);
             }
 
+            case OBJECT_CONSTRUCTOR: {
+                ObjectConstructor obj = (ObjectConstructor) value;
+                return translateObjectConstructor(tCtx, obj);
+            }
+
             case QNAME: {
                 QNameNode qnNode = (QNameNode) value;
                 return translateQNameNode(tCtx, qnNode);
@@ -1195,6 +1202,22 @@
         return lVar;
     }
 
+    private LogicalVariable translateObjectConstructor(TranslationContext tCtx, ObjectConstructor obj)
+            throws SystemException {
+        List<ILogicalExpression> content = new ArrayList<ILogicalExpression>();
+        for (ASTNode aVal : obj.getContent()) {
+            String key = ((PairConstructor) aVal).getKey();
+            ILogicalExpression ke = ce(SequenceType.create(BuiltinTypeRegistry.XS_STRING, Quantifier.QUANT_ONE),
+                    unquote(key));
+            content.add(ke);
+            ILogicalExpression ve = vre(translateExpression(((PairConstructor) aVal).getValue(), tCtx));
+            content.add(ve);
+        }
+        ILogicalExpression contentExpr = sfce(BuiltinOperators.CONCATENATE,
+                content.toArray(new ILogicalExpression[content.size()]));
+        return createAssignment(sfce(BuiltinOperators.OBJECT_CONSTRUCTOR, contentExpr), tCtx);
+    }
+
     private LogicalVariable translateDirectElementConstructorNode(TranslationContext tCtx,
             DirectElementConstructorNode decNode) throws SystemException {
         QNameNode startName = decNode.getStartTagName();
@@ -1291,6 +1314,10 @@
                 t = SequenceType.create(BuiltinTypeRegistry.XS_STRING, Quantifier.QUANT_ONE);
                 value = unquote(image);
                 break;
+            case NULL:
+                t = SequenceType.create(BuiltinTypeRegistry.JS_NULL, Quantifier.QUANT_ONE);
+                value = null;
+                break;
             default:
                 throw new IllegalStateException("Unknown type: " + lType);
         }
@@ -1954,6 +1981,11 @@
                         stringVB.write((CharSequence) value, dOut);
                         break;
                     }
+                    case BuiltinTypeConstants.JS_NULL_TYPE_ID: {
+                        baaos.reset();
+                        dOut.write((byte) ValueTag.JS_NULL_TAG);
+                        break;
+                    }
                     default:
                         throw new SystemException(ErrorCode.SYSE0001);
                 }
diff --git a/vxquery-core/src/main/javacc/xquery-grammar.jj b/vxquery-core/src/main/javacc/xquery-grammar.jj
index 6dc9865..32e3b5b 100644
--- a/vxquery-core/src/main/javacc/xquery-grammar.jj
+++ b/vxquery-core/src/main/javacc/xquery-grammar.jj
@@ -97,17 +97,17 @@
 
 PARSER_END(XMLQuery)
 
-    
+
 
 TOKEN_MGR_DECLS : {
   public Stack<Integer> stateStack = new Stack<Integer>();
   static final int PARENMARKER = 2000;
   public int offset = 0;
-  
-  
-  void CommonTokenAction(Token t) {}    
 
-  
+
+  void CommonTokenAction(Token t) {}
+
+
   /**
    * Push the current state onto the state stack.
    */
@@ -115,7 +115,7 @@
   {
       stateStack.addElement(curLexState);
   }
-  
+
   /**
    * Push the given state onto the state stack.
    * @param state Must be a valid state.
@@ -124,7 +124,7 @@
   {
       stateStack.push(state);
   }
-  
+
   /**
    * Pop the state on the state stack, and switch to that state.
    */
@@ -136,12 +136,12 @@
     }
 
     int nextState = stateStack.pop();
-    
+
     if(nextState == PARENMARKER)
       printLinePos();
     SwitchTo(nextState);
   }
-  
+
   /**
    * Push the given state onto the state stack.
    * @param state Must be a valid state.
@@ -158,8 +158,8 @@
   }
 
   /**
-   * Push a parenthesis state.  This pushes, in addition to the 
-   * lexical state value, a special marker that lets 
+   * Push a parenthesis state.  This pushes, in addition to the
+   * lexical state value, a special marker that lets
    * resetParenStateOrSwitch(int state)
    * know if it should pop and switch.  Used for the comma operator.
    */
@@ -1003,7 +1003,7 @@
     }
 }
 
-ASTNode OrExpr() : 
+ASTNode OrExpr() :
 {
     ASTNode result;
     ASTNode temp;
@@ -1021,7 +1021,7 @@
     }
 }
 
-ASTNode AndExpr(): 
+ASTNode AndExpr():
 {
     ASTNode result;
     ASTNode temp;
@@ -1039,7 +1039,7 @@
     }
 }
 
-ASTNode ComparisonExpr(): 
+ASTNode ComparisonExpr():
 {
     ASTNode result;
     ASTNode temp;
@@ -1060,7 +1060,7 @@
 }
 
 // TODO - Not yet implemented.
-ASTNode FTContainsExpr(): 
+ASTNode FTContainsExpr():
 {
     ASTNode result;
 }
@@ -1072,7 +1072,7 @@
     }
 }
 
-ASTNode RangeExpr() : 
+ASTNode RangeExpr() :
 {
     ASTNode result;
     ASTNode temp;
@@ -1090,7 +1090,7 @@
     }
 }
 
-ASTNode AdditiveExpr(): 
+ASTNode AdditiveExpr():
 {
     ASTNode result;
     ASTNode temp;
@@ -1116,7 +1116,7 @@
     }
 }
 
-ASTNode MultiplicativeExpr(): 
+ASTNode MultiplicativeExpr():
 {
     ASTNode result = null;
     ASTNode temp;
@@ -1150,7 +1150,7 @@
     }
 }
 
-ASTNode UnionExpr(): 
+ASTNode UnionExpr():
 {
     ASTNode result = null;
     ASTNode temp;
@@ -1173,7 +1173,7 @@
     }
 }
 
-ASTNode IntersectExceptExpr(): 
+ASTNode IntersectExceptExpr():
 {
     ASTNode result = null;
     ASTNode temp;
@@ -1199,7 +1199,7 @@
     }
 }
 
-ASTNode InstanceofExpr(): 
+ASTNode InstanceofExpr():
 {
     ASTNode result;
     SequenceTypeNode type;
@@ -1215,7 +1215,7 @@
     }
 }
 
-ASTNode TreatExpr(): 
+ASTNode TreatExpr():
 {
     ASTNode result;
     SequenceTypeNode type;
@@ -1231,7 +1231,7 @@
     }
 }
 
-ASTNode CastableExpr(): 
+ASTNode CastableExpr():
 {
     ASTNode result;
     SingleTypeNode type;
@@ -1247,7 +1247,7 @@
     }
 }
 
-ASTNode CastExpr(): 
+ASTNode CastExpr():
 {
     ASTNode result;
     SingleTypeNode type;
@@ -1263,7 +1263,7 @@
     }
 }
 
-ASTNode UnaryExpr(): 
+ASTNode UnaryExpr():
 {
     ASTNode expr;
     List<UnaryExprNode.Sign> signs = new ArrayList<UnaryExprNode.Sign>();
@@ -1288,7 +1288,7 @@
     }
 }
 
-ASTNode ValueExpr(): 
+ASTNode ValueExpr():
 {
     ASTNode expr;
 }
@@ -1694,7 +1694,7 @@
 {
     (
         LOOKAHEAD(2) test = KindTest()
-        | test = NameTest() 
+        | test = NameTest()
     ) {
         return test;
     }
@@ -1816,6 +1816,12 @@
         l.setType(LiteralNode.LiteralType.STRING);
         return l;
     }
+    | t = "null" {
+        LiteralNode l1 = new LiteralNode(createSourceLocation(t));
+        l1.setImage(t.image);
+        l1.setType(LiteralNode.LiteralType.NULL);
+        return l1;
+     }
 }
 
 ASTNode NumericLiteral()   :
@@ -1950,6 +1956,80 @@
         return result;
     }
 }
+ASTNode JsonConstructor() :
+{
+    ASTNode result;
+}
+{
+    (
+        result = ObjectConstructor()
+        | result = ArrayConstructor()
+    ) {
+        return result;
+    }
+}
+
+ASTNode ObjectConstructor() :
+{
+    List<ASTNode> content = new ArrayList<ASTNode>();
+    Token t;
+    ASTNode pc;
+}
+{
+    t = <LbraceExprEnclosure>
+    (
+        pc = PairConstructor() {
+            content.add(pc);
+        } (
+            "," pc = PairConstructor() {
+                content.add(pc);
+            }
+        )*
+    )*
+    <Rbrace>
+    {
+        ObjectConstructor obj = new ObjectConstructor(createSourceLocation(t));
+        obj.setContent(content);
+        return obj;
+    }
+}
+
+ASTNode PairConstructor() :
+{
+    String key;
+    ASTNode value;
+    Token t;
+}
+{
+    t = <StringLiteral> {
+        key = t.image;
+    }
+    (
+        ":"
+        | ":?"
+    )
+    (
+        value = ExprSingle()
+    ) {
+        PairConstructor pc = new PairConstructor(createSourceLocation(t));
+        pc.setKey(key);
+        pc.setValue(value);
+        return pc;
+    }
+}
+
+ASTNode ArrayConstructor()  :
+{
+    ASTNode expr=null;
+    Token start;
+}
+{
+    (start = "[") [expr = Expr()] "]" {
+        ArrayConstructor an = new ArrayConstructor(createSourceLocation(start));
+        an.setExpression(expr);
+        return an;
+    }
+}
 
 ASTNode DirectConstructor()  :
 {
@@ -2216,7 +2296,7 @@
                     }
                     buffer.append("}");
                 }
-            )* <CloseApos> 
+            )* <CloseApos>
         )
     ) {
         if (bufferStart != null) {
@@ -2433,7 +2513,7 @@
     start = "processing-instruction" (
         target = NCName()
         | (
-            <LbraceExprEnclosure>  target = Expr() <Rbrace> 
+            <LbraceExprEnclosure>  target = Expr() <Rbrace>
         )
     ) <LbraceExprEnclosure>  [content = Expr()] <Rbrace> {
         ComputedPIConstructorNode pi = new ComputedPIConstructorNode(createSourceLocation(start));
@@ -2443,30 +2523,6 @@
     }
 }
 
-ASTNode JsonConstructor()  :
-{
-    ASTNode result;
-}
-{
-    result = ArrayConstructor()
-    {
-        return result;
-    }
-}
-
-ASTNode ArrayConstructor()  :
-{
-    ASTNode expr=null;
-    Token start;
-}
-{
-    (start = "[") [expr = Expr()] "]" {
-        ArrayConstructor an = new ArrayConstructor(createSourceLocation(start));
-        an.setExpression(expr);
-        return an;
-    }
-}
-
 SingleTypeNode SingleType()  :
 {
     AtomicTypeNode type;
@@ -2822,38 +2878,38 @@
     FTOr() (FTPosFilter())* ["weight" RangeExpr()]
 }
 
-void FTOrExpr()  : 
+void FTOrExpr()  :
 {}
 {
     FTOr()
 }
 
-void FTOr()  : 
+void FTOr()  :
 {}
 {
     FTAnd() ("ftor"{ binaryTokenStack.push(token); } FTAnd())*
 }
 
-void FTAnd()  : 
+void FTAnd()  :
 {}
 {
     FTMildNot() ("ftand"{ binaryTokenStack.push(token); } FTMildNot())*
 }
 
-void FTMildNot()  : 
+void FTMildNot()  :
 {}
 {
     FTUnaryNot() ( ( "not"{ binaryTokenStack.push(token); } "in"{ binaryTokenStack.push(token); }) FTUnaryNot())*
 }
 
-void FTUnaryNot()  : 
+void FTUnaryNot()  :
 {boolean keepUnary=false;}
 {
    (
 "ftnot"{keepUnary=true;})? FTPrimaryWithOptions()
 }
 
-void FTPrimaryWithOptions(): 
+void FTPrimaryWithOptions():
 {}
 {
    (
@@ -2881,7 +2937,7 @@
 void FTExtensionSelection()  :
 {}
 {
-    (Pragma())+  <LbraceExprEnclosure>  [FTSelection()] <Rbrace> 
+    (Pragma())+  <LbraceExprEnclosure>  [FTSelection()] <Rbrace>
 }
 
 void FTAnyallOption()  :
@@ -2959,19 +3015,19 @@
 void FTMatchOptions()  :
 {}
 {
-    (LOOKAHEAD(2) FTMatchOption())+ 
+    (LOOKAHEAD(2) FTMatchOption())+
 }
 
 void FTMatchOption()  :
 {}
 {
-    LOOKAHEAD(2) FTLanguageOption() 
-    | LOOKAHEAD(2) FTWildCardOption() 
-    | LOOKAHEAD(2) FTThesaurusOption() 
-    | LOOKAHEAD(2) FTStemOption() 
-    | LOOKAHEAD(2) FTCaseOption() 
-    | LOOKAHEAD(2) FTDiacriticsOption() 
-    | LOOKAHEAD(2) FTStopwordOption() 
+    LOOKAHEAD(2) FTLanguageOption()
+    | LOOKAHEAD(2) FTWildCardOption()
+    | LOOKAHEAD(2) FTThesaurusOption()
+    | LOOKAHEAD(2) FTStemOption()
+    | LOOKAHEAD(2) FTCaseOption()
+    | LOOKAHEAD(2) FTDiacriticsOption()
+    | LOOKAHEAD(2) FTStopwordOption()
     | LOOKAHEAD(2) FTExtensionOption()
 }
 
@@ -3026,7 +3082,7 @@
 void FTLanguageOption()  :
 {}
 {
-    "language" <StringLiteral> 
+    "language" <StringLiteral>
 }
 
 void FTWildCardOption()  :
@@ -3038,7 +3094,7 @@
 void FTExtensionOption()  :
 {}
 {
-    "option" QName() <StringLiteral> 
+    "option" QName() <StringLiteral>
 }
 
 void FTIgnoreOption()  :
@@ -4028,4 +4084,4 @@
  < NotNumber : ( (
 "." <Digits>) |  (
 <Digits> ("." (["0" - "9"])*)?)) (["e", "E"] (["+", "-"])? <Digits>)? ["a" - "z", "A" - "Z"] (["0" - "9", "a" - "z", "A" - "Z"])* >
-}
+}
\ No newline at end of file
diff --git a/vxquery-core/src/main/resources/org/apache/vxquery/xmlquery/exceptions/XMLQueryErrorMessages.properties b/vxquery-core/src/main/resources/org/apache/vxquery/xmlquery/exceptions/XMLQueryErrorMessages.properties
index e958fa6..b08a271 100644
--- a/vxquery-core/src/main/resources/org/apache/vxquery/xmlquery/exceptions/XMLQueryErrorMessages.properties
+++ b/vxquery-core/src/main/resources/org/apache/vxquery/xmlquery/exceptions/XMLQueryErrorMessages.properties
@@ -139,4 +139,24 @@
 ERR_FORX0002_DESCRIPTION=Invalid regular expression.
 ERR_FORX0003_DESCRIPTION=Regular expression matches zero-length string.
 ERR_FORX0004_DESCRIPTION=Invalid replacement string.
-ERR_FOTY0012_DESCRIPTION=Argument node does not have a typed value.
\ No newline at end of file
+ERR_FOTY0012_DESCRIPTION=Argument node does not have a typed value.
+ERR_JNDY0003_DESCRIPTION=It is a dynamic error if two pairs in an object constructor or in a simple object union have the same name.
+ERR_JNTY0004_DESCRIPTION=Arrays and objects cannot be atomized. It is a type error to call fn:data on a sequence containing an array or an object.
+ERR_JNUP0005_DESCRIPTION=It is a dynamic error if a pending update list contains two JSON insert update primitives on the same object and pair name.
+ERR_JNUP0006_DESCRIPTION=It is a dynamic error if upd:applyUpdates causes an object to contain two pairs with the same name.
+ERR_JNUP0007_DESCRIPTION=It is a type error if, in an updating expression, an array selector cannot be cast to xs:integer or if an object selector cannot be cast to xs:string.
+ERR_JNUP0008_DESCRIPTION=It is a dynamic error if the target of a JSON delete or JSON replace expression is not an array or an object. It is a dynamic error if the target of a renaming expression is not an object. It is a dynamic error if the target of an appending expression is not an array. It is a dynamic error if the target of a position-inserting expression is not an array. It is a dynamic error if the target of a non-position-inserting expression is not an object.
+ERR_JNUP0009_DESCRIPTION=It is a dynamic error if a pending update list contains two JSON replacing update primitives on the same object or array, and with the same selector.
+ERR_JNUP0010_DESCRIPTION=It is a dynamic error if a pending update list contains two JSON renaming update primitives on the same object and with the same selector.
+ERR_JNTY0011_DESCRIPTION=It is a type error if the content sequence in a node constructor or in an XQUF insert or replace update expression contains an object or an array.
+ERR_JNSE0012_DESCRIPTION=It is a dynamic error to serialize something else than a unique JSON item with the JSON output method if the jsoniq-multiple-top-level-items is set to no.
+ERR_JNSE0014_DESCRIPTION=It is a dynamic error to serialize a function, a node or a standalone atomic item with the JSON output method.
+ERR_JNSE0015_DESCRIPTION=It is a dynamic error to serialize a top-level item which is not a JSON item if the jsoniq-multiple-top-level-items serialization parameter is not set to "array".
+ERR_JNUP0016_DESCRIPTION=It is a dynamic error if it is attempted to create a replace, delete or rename update primitive with a selector that cannot be resolved against the target array or object.
+ERR_JNTY0018_DESCRIPTION=It is a type error if there is not exactly one supplied parameter for an object or array selector.
+ERR_JNUP0019_DESCRIPTION=It is a dynamic error if the content expression, in an object insert expression, does not evaluate to a sequence of objects.
+ERR_JNTY0020_DESCRIPTION=It is a dynamic error if, when calling jn:parse-json, the option "jsoniq-multiple-top-level-items" is not a boolean.
+ERR_JNDY0021_DESCRIPTION=It is a dynamic error if parsing a string to one or several objects or arrays is not successful, or if it results in more than one item and "jsoniq-multiple-top-level-items" is false.
+ERR_JNSE0022_DESCRIPTION=It is a dynamic error if an object or array is encountered upon serializing as XML, XHTML, HTML or Text.
+ERR_JNTY0023_DESCRIPTION=It is a dynamic error if, when calling jn:decode-from-roundtrip, the type specified in an Encoded Object is not recognized, or if the value cannot be cast to it (if it is an atomic type) or if the parsed XML node does match it (if it is an XML node type).
+ERR_JNTY0024_DESCRIPTION=Arrays and objects do not have a string value. It is a type error to call fn:string on an array or an object.
\ No newline at end of file
diff --git a/vxquery-xtest/src/test/java/org/apache/vxquery/xtest/AbstractXQueryTest.java b/vxquery-xtest/src/test/java/org/apache/vxquery/xtest/AbstractXQueryTest.java
index 5411215..bf65631 100644
--- a/vxquery-xtest/src/test/java/org/apache/vxquery/xtest/AbstractXQueryTest.java
+++ b/vxquery-xtest/src/test/java/org/apache/vxquery/xtest/AbstractXQueryTest.java
@@ -61,7 +61,7 @@
             case EXPECTED_RESULT_GOT_DIFFERENT_RESULT:
             case EXPECTED_RESULT_GOT_ERROR:
             case EXPECTED_RESULT_GOT_FAILURE:
-                fail(result.state + " (" + result.time + " ms): " + result.testCase.getXQueryDisplayName());
+                fail(result.state + " (" + result.time + " ms): " + result.testCase.getXQueryDisplayName() + " " + result.error);
                 break;
             case EXPECTED_ERROR_GOT_SAME_ERROR:
             case EXPECTED_RESULT_GOT_SAME_RESULT:
diff --git a/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Array/q01_array.txt b/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Array/q01_array.txt
index 404b10d..bace2a0 100644
--- a/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Array/q01_array.txt
+++ b/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Array/q01_array.txt
@@ -1 +1 @@
-[ 1 ]
\ No newline at end of file
+[1]
\ No newline at end of file
diff --git a/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Array/q02_array.txt b/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Array/q02_array.txt
index 6038e9b..8d22e93 100644
--- a/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Array/q02_array.txt
+++ b/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Array/q02_array.txt
@@ -1 +1 @@
-[ 1, string, 3.1 ]
\ No newline at end of file
+[1,"string",3.1]
\ No newline at end of file
diff --git a/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Array/q03_array.txt b/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Array/q03_array.txt
index 6330c79..5a56543 100644
--- a/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Array/q03_array.txt
+++ b/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Array/q03_array.txt
@@ -1 +1 @@
-[ [ 1, 2 ], [ 2, 3 ] ]
\ No newline at end of file
+[[1,2],[2,3]]
\ No newline at end of file
diff --git a/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Array/q04_array.txt b/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Array/q04_array.txt
index 8878e54..0637a08 100644
--- a/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Array/q04_array.txt
+++ b/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Array/q04_array.txt
@@ -1 +1 @@
-[ ]
\ No newline at end of file
+[]
\ No newline at end of file
diff --git a/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Object/q01_object.txt b/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Object/q01_object.txt
index 56a6051..69e2e10 100644
--- a/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Object/q01_object.txt
+++ b/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Object/q01_object.txt
@@ -1 +1 @@
-1
\ No newline at end of file
+{"name":"Riyafa"}
\ No newline at end of file
diff --git a/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Object/q02_object.txt b/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Object/q02_object.txt
new file mode 100644
index 0000000..7073179
--- /dev/null
+++ b/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Object/q02_object.txt
@@ -0,0 +1 @@
+{"string":"name","number1":123.5,"number2":-123.5,"number3":123,"number4":123,"number5":1.23E11,"null":null}
\ No newline at end of file
diff --git a/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Object/q03_object.txt b/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Object/q03_object.txt
new file mode 100644
index 0000000..afcdda9
--- /dev/null
+++ b/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Object/q03_object.txt
@@ -0,0 +1 @@
+{"object1":{"more":"object","number":123},"object2":{"object3":{"number":23}}}
\ No newline at end of file
diff --git a/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Object/q04_object.txt b/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Object/q04_object.txt
new file mode 100644
index 0000000..9e26dfe
--- /dev/null
+++ b/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Object/q04_object.txt
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Object/q05_object.txt b/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Object/q05_object.txt
new file mode 100644
index 0000000..5dd4417
--- /dev/null
+++ b/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Object/q05_object.txt
@@ -0,0 +1 @@
+{"a":2016-06-07,"b":2}
\ No newline at end of file
diff --git a/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Object/q06_object.txt b/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Object/q06_object.txt
new file mode 100644
index 0000000..38e1ec3
--- /dev/null
+++ b/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Object/q06_object.txt
@@ -0,0 +1 @@
+{"a":[1,2,3],"b":2}
\ No newline at end of file
diff --git a/vxquery-xtest/src/test/resources/Queries/XQuery/Json/Object/q01_object.xq b/vxquery-xtest/src/test/resources/Queries/XQuery/Json/Object/q01_object.xq
index 52c9044..86f9471 100644
--- a/vxquery-xtest/src/test/resources/Queries/XQuery/Json/Object/q01_object.xq
+++ b/vxquery-xtest/src/test/resources/Queries/XQuery/Json/Object/q01_object.xq
@@ -16,5 +16,5 @@
    under the License. :)
 
 (: Json Object Query :)
-(: Just an object example :)
-    1
+(: Pasrse object with a single item :)
+{"name":"Riyafa"}
diff --git a/vxquery-xtest/src/test/resources/Queries/XQuery/Json/Object/q02_object.xq b/vxquery-xtest/src/test/resources/Queries/XQuery/Json/Object/q02_object.xq
new file mode 100644
index 0000000..1e5fbdc
--- /dev/null
+++ b/vxquery-xtest/src/test/resources/Queries/XQuery/Json/Object/q02_object.xq
@@ -0,0 +1,28 @@
+(: Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+   
+     http://www.apache.org/licenses/LICENSE-2.0
+   
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License. :)
+
+(: Json Object Query :)
+(: Pasrse object with multiple items :)
+{
+    "string":"name",
+    "number1":+123.5,
+    "number2":-123.5,
+    "number3":123,
+    "number4":00123,
+    "number5":1.23E+11,
+    "null":null
+}
\ No newline at end of file
diff --git a/vxquery-xtest/src/test/resources/Queries/XQuery/Json/Object/q03_object.xq b/vxquery-xtest/src/test/resources/Queries/XQuery/Json/Object/q03_object.xq
new file mode 100644
index 0000000..5cd8de7
--- /dev/null
+++ b/vxquery-xtest/src/test/resources/Queries/XQuery/Json/Object/q03_object.xq
@@ -0,0 +1,30 @@
+(: Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+   
+     http://www.apache.org/licenses/LICENSE-2.0
+   
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License. :)
+
+(: Json Object Query :)
+(: Pasrse object with nested objects :)
+{
+    "object1": {
+        "more": "object",
+        "number": 123
+    },
+    "object2": {
+        "object3": {
+            "number": 23
+        }
+    }
+}
\ No newline at end of file
diff --git a/vxquery-xtest/src/test/resources/Queries/XQuery/Json/Object/q04_object.xq b/vxquery-xtest/src/test/resources/Queries/XQuery/Json/Object/q04_object.xq
new file mode 100644
index 0000000..ecdaa5d
--- /dev/null
+++ b/vxquery-xtest/src/test/resources/Queries/XQuery/Json/Object/q04_object.xq
@@ -0,0 +1,20 @@
+(: Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+   
+     http://www.apache.org/licenses/LICENSE-2.0
+   
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License. :)
+
+(: Json Object Query :)
+(: Pasrse empty object :)
+{ }
\ No newline at end of file
diff --git a/vxquery-xtest/src/test/resources/Queries/XQuery/Json/Object/q05_object.xq b/vxquery-xtest/src/test/resources/Queries/XQuery/Json/Object/q05_object.xq
new file mode 100644
index 0000000..0ed375f
--- /dev/null
+++ b/vxquery-xtest/src/test/resources/Queries/XQuery/Json/Object/q05_object.xq
@@ -0,0 +1,23 @@
+(: Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+   
+     http://www.apache.org/licenses/LICENSE-2.0
+   
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License. :)
+
+(: Json Object Query :)
+(: Pasrse object with functions :)
+{
+    "a": xs:date("2016-06-07"),
+    "b": 2
+}
\ No newline at end of file
diff --git a/vxquery-xtest/src/test/resources/Queries/XQuery/Json/Object/q06_object.xq b/vxquery-xtest/src/test/resources/Queries/XQuery/Json/Object/q06_object.xq
new file mode 100644
index 0000000..b4231d3
--- /dev/null
+++ b/vxquery-xtest/src/test/resources/Queries/XQuery/Json/Object/q06_object.xq
@@ -0,0 +1,27 @@
+(: Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+   
+     http://www.apache.org/licenses/LICENSE-2.0
+   
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License. :)
+
+(: Json Object Query :)
+(: Pasrse object with arrays :)
+{
+    "a": [
+        1,
+        2,
+        3
+    ],
+    "b": 2
+}
\ No newline at end of file
diff --git a/vxquery-xtest/src/test/resources/Queries/XQuery/Json/Object/q07_object.xq b/vxquery-xtest/src/test/resources/Queries/XQuery/Json/Object/q07_object.xq
new file mode 100644
index 0000000..dee64ae
--- /dev/null
+++ b/vxquery-xtest/src/test/resources/Queries/XQuery/Json/Object/q07_object.xq
@@ -0,0 +1,24 @@
+(: Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+   
+     http://www.apache.org/licenses/LICENSE-2.0
+   
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License. :)
+
+(: Json Object Query :)
+(: Pasrse object with arrays :)
+{
+    "a":123,
+    "a":234,
+    "b":456
+}
\ No newline at end of file
diff --git a/vxquery-xtest/src/test/resources/cat/JsonObjectQueries.xml b/vxquery-xtest/src/test/resources/cat/JsonObjectQueries.xml
index dcdf6e6..8543d3a 100644
--- a/vxquery-xtest/src/test/resources/cat/JsonObjectQueries.xml
+++ b/vxquery-xtest/src/test/resources/cat/JsonObjectQueries.xml
@@ -16,13 +16,43 @@
 -->
 
 <test-group xmlns="http://www.w3.org/2005/02/query-test-XQTSCatalog" name="JsonObjectQueries" featureOwner="VXQuery">
-   <GroupInfo>
-      <title>Json Object</title>
-      <description/>
-   </GroupInfo>
-   <test-case name="json-object-q01" FilePath="Json/Object/" Creator="Christina Pavlopoulou">
-      <description>Object.</description>
-      <query name="q01_object" date="2016-06-09"/>
-      <output-file compare="Text">q01_object.txt</output-file>
-   </test-case>
+    <GroupInfo>
+        <title>Json Object</title>
+        <description/>
+    </GroupInfo>
+    <test-case name="json-object-q01" FilePath="Json/Object/" Creator="Riyafa Abdul Hameed">
+        <description>Object.</description>
+        <query name="q01_object" date="2016-06-11"/>
+        <output-file compare="Text">q01_object.txt</output-file>
+    </test-case>
+    <test-case name="json-object-q02" FilePath="Json/Object/" Creator="Riyafa Abdul Hameed">
+        <description>Object.</description>
+        <query name="q02_object" date="2016-06-11"/>
+        <output-file compare="Text">q02_object.txt</output-file>
+    </test-case>
+    <test-case name="json-object-q03" FilePath="Json/Object/" Creator="Riyafa Abdul Hameed">
+        <description>Object.</description>
+        <query name="q03_object" date="2016-06-11"/>
+        <output-file compare="Text">q03_object.txt</output-file>
+    </test-case>
+    <test-case name="json-object-q04" FilePath="Json/Object/" Creator="Riyafa Abdul Hameed">
+        <description>Object.</description>
+        <query name="q04_object" date="2016-06-11"/>
+        <output-file compare="Text">q04_object.txt</output-file>
+    </test-case>
+    <test-case name="json-object-q05" FilePath="Json/Object/" Creator="Riyafa Abdul Hameed">
+        <description>Object.</description>
+        <query name="q05_object" date="2016-06-11"/>
+        <output-file compare="Text">q05_object.txt</output-file>
+    </test-case>
+    <test-case name="json-object-q06" FilePath="Json/Object/" Creator="Riyafa Abdul Hameed">
+        <description>Object.</description>
+        <query name="q06_object" date="2016-06-11"/>
+        <output-file compare="Text">q06_object.txt</output-file>
+    </test-case>
+    <test-case name="json-object-q07" FilePath="Json/Object/" Creator="Riyafa Abdul Hameed">
+        <description>Object.</description>
+        <query name="q07_object" date="2016-06-14"/>
+        <expected-error>JNDY0003</expected-error>
+    </test-case>
 </test-group>
\ No newline at end of file