diff --git a/tests/JavaTest.java b/tests/JavaTest.java
index 6505767..23ebb5b 100644
--- a/tests/JavaTest.java
+++ b/tests/JavaTest.java
@@ -1,3 +1,37 @@
+
+import static com.google.flatbuffers.Constants.*;
+
+import MyGame.Example.*;
+import optional_scalars.ScalarStuff;
+import optional_scalars.OptionalByte;
+import MyGame.MonsterExtra;
+import NamespaceA.*;
+import NamespaceA.NamespaceB.*;
+import com.google.flatbuffers.ByteBufferUtil;
+import com.google.flatbuffers.ByteVector;
+import com.google.flatbuffers.FlatBufferBuilder;
+import com.google.flatbuffers.FlexBuffers;
+import com.google.flatbuffers.FlexBuffersBuilder;
+import com.google.flatbuffers.StringVector;
+import com.google.flatbuffers.UnionVector;
+
+import com.google.flatbuffers.FlexBuffers.FlexBufferException;
+import com.google.flatbuffers.FlexBuffers.Reference;
+import com.google.flatbuffers.FlexBuffers.Vector;
+import com.google.flatbuffers.ArrayReadWriteBuf;
+import com.google.flatbuffers.FlexBuffers.KeyVector;
+
+import java.io.*;
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.CharBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
 /*
  * Copyright 2014 Google Inc. All rights reserved.
  *
@@ -14,17 +48,7 @@
  * limitations under the License.
  */
 
-import java.io.*;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.channels.FileChannel;
-import MyGame.Example.*;
-import NamespaceA.*;
-import NamespaceA.NamespaceB.*;
-import com.google.flatbuffers.ByteBufferUtil;
-import static com.google.flatbuffers.Constants.*;
-import com.google.flatbuffers.FlatBufferBuilder;
-import MyGame.MonsterExtra;
+
 
 class JavaTest {
     public static void main(String[] args) {
@@ -77,6 +101,14 @@
 
         TestFixedLengthArrays();
 
+        TestFlexBuffers();
+
+        TestVectorOfBytes();
+
+        TestSharedStringPool();
+
+        TestScalarOptional();
+
         System.out.println("FlatBuffers test: completed successfully");
     }
 
@@ -120,6 +152,14 @@
             invsum += monster.inventory(i);
         TestEq(invsum, 10);
 
+        // Method using a vector access object:
+        ByteVector inventoryVector = monster.inventoryVector();
+        TestEq(inventoryVector.length(), 5);
+        invsum = 0;
+        for (int i = 0; i < inventoryVector.length(); i++)
+            invsum += inventoryVector.getAsUnsigned(i);
+        TestEq(invsum, 10);
+
         // Alternative way of accessing a vector:
         ByteBuffer ibb = monster.inventoryAsByteBuffer();
         invsum = 0;
@@ -132,10 +172,22 @@
         TestEq(monster.test4Length(), 2);
         TestEq(test_0.a() + test_0.b() + test_1.a() + test_1.b(), 100);
 
+        Test.Vector test4Vector = monster.test4Vector();
+        test_0 = test4Vector.get(0);
+        test_1 = test4Vector.get(1);
+        TestEq(test4Vector.length(), 2);
+        TestEq(test_0.a() + test_0.b() + test_1.a() + test_1.b(), 100);
+
         TestEq(monster.testarrayofstringLength(), 2);
         TestEq(monster.testarrayofstring(0),"test1");
         TestEq(monster.testarrayofstring(1),"test2");
 
+        // Method using a vector access object:
+        StringVector testarrayofstringVector = monster.testarrayofstringVector();
+        TestEq(testarrayofstringVector.length(), 2);
+        TestEq(testarrayofstringVector.get(0),"test1");
+        TestEq(testarrayofstringVector.get(1),"test2");
+
         TestEq(monster.testbool(), true);
     }
 
@@ -212,6 +264,10 @@
 
         TestEq(monsterObject.inventory(1), (int)inventory[1]);
         TestEq(monsterObject.inventoryLength(), inventory.length);
+        ByteVector inventoryVector = monsterObject.inventoryVector();
+        TestEq(inventoryVector.getAsUnsigned(1), (int)inventory[1]);
+        TestEq(inventoryVector.length(), inventory.length);
+
         TestEq(ByteBuffer.wrap(inventory), monsterObject.inventoryAsByteBuffer());
     }
 
@@ -233,6 +289,9 @@
 
         TestEq(monsterObject.inventory(1), (int)inventory[1]);
         TestEq(monsterObject.inventoryLength(), inventory.length);
+        ByteVector inventoryVector = monsterObject.inventoryVector();
+        TestEq(inventoryVector.getAsUnsigned(1), (int)inventory[1]);
+        TestEq(inventoryVector.length(), inventory.length);
         TestEq(ByteBuffer.wrap(inventory), monsterObject.inventoryAsByteBuffer());
     }
 
@@ -242,7 +301,9 @@
             public ByteBuffer newByteBuffer(int capacity) {
                 ByteBuffer bb;
                 try {
-                    bb =  new RandomAccessFile("javatest.bin", "rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 0, capacity).order(ByteOrder.LITTLE_ENDIAN);
+                    RandomAccessFile f = new RandomAccessFile("javatest.bin", "rw");
+                    bb =  f.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, capacity).order(ByteOrder.LITTLE_ENDIAN);
+                    f.close();
                 } catch(Throwable e) {
                     System.out.println("FlatBuffers test: couldn't map ByteBuffer to a file");
                     bb = null;
@@ -380,18 +441,21 @@
         TestEq(monster.testarrayoftables(0).name(), "Barney");
         TestEq(monster.testarrayoftables(1).name(), "Frodo");
         TestEq(monster.testarrayoftables(2).name(), "Wilma");
+        Monster.Vector testarrayoftablesVector = monster.testarrayoftablesVector();
+        TestEq(testarrayoftablesVector.get(0).name(), "Barney");
+        TestEq(testarrayoftablesVector.get(1).name(), "Frodo");
+        TestEq(testarrayoftablesVector.get(2).name(), "Wilma");
 
         // Example of searching for a table by the key
         TestEq(monster.testarrayoftablesByKey("Frodo").name(), "Frodo");
         TestEq(monster.testarrayoftablesByKey("Barney").name(), "Barney");
         TestEq(monster.testarrayoftablesByKey("Wilma").name(), "Wilma");
+        TestEq(testarrayoftablesVector.getByKey("Frodo").name(), "Frodo");
+        TestEq(testarrayoftablesVector.getByKey("Barney").name(), "Barney");
+        TestEq(testarrayoftablesVector.getByKey("Wilma").name(), "Wilma");
 
         // testType is an existing field and mutating it should succeed
         TestEq(monster.testType(), (byte)Any.Monster);
-        TestEq(monster.mutateTestType(Any.NONE), true);
-        TestEq(monster.testType(), (byte)Any.NONE);
-        TestEq(monster.mutateTestType(Any.Monster), true);
-        TestEq(monster.testType(), (byte)Any.Monster);
 
         //mutate the inventory vector
         TestEq(monster.mutateInventory(0, 1), true);
@@ -403,6 +467,10 @@
         for (int i = 0; i < monster.inventoryLength(); i++) {
             TestEq(monster.inventory(i), i + 1);
         }
+        ByteVector inventoryVector =  monster.inventoryVector();
+        for (int i = 0; i < inventoryVector.length(); i++) {
+            TestEq((int)inventoryVector.get(i), i + 1);
+        }
 
         //reverse mutation
         TestEq(monster.mutateInventory(0, 0), true);
@@ -445,11 +513,16 @@
         );
 
         final Movie movie = Movie.getRootAsMovie(fbb.dataBuffer());
+        ByteVector charactersTypeByteVector = movie.charactersTypeVector();
+        UnionVector charactersVector = movie.charactersVector();
 
         TestEq(movie.charactersTypeLength(), characterTypeVector.length);
+        TestEq(charactersTypeByteVector.length(), characterTypeVector.length);
         TestEq(movie.charactersLength(), characterVector.length);
+        TestEq(charactersVector.length(), characterVector.length);
 
         TestEq(movie.charactersType(0), characterTypeVector[0]);
+        TestEq(charactersTypeByteVector.get(0), characterTypeVector[0]);
 
         TestEq(((Attacker)movie.characters(new Attacker(), 0)).swordAttackDamage(), swordAttackDamage);
     }
@@ -463,6 +536,9 @@
         int[][]     d_a = new int[2][2];
         byte[]      d_b = new byte[2];
         byte[][]    d_c = new byte[2][2];
+        long[][]    d_d = new long[2][2];
+        int         e;
+        long[]      f = new long[2];
 
         a = 0.5f;
         for (int i = 0; i < 15; i++) b[i] = i;
@@ -477,9 +553,16 @@
         d_c[0][1] = TestEnum.B;
         d_c[1][0] = TestEnum.C;
         d_c[1][1] = TestEnum.B;
+        d_d[0][0] = -1;
+        d_d[0][1] = 1;
+        d_d[1][0] = -2;
+        d_d[1][1] = 2;
+        e = 2;
+        f[0] = -1;
+        f[1] = 1;
 
         int arrayOffset = ArrayStruct.createArrayStruct(builder,
-            a, b, c, d_a, d_b, d_c);
+            a, b, c, d_a, d_b, d_c, d_d, e, f);
 
         // Create a table with the ArrayStruct.
         ArrayTable.startArrayTable(builder);
@@ -504,14 +587,807 @@
         TestEq(table.a().d(nested, 0).c(1), TestEnum.B);
         TestEq(table.a().d(nested, 1).c(0), TestEnum.C);
         TestEq(table.a().d(nested, 1).c(1), TestEnum.B);
+        TestEq(table.a().d(nested, 0).d(0), (long)-1);
+        TestEq(table.a().d(nested, 0).d(1), (long)1);
+        TestEq(table.a().d(nested, 1).d(0), (long)-2);
+        TestEq(table.a().d(nested, 1).d(1), (long)2);
+        TestEq(table.a().e(), 2);
+        TestEq(table.a().f(0), (long)-1);
+        TestEq(table.a().f(1), (long)1);
+    }
+
+    public static void testFlexBuffersTest() {
+        FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(512),
+                FlexBuffersBuilder.BUILDER_FLAG_SHARE_KEYS_AND_STRINGS);
+        testFlexBuffersTest(builder);
+        int bufferLimit1 = ((ArrayReadWriteBuf) builder.getBuffer()).limit();
+
+        // Repeat after clearing the builder to ensure the builder is reusable
+        builder.clear();
+        testFlexBuffersTest(builder);
+        int bufferLimit2 = ((ArrayReadWriteBuf) builder.getBuffer()).limit();
+        TestEq(bufferLimit1, bufferLimit2);
+    }
+
+    public static void testFlexBuffersTest(FlexBuffersBuilder builder) {
+        // Write the equivalent of:
+        // { vec: [ -100, "Fred", 4.0, false ], bar: [ 1, 2, 3 ], bar3: [ 1, 2, 3 ],
+        // foo: 100, bool: true, mymap: { foo: "Fred" } }
+        // It's possible to do this without std::function support as well.
+        int map1 = builder.startMap();
+
+        int vec1 = builder.startVector();
+        builder.putInt(-100);
+        builder.putString("Fred");
+        builder.putBlob(new byte[]{(byte) 77});
+        builder.putBoolean(false);
+        builder.putInt(Long.MAX_VALUE);
+
+        int map2 = builder.startMap();
+        builder.putInt("test", 200);
+        builder.endMap(null, map2);
+
+        builder.putFloat(150.9);
+        builder.putFloat(150.9999998);
+        builder.endVector("vec", vec1, false, false);
+
+        vec1 = builder.startVector();
+        builder.putInt(1);
+        builder.putInt(2);
+        builder.putInt(3);
+        builder.endVector("bar", vec1, true, false);
+
+        vec1 = builder.startVector();
+        builder.putBoolean(true);
+        builder.putBoolean(false);
+        builder.putBoolean(true);
+        builder.putBoolean(false);
+        builder.endVector("bools", vec1, true, false);
+
+        builder.putBoolean("bool", true);
+        builder.putFloat("foo", 100);
+
+        map2 = builder.startMap();
+        builder.putString("bar", "Fred");  // Testing key and string reuse.
+        builder.putInt("int", -120);
+        builder.putFloat("float", -123.0f);
+        builder.putBlob("blob", new byte[]{ 65, 67 });
+        builder.endMap("mymap", map2);
+
+        builder.endMap(null, map1);
+        builder.finish();
+
+        FlexBuffers.Map m = FlexBuffers.getRoot(builder.getBuffer()).asMap();
+
+        TestEq(m.size(), 6);
+
+        // test empty (an null)
+        TestEq(m.get("no_key").asString(), ""); // empty if fail
+        TestEq(m.get("no_key").asMap(), FlexBuffers.Map.empty()); // empty if fail
+        TestEq(m.get("no_key").asKey(), FlexBuffers.Key.empty()); // empty if fail
+        TestEq(m.get("no_key").asVector(), FlexBuffers.Vector.empty()); // empty if fail
+        TestEq(m.get("no_key").asBlob(), FlexBuffers.Blob.empty()); // empty if fail
+        assert(m.get("no_key").asVector().isEmpty()); // empty if fail
+
+        // testing "vec" field
+        FlexBuffers.Vector vec = m.get("vec").asVector();
+        TestEq(vec.size(), 8);
+        TestEq(vec.get(0).asLong(), (long) -100);
+        TestEq(vec.get(1).asString(), "Fred");
+        TestEq(vec.get(2).isBlob(), true);
+        TestEq(vec.get(2).asBlob().size(), 1);
+        TestEq(vec.get(2).asBlob().data().get(0), (byte) 77);
+        TestEq(vec.get(3).isBoolean(), true);   // Check if type is a bool
+        TestEq(vec.get(3).asBoolean(), false);  // Check if value is false
+        TestEq(vec.get(4).asLong(), Long.MAX_VALUE);
+        TestEq(vec.get(5).isMap(), true);
+        TestEq(vec.get(5).asMap().get("test").asInt(), 200);
+        TestEq(Float.compare((float)vec.get(6).asFloat(), 150.9f), 0);
+        TestEq(Double.compare(vec.get(7).asFloat(), 150.9999998), 0);
+        TestEq((long)0, (long)vec.get(1).asLong()); //conversion fail returns 0 as C++
+
+        // bar vector
+        FlexBuffers.Vector tvec = m.get("bar").asVector();
+        TestEq(tvec.size(), 3);
+        TestEq(tvec.get(0).asInt(), 1);
+        TestEq(tvec.get(1).asInt(), 2);
+        TestEq(tvec.get(2).asInt(), 3);
+        TestEq(((FlexBuffers.TypedVector) tvec).getElemType(), FlexBuffers.FBT_INT);
+
+        // bools vector
+        FlexBuffers.Vector bvec = m.get("bools").asVector();
+        TestEq(bvec.size(), 4);
+        TestEq(bvec.get(0).asBoolean(), true);
+        TestEq(bvec.get(1).asBoolean(), false);
+        TestEq(bvec.get(2).asBoolean(), true);
+        TestEq(bvec.get(3).asBoolean(), false);
+        TestEq(((FlexBuffers.TypedVector) bvec).getElemType(), FlexBuffers.FBT_BOOL);
+
+
+        TestEq((float)m.get("foo").asFloat(), (float) 100);
+        TestEq(m.get("unknown").isNull(), true);
+
+        // mymap vector
+        FlexBuffers.Map mymap = m.get("mymap").asMap();
+        TestEq(mymap.keys().get(0), m.keys().get(0)); // These should be equal by pointer equality, since key and value are shared.
+        TestEq(mymap.keys().get(0).toString(), "bar");
+        TestEq(mymap.values().get(0).asString(), vec.get(1).asString());
+        TestEq(mymap.get("int").asInt(), -120);
+        TestEq((float)mymap.get("float").asFloat(), -123.0f);
+        TestEq(Arrays.equals(mymap.get("blob").asBlob().getBytes(), new byte[]{ 65, 67 }), true);
+        TestEq(mymap.get("blob").asBlob().toString(), "AC");
+        TestEq(mymap.get("blob").toString(), "\"AC\"");
+    }
+
+    public static void testFlexBufferVectorStrings() {
+        FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(10000000));
+
+        int size = 3000;
+        StringBuilder sb = new StringBuilder();
+        for (int i=0; i< size; i++) {
+            sb.append("a");
+        }
+
+        String text = sb.toString();
+        TestEq(text.length(), size);
+
+        int pos = builder.startVector();
+
+        for (int i=0; i<size; i++) {
+            builder.putString(text);
+        }
+
+        try {
+            builder.endVector(null, pos, true, false);
+            // this should raise an exception as
+            // typed vector of string was deprecated
+            assert false;
+        } catch(FlexBufferException fb) {
+            // no op
+        }
+        // we finish the vector again as non-typed
+        builder.endVector(null, pos, false, false);
+
+        ByteBuffer b = builder.finish();
+        Vector v = FlexBuffers.getRoot(b).asVector();
+
+        TestEq(v.size(), size);
+        for (int i=0; i<size; i++) {
+            TestEq(v.get(i).asString().length(), size);
+            TestEq(v.get(i).asString(), text);
+        }
+    }
+
+    public static void testDeprecatedTypedVectorString() {
+        // tests whether we are able to support reading deprecated typed vector string
+        // data is equivalent to [ "abc", "abc", "abc", "abc"]
+        byte[] data = new byte[] {0x03, 0x61, 0x62, 0x63, 0x00, 0x03, 0x61, 0x62, 0x63, 0x00,
+            0x03, 0x61, 0x62, 0x63, 0x00, 0x03, 0x61, 0x62, 0x63, 0x00, 0x04, 0x14, 0x10,
+             0x0c, 0x08, 0x04, 0x3c, 0x01};
+        Reference ref = FlexBuffers.getRoot(ByteBuffer.wrap(data));
+        TestEq(ref.getType(), FlexBuffers.FBT_VECTOR_STRING_DEPRECATED);
+        TestEq(ref.isTypedVector(), true);
+        Vector vec = ref.asVector();
+        for (int i=0; i< vec.size(); i++) {
+            TestEq("abc", vec.get(i).asString());
+        }
+    }
+
+    public static void testSingleElementBoolean() {
+        FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(100));
+        builder.putBoolean(true);
+        ByteBuffer b = builder.finish();
+        assert(FlexBuffers.getRoot(b).asBoolean());
+    }
+
+    public static void testSingleElementByte() {
+        FlexBuffersBuilder builder = new FlexBuffersBuilder();
+        builder.putInt(10);
+        ByteBuffer b = builder.finish();
+        TestEq(10, FlexBuffers.getRoot(b).asInt());
+    }
+
+    public static void testSingleElementShort() {
+        FlexBuffersBuilder builder = new FlexBuffersBuilder();
+        builder.putInt(Short.MAX_VALUE);
+        ByteBuffer b = builder.finish();
+        TestEq(Short.MAX_VALUE, (short)FlexBuffers.getRoot(b).asInt());
+    }
+
+    public static void testSingleElementInt() {
+        FlexBuffersBuilder builder = new FlexBuffersBuilder();
+        builder.putInt(Integer.MIN_VALUE);
+        ByteBuffer b = builder.finish();
+        TestEq(Integer.MIN_VALUE, FlexBuffers.getRoot(b).asInt());
+    }
+
+    public static void testSingleElementLong() {
+        FlexBuffersBuilder builder = new FlexBuffersBuilder();
+        builder.putInt(Long.MAX_VALUE);
+        ByteBuffer b = builder.finish();
+        TestEq(Long.MAX_VALUE, FlexBuffers.getRoot(b).asLong());
+    }
+
+    public static void testSingleElementFloat() {
+        FlexBuffersBuilder builder = new FlexBuffersBuilder();
+        builder.putFloat(Float.MAX_VALUE);
+        ByteBuffer b = builder.finish();
+        TestEq(Float.compare(Float.MAX_VALUE, (float) FlexBuffers.getRoot(b).asFloat()), 0);
+    }
+
+    public static void testSingleElementDouble() {
+        FlexBuffersBuilder builder = new FlexBuffersBuilder();
+        builder.putFloat(Double.MAX_VALUE);
+        ByteBuffer b = builder.finish();
+        TestEq(Double.compare(Double.MAX_VALUE, FlexBuffers.getRoot(b).asFloat()), 0);
+    }
+
+    public static void testSingleElementBigString() {
+        FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(10000));
+        StringBuilder sb = new StringBuilder();
+
+        for (int i=0; i< 3000; i++) {
+            sb.append("a");
+        }
+
+        builder.putString(sb.toString());
+        ByteBuffer b = builder.finish();
+
+        FlexBuffers.Reference r = FlexBuffers.getRoot(b);
+
+        TestEq(FlexBuffers.FBT_STRING, r.getType());
+        TestEq(sb.toString(), r.asString());
+    }
+
+    public static void testSingleElementSmallString() {
+        FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(10000));
+
+        builder.putString("aa");
+        ByteBuffer b = builder.finish();
+        FlexBuffers.Reference r = FlexBuffers.getRoot(b);
+
+        TestEq(FlexBuffers.FBT_STRING, r.getType());
+        TestEq("aa", r.asString());
+    }
+
+    public static void testSingleElementBlob() {
+        FlexBuffersBuilder builder = new FlexBuffersBuilder();
+        builder.putBlob(new byte[]{5, 124, 118, -1});
+        ByteBuffer b = builder.finish();
+        FlexBuffers.Reference r = FlexBuffers.getRoot(b);
+        byte[] result = r.asBlob().getBytes();
+        TestEq((byte)5, result[0]);
+        TestEq((byte)124, result[1]);
+        TestEq((byte)118, result[2]);
+        TestEq((byte)-1, result[3]);
+    }
+
+    public static void testSingleElementUByte() {
+        FlexBuffersBuilder builder = new FlexBuffersBuilder();
+        builder.putUInt(0xFF);
+        ByteBuffer b = builder.finish();
+        FlexBuffers.Reference r = FlexBuffers.getRoot(b);
+        TestEq(255, (int)r.asUInt());
+    }
+
+    public static void testSingleElementUShort() {
+        FlexBuffersBuilder builder = new FlexBuffersBuilder();
+        builder.putUInt(0xFFFF);
+        ByteBuffer b = builder.finish();
+        FlexBuffers.Reference r = FlexBuffers.getRoot(b);
+        TestEq(65535, (int)r.asUInt());
+    }
+
+    public static void testSingleElementUInt() {
+        FlexBuffersBuilder builder = new FlexBuffersBuilder();
+        builder.putUInt(0xFFFF_FFFFL);
+        ByteBuffer b = builder.finish();
+        FlexBuffers.Reference r = FlexBuffers.getRoot(b);
+        TestEq(4294967295L, r.asUInt());
+    }
+
+    public static void testSingleFixedTypeVector() {
+
+        int[] ints = new int[]{5, 124, 118, -1};
+        float[] floats = new float[]{5.5f, 124.124f, 118.118f, -1.1f};
+        String[] strings = new String[]{"This", "is", "a", "typed", "array"};
+        boolean[] booleans = new boolean[]{false, true, true, false};
+
+
+        FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(512),
+                FlexBuffersBuilder.BUILDER_FLAG_NONE);
+
+        int mapPos = builder.startMap();
+
+        int vecPos = builder.startVector();
+        for (final int i : ints) {
+            builder.putInt(i);
+        }
+        builder.endVector("ints", vecPos, true, false);
+
+        vecPos = builder.startVector();
+        for (final float i : floats) {
+            builder.putFloat(i);
+        }
+        builder.endVector("floats", vecPos, true, false);
+
+        vecPos = builder.startVector();
+        for (final boolean i : booleans) {
+            builder.putBoolean(i);
+        }
+        builder.endVector("booleans", vecPos, true, false);
+
+        builder.endMap(null, mapPos);
+
+
+        ByteBuffer b = builder.finish();
+        FlexBuffers.Reference r = FlexBuffers.getRoot(b);
+        assert(r.asMap().get("ints").isTypedVector());
+        assert(r.asMap().get("floats").isTypedVector());
+        assert(r.asMap().get("booleans").isTypedVector());
+    }
+
+    public static void testSingleElementVector() {
+        FlexBuffersBuilder b = new FlexBuffersBuilder();
+
+        int vecPos = b.startVector();
+        b.putInt(99);
+        b.putString("wow");
+        int vecpos2 = b.startVector();
+        b.putInt(99);
+        b.putString("wow");
+        b.endVector(null, vecpos2, false, false);
+        b.endVector(null, vecPos, false, false);
+        b.finish();
+
+        FlexBuffers.Reference r = FlexBuffers.getRoot(b.getBuffer());
+        TestEq(FlexBuffers.FBT_VECTOR, r.getType());
+        FlexBuffers.Vector vec = FlexBuffers.getRoot(b.getBuffer()).asVector();
+        TestEq(3, vec.size());
+        TestEq(99, vec.get(0).asInt());
+        TestEq("wow", vec.get(1).asString());
+        TestEq("[ 99, \"wow\" ]", vec.get(2).toString());
+        TestEq("[ 99, \"wow\", [ 99, \"wow\" ] ]", FlexBuffers.getRoot(b.getBuffer()).toString());
+    }
+
+    public static void testSingleElementMap() {
+        FlexBuffersBuilder b = new FlexBuffersBuilder();
+
+        int mapPost = b.startMap();
+        b.putInt("myInt", 0x7fffffbbbfffffffL);
+        b.putString("myString", "wow");
+        b.putString("myString2", "incredible");
+        int start = b.startVector();
+        b.putInt(99);
+        b.putString("wow");
+        b.endVector("myVec", start, false, false);
+
+        b.putFloat("double", 0x1.ffffbbbffffffP+1023);
+        b.endMap(null, mapPost);
+        b.finish();
+
+        FlexBuffers.Reference r = FlexBuffers.getRoot(b.getBuffer());
+        TestEq(FlexBuffers.FBT_MAP, r.getType());
+        FlexBuffers.Map map = FlexBuffers.getRoot(b.getBuffer()).asMap();
+        TestEq(5, map.size());
+        TestEq(0x7fffffbbbfffffffL, map.get("myInt").asLong());
+        TestEq("wow", map.get("myString").asString());
+        TestEq("incredible", map.get("myString2").asString());
+        TestEq(99, map.get("myVec").asVector().get(0).asInt());
+        TestEq("wow", map.get("myVec").asVector().get(1).asString());
+        TestEq(Double.compare(0x1.ffffbbbffffffP+1023, map.get("double").asFloat()), 0);
+        TestEq("{ \"double\" : 1.7976894783391937E308, \"myInt\" : 9223371743723257855, \"myString\" : \"wow\", \"myString2\" : \"incredible\", \"myVec\" : [ 99, \"wow\" ] }",
+                FlexBuffers.getRoot(b.getBuffer()).toString());
+    }
+
+    public static void testFlexBuferEmpty() {
+        FlexBuffers.Blob blob = FlexBuffers.Blob.empty();
+        FlexBuffers.Map ary = FlexBuffers.Map.empty();
+        FlexBuffers.Vector map = FlexBuffers.Vector.empty();
+        FlexBuffers.TypedVector typedAry = FlexBuffers.TypedVector.empty();
+        TestEq(blob.size(), 0);
+        TestEq(map.size(), 0);
+        TestEq(ary.size(), 0);
+        TestEq(typedAry.size(), 0);
+    }
+
+    public static void testHashMapToMap() {
+        int entriesCount = 12;
+
+        HashMap<String, String> source =  new HashMap<>();
+        for (int i = 0; i < entriesCount; i++) {
+            source.put("foo_param_" + i, "foo_value_" + i);
+        }
+
+        FlexBuffersBuilder builder = new FlexBuffersBuilder(1000);
+        int mapStart = builder.startMap();
+        for (Map.Entry<String, String> entry : source.entrySet()) {
+            builder.putString(entry.getKey(), entry.getValue());
+        }
+        builder.endMap(null, mapStart);
+        ByteBuffer bb = builder.finish();
+        bb.rewind();
+
+        FlexBuffers.Reference rootReference = FlexBuffers.getRoot(bb);
+
+        TestEq(rootReference.isMap(), true);
+
+        FlexBuffers.Map flexMap = rootReference.asMap();
+
+        FlexBuffers.KeyVector keys = flexMap.keys();
+        FlexBuffers.Vector values = flexMap.values();
+
+        TestEq(entriesCount, keys.size());
+        TestEq(entriesCount, values.size());
+
+        HashMap<String, String> result =  new HashMap<>();
+        for (int i = 0; i < keys.size(); i++) {
+            result.put(keys.get(i).toString(), values.get(i).asString());
+        }
+
+        TestEq(source, result);
+    }
+
+    public static void testBuilderGrowth() {
+        FlexBuffersBuilder builder = new FlexBuffersBuilder();
+        String someString = "This is a small string";
+        builder.putString(someString);
+        ByteBuffer b = builder.finish();
+        TestEq(someString, FlexBuffers.getRoot(b).asString());
+
+        FlexBuffersBuilder failBuilder = new FlexBuffersBuilder(ByteBuffer.allocate(1));
+        failBuilder.putString(someString);
+    }
+    
+    public static void testFlexBuffersUtf8Map() {
+        FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(512),
+                FlexBuffersBuilder.BUILDER_FLAG_SHARE_KEYS_AND_STRINGS);
+
+        String key0 = "😨 face1";
+        String key1 = "😩 face2";
+        String key2 = "😨 face3";
+        String key3 = "trademark ®";
+        String key4 = "€ euro";
+        String utf8keys[] = { "😨 face1", "😩 face2", "😨 face3", "trademark ®", "€ euro"};
+
+        int map = builder.startMap();
+
+        for (int i=0; i< utf8keys.length; i++) {
+            builder.putString(utf8keys[i], utf8keys[i]);  // Testing key and string reuse.
+        }
+        builder.endMap(null, map);
+        builder.finish();
+
+        FlexBuffers.Map m = FlexBuffers.getRoot(builder.getBuffer()).asMap();
+
+        TestEq(m.size(), 5);
+
+        KeyVector kv = m.keys();
+        for (int i=0; i< utf8keys.length; i++) {
+            TestEq(kv.get(i).toString(), m.get(i).asString());
+        }
+
+        TestEq(m.get(key0).asString(), utf8keys[0]);
+        TestEq(m.get(key1).asString(), utf8keys[1]);
+        TestEq(m.get(key2).asString(), utf8keys[2]);
+        TestEq(m.get(key3).asString(), utf8keys[3]);
+        TestEq(m.get(key4).asString(), utf8keys[4]);
+    }
+
+    public static void TestFlexBuffers() {
+        testSingleElementByte();
+        testSingleElementShort();
+        testSingleElementInt();
+        testSingleElementLong();
+        testSingleElementFloat();
+        testSingleElementDouble();
+        testSingleElementSmallString();
+        testSingleElementBigString();
+        testSingleElementBlob();
+        testSingleElementVector();
+        testSingleFixedTypeVector();
+        testSingleElementUShort();
+        testSingleElementUInt();
+        testSingleElementUByte();
+        testSingleElementMap();
+        testFlexBuffersTest();
+        testHashMapToMap();
+        testFlexBuferEmpty();
+        testFlexBufferVectorStrings();
+        testDeprecatedTypedVectorString();
+        testBuilderGrowth();
+        testFlexBuffersUtf8Map();
+    }
+
+    static void TestVectorOfBytes() {
+        FlatBufferBuilder fbb = new FlatBufferBuilder(16);
+        int str = fbb.createString("ByteMonster");
+        byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        int offset = Monster.createInventoryVector(fbb, data);
+        Monster.startMonster(fbb);
+        Monster.addName(fbb, str);
+        Monster.addInventory(fbb, offset);
+        int monster1 = Monster.endMonster(fbb);
+        Monster.finishMonsterBuffer(fbb, monster1);
+        Monster monsterObject = Monster.getRootAsMonster(fbb.dataBuffer());
+
+        TestEq(monsterObject.inventoryLength(), data.length);
+        TestEq(monsterObject.inventory(4), (int) data[4]);
+        TestEq(ByteBuffer.wrap(data), monsterObject.inventoryAsByteBuffer());
+
+        fbb.clear();
+        ByteBuffer bb = ByteBuffer.wrap(data);
+        offset = fbb.createByteVector(bb);
+        str = fbb.createString("ByteMonster");
+        Monster.startMonster(fbb);
+        Monster.addName(fbb, str);
+        Monster.addInventory(fbb, offset);
+        monster1 = Monster.endMonster(fbb);
+        Monster.finishMonsterBuffer(fbb, monster1);
+        Monster monsterObject2 = Monster.getRootAsMonster(fbb.dataBuffer());
+
+        TestEq(monsterObject2.inventoryLength(), data.length);
+        for (int i = 0; i < data.length; i++) {
+          TestEq(monsterObject2.inventory(i), (int) bb.get(i));
+        }
+
+        fbb.clear();
+        offset = fbb.createByteVector(data, 3, 4);
+        str = fbb.createString("ByteMonster");
+        Monster.startMonster(fbb);
+        Monster.addName(fbb, str);
+        Monster.addInventory(fbb, offset);
+        monster1 = Monster.endMonster(fbb);
+        Monster.finishMonsterBuffer(fbb, monster1);
+        Monster monsterObject3 = Monster.getRootAsMonster(fbb.dataBuffer());
+
+        TestEq(monsterObject3.inventoryLength(), 4);
+        TestEq(monsterObject3.inventory(0), (int) data[3]);
+
+        fbb.clear();
+        bb = ByteBuffer.wrap(data);
+        offset = Monster.createInventoryVector(fbb, bb);
+        str = fbb.createString("ByteMonster");
+        Monster.startMonster(fbb);
+        Monster.addName(fbb, str);
+        Monster.addInventory(fbb, offset);
+        monster1 = Monster.endMonster(fbb);
+        Monster.finishMonsterBuffer(fbb, monster1);
+        Monster monsterObject4 = Monster.getRootAsMonster(fbb.dataBuffer());
+
+        TestEq(monsterObject4.inventoryLength(), data.length);
+        TestEq(monsterObject4.inventory(8), (int) 8);
+
+        fbb.clear();
+        byte[] largeData = new byte[1024];
+        offset = fbb.createByteVector(largeData);
+        str = fbb.createString("ByteMonster");
+        Monster.startMonster(fbb);
+        Monster.addName(fbb, str);
+        Monster.addInventory(fbb, offset);
+        monster1 = Monster.endMonster(fbb);
+        Monster.finishMonsterBuffer(fbb, monster1);
+        Monster monsterObject5 = Monster.getRootAsMonster(fbb.dataBuffer());
+
+        TestEq(monsterObject5.inventoryLength(), largeData.length);
+        TestEq(monsterObject5.inventory(25), (int) largeData[25]);
+
+        fbb.clear();
+        bb = ByteBuffer.wrap(largeData);
+        bb.position(512);
+        ByteBuffer bb2 = bb.slice();
+        TestEq(bb2.arrayOffset(), 512);
+        offset = fbb.createByteVector(bb2);
+        str = fbb.createString("ByteMonster");
+        Monster.startMonster(fbb);
+        Monster.addName(fbb, str);
+        Monster.addInventory(fbb, offset);
+        monster1 = Monster.endMonster(fbb);
+        Monster.finishMonsterBuffer(fbb, monster1);
+        Monster monsterObject6 = Monster.getRootAsMonster(fbb.dataBuffer());
+
+        TestEq(monsterObject6.inventoryLength(), 512);
+        TestEq(monsterObject6.inventory(0), (int) largeData[512]);
+
+        fbb.clear();
+        bb = ByteBuffer.wrap(largeData);
+        bb.limit(256);
+        offset = fbb.createByteVector(bb);
+        str = fbb.createString("ByteMonster");
+        Monster.startMonster(fbb);
+        Monster.addName(fbb, str);
+        Monster.addInventory(fbb, offset);
+        monster1 = Monster.endMonster(fbb);
+        Monster.finishMonsterBuffer(fbb, monster1);
+        Monster monsterObject7 = Monster.getRootAsMonster(fbb.dataBuffer());
+
+        TestEq(monsterObject7.inventoryLength(), 256);
+
+        fbb.clear();
+        bb = ByteBuffer.allocateDirect(2048);
+        offset = fbb.createByteVector(bb);
+        str = fbb.createString("ByteMonster");
+        Monster.startMonster(fbb);
+        Monster.addName(fbb, str);
+        Monster.addInventory(fbb, offset);
+        monster1 = Monster.endMonster(fbb);
+        Monster.finishMonsterBuffer(fbb, monster1);
+        Monster monsterObject8 = Monster.getRootAsMonster(fbb.dataBuffer());
+
+        TestEq(monsterObject8.inventoryLength(), 2048);
+    }
+
+    static void TestSharedStringPool() {
+        FlatBufferBuilder fb = new FlatBufferBuilder(1);
+        String testString = "My string";
+        int offset = fb.createSharedString(testString);
+        for (int i=0; i< 10; i++) {
+            TestEq(offset, fb.createSharedString(testString));
+        }
+    }
+
+    static void TestScalarOptional() {
+        FlatBufferBuilder fbb = new FlatBufferBuilder(1);
+        ScalarStuff.startScalarStuff(fbb);
+        int pos = ScalarStuff.endScalarStuff(fbb);
+        fbb.finish(pos);
+
+        ScalarStuff scalarStuff = ScalarStuff.getRootAsScalarStuff(fbb.dataBuffer());
+        TestEq(scalarStuff.justI8(), (byte)0);
+        TestEq(scalarStuff.maybeI8(), (byte)0);
+        TestEq(scalarStuff.defaultI8(), (byte)42);
+        TestEq(scalarStuff.justU8(), 0);
+        TestEq(scalarStuff.maybeU8(), 0);
+        TestEq(scalarStuff.defaultU8(), 42);
+        TestEq(scalarStuff.justI16(), (short)0);
+        TestEq(scalarStuff.maybeI16(), (short)0);
+        TestEq(scalarStuff.defaultI16(), (short)42);
+        TestEq(scalarStuff.justU16(), 0);
+        TestEq(scalarStuff.maybeU16(), 0);
+        TestEq(scalarStuff.defaultU16(), 42);
+        TestEq(scalarStuff.justI32(), 0);
+        TestEq(scalarStuff.maybeI32(), 0);
+        TestEq(scalarStuff.defaultI32(), 42);
+        TestEq(scalarStuff.justU32(), 0L);
+        TestEq(scalarStuff.maybeU32(), 0L);
+        TestEq(scalarStuff.defaultU32(), 42L);
+        TestEq(scalarStuff.justI64(), 0L);
+        TestEq(scalarStuff.maybeI64(), 0L);
+        TestEq(scalarStuff.defaultI64(), 42L);
+        TestEq(scalarStuff.justU64(), 0L);
+        TestEq(scalarStuff.maybeU64(), 0L);
+        TestEq(scalarStuff.defaultU64(), 42L);
+        TestEq(scalarStuff.justF32(), 0.0f);
+        TestEq(scalarStuff.maybeF32(), 0f);
+        TestEq(scalarStuff.defaultF32(), 42.0f);
+        TestEq(scalarStuff.justF64(), 0.0);
+        TestEq(scalarStuff.maybeF64(), 0.0);
+        TestEq(scalarStuff.defaultF64(), 42.0);
+        TestEq(scalarStuff.justBool(), false);
+        TestEq(scalarStuff.maybeBool(), false);
+        TestEq(scalarStuff.defaultBool(), true);
+        TestEq(scalarStuff.justEnum(), OptionalByte.None);
+        TestEq(scalarStuff.maybeEnum(), OptionalByte.None);
+        TestEq(scalarStuff.defaultEnum(), OptionalByte.One);
+
+        TestEq(scalarStuff.hasMaybeI8(), false);
+        TestEq(scalarStuff.hasMaybeI16(), false);
+        TestEq(scalarStuff.hasMaybeI32(), false);
+        TestEq(scalarStuff.hasMaybeI64(), false);
+        TestEq(scalarStuff.hasMaybeU8(), false);
+        TestEq(scalarStuff.hasMaybeU16(), false);
+        TestEq(scalarStuff.hasMaybeU32(), false);
+        TestEq(scalarStuff.hasMaybeU64(), false);
+        TestEq(scalarStuff.hasMaybeF32(), false);
+        TestEq(scalarStuff.hasMaybeF64(), false);
+        TestEq(scalarStuff.hasMaybeBool(), false);
+        TestEq(scalarStuff.hasMaybeEnum(), false);
+
+        fbb.clear();
+
+        ScalarStuff.startScalarStuff(fbb);
+        ScalarStuff.addJustI8(fbb, (byte)5);
+        ScalarStuff.addMaybeI8(fbb, (byte)5);
+        ScalarStuff.addDefaultI8(fbb, (byte)5);
+        ScalarStuff.addJustU8(fbb, 6);
+        ScalarStuff.addMaybeU8(fbb, 6);
+        ScalarStuff.addDefaultU8(fbb, 6);
+        ScalarStuff.addJustI16(fbb, (short)7);
+        ScalarStuff.addMaybeI16(fbb, (short)7);
+        ScalarStuff.addDefaultI16(fbb, (short)7);
+        ScalarStuff.addJustU16(fbb, 8);
+        ScalarStuff.addMaybeU16(fbb, 8);
+        ScalarStuff.addDefaultU16(fbb, 8);
+        ScalarStuff.addJustI32(fbb, 9);
+        ScalarStuff.addMaybeI32(fbb, 9);
+        ScalarStuff.addDefaultI32(fbb, 9);
+        ScalarStuff.addJustU32(fbb, (long)10);
+        ScalarStuff.addMaybeU32(fbb, (long)10);
+        ScalarStuff.addDefaultU32(fbb, (long)10);
+        ScalarStuff.addJustI64(fbb, 11L);
+        ScalarStuff.addMaybeI64(fbb, 11L);
+        ScalarStuff.addDefaultI64(fbb, 11L);
+        ScalarStuff.addJustU64(fbb, 12L);
+        ScalarStuff.addMaybeU64(fbb, 12L);
+        ScalarStuff.addDefaultU64(fbb, 12L);
+        ScalarStuff.addJustF32(fbb, 13.0f);
+        ScalarStuff.addMaybeF32(fbb, 13.0f);
+        ScalarStuff.addDefaultF32(fbb, 13.0f);
+        ScalarStuff.addJustF64(fbb, 14.0);
+        ScalarStuff.addMaybeF64(fbb, 14.0);
+        ScalarStuff.addDefaultF64(fbb, 14.0);
+        ScalarStuff.addJustBool(fbb, true);
+        ScalarStuff.addMaybeBool(fbb, true);
+        ScalarStuff.addDefaultBool(fbb, true);
+        ScalarStuff.addJustEnum(fbb, OptionalByte.Two);
+        ScalarStuff.addMaybeEnum(fbb, OptionalByte.Two);
+        ScalarStuff.addDefaultEnum(fbb, OptionalByte.Two);
+
+        pos = ScalarStuff.endScalarStuff(fbb);
+
+        fbb.finish(pos);
+
+        scalarStuff = ScalarStuff.getRootAsScalarStuff(fbb.dataBuffer());
+
+        TestEq(scalarStuff.justI8(), (byte)5);
+        TestEq(scalarStuff.maybeI8(), (byte)5);
+        TestEq(scalarStuff.defaultI8(), (byte)5);
+        TestEq(scalarStuff.justU8(), 6);
+        TestEq(scalarStuff.maybeU8(), 6);
+        TestEq(scalarStuff.defaultU8(), 6);
+        TestEq(scalarStuff.justI16(), (short)7);
+        TestEq(scalarStuff.maybeI16(), (short)7);
+        TestEq(scalarStuff.defaultI16(), (short)7);
+        TestEq(scalarStuff.justU16(), 8);
+        TestEq(scalarStuff.maybeU16(), 8);
+        TestEq(scalarStuff.defaultU16(), 8);
+        TestEq(scalarStuff.justI32(), 9);
+        TestEq(scalarStuff.maybeI32(), 9);
+        TestEq(scalarStuff.defaultI32(), 9);
+        TestEq(scalarStuff.justU32(), 10L);
+        TestEq(scalarStuff.maybeU32(), 10L);
+        TestEq(scalarStuff.defaultU32(), 10L);
+        TestEq(scalarStuff.justI64(), 11L);
+        TestEq(scalarStuff.maybeI64(), 11L);
+        TestEq(scalarStuff.defaultI64(), 11L);
+        TestEq(scalarStuff.justU64(), 12L);
+        TestEq(scalarStuff.maybeU64(), 12L);
+        TestEq(scalarStuff.defaultU64(), 12L);
+        TestEq(scalarStuff.justF32(), 13.0f);
+        TestEq(scalarStuff.maybeF32(), 13.0f);
+        TestEq(scalarStuff.defaultF32(), 13.0f);
+        TestEq(scalarStuff.justF64(), 14.0);
+        TestEq(scalarStuff.maybeF64(), 14.0);
+        TestEq(scalarStuff.defaultF64(), 14.0);
+        TestEq(scalarStuff.justBool(), true);
+        TestEq(scalarStuff.maybeBool(), true);
+        TestEq(scalarStuff.defaultBool(), true);
+        TestEq(scalarStuff.justEnum(), OptionalByte.Two);
+        TestEq(scalarStuff.maybeEnum(), OptionalByte.Two);
+        TestEq(scalarStuff.defaultEnum(), OptionalByte.Two);
+
+        TestEq(scalarStuff.hasMaybeI8(), true);
+        TestEq(scalarStuff.hasMaybeI16(), true);
+        TestEq(scalarStuff.hasMaybeI32(), true);
+        TestEq(scalarStuff.hasMaybeI64(), true);
+        TestEq(scalarStuff.hasMaybeU8(), true);
+        TestEq(scalarStuff.hasMaybeU16(), true);
+        TestEq(scalarStuff.hasMaybeU32(), true);
+        TestEq(scalarStuff.hasMaybeU64(), true);
+        TestEq(scalarStuff.hasMaybeF32(), true);
+        TestEq(scalarStuff.hasMaybeF64(), true);
+        TestEq(scalarStuff.hasMaybeBool(), true);
+        TestEq(scalarStuff.hasMaybeEnum(), true);
     }
 
     static <T> void TestEq(T a, T b) {
-        if (!a.equals(b)) {
+        if ((a == null && a != b) || (a != null && !a.equals(b))) {
             System.out.println("" + a.getClass().getName() + " " + b.getClass().getName());
             System.out.println("FlatBuffers test FAILED: \'" + a + "\' != \'" + b + "\'");
+            new Throwable().printStackTrace();
             assert false;
             System.exit(1);
         }
     }
+
 }
