
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.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */



class JavaTest {
    public static void main(String[] args) {

        // First, let's test reading a FlatBuffer generated by C++ code:
        // This file was generated from monsterdata_test.json

        byte[] data = null;
        File file = new File("monsterdata_test.mon");
        RandomAccessFile f = null;
        try {
            f = new RandomAccessFile(file, "r");
            data = new byte[(int)f.length()];
            f.readFully(data);
            f.close();
        } catch(java.io.IOException e) {
            System.out.println("FlatBuffers test: couldn't read file");
            return;
        }

        // Now test it:

        ByteBuffer bb = ByteBuffer.wrap(data);
        TestBuffer(bb);

        // Second, let's create a FlatBuffer from scratch in Java, and test it also.
        // We use an initial size of 1 to exercise the reallocation algorithm,
        // normally a size larger than the typical FlatBuffer you generate would be
        // better for performance.
        FlatBufferBuilder fbb = new FlatBufferBuilder(1);

        TestBuilderBasics(fbb, true);
        TestBuilderBasics(fbb, false);

        TestExtendedBuffer(fbb.dataBuffer().asReadOnlyBuffer());

        TestNamespaceNesting();

        TestNestedFlatBuffer();

        TestCreateByteVector();

        TestCreateUninitializedVector();

        TestByteBufferFactory();

        TestSizedInputStream();

        TestVectorOfUnions();

        TestFixedLengthArrays();

        TestFlexBuffers();

        TestVectorOfBytes();

        TestSharedStringPool();

        TestScalarOptional();

        TestPackUnpack(bb);

        System.out.println("FlatBuffers test: completed successfully");
    }

    static void TestEnums() {
      TestEq(Color.name(Color.Red), "Red");
      TestEq(Color.name(Color.Blue), "Blue");
      TestEq(Any.name(Any.NONE), "NONE");
      TestEq(Any.name(Any.Monster), "Monster");
    }

    static void TestBuffer(ByteBuffer bb) {
        TestEq(Monster.MonsterBufferHasIdentifier(bb), true);

        Monster monster = Monster.getRootAsMonster(bb);

        TestEq(monster.hp(), (short)80);
        TestEq(monster.mana(), (short)150);  // default

        TestEq(monster.name(), "MyMonster");
        // monster.friendly() // can't access, deprecated

        Vec3 pos = monster.pos();
        TestEq(pos.x(), 1.0f);
        TestEq(pos.y(), 2.0f);
        TestEq(pos.z(), 3.0f);
        TestEq(pos.test1(), 3.0);
        // issue: int != byte
        TestEq(pos.test2(), (int) Color.Green);
        Test t = pos.test3();
        TestEq(t.a(), (short)5);
        TestEq(t.b(), (byte)6);

        TestEq(monster.testType(), (byte)Any.Monster);
        Monster monster2 = new Monster();
        TestEq(monster.test(monster2) != null, true);
        TestEq(monster2.name(), "Fred");

        TestEq(monster.inventoryLength(), 5);
        int invsum = 0;
        for (int i = 0; i < monster.inventoryLength(); i++)
            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;
        while (ibb.position() < ibb.limit())
            invsum += ibb.get();
        TestEq(invsum, 10);

        Test test_0 = monster.test4(0);
        Test test_1 = monster.test4(1);
        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);
    }

    // this method checks additional fields not present in the binary buffer read from file
    // these new tests are performed on top of the regular tests
    static void TestExtendedBuffer(ByteBuffer bb) {
        TestBuffer(bb);

        Monster monster = Monster.getRootAsMonster(bb);

        TestEq(monster.testhashu32Fnv1(), Integer.MAX_VALUE + 1L);
    }

    static void TestNamespaceNesting() {
        // reference / manipulate these to verify compilation
        FlatBufferBuilder fbb = new FlatBufferBuilder(1);

        TableInNestedNS.startTableInNestedNS(fbb);
        TableInNestedNS.addFoo(fbb, 1234);
        int nestedTableOff = TableInNestedNS.endTableInNestedNS(fbb);

        TableInFirstNS.startTableInFirstNS(fbb);
        TableInFirstNS.addFooTable(fbb, nestedTableOff);
        int off = TableInFirstNS.endTableInFirstNS(fbb);
    }

    static void TestNestedFlatBuffer() {
        final String nestedMonsterName = "NestedMonsterName";
        final short nestedMonsterHp = 600;
        final short nestedMonsterMana = 1024;

        FlatBufferBuilder fbb1 = new FlatBufferBuilder(16);
        int str1 = fbb1.createString(nestedMonsterName);
        Monster.startMonster(fbb1);
        Monster.addName(fbb1, str1);
        Monster.addHp(fbb1, nestedMonsterHp);
        Monster.addMana(fbb1, nestedMonsterMana);
        int monster1 = Monster.endMonster(fbb1);
        Monster.finishMonsterBuffer(fbb1, monster1);
        byte[] fbb1Bytes = fbb1.sizedByteArray();
        fbb1 = null;

        FlatBufferBuilder fbb2 = new FlatBufferBuilder(16);
        int str2 = fbb2.createString("My Monster");
        int nestedBuffer = Monster.createTestnestedflatbufferVector(fbb2, fbb1Bytes);
        Monster.startMonster(fbb2);
        Monster.addName(fbb2, str2);
        Monster.addHp(fbb2, (short)50);
        Monster.addMana(fbb2, (short)32);
        Monster.addTestnestedflatbuffer(fbb2, nestedBuffer);
        int monster = Monster.endMonster(fbb2);
        Monster.finishMonsterBuffer(fbb2, monster);

        // Now test the data extracted from the nested buffer
        Monster mons = Monster.getRootAsMonster(fbb2.dataBuffer());
        Monster nestedMonster = mons.testnestedflatbufferAsMonster();

        TestEq(nestedMonsterMana, nestedMonster.mana());
        TestEq(nestedMonsterHp, nestedMonster.hp());
        TestEq(nestedMonsterName, nestedMonster.name());
    }

    static void TestCreateByteVector() {
        FlatBufferBuilder fbb = new FlatBufferBuilder(16);
        int str = fbb.createString("MyMonster");
        byte[] inventory = new byte[] { 0, 1, 2, 3, 4 };
        int vec = fbb.createByteVector(inventory);
        Monster.startMonster(fbb);
        Monster.addInventory(fbb, vec);
        Monster.addName(fbb, str);
        int monster1 = Monster.endMonster(fbb);
        Monster.finishMonsterBuffer(fbb, monster1);
        Monster monsterObject = Monster.getRootAsMonster(fbb.dataBuffer());

        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());
    }

    static void TestCreateUninitializedVector() {
        FlatBufferBuilder fbb = new FlatBufferBuilder(16);
        int str = fbb.createString("MyMonster");
        byte[] inventory = new byte[] { 0, 1, 2, 3, 4 };
        ByteBuffer bb = fbb.createUnintializedVector(1, inventory.length, 1);
        for (byte i:inventory) {
            bb.put(i);
        }
        int vec = fbb.endVector();
        Monster.startMonster(fbb);
        Monster.addInventory(fbb, vec);
        Monster.addName(fbb, str);
        int monster1 = Monster.endMonster(fbb);
        Monster.finishMonsterBuffer(fbb, monster1);
        Monster monsterObject = Monster.getRootAsMonster(fbb.dataBuffer());

        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());
    }

    static void TestByteBufferFactory() {
        final class MappedByteBufferFactory extends FlatBufferBuilder.ByteBufferFactory {
            @Override
            public ByteBuffer newByteBuffer(int capacity) {
                ByteBuffer bb;
                try {
                    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;
                }
                return bb;
            }
        }

        FlatBufferBuilder fbb = new FlatBufferBuilder(1, new MappedByteBufferFactory());

        TestBuilderBasics(fbb, false);
    }

    static void TestSizedInputStream() {
        // Test on default FlatBufferBuilder that uses HeapByteBuffer
        FlatBufferBuilder fbb = new FlatBufferBuilder(1);

        TestBuilderBasics(fbb, false);

        InputStream in = fbb.sizedInputStream();
        byte[] array = fbb.sizedByteArray();
        int count = 0;
        int currentVal = 0;

        while (currentVal != -1 && count < array.length) {
            try {
                currentVal = in.read();
            } catch(java.io.IOException e) {
                System.out.println("FlatBuffers test: couldn't read from InputStream");
                return;
            }
            TestEq((byte)currentVal, array[count]);
            count++;
        }
        TestEq(count, array.length);
    }

    static void TestBuilderBasics(FlatBufferBuilder fbb, boolean sizePrefix) {
        int[] names = {fbb.createString("Frodo"), fbb.createString("Barney"), fbb.createString("Wilma")};
        int[] off = new int[3];
        Monster.startMonster(fbb);
        Monster.addName(fbb, names[0]);
        off[0] = Monster.endMonster(fbb);
        Monster.startMonster(fbb);
        Monster.addName(fbb, names[1]);
        off[1] = Monster.endMonster(fbb);
        Monster.startMonster(fbb);
        Monster.addName(fbb, names[2]);
        off[2] = Monster.endMonster(fbb);
        int sortMons = fbb.createSortedVectorOfTables(new Monster(), off);

        // We set up the same values as monsterdata.json:

        int str = fbb.createString("MyMonster");

        int inv = Monster.createInventoryVector(fbb, new byte[] { 0, 1, 2, 3, 4 });

        int fred = fbb.createString("Fred");
        Monster.startMonster(fbb);
        Monster.addName(fbb, fred);
        int mon2 = Monster.endMonster(fbb);

        Monster.startTest4Vector(fbb, 2);
        Test.createTest(fbb, (short)10, (byte)20);
        Test.createTest(fbb, (short)30, (byte)40);
        int test4 = fbb.endVector();

        int testArrayOfString = Monster.createTestarrayofstringVector(fbb, new int[] {
                fbb.createString("test1"),
                fbb.createString("test2")
        });

        Monster.startMonster(fbb);
        Monster.addPos(fbb, Vec3.createVec3(fbb, 1.0f, 2.0f, 3.0f, 3.0,
                Color.Green, (short)5, (byte)6));
        Monster.addHp(fbb, (short)80);
        Monster.addName(fbb, str);
        Monster.addInventory(fbb, inv);
        Monster.addTestType(fbb, (byte)Any.Monster);
        Monster.addTest(fbb, mon2);
        Monster.addTest4(fbb, test4);
        Monster.addTestarrayofstring(fbb, testArrayOfString);
        Monster.addTestbool(fbb, true);
        Monster.addTesthashu32Fnv1(fbb, Integer.MAX_VALUE + 1L);
        Monster.addTestarrayoftables(fbb, sortMons);
        int mon = Monster.endMonster(fbb);

        if (sizePrefix) {
            Monster.finishSizePrefixedMonsterBuffer(fbb, mon);
        } else {
            Monster.finishMonsterBuffer(fbb, mon);
        }

        // Write the result to a file for debugging purposes:
        // Note that the binaries are not necessarily identical, since the JSON
        // parser may serialize in a slightly different order than the above
        // Java code. They are functionally equivalent though.

        try {
            String filename = "monsterdata_java_wire" + (sizePrefix ? "_sp" : "") + ".mon";
            FileChannel fc = new FileOutputStream(filename).getChannel();
            fc.write(fbb.dataBuffer().duplicate());
            fc.close();
        } catch(java.io.IOException e) {
            System.out.println("FlatBuffers test: couldn't write file");
            return;
        }

        // Test it:
        ByteBuffer dataBuffer = fbb.dataBuffer();
        if (sizePrefix) {
            TestEq(ByteBufferUtil.getSizePrefix(dataBuffer) + SIZE_PREFIX_LENGTH,
                   dataBuffer.remaining());
            dataBuffer = ByteBufferUtil.removeSizePrefix(dataBuffer);
        }
        TestExtendedBuffer(dataBuffer);

        // Make sure it also works with read only ByteBuffers. This is slower,
        // since creating strings incurs an additional copy
        // (see Table.__string).
        TestExtendedBuffer(dataBuffer.asReadOnlyBuffer());

        TestEnums();

        //Attempt to mutate Monster fields and check whether the buffer has been mutated properly
        // revert to original values after testing
        Monster monster = Monster.getRootAsMonster(dataBuffer);

        // mana is optional and does not exist in the buffer so the mutation should fail
        // the mana field should retain its default value
        TestEq(monster.mutateMana((short)10), false);
        TestEq(monster.mana(), (short)150);

        // Accessing a vector of sorted by the key tables
        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);

        //mutate the inventory vector
        TestEq(monster.mutateInventory(0, 1), true);
        TestEq(monster.mutateInventory(1, 2), true);
        TestEq(monster.mutateInventory(2, 3), true);
        TestEq(monster.mutateInventory(3, 4), true);
        TestEq(monster.mutateInventory(4, 5), true);

        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);
        TestEq(monster.mutateInventory(1, 1), true);
        TestEq(monster.mutateInventory(2, 2), true);
        TestEq(monster.mutateInventory(3, 3), true);
        TestEq(monster.mutateInventory(4, 4), true);

        // get a struct field and edit one of its fields
        Vec3 pos = monster.pos();
        TestEq(pos.x(), 1.0f);
        pos.mutateX(55.0f);
        TestEq(pos.x(), 55.0f);
        pos.mutateX(1.0f);
        TestEq(pos.x(), 1.0f);
    }

    static void TestVectorOfUnions() {
        final FlatBufferBuilder fbb = new FlatBufferBuilder();

        final int swordAttackDamage = 1;

        final int[] characterVector = new int[] {
            Attacker.createAttacker(fbb, swordAttackDamage),
        };

        final byte[] characterTypeVector = new byte[]{
            Character.MuLan,
        };

        Movie.finishMovieBuffer(
            fbb,
            Movie.createMovie(
                fbb,
                (byte)0,
                (byte)0,
                Movie.createCharactersTypeVector(fbb, characterTypeVector),
                Movie.createCharactersVector(fbb, characterVector)
            )
        );

        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);
    }

    static void TestFixedLengthArrays() {
        FlatBufferBuilder builder = new FlatBufferBuilder(0);

        float       a;
        int[]       b = new int[15];
        byte        c;
        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;
        c = 1;
        d_a[0][0] = 1;
        d_a[0][1] = 2;
        d_a[1][0] = 3;
        d_a[1][1] = 4;
        d_b[0] = TestEnum.B;
        d_b[1] = TestEnum.C;
        d_c[0][0] = TestEnum.A;
        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, d_d, e, f);

        // Create a table with the ArrayStruct.
        ArrayTable.startArrayTable(builder);
        ArrayTable.addA(builder, arrayOffset);
        int tableOffset = ArrayTable.endArrayTable(builder);

        ArrayTable.finishArrayTableBuffer(builder, tableOffset);

        ArrayTable table = ArrayTable.getRootAsArrayTable(builder.dataBuffer());
        NestedStruct nested = new NestedStruct();

        TestEq(table.a().a(), 0.5f);
        for (int i = 0; i < 15; i++) TestEq(table.a().b(i), i);
        TestEq(table.a().c(), (byte)1);
        TestEq(table.a().d(nested, 0).a(0), 1);
        TestEq(table.a().d(nested, 0).a(1), 2);
        TestEq(table.a().d(nested, 1).a(0), 3);
        TestEq(table.a().d(nested, 1).a(1), 4);
        TestEq(table.a().d(nested, 0).b(), TestEnum.B);
        TestEq(table.a().d(nested, 1).b(), TestEnum.C);
        TestEq(table.a().d(nested, 0).c(0), TestEnum.A);
        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 testSingleElementLongBlob() {

        // verifies blobs of up to 2^16 in length
        for (int i = 2; i <= 1<<16; i = i<<1) {
            byte[] input = new byte[i-1];
            for (int index = 0; index < input.length; index++) {
                input[index] = (byte)(index % 64);
            }

            FlexBuffersBuilder builder = new FlexBuffersBuilder();
            builder.putBlob(input);
            ByteBuffer b = builder.finish();
            FlexBuffers.Reference r = FlexBuffers.getRoot(b);
            byte[] result = r.asBlob().getBytes();
            
            for (int index = 0; index < input.length; index++) {
                TestEq((byte)(index % 64), result[index]);
            }
        }
    }

    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 testFlexBuffersMapLookup() {
        FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(512),
                FlexBuffersBuilder.BUILDER_FLAG_SHARE_KEYS_AND_STRINGS);

        String key0 = "123";
        String key1 = "1234";
        String key2 = "12345";
        String[] keys = new String[]{key0, key1, key2};

        int map = builder.startMap();

        for (int i=0; i< keys.length; i++) {
            builder.putString(keys[i], keys[i]);  // Testing key and string reuse.
        }
        builder.endMap(null, map);
        builder.finish();

        FlexBuffers.Map m = FlexBuffers.getRoot(builder.getBuffer()).asMap();
        for (int i=0; i< keys.length; i++) {
            TestEq(m.get(keys[i]).asString(), keys[i]);
            TestEq(m.get(keys[i].getBytes(StandardCharsets.UTF_8)).asString(), keys[i]);
        }
    }

    public static void TestFlexBuffers() {
        testSingleElementByte();
        testSingleElementShort();
        testSingleElementInt();
        testSingleElementLong();
        testSingleElementFloat();
        testSingleElementDouble();
        testSingleElementSmallString();
        testSingleElementBigString();
        testSingleElementBlob();
        testSingleElementLongBlob();
        testSingleElementVector();
        testSingleFixedTypeVector();
        testSingleElementUShort();
        testSingleElementUInt();
        testSingleElementUByte();
        testSingleElementMap();
        testFlexBuffersTest();
        testHashMapToMap();
        testFlexBuferEmpty();
        testFlexBufferVectorStrings();
        testDeprecatedTypedVectorString();
        testBuilderGrowth();
        testFlexBuffersUtf8Map();
        testFlexBuffersMapLookup();
    }

    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 void TestObject(MonsterT monster) {
        TestEq(monster.getHp(), (short) 80);
        TestEq(monster.getMana(), (short) 150);  // default

        TestEq(monster.getName(), "MyMonster");
        TestEq(monster.getColor(), Color.Blue);
        // monster.friendly() // can't access, deprecated

        Vec3T pos = monster.getPos();
        TestEq(pos.getX(), 1.0f);
        TestEq(pos.getY(), 2.0f);
        TestEq(pos.getZ(), 3.0f);
        TestEq(pos.getTest1(), 3.0);
        // issue: int != byte
        TestEq(pos.getTest2(), (int) Color.Green);
        TestT t = pos.getTest3();
        TestEq(t.getA(), (short) 5);
        TestEq(t.getB(), (byte) 6);

        TestEq(monster.getTest().getType(), (byte) Any.Monster);
        MonsterT monster2 = (MonsterT) monster.getTest().getValue();
        TestEq(monster2 != null, true);
        TestEq(monster2.getName(), "Fred");

        int[] inv = monster.getInventory();
        TestEq(inv.length, 5);
        int[] expInv = {0, 1, 2, 3, 4};
        for (int i = 0; i < inv.length; i++)
            TestEq(expInv[i], inv[i]);

        TestT[] test4 = monster.getTest4();
        TestT test_0 = test4[0];
        TestT test_1 = test4[1];
        TestEq(test4.length, 2);
        TestEq(test_0.getA(), (short) 10);
        TestEq(test_0.getB(), (byte) 20);
        TestEq(test_1.getA(), (short) 30);
        TestEq(test_1.getB(), (byte) 40);

        String[] testarrayofstring = monster.getTestarrayofstring();
        TestEq(testarrayofstring.length, 2);
        TestEq(testarrayofstring[0], "test1");
        TestEq(testarrayofstring[1], "test2");

        MonsterT[] testarrayoftables = monster.getTestarrayoftables();
        TestEq(testarrayoftables.length, 0);

        MonsterT enemy = monster.getEnemy();
        TestEq(enemy != null, true);
        TestEq(enemy.getName(), "Fred");

        int[] testnestedflatbuffer = monster.getTestnestedflatbuffer();
        TestEq(testnestedflatbuffer.length, 0);

        TestEq(monster.getTestempty() == null, true);

        TestEq(monster.getTestbool(), true);

        boolean[] testarrayofbools = monster.getTestarrayofbools();
        TestEq(testarrayofbools.length, 3);
        TestEq(testarrayofbools[0], true);
        TestEq(testarrayofbools[1], false);
        TestEq(testarrayofbools[2], true);

        TestEq(monster.getTestf(), 3.14159f);
        TestEq(monster.getTestf2(), 3.0f);
        TestEq(monster.getTestf3(), 0.0f);
        TestEq(monster.getTestf3(), 0.0f);

        AbilityT[] testarrayofsortedstruct = monster.getTestarrayofsortedstruct();
        TestEq(testarrayofsortedstruct.length, 3);
        TestEq(testarrayofsortedstruct[0].getId(), (long) 0);
        TestEq(testarrayofsortedstruct[1].getId(), (long) 1);
        TestEq(testarrayofsortedstruct[2].getId(), (long) 5);
        TestEq(testarrayofsortedstruct[0].getDistance(), (long) 45);
        TestEq(testarrayofsortedstruct[1].getDistance(), (long) 21);
        TestEq(testarrayofsortedstruct[2].getDistance(), (long) 12);

        int[] flex = monster.getFlex();
        TestEq(flex.length, 0);

        long[] vectorOfLongs = monster.getVectorOfLongs();
        TestEq(vectorOfLongs.length, 5);
        long l = 1;
        for (int i = 0; i < vectorOfLongs.length; i++) {
            TestEq(vectorOfLongs[i], l);
            l *= 100;
        }

        double[] vectorOfDoubles = monster.getVectorOfDoubles();
        TestEq(vectorOfDoubles.length, 3);
        TestEq(vectorOfDoubles[0], -1.7976931348623157E308);
        TestEq(vectorOfDoubles[1], 0.0);
        TestEq(vectorOfDoubles[2], 1.7976931348623157E308);

        TestEq(monster.getParentNamespaceTest() == null, true);
        ReferrableT[] vectorOfReferrables = monster.getVectorOfReferrables();
        TestEq(vectorOfReferrables.length, 0);

        TestEq(monster.getSignedEnum(), (byte) -1);
    }

    static void TestPackUnpack(ByteBuffer bb) {
        Monster m = Monster.getRootAsMonster(bb);
        MonsterT mObject = m.unpack();
        TestObject(mObject);
        FlatBufferBuilder fbb = new FlatBufferBuilder();
        int monster = Monster.pack(fbb, mObject);
        Monster.finishMonsterBuffer(fbb, monster);
        TestBuffer(fbb.dataBuffer());

        byte[] bytes = mObject.serializeToBinary();
        MonsterT newMonsterT = MonsterT.deserializeFromBinary(bytes);
        TestObject(newMonsterT);
    }

    static <T> void TestEq(T a, T 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);
        }
    }

}
