JSON object builder, pointable and unit tests.
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/datamodel/accessors/SequencePointable.java b/vxquery-core/src/main/java/org/apache/vxquery/datamodel/accessors/SequencePointable.java
index 0aa66f7..9ccac0b 100644
--- a/vxquery-core/src/main/java/org/apache/vxquery/datamodel/accessors/SequencePointable.java
+++ b/vxquery-core/src/main/java/org/apache/vxquery/datamodel/accessors/SequencePointable.java
@@ -24,8 +24,8 @@
 import org.apache.hyracks.data.std.primitive.VoidPointable;
 
 public class SequencePointable extends AbstractPointable {
-    private static final int ENTRY_COUNT_SIZE = 4;
-    private static final int SLOT_SIZE = 4;
+    private static final int ENTRY_COUNT_SIZE = IntegerPointable.TYPE_TRAITS.getFixedLength();
+    private static final int SLOT_SIZE = IntegerPointable.TYPE_TRAITS.getFixedLength();
     public static final IPointableFactory FACTORY = new IPointableFactory() {
         private static final long serialVersionUID = 1L;
 
@@ -77,4 +77,4 @@
     private static int getDataAreaOffset(byte[] bytes, int start) {
         return getSlotArrayOffset(start) + getEntryCount(bytes, start) * SLOT_SIZE;
     }
-}
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..953a8fa
--- /dev/null
+++ b/vxquery-core/src/main/java/org/apache/vxquery/datamodel/accessors/jsonItem/ObjectPointable.java
@@ -0,0 +1,124 @@
+/*
+ * 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.datamodel.accessors.jsonItem;
+
+import java.io.IOException;
+
+import org.apache.hyracks.api.dataflow.value.ITypeTraits;
+import org.apache.hyracks.data.std.api.AbstractPointable;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.api.IPointableFactory;
+import org.apache.hyracks.data.std.primitive.IntegerPointable;
+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.builders.sequence.SequenceBuilder;
+import org.apache.vxquery.datamodel.values.ValueTag;
+import org.apache.vxquery.runtime.functions.util.FunctionHelper;
+
+/**
+ * The datamodel of the JSON object is represented in this class:
+ * Byte 1: Value tag of object (109)
+ * Byte 2 to 5: number of key-value pairs in the object
+ * Next few bytes: Offsets for each key-value pair in the object in the order appearing in the json data
+ * Next bytes: The keys in the object each followed by the value of the key. Each key is a StringPointable and the value
+ * of the key will be the respective pointable starting with its valuetag.
+ */
+public class ObjectPointable extends AbstractPointable {
+    public static final IPointableFactory FACTORY = new IPointableFactory() {
+        private static final long serialVersionUID = 1L;
+
+        @Override
+        public ITypeTraits getTypeTraits() {
+            return VoidPointable.TYPE_TRAITS;
+        }
+
+        @Override
+        public IPointable createPointable() {
+            return new ObjectPointable();
+        }
+    };
+    private static final int ENTRY_COUNT_SIZE = IntegerPointable.TYPE_TRAITS.getFixedLength();
+    private static final int SLOT_SIZE = IntegerPointable.TYPE_TRAITS.getFixedLength();
+    private final ArrayBackedValueStorage abvs = new ArrayBackedValueStorage();
+    private final SequenceBuilder sb = new SequenceBuilder();
+    private final UTF8StringPointable key1 = (UTF8StringPointable) UTF8StringPointable.FACTORY.createPointable();
+
+    private static int getSlotValue(byte[] bytes, int start, int idx) {
+        return IntegerPointable.getInteger(bytes, getSlotArrayOffset(start) + idx * SLOT_SIZE);
+    }
+
+    private static int getEntryCount(byte[] bytes, int start) {
+        return IntegerPointable.getInteger(bytes, start);
+    }
+
+    private static int getKeyLength(byte[] b, int s) {
+        return UTF8StringPointable.getUTFLength(b, s) + 2;
+    }
+
+    private static int getSlotArrayOffset(int start) {
+        return start + ENTRY_COUNT_SIZE;
+    }
+
+    private static int getDataAreaOffset(byte[] bytes, int start) {
+        return getSlotArrayOffset(start) + getEntryCount(bytes, start) * SLOT_SIZE;
+    }
+
+    public void getKeys(IPointable result) throws IOException {
+        abvs.reset();
+        sb.reset(abvs);
+        int dataAreaOffset = getDataAreaOffset(bytes, start);
+        int entryCount = getEntryCount();
+        int s;
+        for (int i = 0; i < entryCount; i++) {
+            s = dataAreaOffset + getRelativeEntryStartOffset(i);
+            key1.set(bytes, s, getKeyLength(bytes, s));
+            sb.addItem(ValueTag.XS_STRING_TAG, key1);
+        }
+        sb.finish();
+        result.set(abvs);
+    }
+
+    public boolean getValue(UTF8StringPointable key, IPointable result) {
+        int dataAreaOffset = getDataAreaOffset(bytes, start);
+        int entryCount = getEntryCount();
+        int start, length, i;
+        for (i = 0; i < entryCount; i++) {
+            start = dataAreaOffset + getRelativeEntryStartOffset(i);
+            length = getKeyLength(bytes, start);
+            if (FunctionHelper.arraysEqual(bytes, start, length, key.getByteArray(), key.getStartOffset(),
+                    key.getLength())) {
+                result.set(bytes, start + length, getEntryLength(i) - length);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private int getRelativeEntryStartOffset(int idx) {
+        return idx == 0 ? 0 : getSlotValue(bytes, start, idx - 1);
+    }
+
+    private int getEntryLength(int idx) {
+        return getSlotValue(bytes, start, idx) - getRelativeEntryStartOffset(idx);
+    }
+
+    public int getEntryCount() {
+        return getEntryCount(bytes, start);
+    }
+
+}
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/datamodel/builders/jsonItem/ObjectBuilder.java b/vxquery-core/src/main/java/org/apache/vxquery/datamodel/builders/jsonItem/ObjectBuilder.java
new file mode 100644
index 0000000..f4b7649
--- /dev/null
+++ b/vxquery-core/src/main/java/org/apache/vxquery/datamodel/builders/jsonItem/ObjectBuilder.java
@@ -0,0 +1,66 @@
+/*
+ * 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.datamodel.builders.jsonItem;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.hyracks.data.std.api.IMutableValueStorage;
+import org.apache.hyracks.data.std.api.IValueReference;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
+import org.apache.vxquery.datamodel.builders.base.AbstractBuilder;
+import org.apache.vxquery.datamodel.builders.base.IBuilder;
+import org.apache.vxquery.datamodel.values.ValueTag;
+import org.apache.vxquery.util.GrowableIntArray;
+
+public class ObjectBuilder extends AbstractBuilder implements IBuilder {
+    private final GrowableIntArray slots = new GrowableIntArray();
+    private final ArrayBackedValueStorage dataArea = new ArrayBackedValueStorage();
+    private IMutableValueStorage mvs;
+
+    public void reset(IMutableValueStorage mvs) {
+        this.mvs = mvs;
+        slots.clear();
+        dataArea.reset();
+    }
+
+    @Override
+    public int getValueTag() {
+        return ValueTag.OBJECT_TAG;
+    }
+
+    public void addItem(UTF8StringPointable key, IValueReference value) throws IOException {
+        dataArea.getDataOutput().write(key.getByteArray(), key.getStartOffset(), key.getLength());
+        dataArea.getDataOutput().write(value.getByteArray(), value.getStartOffset(), value.getLength());
+        slots.append(dataArea.getLength());
+    }
+
+    public void finish() throws IOException {
+        DataOutput out = mvs.getDataOutput();
+        out.write(ValueTag.OBJECT_TAG);
+        int size = slots.getSize();
+        out.writeInt(size);
+        if (size > 0) {
+            int[] slotArray = slots.getArray();
+            for (int i = 0; i < size; ++i) {
+                out.writeInt(slotArray[i]);
+            }
+            out.write(dataArea.getByteArray(), dataArea.getStartOffset(), dataArea.getLength());
+        }
+    }
+}
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/datamodel/builders/sequence/SequenceBuilder.java b/vxquery-core/src/main/java/org/apache/vxquery/datamodel/builders/sequence/SequenceBuilder.java
index 5cd31b1..e347818 100644
--- a/vxquery-core/src/main/java/org/apache/vxquery/datamodel/builders/sequence/SequenceBuilder.java
+++ b/vxquery-core/src/main/java/org/apache/vxquery/datamodel/builders/sequence/SequenceBuilder.java
@@ -42,6 +42,12 @@
         slots.append(dataArea.getLength());
     }
 
+    public void addItem(int tagValue, IValueReference p) throws IOException {
+        dataArea.getDataOutput().write(tagValue);
+        dataArea.getDataOutput().write(p.getByteArray(), p.getStartOffset(), p.getLength());
+        slots.append(dataArea.getLength());
+    }
+
     public void finish() throws IOException {
         if (slots.getSize() != 1) {
             out.write(ValueTag.SEQUENCE_TAG);
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/datamodel/values/ValueTag.java b/vxquery-core/src/main/java/org/apache/vxquery/datamodel/values/ValueTag.java
index d2c8a9b..2e4d5c7 100644
--- a/vxquery-core/src/main/java/org/apache/vxquery/datamodel/values/ValueTag.java
+++ b/vxquery-core/src/main/java/org/apache/vxquery/datamodel/values/ValueTag.java
@@ -74,6 +74,8 @@
     public static final int XS_NMTOKENS_TAG = BuiltinTypeConstants.XS_NMTOKENS_TYPE_ID;
     public static final int XS_ENTITIES_TAG = BuiltinTypeConstants.XS_ENTITIES_TYPE_ID;
 
+    public static final int JS_NULL_TAG = BuiltinTypeConstants.JS_NULL_TYPE_ID;
+
     public static final int SEQUENCE_TAG = 100;
     public static final int DOCUMENT_NODE_TAG = 101;
     public static final int ELEMENT_NODE_TAG = 102;
@@ -83,6 +85,7 @@
     public static final int PI_NODE_TAG = 106;
     public static final int NODE_TREE_TAG = 107;
     public static final int ARRAY_TAG = 108;
+    public static final int OBJECT_TAG = 109;
 
     public static boolean isAtomic(int tag) {
         return tag < 100;
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/datamodel/values/XDMConstants.java b/vxquery-core/src/main/java/org/apache/vxquery/datamodel/values/XDMConstants.java
index bc058c7..3dc7e9e 100644
--- a/vxquery-core/src/main/java/org/apache/vxquery/datamodel/values/XDMConstants.java
+++ b/vxquery-core/src/main/java/org/apache/vxquery/datamodel/values/XDMConstants.java
@@ -19,11 +19,10 @@
 import java.io.IOException;
 import java.util.Arrays;
 
-import org.apache.vxquery.datamodel.builders.sequence.SequenceBuilder;
-
 import org.apache.hyracks.data.std.api.IPointable;
 import org.apache.hyracks.data.std.primitive.BooleanPointable;
 import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
+import org.apache.vxquery.datamodel.builders.sequence.SequenceBuilder;
 
 public class XDMConstants {
     private static final byte[] BOOLEAN_TRUE_CONSTANT;
@@ -34,6 +33,8 @@
 
     private static final byte[] EMPTY_STRING;
 
+    private static final byte[] JS_NULL_CONSTANT;
+
     static {
         BOOLEAN_TRUE_CONSTANT = new byte[2];
         BOOLEAN_TRUE_CONSTANT[0] = ValueTag.XS_BOOLEAN_TAG;
@@ -52,11 +53,17 @@
             throw new RuntimeException(e);
         }
         EMPTY_SEQUENCE = Arrays.copyOf(abvs.getByteArray(), abvs.getLength());
-        
+
         EMPTY_STRING = new byte[3];
         EMPTY_STRING[0] = ValueTag.XS_STRING_TAG;
         EMPTY_STRING[1] = 0;
         EMPTY_STRING[2] = 0;
+
+        JS_NULL_CONSTANT = new byte[1];
+        JS_NULL_CONSTANT[0] = ValueTag.JS_NULL_TAG;
+    }
+
+    private XDMConstants() {
     }
 
     public static void setTrue(IPointable p) {
@@ -75,10 +82,11 @@
         set(p, EMPTY_STRING);
     }
 
-    private static void set(IPointable p, byte[] array) {
-        p.set(array, 0, array.length);
+    public static void setJsNull(IPointable p) {
+        set(p, JS_NULL_CONSTANT);
     }
 
-    private XDMConstants() {
+    private static void set(IPointable p, byte[] array) {
+        p.set(array, 0, array.length);
     }
 }
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/types/BuiltinTypeConstants.java b/vxquery-core/src/main/java/org/apache/vxquery/types/BuiltinTypeConstants.java
index eefebcc..5ac51ec 100644
--- a/vxquery-core/src/main/java/org/apache/vxquery/types/BuiltinTypeConstants.java
+++ b/vxquery-core/src/main/java/org/apache/vxquery/types/BuiltinTypeConstants.java
@@ -72,5 +72,7 @@
     public static final int XS_NMTOKENS_TYPE_ID = 50;
     public static final int XS_ENTITIES_TYPE_ID = 51;
 
-    public static final int BUILTIN_TYPE_COUNT = 52;
+    public static final int JS_NULL_TYPE_ID = 52;
+
+    public static final int BUILTIN_TYPE_COUNT = 53;
 }
diff --git a/vxquery-core/src/test/java/org/apache/vxquery/datamodel/AbstractPointableTest.java b/vxquery-core/src/test/java/org/apache/vxquery/datamodel/AbstractPointableTest.java
index fa4e831..d3de095 100644
--- a/vxquery-core/src/test/java/org/apache/vxquery/datamodel/AbstractPointableTest.java
+++ b/vxquery-core/src/test/java/org/apache/vxquery/datamodel/AbstractPointableTest.java
@@ -25,6 +25,7 @@
 public class AbstractPointableTest {
     private final ArrayBackedValueStorage abvsInput = new ArrayBackedValueStorage();
     private final StringValueBuilder svb = new StringValueBuilder();
+    private boolean includeTag = true;
 
     protected void getTaggedValuePointable(Object value, IPointable result) throws IOException {
         int start = abvsInput.getLength();
@@ -42,23 +43,36 @@
         result.set(abvsInput.getByteArray(), start, abvsInput.getLength() - start);
     }
 
+    protected void getTaggedValuePointable(Object value, boolean includeTag, IPointable result) throws IOException {
+        this.includeTag = includeTag;
+        getTaggedValuePointable(value, result);
+    }
+
     protected void writeInteger(Integer value, DataOutput dOut) throws IOException {
-        dOut.write(ValueTag.XS_INT_TAG);
+        if (includeTag) {
+            dOut.write(ValueTag.XS_INT_TAG);
+        }
         dOut.writeInt(value);
     }
 
     protected void writeLong(Long value, DataOutput dOut) throws IOException {
-        dOut.write(ValueTag.XS_LONG_TAG);
+        if (includeTag) {
+            dOut.write(ValueTag.XS_LONG_TAG);
+        }
         dOut.writeLong(value);
     }
 
     protected void writeDouble(Double value, DataOutput dOut) throws IOException {
-        dOut.write(ValueTag.XS_DOUBLE_TAG);
+        if (includeTag) {
+            dOut.write(ValueTag.XS_DOUBLE_TAG);
+        }
         dOut.writeDouble(value);
     }
 
     protected void writeString(String value, DataOutput dOut) throws IOException {
-        dOut.write(ValueTag.XS_STRING_TAG);
+        if (includeTag) {
+            dOut.write(ValueTag.XS_STRING_TAG);
+        }
         svb.write(value, dOut);
     }
 
diff --git a/vxquery-core/src/test/java/org/apache/vxquery/datamodel/ObjectByteTest.java b/vxquery-core/src/test/java/org/apache/vxquery/datamodel/ObjectByteTest.java
new file mode 100644
index 0000000..4bdb503
--- /dev/null
+++ b/vxquery-core/src/test/java/org/apache/vxquery/datamodel/ObjectByteTest.java
@@ -0,0 +1,264 @@
+/*
+ * 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.datamodel;
+
+import java.io.IOException;
+
+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.accessors.jsonItem.ObjectPointable;
+import org.apache.vxquery.datamodel.builders.jsonItem.ObjectBuilder;
+import org.apache.vxquery.datamodel.values.ValueTag;
+import org.apache.vxquery.runtime.functions.util.FunctionHelper;
+import org.junit.Test;
+
+import junit.framework.Assert;
+
+public class ObjectByteTest extends AbstractPointableTest {
+    private ArrayBackedValueStorage abvsResult = new ArrayBackedValueStorage();
+    private ObjectBuilder ob = new ObjectBuilder();
+    private TaggedValuePointable tvp = (TaggedValuePointable) TaggedValuePointable.FACTORY.createPointable();
+    private UTF8StringPointable tvpKey1 = (UTF8StringPointable) UTF8StringPointable.FACTORY.createPointable();
+    private TaggedValuePointable tvpValue1 = (TaggedValuePointable) TaggedValuePointable.FACTORY.createPointable();
+    private UTF8StringPointable tvpKey2 = (UTF8StringPointable) UTF8StringPointable.FACTORY.createPointable();
+    private TaggedValuePointable tvpValue2 = (TaggedValuePointable) TaggedValuePointable.FACTORY.createPointable();
+    private UTF8StringPointable tvpKey3 = (UTF8StringPointable) UTF8StringPointable.FACTORY.createPointable();
+    private TaggedValuePointable tvpValue3 = (TaggedValuePointable) TaggedValuePointable.FACTORY.createPointable();
+    private SequencePointable sp = (SequencePointable) SequencePointable.FACTORY.createPointable();
+    private ObjectPointable op = (ObjectPointable) ObjectPointable.FACTORY.createPointable();
+    private IPointable vp = VoidPointable.FACTORY.createPointable();
+
+    @Test
+    public void testEmptyObject() {
+        // Build test Object
+        abvsResult.reset();
+        try {
+            ob.reset(abvsResult);
+            ob.finish();
+        } catch (IOException e) {
+            Assert.fail("Test failed to write the Object pointable.");
+        }
+        tvp.set(abvsResult);
+
+        // Check results.
+        if (tvp.getTag() != ValueTag.OBJECT_TAG) {
+            Assert.fail("Type tag is incorrect. Expected: " + ValueTag.OBJECT_TAG + " Got: " + tvp.getTag());
+        }
+        tvp.getValue(op);
+        if (op.getEntryCount() != 0) {
+            Assert.fail("Object size is incorrect. Expected: 0 Got: " + op.getEntryCount());
+        }
+    }
+
+    @Test
+    public void testSingleItemObject() {
+        // Build test Object
+        abvsResult.reset();
+        try {
+            ob.reset(abvsResult);
+            getTaggedValuePointable("id", false, tvpKey1);
+            getTaggedValuePointable(1, tvpValue1);
+            ob.addItem(tvpKey1, tvpValue1);
+            ob.finish();
+        } catch (IOException e) {
+            Assert.fail("Test failed to write the object pointable.");
+        }
+        tvp.set(abvsResult);
+
+        // Check results.
+        if (tvp.getTag() != ValueTag.OBJECT_TAG) {
+            Assert.fail("Type tag is incorrect. Expected: " + ValueTag.OBJECT_TAG + " Got: " + tvp.getTag());
+        }
+
+        tvp.getValue(op);
+        if (op.getEntryCount() != 1) {
+            Assert.fail("Object size is incorrect. Expected: 1 Got: " + op.getEntryCount());
+        }
+        try {
+            op.getKeys(tvp);
+        } catch (IOException e) {
+            Assert.fail("Test failed to write the object pointable.");
+        }
+        if (tvp.getTag() != ValueTag.XS_STRING_TAG) {
+            Assert.fail("Type tag is incorrect. Expected: " + ValueTag.XS_STRING_TAG + " Got: " + tvp.getTag());
+        }
+        if (!compareKeys(tvp, tvpKey1)) {
+            Assert.fail("Key is incorrect. Expected: id");
+        }
+
+        if (!op.getValue(tvpKey1, tvp)) {
+            Assert.fail("Value not found for the given key:id");
+        }
+        if (!FunctionHelper.arraysEqual(tvp, tvpValue1)) {
+            Assert.fail("Value is incorrect for the given key. Expected: 1 with valuetag: " + ValueTag.XS_INT_TAG
+                    + " Got valuetag: " + tvp.getTag());
+        }
+    }
+
+    @Test
+    public void testManyItemObject() {
+        // Build test object
+        try {
+            // Add three items
+            ob.reset(abvsResult);
+            getTaggedValuePointable("name", false, tvpKey1);
+            getTaggedValuePointable("A green door", tvpValue1);
+            ob.addItem(tvpKey1, tvpValue1);
+            getTaggedValuePointable("price", false, tvpKey2);
+            getTaggedValuePointable(12.5, tvpValue2);
+            ob.addItem(tvpKey2, tvpValue2);
+            getTaggedValuePointable("properties", false, tvpKey3);
+            getTaggedValuePointable(100L, tvpValue3);
+            ob.addItem(tvpKey3, tvpValue3);
+            ob.finish();
+        } catch (IOException e) {
+            Assert.fail("Test failed to write the object pointable.");
+        }
+        tvp.set(abvsResult);
+
+        // Check results.
+        if (tvp.getTag() != ValueTag.OBJECT_TAG) {
+            Assert.fail("Type tag is incorrect. Expected: " + ValueTag.OBJECT_TAG + " Got: " + tvp.getTag());
+        }
+        tvp.getValue(op);
+        if (op.getEntryCount() != 3) {
+            Assert.fail("Object size is incorrect. Expected: 3 Got: " + op.getEntryCount());
+        }
+
+        //Test keys
+        try {
+            op.getKeys(tvp);
+        } catch (IOException e) {
+            Assert.fail("Test failed to write the object pointable.");
+        }
+
+        if (tvp.getTag() != ValueTag.SEQUENCE_TAG) {
+            Assert.fail("Tag type is incorrect. Expected: " + ValueTag.SEQUENCE_TAG + " Got: " + tvp.getTag());
+        }
+        tvp.getValue(sp);
+        if (sp.getEntryCount() != 3) {
+            Assert.fail("Object size is incorrect. Expected: 3 Got: " + sp.getEntryCount());
+        }
+        sp.getEntry(0, tvp);
+        if (tvp.getTag() != ValueTag.XS_STRING_TAG) {
+            Assert.fail("Type tag is incorrect. Expected: " + ValueTag.XS_STRING_TAG + " Got: " + tvp.getTag());
+        }
+        if (!compareKeys(tvp, tvpKey1)) {
+            Assert.fail("Object key one is incorrect. Expected: name");
+        }
+        sp.getEntry(1, tvp);
+        if (tvp.getTag() != ValueTag.XS_STRING_TAG) {
+            Assert.fail("Type tag is incorrect. Expected: " + ValueTag.XS_STRING_TAG + " Got: " + tvp.getTag());
+        }
+        if (!compareKeys(tvp, tvpKey2)) {
+            Assert.fail("Object key two is incorrect. Expected: price");
+        }
+        sp.getEntry(2, tvp);
+        if (tvp.getTag() != ValueTag.XS_STRING_TAG) {
+            Assert.fail("Type tag is incorrect. Expected: " + ValueTag.XS_STRING_TAG + " Got: " + tvp.getTag());
+        }
+        if (!compareKeys(tvp, tvpKey3)) {
+            Assert.fail("Object key three is incorrect. Expected: properties");
+        }
+
+        //Test values
+        if (!op.getValue(tvpKey1, tvp)) {
+            Assert.fail("Value not found for the given key: name");
+        }
+        if (!FunctionHelper.arraysEqual(tvp, tvpValue1)) {
+            Assert.fail("Value is incorrect for the given key. Expected: A green door with valuetag: "
+                    + ValueTag.XS_STRING_TAG + " Got valuetag: " + tvp.getTag());
+        }
+
+        if (!op.getValue(tvpKey2, tvp)) {
+            Assert.fail("Value not found for the given key: price");
+        }
+        if (!FunctionHelper.arraysEqual(tvp, tvpValue2)) {
+            Assert.fail("Value is incorrect for the given key. Expected: 12.5 with valuetag: " + ValueTag.XS_DOUBLE_TAG
+                    + " Got valuetag: " + tvp.getTag());
+        }
+
+        if (!op.getValue(tvpKey3, tvp)) {
+            Assert.fail("Value not found for the given key: properties");
+        }
+        if (!FunctionHelper.arraysEqual(tvp, tvpValue3)) {
+            Assert.fail("Value is incorrect for the given key. Expected: 100 with valuetag: " + ValueTag.XS_LONG_TAG
+                    + " Got valuetag: " + tvp.getTag());
+        }
+    }
+
+    @Test
+    public void testItemNotExistObject() {
+        // Build empty test Object
+        abvsResult.reset();
+        try {
+            ob.reset(abvsResult);
+            ob.finish();
+        } catch (IOException e) {
+            Assert.fail("Test failed to write the Object pointable.");
+        }
+        tvp.set(abvsResult);
+        tvp.getValue(op);
+        try {
+            getTaggedValuePointable("key", false, tvpKey1);
+            if (op.getValue(tvpKey1, tvp)) {
+                Assert.fail("key not in object. Expected: false Got: true");
+            }
+        } catch (IOException e) {
+            Assert.fail("Test failed to write the object pointable.");
+        }
+
+        // Build test object
+        try {
+            // Add two items
+            abvsResult.reset();
+            ob.reset(abvsResult);
+            getTaggedValuePointable("name", false, tvpKey1);
+            getTaggedValuePointable("A green door", tvpValue1);
+            ob.addItem(tvpKey1, tvpValue1);
+            getTaggedValuePointable("price", false, tvpKey2);
+            getTaggedValuePointable(12.5, tvpValue2);
+            ob.addItem(tvpKey2, tvpValue2);
+            ob.finish();
+        } catch (IOException e) {
+            Assert.fail("Test failed to write the object pointable.");
+        }
+
+        tvp.set(abvsResult);
+        tvp.getValue(op);
+        try {
+            getTaggedValuePointable("key", false, tvpKey3);
+            if (op.getValue(tvpKey3, tvp)) {
+                Assert.fail("key not in object. Expected: false Got: true");
+            }
+
+            if (!op.getValue(tvpKey1, tvp)) {
+                Assert.fail("key in object. Expected: true Got: false");
+            }
+        } catch (IOException e) {
+            Assert.fail("Test failed to write the object pointable.");
+        }
+    }
+
+    private boolean compareKeys(TaggedValuePointable tvp1, IPointable tvp2) {
+        tvp1.getValue(vp);
+        return FunctionHelper.arraysEqual(vp.getByteArray(), vp.getStartOffset(), vp.getLength(), tvp2.getByteArray(),
+                tvp2.getStartOffset(), tvp2.getLength());
+    }
+}