
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 TestFlexBuffers() {
        testSingleElementByte();
        testSingleElementShort();
        testSingleElementInt();
        testSingleElementLong();
        testSingleElementFloat();
        testSingleElementDouble();
        testSingleElementSmallString();
        testSingleElementBigString();
        testSingleElementBlob();
        testSingleElementLongBlob();
        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 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);
        }
    }

}
