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

        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 testSingleElementUByte() {
        FlexBuffersBuilder builder = new FlexBuffersBuilder();
        builder.putUInt(0xFF);
        ByteBuffer b = builder.finish();
        FlexBuffers.Reference r = FlexBuffers.getRoot(b);
        TestEq(255, (int)r.asUInt());
    }

    public static void testSingleElementUShort() {
        FlexBuffersBuilder builder = new FlexBuffersBuilder();
        builder.putUInt(0xFFFF);
        ByteBuffer b = builder.finish();
        FlexBuffers.Reference r = FlexBuffers.getRoot(b);
        TestEq(65535, (int)r.asUInt());
    }

    public static void testSingleElementUInt() {
        FlexBuffersBuilder builder = new FlexBuffersBuilder();
        builder.putUInt(0xFFFF_FFFFL);
        ByteBuffer b = builder.finish();
        FlexBuffers.Reference r = FlexBuffers.getRoot(b);
        TestEq(4294967295L, r.asUInt());
    }

    public static void testSingleFixedTypeVector() {

        int[] ints = new int[]{5, 124, 118, -1};
        float[] floats = new float[]{5.5f, 124.124f, 118.118f, -1.1f};
        String[] strings = new String[]{"This", "is", "a", "typed", "array"};
        boolean[] booleans = new boolean[]{false, true, true, false};


        FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(512),
                FlexBuffersBuilder.BUILDER_FLAG_NONE);

        int mapPos = builder.startMap();

        int vecPos = builder.startVector();
        for (final int i : ints) {
            builder.putInt(i);
        }
        builder.endVector("ints", vecPos, true, false);

        vecPos = builder.startVector();
        for (final float i : floats) {
            builder.putFloat(i);
        }
        builder.endVector("floats", vecPos, true, false);

        vecPos = builder.startVector();
        for (final boolean i : booleans) {
            builder.putBoolean(i);
        }
        builder.endVector("booleans", vecPos, true, false);

        builder.endMap(null, mapPos);


        ByteBuffer b = builder.finish();
        FlexBuffers.Reference r = FlexBuffers.getRoot(b);
        assert(r.asMap().get("ints").isTypedVector());
        assert(r.asMap().get("floats").isTypedVector());
        assert(r.asMap().get("booleans").isTypedVector());
    }

    public static void testSingleElementVector() {
        FlexBuffersBuilder b = new FlexBuffersBuilder();

        int vecPos = b.startVector();
        b.putInt(99);
        b.putString("wow");
        int vecpos2 = b.startVector();
        b.putInt(99);
        b.putString("wow");
        b.endVector(null, vecpos2, false, false);
        b.endVector(null, vecPos, false, false);
        b.finish();

        FlexBuffers.Reference r = FlexBuffers.getRoot(b.getBuffer());
        TestEq(FlexBuffers.FBT_VECTOR, r.getType());
        FlexBuffers.Vector vec = FlexBuffers.getRoot(b.getBuffer()).asVector();
        TestEq(3, vec.size());
        TestEq(99, vec.get(0).asInt());
        TestEq("wow", vec.get(1).asString());
        TestEq("[ 99, \"wow\" ]", vec.get(2).toString());
        TestEq("[ 99, \"wow\", [ 99, \"wow\" ] ]", FlexBuffers.getRoot(b.getBuffer()).toString());
    }

    public static void testSingleElementMap() {
        FlexBuffersBuilder b = new FlexBuffersBuilder();

        int mapPost = b.startMap();
        b.putInt("myInt", 0x7fffffbbbfffffffL);
        b.putString("myString", "wow");
        b.putString("myString2", "incredible");
        int start = b.startVector();
        b.putInt(99);
        b.putString("wow");
        b.endVector("myVec", start, false, false);

        b.putFloat("double", 0x1.ffffbbbffffffP+1023);
        b.endMap(null, mapPost);
        b.finish();

        FlexBuffers.Reference r = FlexBuffers.getRoot(b.getBuffer());
        TestEq(FlexBuffers.FBT_MAP, r.getType());
        FlexBuffers.Map map = FlexBuffers.getRoot(b.getBuffer()).asMap();
        TestEq(5, map.size());
        TestEq(0x7fffffbbbfffffffL, map.get("myInt").asLong());
        TestEq("wow", map.get("myString").asString());
        TestEq("incredible", map.get("myString2").asString());
        TestEq(99, map.get("myVec").asVector().get(0).asInt());
        TestEq("wow", map.get("myVec").asVector().get(1).asString());
        TestEq(Double.compare(0x1.ffffbbbffffffP+1023, map.get("double").asFloat()), 0);
        TestEq("{ \"double\" : 1.7976894783391937E308, \"myInt\" : 9223371743723257855, \"myString\" : \"wow\", \"myString2\" : \"incredible\", \"myVec\" : [ 99, \"wow\" ] }",
                FlexBuffers.getRoot(b.getBuffer()).toString());
    }

    public static void testFlexBuferEmpty() {
        FlexBuffers.Blob blob = FlexBuffers.Blob.empty();
        FlexBuffers.Map ary = FlexBuffers.Map.empty();
        FlexBuffers.Vector map = FlexBuffers.Vector.empty();
        FlexBuffers.TypedVector typedAry = FlexBuffers.TypedVector.empty();
        TestEq(blob.size(), 0);
        TestEq(map.size(), 0);
        TestEq(ary.size(), 0);
        TestEq(typedAry.size(), 0);
    }

    public static void testHashMapToMap() {
        int entriesCount = 12;

        HashMap<String, String> source =  new HashMap<>();
        for (int i = 0; i < entriesCount; i++) {
            source.put("foo_param_" + i, "foo_value_" + i);
        }

        FlexBuffersBuilder builder = new FlexBuffersBuilder(1000);
        int mapStart = builder.startMap();
        for (Map.Entry<String, String> entry : source.entrySet()) {
            builder.putString(entry.getKey(), entry.getValue());
        }
        builder.endMap(null, mapStart);
        ByteBuffer bb = builder.finish();
        bb.rewind();

        FlexBuffers.Reference rootReference = FlexBuffers.getRoot(bb);

        TestEq(rootReference.isMap(), true);

        FlexBuffers.Map flexMap = rootReference.asMap();

        FlexBuffers.KeyVector keys = flexMap.keys();
        FlexBuffers.Vector values = flexMap.values();

        TestEq(entriesCount, keys.size());
        TestEq(entriesCount, values.size());

        HashMap<String, String> result =  new HashMap<>();
        for (int i = 0; i < keys.size(); i++) {
            result.put(keys.get(i).toString(), values.get(i).asString());
        }

        TestEq(source, result);
    }

    public static void testBuilderGrowth() {
        FlexBuffersBuilder builder = new FlexBuffersBuilder();
        String someString = "This is a small string";
        builder.putString(someString);
        ByteBuffer b = builder.finish();
        TestEq(someString, FlexBuffers.getRoot(b).asString());

        FlexBuffersBuilder failBuilder = new FlexBuffersBuilder(ByteBuffer.allocate(1));
        failBuilder.putString(someString);
    }
    
    public static void testFlexBuffersUtf8Map() {
        FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(512),
                FlexBuffersBuilder.BUILDER_FLAG_SHARE_KEYS_AND_STRINGS);

        String key0 = "😨 face1";
        String key1 = "😩 face2";
        String key2 = "😨 face3";
        String key3 = "trademark ®";
        String key4 = "€ euro";
        String utf8keys[] = { "😨 face1", "😩 face2", "😨 face3", "trademark ®", "€ euro"};

        int map = builder.startMap();

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

        FlexBuffers.Map m = FlexBuffers.getRoot(builder.getBuffer()).asMap();

        TestEq(m.size(), 5);

        KeyVector kv = m.keys();
        for (int i=0; i< utf8keys.length; i++) {
            TestEq(kv.get(i).toString(), m.get(i).asString());
        }

        TestEq(m.get(key0).asString(), utf8keys[0]);
        TestEq(m.get(key1).asString(), utf8keys[1]);
        TestEq(m.get(key2).asString(), utf8keys[2]);
        TestEq(m.get(key3).asString(), utf8keys[3]);
        TestEq(m.get(key4).asString(), utf8keys[4]);
    }

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

    static void TestVectorOfBytes() {
        FlatBufferBuilder fbb = new FlatBufferBuilder(16);
        int str = fbb.createString("ByteMonster");
        byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
        int offset = Monster.createInventoryVector(fbb, data);
        Monster.startMonster(fbb);
        Monster.addName(fbb, str);
        Monster.addInventory(fbb, offset);
        int monster1 = Monster.endMonster(fbb);
        Monster.finishMonsterBuffer(fbb, monster1);
        Monster monsterObject = Monster.getRootAsMonster(fbb.dataBuffer());

        TestEq(monsterObject.inventoryLength(), data.length);
        TestEq(monsterObject.inventory(4), (int) data[4]);
        TestEq(ByteBuffer.wrap(data), monsterObject.inventoryAsByteBuffer());

        fbb.clear();
        ByteBuffer bb = ByteBuffer.wrap(data);
        offset = fbb.createByteVector(bb);
        str = fbb.createString("ByteMonster");
        Monster.startMonster(fbb);
        Monster.addName(fbb, str);
        Monster.addInventory(fbb, offset);
        monster1 = Monster.endMonster(fbb);
        Monster.finishMonsterBuffer(fbb, monster1);
        Monster monsterObject2 = Monster.getRootAsMonster(fbb.dataBuffer());

        TestEq(monsterObject2.inventoryLength(), data.length);
        for (int i = 0; i < data.length; i++) {
          TestEq(monsterObject2.inventory(i), (int) bb.get(i));
        }

        fbb.clear();
        offset = fbb.createByteVector(data, 3, 4);
        str = fbb.createString("ByteMonster");
        Monster.startMonster(fbb);
        Monster.addName(fbb, str);
        Monster.addInventory(fbb, offset);
        monster1 = Monster.endMonster(fbb);
        Monster.finishMonsterBuffer(fbb, monster1);
        Monster monsterObject3 = Monster.getRootAsMonster(fbb.dataBuffer());

        TestEq(monsterObject3.inventoryLength(), 4);
        TestEq(monsterObject3.inventory(0), (int) data[3]);

        fbb.clear();
        bb = ByteBuffer.wrap(data);
        offset = Monster.createInventoryVector(fbb, bb);
        str = fbb.createString("ByteMonster");
        Monster.startMonster(fbb);
        Monster.addName(fbb, str);
        Monster.addInventory(fbb, offset);
        monster1 = Monster.endMonster(fbb);
        Monster.finishMonsterBuffer(fbb, monster1);
        Monster monsterObject4 = Monster.getRootAsMonster(fbb.dataBuffer());

        TestEq(monsterObject4.inventoryLength(), data.length);
        TestEq(monsterObject4.inventory(8), (int) 8);

        fbb.clear();
        byte[] largeData = new byte[1024];
        offset = fbb.createByteVector(largeData);
        str = fbb.createString("ByteMonster");
        Monster.startMonster(fbb);
        Monster.addName(fbb, str);
        Monster.addInventory(fbb, offset);
        monster1 = Monster.endMonster(fbb);
        Monster.finishMonsterBuffer(fbb, monster1);
        Monster monsterObject5 = Monster.getRootAsMonster(fbb.dataBuffer());

        TestEq(monsterObject5.inventoryLength(), largeData.length);
        TestEq(monsterObject5.inventory(25), (int) largeData[25]);

        fbb.clear();
        bb = ByteBuffer.wrap(largeData);
        bb.position(512);
        ByteBuffer bb2 = bb.slice();
        TestEq(bb2.arrayOffset(), 512);
        offset = fbb.createByteVector(bb2);
        str = fbb.createString("ByteMonster");
        Monster.startMonster(fbb);
        Monster.addName(fbb, str);
        Monster.addInventory(fbb, offset);
        monster1 = Monster.endMonster(fbb);
        Monster.finishMonsterBuffer(fbb, monster1);
        Monster monsterObject6 = Monster.getRootAsMonster(fbb.dataBuffer());

        TestEq(monsterObject6.inventoryLength(), 512);
        TestEq(monsterObject6.inventory(0), (int) largeData[512]);

        fbb.clear();
        bb = ByteBuffer.wrap(largeData);
        bb.limit(256);
        offset = fbb.createByteVector(bb);
        str = fbb.createString("ByteMonster");
        Monster.startMonster(fbb);
        Monster.addName(fbb, str);
        Monster.addInventory(fbb, offset);
        monster1 = Monster.endMonster(fbb);
        Monster.finishMonsterBuffer(fbb, monster1);
        Monster monsterObject7 = Monster.getRootAsMonster(fbb.dataBuffer());

        TestEq(monsterObject7.inventoryLength(), 256);

        fbb.clear();
        bb = ByteBuffer.allocateDirect(2048);
        offset = fbb.createByteVector(bb);
        str = fbb.createString("ByteMonster");
        Monster.startMonster(fbb);
        Monster.addName(fbb, str);
        Monster.addInventory(fbb, offset);
        monster1 = Monster.endMonster(fbb);
        Monster.finishMonsterBuffer(fbb, monster1);
        Monster monsterObject8 = Monster.getRootAsMonster(fbb.dataBuffer());

        TestEq(monsterObject8.inventoryLength(), 2048);
    }

    static void TestSharedStringPool() {
        FlatBufferBuilder fb = new FlatBufferBuilder(1);
        String testString = "My string";
        int offset = fb.createSharedString(testString);
        for (int i=0; i< 10; i++) {
            TestEq(offset, fb.createSharedString(testString));
        }
    }

    static void TestScalarOptional() {
        FlatBufferBuilder fbb = new FlatBufferBuilder(1);
        ScalarStuff.startScalarStuff(fbb);
        int pos = ScalarStuff.endScalarStuff(fbb);
        fbb.finish(pos);

        ScalarStuff scalarStuff = ScalarStuff.getRootAsScalarStuff(fbb.dataBuffer());
        TestEq(scalarStuff.justI8(), (byte)0);
        TestEq(scalarStuff.maybeI8(), (byte)0);
        TestEq(scalarStuff.defaultI8(), (byte)42);
        TestEq(scalarStuff.justU8(), 0);
        TestEq(scalarStuff.maybeU8(), 0);
        TestEq(scalarStuff.defaultU8(), 42);
        TestEq(scalarStuff.justI16(), (short)0);
        TestEq(scalarStuff.maybeI16(), (short)0);
        TestEq(scalarStuff.defaultI16(), (short)42);
        TestEq(scalarStuff.justU16(), 0);
        TestEq(scalarStuff.maybeU16(), 0);
        TestEq(scalarStuff.defaultU16(), 42);
        TestEq(scalarStuff.justI32(), 0);
        TestEq(scalarStuff.maybeI32(), 0);
        TestEq(scalarStuff.defaultI32(), 42);
        TestEq(scalarStuff.justU32(), 0L);
        TestEq(scalarStuff.maybeU32(), 0L);
        TestEq(scalarStuff.defaultU32(), 42L);
        TestEq(scalarStuff.justI64(), 0L);
        TestEq(scalarStuff.maybeI64(), 0L);
        TestEq(scalarStuff.defaultI64(), 42L);
        TestEq(scalarStuff.justU64(), 0L);
        TestEq(scalarStuff.maybeU64(), 0L);
        TestEq(scalarStuff.defaultU64(), 42L);
        TestEq(scalarStuff.justF32(), 0.0f);
        TestEq(scalarStuff.maybeF32(), 0f);
        TestEq(scalarStuff.defaultF32(), 42.0f);
        TestEq(scalarStuff.justF64(), 0.0);
        TestEq(scalarStuff.maybeF64(), 0.0);
        TestEq(scalarStuff.defaultF64(), 42.0);
        TestEq(scalarStuff.justBool(), false);
        TestEq(scalarStuff.maybeBool(), false);
        TestEq(scalarStuff.defaultBool(), true);
        TestEq(scalarStuff.justEnum(), OptionalByte.None);
        TestEq(scalarStuff.maybeEnum(), OptionalByte.None);
        TestEq(scalarStuff.defaultEnum(), OptionalByte.One);

        TestEq(scalarStuff.hasMaybeI8(), false);
        TestEq(scalarStuff.hasMaybeI16(), false);
        TestEq(scalarStuff.hasMaybeI32(), false);
        TestEq(scalarStuff.hasMaybeI64(), false);
        TestEq(scalarStuff.hasMaybeU8(), false);
        TestEq(scalarStuff.hasMaybeU16(), false);
        TestEq(scalarStuff.hasMaybeU32(), false);
        TestEq(scalarStuff.hasMaybeU64(), false);
        TestEq(scalarStuff.hasMaybeF32(), false);
        TestEq(scalarStuff.hasMaybeF64(), false);
        TestEq(scalarStuff.hasMaybeBool(), false);
        TestEq(scalarStuff.hasMaybeEnum(), false);

        fbb.clear();

        ScalarStuff.startScalarStuff(fbb);
        ScalarStuff.addJustI8(fbb, (byte)5);
        ScalarStuff.addMaybeI8(fbb, (byte)5);
        ScalarStuff.addDefaultI8(fbb, (byte)5);
        ScalarStuff.addJustU8(fbb, 6);
        ScalarStuff.addMaybeU8(fbb, 6);
        ScalarStuff.addDefaultU8(fbb, 6);
        ScalarStuff.addJustI16(fbb, (short)7);
        ScalarStuff.addMaybeI16(fbb, (short)7);
        ScalarStuff.addDefaultI16(fbb, (short)7);
        ScalarStuff.addJustU16(fbb, 8);
        ScalarStuff.addMaybeU16(fbb, 8);
        ScalarStuff.addDefaultU16(fbb, 8);
        ScalarStuff.addJustI32(fbb, 9);
        ScalarStuff.addMaybeI32(fbb, 9);
        ScalarStuff.addDefaultI32(fbb, 9);
        ScalarStuff.addJustU32(fbb, (long)10);
        ScalarStuff.addMaybeU32(fbb, (long)10);
        ScalarStuff.addDefaultU32(fbb, (long)10);
        ScalarStuff.addJustI64(fbb, 11L);
        ScalarStuff.addMaybeI64(fbb, 11L);
        ScalarStuff.addDefaultI64(fbb, 11L);
        ScalarStuff.addJustU64(fbb, 12L);
        ScalarStuff.addMaybeU64(fbb, 12L);
        ScalarStuff.addDefaultU64(fbb, 12L);
        ScalarStuff.addJustF32(fbb, 13.0f);
        ScalarStuff.addMaybeF32(fbb, 13.0f);
        ScalarStuff.addDefaultF32(fbb, 13.0f);
        ScalarStuff.addJustF64(fbb, 14.0);
        ScalarStuff.addMaybeF64(fbb, 14.0);
        ScalarStuff.addDefaultF64(fbb, 14.0);
        ScalarStuff.addJustBool(fbb, true);
        ScalarStuff.addMaybeBool(fbb, true);
        ScalarStuff.addDefaultBool(fbb, true);
        ScalarStuff.addJustEnum(fbb, OptionalByte.Two);
        ScalarStuff.addMaybeEnum(fbb, OptionalByte.Two);
        ScalarStuff.addDefaultEnum(fbb, OptionalByte.Two);

        pos = ScalarStuff.endScalarStuff(fbb);

        fbb.finish(pos);

        scalarStuff = ScalarStuff.getRootAsScalarStuff(fbb.dataBuffer());

        TestEq(scalarStuff.justI8(), (byte)5);
        TestEq(scalarStuff.maybeI8(), (byte)5);
        TestEq(scalarStuff.defaultI8(), (byte)5);
        TestEq(scalarStuff.justU8(), 6);
        TestEq(scalarStuff.maybeU8(), 6);
        TestEq(scalarStuff.defaultU8(), 6);
        TestEq(scalarStuff.justI16(), (short)7);
        TestEq(scalarStuff.maybeI16(), (short)7);
        TestEq(scalarStuff.defaultI16(), (short)7);
        TestEq(scalarStuff.justU16(), 8);
        TestEq(scalarStuff.maybeU16(), 8);
        TestEq(scalarStuff.defaultU16(), 8);
        TestEq(scalarStuff.justI32(), 9);
        TestEq(scalarStuff.maybeI32(), 9);
        TestEq(scalarStuff.defaultI32(), 9);
        TestEq(scalarStuff.justU32(), 10L);
        TestEq(scalarStuff.maybeU32(), 10L);
        TestEq(scalarStuff.defaultU32(), 10L);
        TestEq(scalarStuff.justI64(), 11L);
        TestEq(scalarStuff.maybeI64(), 11L);
        TestEq(scalarStuff.defaultI64(), 11L);
        TestEq(scalarStuff.justU64(), 12L);
        TestEq(scalarStuff.maybeU64(), 12L);
        TestEq(scalarStuff.defaultU64(), 12L);
        TestEq(scalarStuff.justF32(), 13.0f);
        TestEq(scalarStuff.maybeF32(), 13.0f);
        TestEq(scalarStuff.defaultF32(), 13.0f);
        TestEq(scalarStuff.justF64(), 14.0);
        TestEq(scalarStuff.maybeF64(), 14.0);
        TestEq(scalarStuff.defaultF64(), 14.0);
        TestEq(scalarStuff.justBool(), true);
        TestEq(scalarStuff.maybeBool(), true);
        TestEq(scalarStuff.defaultBool(), true);
        TestEq(scalarStuff.justEnum(), OptionalByte.Two);
        TestEq(scalarStuff.maybeEnum(), OptionalByte.Two);
        TestEq(scalarStuff.defaultEnum(), OptionalByte.Two);

        TestEq(scalarStuff.hasMaybeI8(), true);
        TestEq(scalarStuff.hasMaybeI16(), true);
        TestEq(scalarStuff.hasMaybeI32(), true);
        TestEq(scalarStuff.hasMaybeI64(), true);
        TestEq(scalarStuff.hasMaybeU8(), true);
        TestEq(scalarStuff.hasMaybeU16(), true);
        TestEq(scalarStuff.hasMaybeU32(), true);
        TestEq(scalarStuff.hasMaybeU64(), true);
        TestEq(scalarStuff.hasMaybeF32(), true);
        TestEq(scalarStuff.hasMaybeF64(), true);
        TestEq(scalarStuff.hasMaybeBool(), true);
        TestEq(scalarStuff.hasMaybeEnum(), true);
    }

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

}
