Squashed 'third_party/flatbuffers/' changes from e5f331db9..bc44fad35

bc44fad35 UnPackTo disable merge by default (#7527)
4fca4dc60 [TS/JS] Move TS tests to dedicated folder and deps upgrade (#7508)
036032373 Bump junit from 4.13 to 4.13.1 in /java (#7526)
89dfb43f3 Replace `bash JavaTest.sh` with `mvn test` (#7500)
c49aff4b6 enabled cpp17 tests in CI (#7524)
56e60223c prevent force_align attribute on enums (#7523)
89b1f5aa1 remove travis config (#7522)
b90159823 [Java][Flexbuffers] Add API to add nullables into the buffer. (#7521)
8cdc6a288 Install BuildFlatBuffers.cmake (#7519)
a67e35aff Moves all of the swift test code into tests/swift (#7509)
f124e41ae Updated Readme
4c954181c [Java][FlexBuffers] throwing exception for untyped fixed vectors (#7507)
7f7547737 [Android] Remove maven dependency of flatbuffers and use source folder (#7503)
a79d61ea8 Fixes issue with cocoapods failing to be published because of docc (#7505)
d465b39c3 [CMake]: fix breaking find_package change (#7499) (#7502)
c5a609dc2 [C#] Prepares for official Nuget release (#7496)
5634dc3d0 [ISSUE-6268] returns NaN insteadof nan (#7498)
37e37b8ca Updates cocoapods version (#7497)
8fd4534fb update android multidex setting (#7495)
d5427da52 Disable Android Build (#7494)
06c5c7ed0 FlatBuffers Version 2.0.8 (#7492)
b190ce11b Verifier Refinements (#7490)
bf5d23230 Namer applied to Typescript generator (#7488)
ce382d6dd [TS/JS] Add rollup and config to generate iife flatbuffers bundle (#7449)
41d9add7e C++: Add option to skip verifying nested flatbuffers (#7489)
6a8742754 [C++] support native_inline attribute for vector of tables (#7479)
694add668 Refactor test.cpp (#7487)
7edf8c908 Update scorecard to 1.1.2
b86387442 Fix typos (#7483)
e2eb5ee67 Include <array> head in stl_emulation.h (#7480)
994502b6d Version number in file package.json updated to 2.0.7 (#7476)
fa41e8367 [C++] Fixed crash when copying table with empty shared strings (#7477)
799cc8f7b Use type traits for specialization (#7475)
b7eb44147 Disable RTTI and rework use in idl_gen_ts.cpp (#7474)
8d01c5859 CMake project version detection made more robust (#7473)
237e8b71f Moved compiler warnings around (#7471)
eeb8fd60d Include builder.addOffset for vector of structs (#7470)
fef2ffc4d Use schema include name for keep-prefix (#7469)
8367664f1 Flatbuffers Version 2.0.7 (#7462)
d6f06c33f Reworked keep prefix (#7456)
627e8bf36 update grpc version (#7457)
883c42b7d disabling unpackto optimization (#7459)
7aae0af30 Remove old GRPC bash script and convert to python3 (#7454)
b057aa917 Grouped anonymous namespaces together, (#7455)
f1b26ff7f Change to GetTypeName (#7453)
9610a666b Generate SLSA signatures for Released zip files (#7450)
1e0f75a64 [WIP] speedup (#7452)
82b75407a Wrap types in namespace for --ts-flat-files and --gen-all (#7451)
f7c511957 Audit and fixups for GCC and Clang (#7212)
a66de58af Partial support for --ts-flat-files and --gen-all (#7446)
a3508f36d [Kotlin] Make sure namespace path exist for code generation (#7357)
137fec716 Stop using __has_trivial_copy on recent clang versions. (#7443)
214125e41 [C#] Rework how sorted vectors are looked up (#7441)
44a7dc999 Define minimum buffer size (#7440)
3cc2daa78 make_span overloads for pointer to vector (#7374) (#7435)
fa1174aa7 [TypeScript] Fix namespaceless schema generation (#7432)
83d4e2a10 Add checks to verifier (#7438)
8a09f3fb0 Fix FlexBuffers JS/TS bug https://github.com/google/flatbuffers/issues/6934 (#7434)
9dbe819ef Add flatc python tests to CI (#7437)
67c414958 Update TypeScriptTest.py to work better cross platform (#7436)
8b8c7dbdf Update gitingore to reflect name change (#7431)
2ee20a5f3 Remove auto including locale functions (#7430)
4be605604 [C++] Set StructDef::has_key property when deserializing from binary schema (#7386) (#7428)
fc5d86f1e [C++] Make template parameter in stl_emulation.h more explicit to avoid conflicts with cpprestsdk U macro (#7424)
9dce287ad Issue#6959 :Updated Automatically generated rust files. (#7425)
7798be3bb avoid zero-as-null-pointer warning (#7423)
966362e07 [C++] Vector of Tables equality (#7415)
a89c279ed [golang] Perform keyword escaping after case conversion (#7421)
a212b3c03 Turn of fail fast for C++ CI
9230f600d Remove stringop-overflow from error (#7422)
c79362156 [golang] Add support for text parsing with json struct tags (#7353)
ee2ced236 Moved TypeScriptTests to python script (#7411)
468c00a3f Rebased: grpc/compiler: Respect filename suffix and extension during code generation (#7414)
47c757f71 Add tests for flatc (#7405)
9a5ff8900 Add FLATBUFFERS_STRICT_MODE (#7408)
950444a34 [TS] Use TextEncoder and TextDecoder (#7400)
30d76198c Compilation issue msys2 #7399 (#7409)
cce3a66f0 Delete .travis directory
8d1cc6ac7 Revert "Compilation issue msys2 (#7403)" (#7407)
5b207639a Update readme.md
359e0f9d6 Revert "grpc/compiler: Respect filename suffix and extension during code generation (#7343)" (#7406)
ebbed0513 Delete cpp-linter.yml
aa395e5a5 (#7323) Rename CMake files according to project name (#7378)
32328075d Fix error msg format when generate GRPC failed (#7350)
97e89c5ac grpc/compiler: Respect filename suffix and extension during code generation (#7343)
5f6672be4 Fix Clang-Cl compile on Windows (#7308)
28e858c85 [TS/Bazel] Minor improvements to typescript.bzl (#7300)
987bebe67 [TS] fix incorrect reverse when writting array of structs (#7271)
ec0129369 Fix FlexBuffers Verifier tracking vectors reuse at wrong offset
50dd385b3 Add missing const (#7401)
da702cfd8 Compilation issue msys2 (#7403)
6e2791640 keep-prefix keeps relative pathing (#7394)
52fce5e53 fix(#7360): grpc used deprecated functions (#7361)
b7f13cd8e cpp_generator: comment out unused parameter to avoid warnings (#7381)
e42985e5a Updated Newtonsoft.Json to 13.0.1 (#7393)
0a8064637 Fix references to LICENSE file (#7377)
b9eea76a8 [Dart] Implement putBool to fix errors when serializing structs with bools (#7359)
1b9030015 Bump Newtonsoft.Json from 12.0.3 to 13.0.1 in /tests/FlatBuffers.Test (#7363)
83a43fc79 Reenable optional json (#7352)
5f0137602 Only include direct included filed (#7348)
9a1913a87 Revert "Implement optional scalars for JSON (#7322)" (#7351)
b4647beb8 Revert "Move reflection_ts_fbs into a separate directory (#7342)" (#7349)
d6060977a Remove asserting in verifier for flattests
987aa5b5e move -Wextra-semi to GCC 8.0+
42acdb63c [TS] Don't generate self-imports with --ts-flat-file (#7340)
0cc1aeb8c [golang] Create missing namespace directory structure (#7324) (#7325)
ba6c67170 [Kotlin] Remove download benchmark files dependency (#7314)
d2f33fc45 Disable Android on Linux CI build
0d1b72cbc [TS] fix ts import path issue (#7298)
9fce2fbf2 replace io/ioutil to os (#7281)
a18ea40d6 Implement optional scalars for JSON (#7322)
090caa280 Move reflection_ts_fbs into a separate directory (#7342)
49e1ea333 Implement optional scalars for Python (#7318)
11a198870 Started implementation for private flags in rust (#7269)
967df08b1 Adds full supposed for Wasm in the swift lib (#7328)
9aa08a429 Use keep case for Rust union discriminant type. (#7321)
9e8c758f5 Add explicit return types to lobster generated code (#7312)
74a25536b Add size check to fix out of bounds read risk (#7304)
12917af8a Update Rust docs page (#7296)
1ea2472f7 [swift] add had<ArrayName> property for arrays to check presence in a message (#7280)
0fe13cb28 Remove span ConstIterator/cbegin()/cend(). (#7295)
385dddc66 Namerkot (#7245)
750dde766 Make `flatc` generate Rust files not requiring `std` (#7273)
9917a168c [swift] Make swift module public (#7274)
76d3cca19 Rust: fix a name conflict when building with "no_std" feature (#7268)
c86e6d0e3 json inf parsing
d34dc32c2 fix include order
234d86c92 fixed off-by-one in parser
746c73b91 Add Annotations for Monster schema and example buffer
0bbfd4b2e fixes for annotator
716521953 Update readme.md (#7257)
a45f564cf [performance] Add aggressive systematic inlining in ByteBuffer and FlatBufferBuilder (#7253)
9d45a6403 more google merge fixes
ccfb4c20b Handle +/-inf in protos (#7256)
7bcd857b8 Specialize CreateVector with std::initializer_list (#7254)
23c8ab34c Swift update performance benchmark infrastructure (#7255)
70002dc5c various fixes for google merge
6e0e79f24 Add test for nested buffer verifier (#7252)
b856368d7 Turn off go modules temporary until we get a proper fix (#7251)
e37156a30 Keep the underlying storage capacity when clearing the FlatBufferBuilder. Gives a significant performance boost for serialisation of many small messages. (#7250)
a10b0e546 Java namer variable keep case (#7249)
275b73994 allow overriding FLATBUFFERS_MAX_ALIGNMENT
9d1ce9a10 Add parameter back to EndVector (#7246)
79afe6c3d Make Java namespaces keep case by default (#7243)
c6dbb2230 Add write permissions for labeller
18bacd3ea Expand test to make sure {}-initializers are properly understood by template. (#7242)
a2c913aec Add -Wnon-virtual-dtor
67b33b294 set workflows permissions to read-only (#7239)
7b5fd2bd0 [Kotlin] Fix key lookup returning null clashing with default value (#7237)
7181d7770 [Java] Fix key lookup returning null clashing with default value (#7236)
7f663b120 Allow CreateVectorOfStrings() to work with any string-type. (#7238)
173ebb694 Fixes a bug where the create function doesnt optional + required items (#7228)
d65823948 [Kotlin] Update gradle to 7.4.1 and simplify config files. (#7231)
ab4bf59e8 remove toascii (#7234)
eee44bbb2 disable cpp-linter (#7229)
a63fa51a1 Create cpp-linter.yml (#7208)
2049e5210 Adds a way to verify/exposes Entities ids (#7221)
832c618f5 Adds implementation flag for swift (#7202)
14615699f Started to migrate to target_compile_options (#7222)
20aad0c41 [C++] stl_emulation span::count_ is not const anymore (#7226) (#7227)
f083b33f2 code gen flexbuffer verifier (#7207)
bf17df346 [C++] generate sorted #include directives (#7213)
35281dedb Fix for [C++] flatc generates invalid Code in the default constructor for structs, when --cpp-field-case-style is used #7209 (#7211)
c9651b742 Add overloads for C# ByteBuffer/FlatBufferBuilder to allow adding vector blocks from ArraySegments or IntPtr (#7193)
26c3b3ada Update codeql.yml
da6e1b985 Update codeql.yml
ad27d751e Added Oss fuzz badge
0aab623cb Create codeql.yml
6a446bdd8 maximize parallel builds in CI (#7206)
21fb5cbbc Create scorecards.yml
0da6f9486 [C++] Static assert on Flatbuffers Version (#7203)
59e971308 reduce fuzzing time to 1 minute in CI
40866a892 fixed padding in struct for annotated binary (#7199)
b71d968fa Apply Namer prefix/suffix to other generators (#7197)
fac0d7be0 Apply Namer to Java. (#7194)
6c5603fd9 [C#] Fix collision of field name and type name (#7149)
2d21853a7 monster fuzzer fix for json default scalars
fec1a8d01 [swift] Add bazel configuration for Swift (#7195)
7fd857623 structured comments (#7192)
a4cb1599d Namerdart (#7187)
ae4ce7265 fuzzed binary annotator (#7188)
e2be0c0b0 Handle root offset and root table vtable invalidation (#7177)
2ad408697 [TS] Fix generation of struct members in object api (#7148)
4213d9105 VerifySizePrefixed (reflection::Schema) and GetAnySizePrefixedRoot added (#7181)
5a13f622c Correctly parse lists of enums in Dart generated code (#7157)
23a7e4e0b Adds no-includes flags to the swift code generator (#7182)
eeb49c275 Move flatbuffer_ts_library to typescript.bzl (#7183)
824763b31 Typo in flatc options (warning-as-errors instead of warnings-as-errors) (#7180)
d3aeee32b Annotated Flatbuffer Binary (#7174)
0bceba24d [Lua] Apply Namer to Lua (#7171)
b8c77d404 Make inclusion of header <optional> opt-out via macro (#7168)
8468eab83 Namersw (#7167)
2b2e8d4ae Nameroverloads (#7164)
b80b32bfa Use DESCRIPTION only if CMake version >= 3.9 (#7166)

Change-Id: Ic2681dabb1a798b7515e62753ee06aecb9933260
git-subtree-dir: third_party/flatbuffers
git-subtree-split: bc44fad35271e43fd7a79b4d691ac9e41708797f
Signed-off-by: Austin Schuh <austin.schuh@bluerivertech.com>
diff --git a/java/pom.xml b/java/pom.xml
new file mode 100644
index 0000000..34f154a
--- /dev/null
+++ b/java/pom.xml
@@ -0,0 +1,176 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>com.google.flatbuffers</groupId>
+  <artifactId>flatbuffers-java</artifactId>
+  <version>2.0.8</version>
+  <packaging>bundle</packaging>
+  <name>FlatBuffers Java API</name>
+  <description>
+    Memory Efficient Serialization Library
+  </description>
+  <developers>
+    <developer>
+      <name>Wouter van Oortmerssen</name>
+    </developer>
+    <developer>
+      <name>Derek Bailey</name>
+      <email>dbaileychess@gmail.com</email>
+    </developer>
+  </developers>
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+  <url>https://github.com/google/flatbuffers</url>
+  <licenses>
+    <license>
+      <name>Apache License V2.0</name>
+      <url>https://raw.githubusercontent.com/google/flatbuffers/master/LICENSE.txt</url>
+      <distribution>repo</distribution>
+    </license>
+  </licenses>
+  <scm>
+    <url>https://github.com/google/flatbuffers</url>
+    <connection>
+      scm:git:https://github.com/google/flatbuffers.git
+    </connection>
+    <tag>HEAD</tag>
+  </scm>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.13.1</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.truth</groupId>
+      <artifactId>truth</artifactId>
+      <version>1.1.3</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+  <distributionManagement>
+    <snapshotRepository>
+      <id>ossrh</id>
+      <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+    </snapshotRepository>
+  </distributionManagement>
+  <build>
+    <plugins>
+    <plugin>
+      <artifactId>maven-compiler-plugin</artifactId>
+      <configuration>
+        <release>8</release>
+        <testExcludes>
+          <testExclude>**/LongEnum.java</testExclude>
+          <testExclude>MyGame/Example/MonsterStorageGrpc.java</testExclude>
+          <testExclude>MyGame/Example/StructOfStructs**</testExclude>
+          <testExclude>MyGame/OtherNameSpace/TableBT.java</testExclude>
+        </testExcludes>
+      </configuration>
+      <version>3.8.1</version>
+    </plugin>
+    </plugins>
+  </build>
+  <profiles>
+    <profile>
+      <id>jdk9</id>
+      <activation>
+        <jdk>[1.9,)</jdk>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <artifactId>maven-surefire-plugin</artifactId>
+            <configuration>
+              <includes>
+                <include>**/*Test.java</include>
+              </includes>
+            </configuration>
+            <version>2.22.2</version>
+          </plugin>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-source-plugin</artifactId>
+            <version>3.2.1</version>
+            <executions>
+              <execution>
+                <id>attach-sources</id>
+                <goals>
+                  <goal>jar</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-javadoc-plugin</artifactId>
+            <version>3.3.0</version>
+            <configuration>
+              <additionalparam>-Xdoclint:none</additionalparam>
+              <additionalOptions>-Xdoclint:none</additionalOptions>
+            </configuration>
+            <executions>
+              <execution>
+                <id>attach-javadocs</id>
+                <goals>
+                  <goal>jar</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+          <plugin>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>maven-bundle-plugin</artifactId>
+            <version>5.1.2</version>
+            <extensions>true</extensions>
+          </plugin>
+          <plugin>
+            <groupId>org.sonatype.plugins</groupId>
+            <artifactId>nexus-staging-maven-plugin</artifactId>
+            <version>1.6.8</version>
+            <extensions>true</extensions>
+            <configuration>
+              <serverId>ossrh</serverId>
+              <nexusUrl>https://oss.sonatype.org/</nexusUrl>
+              <autoReleaseAfterClose>true</autoReleaseAfterClose>
+            </configuration>
+          </plugin>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-gpg-plugin</artifactId>
+            <version>3.0.1</version>
+            <executions>
+              <execution>
+                <id>sign-artifacts</id>
+                <phase>verify</phase>
+                <goals>
+                  <goal>sign</goal>
+                </goals>
+                <configuration>
+                    <gpgArguments>
+                        <arg>--pinentry-mode</arg>
+                        <arg>loopback</arg>
+                    </gpgArguments>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-release-plugin</artifactId>
+            <version>2.5.3</version>
+            <configuration>
+              <autoVersionSubmodules>true</autoVersionSubmodules>
+              <useReleaseProfile>false</useReleaseProfile>
+              <releaseProfiles>release</releaseProfiles>
+              <goals>deploy</goals>
+            </configuration>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+</project>
+
diff --git a/java/com/google/flatbuffers/ArrayReadWriteBuf.java b/java/src/main/java/com/google/flatbuffers/ArrayReadWriteBuf.java
similarity index 100%
rename from java/com/google/flatbuffers/ArrayReadWriteBuf.java
rename to java/src/main/java/com/google/flatbuffers/ArrayReadWriteBuf.java
diff --git a/java/com/google/flatbuffers/BaseVector.java b/java/src/main/java/com/google/flatbuffers/BaseVector.java
similarity index 100%
rename from java/com/google/flatbuffers/BaseVector.java
rename to java/src/main/java/com/google/flatbuffers/BaseVector.java
diff --git a/java/com/google/flatbuffers/BooleanVector.java b/java/src/main/java/com/google/flatbuffers/BooleanVector.java
similarity index 100%
rename from java/com/google/flatbuffers/BooleanVector.java
rename to java/src/main/java/com/google/flatbuffers/BooleanVector.java
diff --git a/java/com/google/flatbuffers/ByteBufferReadWriteBuf.java b/java/src/main/java/com/google/flatbuffers/ByteBufferReadWriteBuf.java
similarity index 100%
rename from java/com/google/flatbuffers/ByteBufferReadWriteBuf.java
rename to java/src/main/java/com/google/flatbuffers/ByteBufferReadWriteBuf.java
diff --git a/java/com/google/flatbuffers/ByteBufferUtil.java b/java/src/main/java/com/google/flatbuffers/ByteBufferUtil.java
similarity index 100%
rename from java/com/google/flatbuffers/ByteBufferUtil.java
rename to java/src/main/java/com/google/flatbuffers/ByteBufferUtil.java
diff --git a/java/com/google/flatbuffers/ByteVector.java b/java/src/main/java/com/google/flatbuffers/ByteVector.java
similarity index 100%
rename from java/com/google/flatbuffers/ByteVector.java
rename to java/src/main/java/com/google/flatbuffers/ByteVector.java
diff --git a/java/com/google/flatbuffers/Constants.java b/java/src/main/java/com/google/flatbuffers/Constants.java
similarity index 97%
rename from java/com/google/flatbuffers/Constants.java
rename to java/src/main/java/com/google/flatbuffers/Constants.java
index 0c0920f..b9cb8f2 100644
--- a/java/com/google/flatbuffers/Constants.java
+++ b/java/src/main/java/com/google/flatbuffers/Constants.java
@@ -46,7 +46,7 @@
     Changes to the Java implementation need to be sure to change
     the version here and in the code generator on every possible
     incompatible change */
-    public static void FLATBUFFERS_2_0_0() {}
+    public static void FLATBUFFERS_2_0_8() {}
 }
 
 /// @endcond
diff --git a/java/com/google/flatbuffers/DoubleVector.java b/java/src/main/java/com/google/flatbuffers/DoubleVector.java
similarity index 100%
rename from java/com/google/flatbuffers/DoubleVector.java
rename to java/src/main/java/com/google/flatbuffers/DoubleVector.java
diff --git a/java/com/google/flatbuffers/FlatBufferBuilder.java b/java/src/main/java/com/google/flatbuffers/FlatBufferBuilder.java
similarity index 100%
rename from java/com/google/flatbuffers/FlatBufferBuilder.java
rename to java/src/main/java/com/google/flatbuffers/FlatBufferBuilder.java
diff --git a/java/com/google/flatbuffers/FlexBuffers.java b/java/src/main/java/com/google/flatbuffers/FlexBuffers.java
similarity index 100%
rename from java/com/google/flatbuffers/FlexBuffers.java
rename to java/src/main/java/com/google/flatbuffers/FlexBuffers.java
diff --git a/java/com/google/flatbuffers/FlexBuffersBuilder.java b/java/src/main/java/com/google/flatbuffers/FlexBuffersBuilder.java
similarity index 97%
rename from java/com/google/flatbuffers/FlexBuffersBuilder.java
rename to java/src/main/java/com/google/flatbuffers/FlexBuffersBuilder.java
index 7f41bb6..60ab535 100644
--- a/java/com/google/flatbuffers/FlexBuffersBuilder.java
+++ b/java/src/main/java/com/google/flatbuffers/FlexBuffersBuilder.java
@@ -174,6 +174,21 @@
     }
 
     /**
+     * Insert a null value into the buffer
+     */
+    public void putNull() {
+        putNull(null);
+    }
+
+    /**
+     * Insert a null value into the buffer
+     * @param key key used to store element in map
+     */
+    public void putNull(String key) {
+        stack.add(Value.nullValue(putKey(key)));
+    }
+
+    /**
      * Insert a single boolean into the buffer
      * @param val true or false
      */
@@ -451,7 +466,7 @@
     /**
      * Finishes a vector, but writing the information in the buffer
      * @param key   key used to store element in map
-     * @param start reference for begining of the vector. Returned by {@link startVector()}
+     * @param start reference for beginning of the vector. Returned by {@link startVector()}
      * @param typed boolean indicating whether vector is typed
      * @param fixed boolean indicating whether vector is fixed
      * @return      Reference to the vector
@@ -502,7 +517,9 @@
      * @return Value representing the created vector
      */
     private Value createVector(int key, int start, int length, boolean typed, boolean fixed, Value keys) {
-        assert (!fixed || typed); // typed=false, fixed=true combination is not supported.
+        if (fixed & !typed)
+            throw new UnsupportedOperationException("Untyped fixed vector is not supported");
+
         // Figure out smallest bit width we can store this vector with.
         int bitWidth = Math.max(WIDTH_8, widthUInBits(length));
         int prefixElems = 1;
@@ -602,7 +619,7 @@
     /**
      * Finishes a map, but writing the information in the buffer
      * @param key   key used to store element in map
-     * @param start reference for begining of the map. Returned by {@link startMap()}
+     * @param start reference for beginning of the map. Returned by {@link startMap()}
      * @return      Reference to the map
      */
     public int endMap(String key, int start) {
@@ -673,6 +690,10 @@
             this.iValue = Long.MIN_VALUE;
         }
 
+        static Value nullValue(int key) {
+            return new Value(key, FBT_NULL, WIDTH_8, 0);
+        }
+
         static Value bool(int key, boolean b) {
             return new Value(key, FBT_BOOL, WIDTH_8, b ? 1 : 0);
         }
diff --git a/java/com/google/flatbuffers/FloatVector.java b/java/src/main/java/com/google/flatbuffers/FloatVector.java
similarity index 100%
rename from java/com/google/flatbuffers/FloatVector.java
rename to java/src/main/java/com/google/flatbuffers/FloatVector.java
diff --git a/java/com/google/flatbuffers/IntVector.java b/java/src/main/java/com/google/flatbuffers/IntVector.java
similarity index 100%
rename from java/com/google/flatbuffers/IntVector.java
rename to java/src/main/java/com/google/flatbuffers/IntVector.java
diff --git a/java/com/google/flatbuffers/LongVector.java b/java/src/main/java/com/google/flatbuffers/LongVector.java
similarity index 100%
rename from java/com/google/flatbuffers/LongVector.java
rename to java/src/main/java/com/google/flatbuffers/LongVector.java
diff --git a/java/com/google/flatbuffers/ReadBuf.java b/java/src/main/java/com/google/flatbuffers/ReadBuf.java
similarity index 100%
rename from java/com/google/flatbuffers/ReadBuf.java
rename to java/src/main/java/com/google/flatbuffers/ReadBuf.java
diff --git a/java/com/google/flatbuffers/ReadWriteBuf.java b/java/src/main/java/com/google/flatbuffers/ReadWriteBuf.java
similarity index 100%
rename from java/com/google/flatbuffers/ReadWriteBuf.java
rename to java/src/main/java/com/google/flatbuffers/ReadWriteBuf.java
diff --git a/java/com/google/flatbuffers/ShortVector.java b/java/src/main/java/com/google/flatbuffers/ShortVector.java
similarity index 100%
rename from java/com/google/flatbuffers/ShortVector.java
rename to java/src/main/java/com/google/flatbuffers/ShortVector.java
diff --git a/java/com/google/flatbuffers/StringVector.java b/java/src/main/java/com/google/flatbuffers/StringVector.java
similarity index 100%
rename from java/com/google/flatbuffers/StringVector.java
rename to java/src/main/java/com/google/flatbuffers/StringVector.java
diff --git a/java/com/google/flatbuffers/Struct.java b/java/src/main/java/com/google/flatbuffers/Struct.java
similarity index 100%
rename from java/com/google/flatbuffers/Struct.java
rename to java/src/main/java/com/google/flatbuffers/Struct.java
diff --git a/java/com/google/flatbuffers/Table.java b/java/src/main/java/com/google/flatbuffers/Table.java
similarity index 100%
rename from java/com/google/flatbuffers/Table.java
rename to java/src/main/java/com/google/flatbuffers/Table.java
diff --git a/java/com/google/flatbuffers/UnionVector.java b/java/src/main/java/com/google/flatbuffers/UnionVector.java
similarity index 100%
rename from java/com/google/flatbuffers/UnionVector.java
rename to java/src/main/java/com/google/flatbuffers/UnionVector.java
diff --git a/java/com/google/flatbuffers/Utf8.java b/java/src/main/java/com/google/flatbuffers/Utf8.java
similarity index 100%
rename from java/com/google/flatbuffers/Utf8.java
rename to java/src/main/java/com/google/flatbuffers/Utf8.java
diff --git a/java/com/google/flatbuffers/Utf8Old.java b/java/src/main/java/com/google/flatbuffers/Utf8Old.java
similarity index 100%
rename from java/com/google/flatbuffers/Utf8Old.java
rename to java/src/main/java/com/google/flatbuffers/Utf8Old.java
diff --git a/java/com/google/flatbuffers/Utf8Safe.java b/java/src/main/java/com/google/flatbuffers/Utf8Safe.java
similarity index 100%
rename from java/com/google/flatbuffers/Utf8Safe.java
rename to java/src/main/java/com/google/flatbuffers/Utf8Safe.java
diff --git a/java/src/test/java/DictionaryLookup b/java/src/test/java/DictionaryLookup
new file mode 120000
index 0000000..231bcd8
--- /dev/null
+++ b/java/src/test/java/DictionaryLookup
@@ -0,0 +1 @@
+../../../../tests/DictionaryLookup
\ No newline at end of file
diff --git a/java/src/test/java/JavaTest.java b/java/src/test/java/JavaTest.java
new file mode 100644
index 0000000..c392e04
--- /dev/null
+++ b/java/src/test/java/JavaTest.java
@@ -0,0 +1,1533 @@
+
+import static com.google.flatbuffers.Constants.*;
+import static com.google.common.truth.Truth.assertThat;
+
+import DictionaryLookup.*;
+import MyGame.Example.*;
+import com.google.common.io.ByteStreams;
+import optional_scalars.ScalarStuff;
+import optional_scalars.OptionalByte;
+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.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.channels.FileChannel;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.Rule;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+
+/*
+ * 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.
+ */
+
+@RunWith(JUnit4.class)
+public class JavaTest {
+
+    @Rule
+    public TemporaryFolder tempFolder = new TemporaryFolder();
+
+    @org.junit.Test
+    public void mainTest() throws IOException {
+      // First, let's test reading a FlatBuffer generated by C++ code:
+      // This file was generated from monsterdata_test.json
+      byte[] data = ByteStreams.toByteArray(
+        JavaTest.class.getClassLoader().getResourceAsStream("monsterdata_test.mon"));
+
+      // Now test it:
+      ByteBuffer bb = ByteBuffer.wrap(data);
+      TestBuffer(bb);
+      TestPackUnpack(bb);
+    }
+
+    @org.junit.Test
+    public void testFlatBufferBuilder() {
+      // 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());
+    }
+
+    @org.junit.Test
+    public void TestEnums() {
+      assertThat(Color.name(Color.Red)).isEqualTo("Red");
+      assertThat(Color.name(Color.Blue)).isEqualTo("Blue");
+      assertThat(Any.name(Any.NONE)).isEqualTo("NONE");
+      assertThat(Any.name(Any.Monster)).isEqualTo("Monster");
+    }
+
+    static void TestBuffer(ByteBuffer bb) {
+      assertThat(Monster.MonsterBufferHasIdentifier(bb)).isEqualTo(true);
+
+      Monster monster = Monster.getRootAsMonster(bb);
+
+      assertThat(monster.hp()).isEqualTo((short) 80);
+      // default
+      assertThat(monster.mana()).isEqualTo((short) 150);
+
+      assertThat(monster.name()).isEqualTo("MyMonster");
+      // monster.friendly() // can't access, deprecated
+
+        Vec3 pos = monster.pos();
+      assertThat(pos.x()).isEqualTo(1.0f);
+      assertThat(pos.y()).isEqualTo(2.0f);
+      assertThat(pos.z()).isEqualTo(3.0f);
+      assertThat(pos.test1()).isEqualTo(3.0);
+      // issue: int != byte
+      assertThat(pos.test2()).isEqualTo((int) Color.Green);
+      Test t = pos.test3();
+      assertThat(t.a()).isEqualTo((short) 5);
+      assertThat(t.b()).isEqualTo((byte) 6);
+
+      assertThat(monster.testType()).isEqualTo((byte) Any.Monster);
+      Monster monster2 = new Monster();
+      assertThat(monster.test(monster2) != null).isTrue();
+      assertThat(monster2.name()).isEqualTo("Fred");
+
+      assertThat(monster.inventoryLength()).isEqualTo(5);
+      int invsum = 0;
+        for (int i = 0; i < monster.inventoryLength(); i++)
+            invsum += monster.inventory(i);
+      assertThat(invsum).isEqualTo(10);
+
+      // Method using a vector access object:
+        ByteVector inventoryVector = monster.inventoryVector();
+      assertThat(inventoryVector.length()).isEqualTo(5);
+      invsum = 0;
+        for (int i = 0; i < inventoryVector.length(); i++)
+            invsum += inventoryVector.getAsUnsigned(i);
+      assertThat(invsum).isEqualTo(10);
+
+      // Alternative way of accessing a vector:
+        ByteBuffer ibb = monster.inventoryAsByteBuffer();
+        invsum = 0;
+        while (ibb.position() < ibb.limit())
+            invsum += ibb.get();
+      assertThat(invsum).isEqualTo(10);
+
+      Test test_0 = monster.test4(0);
+        Test test_1 = monster.test4(1);
+      assertThat(monster.test4Length()).isEqualTo(2);
+      assertThat(test_0.a() + test_0.b() + test_1.a() + test_1.b()).isEqualTo((Integer) 100);
+
+      Test.Vector test4Vector = monster.test4Vector();
+        test_0 = test4Vector.get(0);
+        test_1 = test4Vector.get(1);
+      assertThat(test4Vector.length()).isEqualTo(2);
+      assertThat(test_0.a() + test_0.b() + test_1.a() + test_1.b()).isEqualTo((Integer) 100);
+
+      assertThat(monster.testarrayofstringLength()).isEqualTo(2);
+      assertThat(monster.testarrayofstring(0)).isEqualTo("test1");
+      assertThat(monster.testarrayofstring(1)).isEqualTo("test2");
+
+      // Method using a vector access object:
+        StringVector testarrayofstringVector = monster.testarrayofstringVector();
+      assertThat(testarrayofstringVector.length()).isEqualTo(2);
+      assertThat(testarrayofstringVector.get(0)).isEqualTo("test1");
+      assertThat(testarrayofstringVector.get(1)).isEqualTo("test2");
+
+      assertThat(monster.testbool()).isEqualTo(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);
+
+      assertThat(monster.testhashu32Fnv1()).isEqualTo((Integer.MAX_VALUE + 1L));
+    }
+
+
+    @org.junit.Test public 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);
+    }
+
+    @org.junit.Test public 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();
+
+      assertThat(nestedMonsterMana).isEqualTo(nestedMonster.mana());
+      assertThat(nestedMonsterHp).isEqualTo(nestedMonster.hp());
+      assertThat(nestedMonsterName).isEqualTo(nestedMonster.name());
+    }
+
+    @org.junit.Test public 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());
+
+      assertThat((Integer) monsterObject.inventory(1)).isEqualTo((int)inventory[1]);
+      assertThat(monsterObject.inventoryLength()).isEqualTo(inventory.length);
+      ByteVector inventoryVector = monsterObject.inventoryVector();
+      assertThat(inventoryVector.getAsUnsigned(1)).isEqualTo((int)inventory[1]);
+      assertThat(inventoryVector.length()).isEqualTo(inventory.length);
+
+      assertThat(ByteBuffer.wrap(inventory)).isEqualTo(
+        monsterObject.inventoryAsByteBuffer());
+    }
+
+    @org.junit.Test public 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());
+
+      assertThat((Integer) monsterObject.inventory(1)).isEqualTo((int)inventory[1]);
+      assertThat(monsterObject.inventoryLength()).isEqualTo(inventory.length);
+      ByteVector inventoryVector = monsterObject.inventoryVector();
+      assertThat(inventoryVector.getAsUnsigned(1)).isEqualTo((int)inventory[1]);
+      assertThat(inventoryVector.length()).isEqualTo(inventory.length);
+      assertThat(ByteBuffer.wrap(inventory)).isEqualTo(
+        monsterObject.inventoryAsByteBuffer());
+    }
+
+    @org.junit.Test public void TestByteBufferFactory() throws IOException {
+      File file = tempFolder.newFile("javatest.bin");
+        final class MappedByteBufferFactory extends FlatBufferBuilder.ByteBufferFactory {
+            @Override
+            public ByteBuffer newByteBuffer(int capacity) {
+                ByteBuffer bb;
+                try {
+                    RandomAccessFile f = new RandomAccessFile(file, "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);
+    }
+
+    @org.junit.Test public 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;
+            }
+          assertThat((byte)currentVal).isEqualTo(array[count]);
+          count++;
+        }
+      assertThat(count).isEqualTo(array.length);
+    }
+
+    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(tempFolder.newFile(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) {
+          assertThat(ByteBufferUtil.getSizePrefix(dataBuffer) + SIZE_PREFIX_LENGTH).isEqualTo(
+            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());
+
+        //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
+      assertThat(monster.mutateMana((short)10)).isFalse();
+      assertThat(monster.mana()).isEqualTo((short) 150);
+
+      // Accessing a vector of sorted by the key tables
+      assertThat(monster.testarrayoftables(0).name()).isEqualTo("Barney");
+      assertThat(monster.testarrayoftables(1).name()).isEqualTo("Frodo");
+      assertThat(monster.testarrayoftables(2).name()).isEqualTo("Wilma");
+      Monster.Vector testarrayoftablesVector = monster.testarrayoftablesVector();
+      assertThat(testarrayoftablesVector.get(0).name()).isEqualTo("Barney");
+      assertThat(testarrayoftablesVector.get(1).name()).isEqualTo("Frodo");
+      assertThat(testarrayoftablesVector.get(2).name()).isEqualTo("Wilma");
+
+      // Example of searching for a table by the key
+      assertThat(monster.testarrayoftablesByKey("Frodo").name()).isEqualTo("Frodo");
+      assertThat(monster.testarrayoftablesByKey("Barney").name()).isEqualTo("Barney");
+      assertThat(monster.testarrayoftablesByKey("Wilma").name()).isEqualTo("Wilma");
+      assertThat(testarrayoftablesVector.getByKey("Frodo").name()).isEqualTo("Frodo");
+      assertThat(testarrayoftablesVector.getByKey("Barney").name()).isEqualTo("Barney");
+      assertThat(testarrayoftablesVector.getByKey("Wilma").name()).isEqualTo("Wilma");
+
+      // testType is an existing field and mutating it should succeed
+      assertThat(monster.testType()).isEqualTo((byte) Any.Monster);
+
+      //mutate the inventory vector
+      assertThat(monster.mutateInventory(0, 1)).isTrue();
+      assertThat(monster.mutateInventory(1, 2)).isTrue();
+      assertThat(monster.mutateInventory(2, 3)).isTrue();
+      assertThat(monster.mutateInventory(3, 4)).isTrue();
+      assertThat(monster.mutateInventory(4, 5)).isTrue();
+
+      for (int i = 0; i < monster.inventoryLength(); i++) {
+        assertThat((Integer) monster.inventory(i)).isEqualTo(i + 1);
+      }
+        ByteVector inventoryVector =  monster.inventoryVector();
+        for (int i = 0; i < inventoryVector.length(); i++) {
+          assertThat((int)inventoryVector.get(i)).isEqualTo(i + 1);
+        }
+
+        //reverse mutation
+      assertThat(monster.mutateInventory(0, 0)).isTrue();
+      assertThat(monster.mutateInventory(1, 1)).isTrue();
+      assertThat(monster.mutateInventory(2, 2)).isTrue();
+      assertThat(monster.mutateInventory(3, 3)).isTrue();
+      assertThat(monster.mutateInventory(4, 4)).isTrue();
+
+      // get a struct field and edit one of its fields
+      Vec3 pos = monster.pos();
+      assertThat(pos.x()).isEqualTo(1.0f);
+      pos.mutateX(55.0f);
+      assertThat(pos.x()).isEqualTo(55.0f);
+      pos.mutateX(1.0f);
+      assertThat(pos.x()).isEqualTo(1.0f);
+    }
+
+    @org.junit.Test public 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();
+
+      assertThat(movie.charactersTypeLength()).isEqualTo(characterTypeVector.length);
+      assertThat(charactersTypeByteVector.length()).isEqualTo(characterTypeVector.length);
+      assertThat(movie.charactersLength()).isEqualTo(characterVector.length);
+      assertThat(charactersVector.length()).isEqualTo(characterVector.length);
+
+      assertThat((Byte) movie.charactersType(0)).isEqualTo(characterTypeVector[0]);
+      assertThat(charactersTypeByteVector.get(0)).isEqualTo(characterTypeVector[0]);
+
+      assertThat(((Attacker)movie.characters(new Attacker(), 0)).swordAttackDamage()).isEqualTo(
+        swordAttackDamage);
+    }
+
+    @org.junit.Test public 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();
+
+      assertThat(table.a().a()).isEqualTo(0.5f);
+      for (int i = 0; i < 15; i++)
+        assertThat(table.a().b(i)).isEqualTo(i);
+      assertThat(table.a().c()).isEqualTo((byte)1);
+      assertThat(table.a().d(nested, 0).a(0)).isEqualTo(1);
+      assertThat(table.a().d(nested, 0).a(1)).isEqualTo(2);
+      assertThat(table.a().d(nested, 1).a(0)).isEqualTo(3);
+      assertThat(table.a().d(nested, 1).a(1)).isEqualTo(4);
+      assertThat(table.a().d(nested, 0).b()).isEqualTo(TestEnum.B);
+      assertThat(table.a().d(nested, 1).b()).isEqualTo(TestEnum.C);
+      assertThat(table.a().d(nested, 0).c(0)).isEqualTo(TestEnum.A);
+      assertThat(table.a().d(nested, 0).c(1)).isEqualTo(TestEnum.B);
+      assertThat(table.a().d(nested, 1).c(0)).isEqualTo(TestEnum.C);
+      assertThat(table.a().d(nested, 1).c(1)).isEqualTo(TestEnum.B);
+      assertThat(table.a().d(nested, 0).d(0)).isEqualTo((long)-1);
+      assertThat(table.a().d(nested, 0).d(1)).isEqualTo((long)1);
+      assertThat(table.a().d(nested, 1).d(0)).isEqualTo((long)-2);
+      assertThat(table.a().d(nested, 1).d(1)).isEqualTo((long)2);
+      assertThat(table.a().e()).isEqualTo(2);
+      assertThat(table.a().f(0)).isEqualTo((long)-1);
+      assertThat(table.a().f(1)).isEqualTo((long)1);
+    }
+
+    @org.junit.Test public 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();
+      assertThat(bufferLimit1).isEqualTo(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();
+
+      assertThat(m.size()).isEqualTo(6);
+
+      // test empty (an null)
+      // empty if fail
+      assertThat(m.get("no_key").asString()).isEqualTo("");
+      // empty if fail
+      assertThat(m.get("no_key").asMap()).isEqualTo(FlexBuffers.Map.empty());
+      // empty if fail
+      assertThat(m.get("no_key").asKey()).isEqualTo(FlexBuffers.Key.empty());
+      // empty if fail
+      assertThat(m.get("no_key").asVector()).isEqualTo(Vector.empty());
+      // empty if fail
+      assertThat(m.get("no_key").asBlob()).isEqualTo(FlexBuffers.Blob.empty());
+      assert(m.get("no_key").asVector().isEmpty()); // empty if fail
+
+        // testing "vec" field
+        FlexBuffers.Vector vec = m.get("vec").asVector();
+      assertThat(vec.size()).isEqualTo(8);
+      assertThat(vec.get(0).asLong()).isEqualTo((long) -100);
+      assertThat(vec.get(1).asString()).isEqualTo("Fred");
+      assertThat(vec.get(2).isBlob()).isTrue();
+      assertThat(vec.get(2).asBlob().size()).isEqualTo(1);
+      assertThat(vec.get(2).asBlob().data().get(0)).isEqualTo((byte) 77);
+      // Check if type is a bool
+      assertThat(vec.get(3).isBoolean()).isTrue();
+      // Check if value is false
+      assertThat(vec.get(3).asBoolean()).isFalse();
+      assertThat(vec.get(4).asLong()).isEqualTo(Long.MAX_VALUE);
+      assertThat(vec.get(5).isMap()).isTrue();
+      assertThat(vec.get(5).asMap().get("test").asInt()).isEqualTo(200);
+      assertThat(Float.compare((float)vec.get(6).asFloat(), 150.9f)).isEqualTo(0);
+      assertThat(Double.compare(vec.get(7).asFloat(), 150.9999998)).isEqualTo(0);
+      //conversion fail returns 0 as C++
+      assertThat((long)0).isEqualTo((long)vec.get(1).asLong());
+
+      // bar vector
+        FlexBuffers.Vector tvec = m.get("bar").asVector();
+      assertThat(tvec.size()).isEqualTo(3);
+      assertThat(tvec.get(0).asInt()).isEqualTo(1);
+      assertThat(tvec.get(1).asInt()).isEqualTo(2);
+      assertThat(tvec.get(2).asInt()).isEqualTo(3);
+      assertThat(((FlexBuffers.TypedVector) tvec).getElemType()).isEqualTo(FlexBuffers.FBT_INT);
+
+      // bools vector
+        FlexBuffers.Vector bvec = m.get("bools").asVector();
+      assertThat(bvec.size()).isEqualTo(4);
+      assertThat(bvec.get(0).asBoolean()).isTrue();
+      assertThat(bvec.get(1).asBoolean()).isFalse();
+      assertThat(bvec.get(2).asBoolean()).isTrue();
+      assertThat(bvec.get(3).asBoolean()).isFalse();
+      assertThat(((FlexBuffers.TypedVector) bvec).getElemType()).isEqualTo(FlexBuffers.FBT_BOOL);
+
+      assertThat((float)m.get("foo").asFloat()).isEqualTo((float) 100);
+      assertThat(m.get("unknown").isNull()).isTrue();
+
+      // mymap vector
+        FlexBuffers.Map mymap = m.get("mymap").asMap();
+      // These should be equal by pointer equality, since key and value are shared.
+      assertThat(mymap.keys().get(0)).isEqualTo(m.keys().get(0));
+      assertThat(mymap.keys().get(0).toString()).isEqualTo("bar");
+      assertThat(mymap.values().get(0).asString()).isEqualTo(vec.get(1).asString());
+      assertThat(mymap.get("int").asInt()).isEqualTo(-120);
+      assertThat((float)mymap.get("float").asFloat()).isEqualTo(-123.0f);
+      assertThat(Arrays.equals(mymap.get("blob").asBlob().getBytes(), new byte[]{ 65, 67 })).isEqualTo(
+        true);
+      assertThat(mymap.get("blob").asBlob().toString()).isEqualTo("AC");
+      assertThat(mymap.get("blob").toString()).isEqualTo("\"AC\"");
+    }
+
+    @org.junit.Test public 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();
+      assertThat(text.length()).isEqualTo(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();
+
+      assertThat(v.size()).isEqualTo(size);
+      for (int i=0; i<size; i++) {
+        assertThat(v.get(i).asString().length()).isEqualTo(size);
+        assertThat(v.get(i).asString()).isEqualTo(text);
+      }
+    }
+
+    @org.junit.Test public 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));
+      assertThat(ref.getType()).isEqualTo(FlexBuffers.FBT_VECTOR_STRING_DEPRECATED);
+      assertThat(ref.isTypedVector()).isTrue();
+      Vector vec = ref.asVector();
+        for (int i=0; i< vec.size(); i++) {
+          assertThat("abc").isEqualTo(vec.get(i).asString());
+        }
+    }
+
+    @org.junit.Test public void testSingleElementBoolean() {
+        FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(100));
+        builder.putBoolean(true);
+        ByteBuffer b = builder.finish();
+        assertThat(FlexBuffers.getRoot(b).asBoolean()).isTrue();
+    }
+
+    @org.junit.Test public void testSingleElementByte() {
+        FlexBuffersBuilder builder = new FlexBuffersBuilder();
+        builder.putInt(10);
+        ByteBuffer b = builder.finish();
+      assertThat(10).isEqualTo(FlexBuffers.getRoot(b).asInt());
+    }
+
+    @org.junit.Test public void testSingleElementShort() {
+        FlexBuffersBuilder builder = new FlexBuffersBuilder();
+        builder.putInt(Short.MAX_VALUE);
+        ByteBuffer b = builder.finish();
+      assertThat(Short.MAX_VALUE).isEqualTo((short) FlexBuffers.getRoot(b).asInt());
+    }
+
+    @org.junit.Test public void testSingleElementInt() {
+        FlexBuffersBuilder builder = new FlexBuffersBuilder();
+        builder.putInt(Integer.MIN_VALUE);
+        ByteBuffer b = builder.finish();
+      assertThat(Integer.MIN_VALUE).isEqualTo(FlexBuffers.getRoot(b).asInt());
+    }
+
+    @org.junit.Test public void testSingleElementLong() {
+        FlexBuffersBuilder builder = new FlexBuffersBuilder();
+        builder.putInt(Long.MAX_VALUE);
+        ByteBuffer b = builder.finish();
+      assertThat(Long.MAX_VALUE).isEqualTo(FlexBuffers.getRoot(b).asLong());
+    }
+
+    @org.junit.Test public void testSingleElementFloat() {
+        FlexBuffersBuilder builder = new FlexBuffersBuilder();
+        builder.putFloat(Float.MAX_VALUE);
+        ByteBuffer b = builder.finish();
+      assertThat(Float.compare(Float.MAX_VALUE, (float) FlexBuffers.getRoot(b).asFloat())).isEqualTo(
+        0);
+    }
+
+    @org.junit.Test public void testSingleElementDouble() {
+        FlexBuffersBuilder builder = new FlexBuffersBuilder();
+        builder.putFloat(Double.MAX_VALUE);
+        ByteBuffer b = builder.finish();
+      assertThat(Double.compare(Double.MAX_VALUE, FlexBuffers.getRoot(b).asFloat())).isEqualTo(0);
+    }
+
+    @org.junit.Test public 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);
+
+      assertThat(FlexBuffers.FBT_STRING).isEqualTo(r.getType());
+      assertThat(sb.toString()).isEqualTo(r.asString());
+    }
+
+    @org.junit.Test public void testSingleElementSmallString() {
+        FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(10000));
+
+        builder.putString("aa");
+        ByteBuffer b = builder.finish();
+        FlexBuffers.Reference r = FlexBuffers.getRoot(b);
+
+      assertThat(FlexBuffers.FBT_STRING).isEqualTo(r.getType());
+      assertThat("aa").isEqualTo(r.asString());
+    }
+
+    @org.junit.Test public 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();
+      assertThat((byte)5).isEqualTo(result[0]);
+      assertThat((byte)124).isEqualTo(result[1]);
+      assertThat((byte)118).isEqualTo(result[2]);
+      assertThat((byte)-1).isEqualTo(result[3]);
+    }
+
+    @org.junit.Test public 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++) {
+              assertThat((byte)(index % 64)).isEqualTo(result[index]);
+            }
+        }
+    }
+
+    @org.junit.Test public void testSingleElementUByte() {
+        FlexBuffersBuilder builder = new FlexBuffersBuilder();
+        builder.putUInt(0xFF);
+        ByteBuffer b = builder.finish();
+        FlexBuffers.Reference r = FlexBuffers.getRoot(b);
+      assertThat(255).isEqualTo((int)r.asUInt());
+    }
+
+    @org.junit.Test public void testSingleElementUShort() {
+        FlexBuffersBuilder builder = new FlexBuffersBuilder();
+        builder.putUInt(0xFFFF);
+        ByteBuffer b = builder.finish();
+        FlexBuffers.Reference r = FlexBuffers.getRoot(b);
+      assertThat(65535).isEqualTo((int)r.asUInt());
+    }
+
+    @org.junit.Test public void testSingleElementUInt() {
+        FlexBuffersBuilder builder = new FlexBuffersBuilder();
+        builder.putUInt(0xFFFF_FFFFL);
+        ByteBuffer b = builder.finish();
+        FlexBuffers.Reference r = FlexBuffers.getRoot(b);
+      assertThat(4294967295L).isEqualTo(r.asUInt());
+    }
+
+    @org.junit.Test public 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());
+    }
+
+    @org.junit.Test public void testSingleElementVector() {
+        FlexBuffersBuilder b = new FlexBuffersBuilder();
+
+        int vecPos = b.startVector();
+        b.putInt(99);
+        b.putString("wow");
+        b.putNull();
+        int vecpos2 = b.startVector();
+        b.putInt(99);
+        b.putString("wow");
+        b.putNull();
+        b.endVector(null, vecpos2, false, false);
+        b.endVector(null, vecPos, false, false);
+        b.finish();
+
+        FlexBuffers.Reference r = FlexBuffers.getRoot(b.getBuffer());
+      assertThat(FlexBuffers.FBT_VECTOR).isEqualTo(r.getType());
+      FlexBuffers.Vector vec = FlexBuffers.getRoot(b.getBuffer()).asVector();
+      assertThat(4).isEqualTo(vec.size());
+      assertThat(99).isEqualTo(vec.get(0).asInt());
+      assertThat("wow").isEqualTo(vec.get(1).asString());
+      assertThat(true).isEqualTo(vec.get(2).isNull());
+      assertThat("[ 99, \"wow\", null ]").isEqualTo(vec.get(3).toString());
+      assertThat("[ 99, \"wow\", null, [ 99, \"wow\", null ] ]").isEqualTo(
+        FlexBuffers.getRoot(b.getBuffer()).toString());
+    }
+
+    @org.junit.Test public void testSingleElementMap() {
+        FlexBuffersBuilder b = new FlexBuffersBuilder();
+
+        int mapPost = b.startMap();
+        b.putInt("myInt", 0x7fffffbbbfffffffL);
+        b.putString("myString", "wow");
+        b.putString("myString2", "incredible");
+        b.putNull("myNull");
+        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());
+      assertThat(FlexBuffers.FBT_MAP).isEqualTo(r.getType());
+      FlexBuffers.Map map = FlexBuffers.getRoot(b.getBuffer()).asMap();
+      assertThat(6).isEqualTo(map.size());
+      assertThat(0x7fffffbbbfffffffL).isEqualTo(map.get("myInt").asLong());
+      assertThat("wow").isEqualTo(map.get("myString").asString());
+      assertThat("incredible").isEqualTo(map.get("myString2").asString());
+      assertThat(true).isEqualTo(map.get("myNull").isNull());
+      assertThat(99).isEqualTo(map.get("myVec").asVector().get(0).asInt());
+      assertThat("wow").isEqualTo(map.get("myVec").asVector().get(1).asString());
+      assertThat(Double.compare(0x1.ffffbbbffffffP+1023, map.get("double").asFloat())).isEqualTo(0);
+      assertThat(
+        "{ \"double\" : 1.7976894783391937E308, \"myInt\" : 9223371743723257855, \"myNull\" : null, \"myString\" : \"wow\", \"myString2\" : \"incredible\", \"myVec\" : [ 99, \"wow\" ] }").isEqualTo(
+        FlexBuffers.getRoot(b.getBuffer()).toString());
+    }
+
+    @org.junit.Test public 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();
+      assertThat(blob.size()).isEqualTo(0);
+      assertThat(map.size()).isEqualTo(0);
+      assertThat(ary.size()).isEqualTo(0);
+      assertThat(typedAry.size()).isEqualTo(0);
+    }
+
+    @org.junit.Test public 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);
+
+      assertThat(rootReference.isMap()).isTrue();
+
+      FlexBuffers.Map flexMap = rootReference.asMap();
+
+        FlexBuffers.KeyVector keys = flexMap.keys();
+        FlexBuffers.Vector values = flexMap.values();
+
+      assertThat(entriesCount).isEqualTo(keys.size());
+      assertThat(entriesCount).isEqualTo(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());
+        }
+
+      assertThat(source).isEqualTo(result);
+    }
+
+    @org.junit.Test public void testBuilderGrowth() {
+        FlexBuffersBuilder builder = new FlexBuffersBuilder();
+        String someString = "This is a small string";
+        builder.putString(someString);
+        ByteBuffer b = builder.finish();
+      assertThat(someString).isEqualTo(FlexBuffers.getRoot(b).asString());
+
+      FlexBuffersBuilder failBuilder = new FlexBuffersBuilder(ByteBuffer.allocate(1));
+        failBuilder.putString(someString);
+    }
+
+    @org.junit.Test
+    public 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();
+
+      assertThat(m.size()).isEqualTo(5);
+
+      KeyVector kv = m.keys();
+        for (int i=0; i< utf8keys.length; i++) {
+          assertThat(kv.get(i).toString()).isEqualTo(m.get(i).asString());
+        }
+
+      assertThat(m.get(key0).asString()).isEqualTo(utf8keys[0]);
+      assertThat(m.get(key1).asString()).isEqualTo(utf8keys[1]);
+      assertThat(m.get(key2).asString()).isEqualTo(utf8keys[2]);
+      assertThat(m.get(key3).asString()).isEqualTo(utf8keys[3]);
+      assertThat(m.get(key4).asString()).isEqualTo(utf8keys[4]);
+    }
+
+    @org.junit.Test public void testFlexBuffersMapLookup() {
+        FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(512),
+                FlexBuffersBuilder.BUILDER_FLAG_SHARE_KEYS_AND_STRINGS);
+
+        String key0 = "123";
+        String key1 = "1234";
+        String key2 = "12345";
+        String[] keys = new String[]{key0, key1, key2};
+
+        int map = builder.startMap();
+
+        for (int i=0; i< keys.length; i++) {
+            builder.putString(keys[i], keys[i]);  // Testing key and string reuse.
+        }
+        builder.endMap(null, map);
+        builder.finish();
+
+        FlexBuffers.Map m = FlexBuffers.getRoot(builder.getBuffer()).asMap();
+        for (int i=0; i< keys.length; i++) {
+          assertThat(m.get(keys[i]).asString()).isEqualTo(keys[i]);
+          assertThat(m.get(keys[i].getBytes(StandardCharsets.UTF_8)).asString()).isEqualTo(keys[i]);
+        }
+    }
+
+    @org.junit.Test public void TestDictionaryLookup() {
+        FlatBufferBuilder fbb = new FlatBufferBuilder(16);
+        int lfIndex = LongFloatEntry.createLongFloatEntry(fbb, 0, 99);
+        int vectorEntriesIdx = LongFloatMap.createEntriesVector(fbb, new int[] { lfIndex });
+        int rootIdx = LongFloatMap.createLongFloatMap(fbb, vectorEntriesIdx);
+
+        LongFloatMap.finishLongFloatMapBuffer(fbb, rootIdx);
+        LongFloatMap map = LongFloatMap.getRootAsLongFloatMap(fbb.dataBuffer());
+      assertThat(map.entriesLength()).isEqualTo(1);
+
+      LongFloatEntry e = map.entries(0);
+      assertThat(e.key()).isEqualTo(0L);
+      assertThat(e.value()).isEqualTo(99.0f);
+
+      LongFloatEntry e2 = map.entriesByKey(0);
+      assertThat(e2.key()).isEqualTo(0L);
+      assertThat(e2.value()).isEqualTo(99.0f);
+    }
+
+    @org.junit.Test public 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());
+
+      assertThat(monsterObject.inventoryLength()).isEqualTo(data.length);
+      assertThat((Integer) monsterObject.inventory(4)).isEqualTo((int) data[4]);
+      assertThat(ByteBuffer.wrap(data)).isEqualTo(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());
+
+      assertThat(monsterObject2.inventoryLength()).isEqualTo(data.length);
+      for (int i = 0; i < data.length; i++) {
+        assertThat((Integer) monsterObject2.inventory(i)).isEqualTo((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());
+
+      assertThat(monsterObject3.inventoryLength()).isEqualTo(4);
+      assertThat((Integer) monsterObject3.inventory(0)).isEqualTo((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());
+
+      assertThat(monsterObject4.inventoryLength()).isEqualTo(data.length);
+      assertThat((Integer) monsterObject4.inventory(8)).isEqualTo((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());
+
+      assertThat(monsterObject5.inventoryLength()).isEqualTo(largeData.length);
+      assertThat((Integer) monsterObject5.inventory(25)).isEqualTo((int) largeData[25]);
+
+      fbb.clear();
+        bb = ByteBuffer.wrap(largeData);
+        bb.position(512);
+        ByteBuffer bb2 = bb.slice();
+      assertThat(bb2.arrayOffset()).isEqualTo(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());
+
+      assertThat(monsterObject6.inventoryLength()).isEqualTo(512);
+      assertThat((Integer) monsterObject6.inventory(0)).isEqualTo((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());
+
+      assertThat(monsterObject7.inventoryLength()).isEqualTo(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());
+
+      assertThat(monsterObject8.inventoryLength()).isEqualTo(2048);
+    }
+
+    @org.junit.Test public void TestSharedStringPool() {
+        FlatBufferBuilder fb = new FlatBufferBuilder(1);
+        String testString = "My string";
+        int offset = fb.createSharedString(testString);
+        for (int i=0; i< 10; i++) {
+          assertThat(offset).isEqualTo(fb.createSharedString(testString));
+        }
+    }
+
+    @org.junit.Test public void TestScalarOptional() {
+        FlatBufferBuilder fbb = new FlatBufferBuilder(1);
+        ScalarStuff.startScalarStuff(fbb);
+        int pos = ScalarStuff.endScalarStuff(fbb);
+        fbb.finish(pos);
+
+        ScalarStuff scalarStuff = ScalarStuff.getRootAsScalarStuff(fbb.dataBuffer());
+      assertThat(scalarStuff.justI8()).isEqualTo((byte)0);
+      assertThat(scalarStuff.maybeI8()).isEqualTo((byte)0);
+      assertThat(scalarStuff.defaultI8()).isEqualTo((byte)42);
+      assertThat(scalarStuff.justU8()).isEqualTo(0);
+      assertThat(scalarStuff.maybeU8()).isEqualTo(0);
+      assertThat(scalarStuff.defaultU8()).isEqualTo(42);
+      assertThat(scalarStuff.justI16()).isEqualTo((short)0);
+      assertThat(scalarStuff.maybeI16()).isEqualTo((short)0);
+      assertThat(scalarStuff.defaultI16()).isEqualTo((short)42);
+      assertThat(scalarStuff.justU16()).isEqualTo(0);
+      assertThat(scalarStuff.maybeU16()).isEqualTo(0);
+      assertThat(scalarStuff.defaultU16()).isEqualTo(42);
+      assertThat(scalarStuff.justI32()).isEqualTo(0);
+      assertThat(scalarStuff.maybeI32()).isEqualTo(0);
+      assertThat(scalarStuff.defaultI32()).isEqualTo(42);
+      assertThat(scalarStuff.justU32()).isEqualTo(0L);
+      assertThat(scalarStuff.maybeU32()).isEqualTo(0L);
+      assertThat(scalarStuff.defaultU32()).isEqualTo(42L);
+      assertThat(scalarStuff.justI64()).isEqualTo(0L);
+      assertThat(scalarStuff.maybeI64()).isEqualTo(0L);
+      assertThat(scalarStuff.defaultI64()).isEqualTo(42L);
+      assertThat(scalarStuff.justU64()).isEqualTo(0L);
+      assertThat(scalarStuff.maybeU64()).isEqualTo(0L);
+      assertThat(scalarStuff.defaultU64()).isEqualTo(42L);
+      assertThat(scalarStuff.justF32()).isEqualTo(0.0f);
+      assertThat(scalarStuff.maybeF32()).isEqualTo(0f);
+      assertThat(scalarStuff.defaultF32()).isEqualTo(42.0f);
+      assertThat(scalarStuff.justF64()).isEqualTo(0.0);
+      assertThat(scalarStuff.maybeF64()).isEqualTo(0.0);
+      assertThat(scalarStuff.defaultF64()).isEqualTo(42.0);
+      assertThat(scalarStuff.justBool()).isFalse();
+      assertThat(scalarStuff.maybeBool()).isFalse();
+      assertThat(scalarStuff.defaultBool()).isTrue();
+      assertThat(scalarStuff.justEnum()).isEqualTo(OptionalByte.None);
+      assertThat(scalarStuff.maybeEnum()).isEqualTo(OptionalByte.None);
+      assertThat(scalarStuff.defaultEnum()).isEqualTo(OptionalByte.One);
+
+      assertThat(scalarStuff.hasMaybeI8()).isFalse();
+      assertThat(scalarStuff.hasMaybeI16()).isFalse();
+      assertThat(scalarStuff.hasMaybeI32()).isFalse();
+      assertThat(scalarStuff.hasMaybeI64()).isFalse();
+      assertThat(scalarStuff.hasMaybeU8()).isFalse();
+      assertThat(scalarStuff.hasMaybeU16()).isFalse();
+      assertThat(scalarStuff.hasMaybeU32()).isFalse();
+      assertThat(scalarStuff.hasMaybeU64()).isFalse();
+      assertThat(scalarStuff.hasMaybeF32()).isFalse();
+      assertThat(scalarStuff.hasMaybeF64()).isFalse();
+      assertThat(scalarStuff.hasMaybeBool()).isFalse();
+      assertThat(scalarStuff.hasMaybeEnum()).isFalse();
+
+      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());
+
+      assertThat(scalarStuff.justI8()).isEqualTo((byte)5);
+      assertThat(scalarStuff.maybeI8()).isEqualTo((byte)5);
+      assertThat(scalarStuff.defaultI8()).isEqualTo((byte)5);
+      assertThat(scalarStuff.justU8()).isEqualTo(6);
+      assertThat(scalarStuff.maybeU8()).isEqualTo(6);
+      assertThat(scalarStuff.defaultU8()).isEqualTo(6);
+      assertThat(scalarStuff.justI16()).isEqualTo((short)7);
+      assertThat(scalarStuff.maybeI16()).isEqualTo((short)7);
+      assertThat(scalarStuff.defaultI16()).isEqualTo((short)7);
+      assertThat(scalarStuff.justU16()).isEqualTo(8);
+      assertThat(scalarStuff.maybeU16()).isEqualTo(8);
+      assertThat(scalarStuff.defaultU16()).isEqualTo(8);
+      assertThat(scalarStuff.justI32()).isEqualTo(9);
+      assertThat(scalarStuff.maybeI32()).isEqualTo(9);
+      assertThat(scalarStuff.defaultI32()).isEqualTo(9);
+      assertThat(scalarStuff.justU32()).isEqualTo(10L);
+      assertThat(scalarStuff.maybeU32()).isEqualTo(10L);
+      assertThat(scalarStuff.defaultU32()).isEqualTo(10L);
+      assertThat(scalarStuff.justI64()).isEqualTo(11L);
+      assertThat(scalarStuff.maybeI64()).isEqualTo(11L);
+      assertThat(scalarStuff.defaultI64()).isEqualTo(11L);
+      assertThat(scalarStuff.justU64()).isEqualTo(12L);
+      assertThat(scalarStuff.maybeU64()).isEqualTo(12L);
+      assertThat(scalarStuff.defaultU64()).isEqualTo(12L);
+      assertThat(scalarStuff.justF32()).isEqualTo(13.0f);
+      assertThat(scalarStuff.maybeF32()).isEqualTo(13.0f);
+      assertThat(scalarStuff.defaultF32()).isEqualTo(13.0f);
+      assertThat(scalarStuff.justF64()).isEqualTo(14.0);
+      assertThat(scalarStuff.maybeF64()).isEqualTo(14.0);
+      assertThat(scalarStuff.defaultF64()).isEqualTo(14.0);
+      assertThat(scalarStuff.justBool()).isTrue();
+      assertThat(scalarStuff.maybeBool()).isTrue();
+      assertThat(scalarStuff.defaultBool()).isTrue();
+      assertThat(scalarStuff.justEnum()).isEqualTo(OptionalByte.Two);
+      assertThat(scalarStuff.maybeEnum()).isEqualTo(OptionalByte.Two);
+      assertThat(scalarStuff.defaultEnum()).isEqualTo(OptionalByte.Two);
+
+      assertThat(scalarStuff.hasMaybeI8()).isTrue();
+      assertThat(scalarStuff.hasMaybeI16()).isTrue();
+      assertThat(scalarStuff.hasMaybeI32()).isTrue();
+      assertThat(scalarStuff.hasMaybeI64()).isTrue();
+      assertThat(scalarStuff.hasMaybeU8()).isTrue();
+      assertThat(scalarStuff.hasMaybeU16()).isTrue();
+      assertThat(scalarStuff.hasMaybeU32()).isTrue();
+      assertThat(scalarStuff.hasMaybeU64()).isTrue();
+      assertThat(scalarStuff.hasMaybeF32()).isTrue();
+      assertThat(scalarStuff.hasMaybeF64()).isTrue();
+      assertThat(scalarStuff.hasMaybeBool()).isTrue();
+      assertThat(scalarStuff.hasMaybeEnum()).isTrue();
+    }
+
+    static void TestObject(MonsterT monster) {
+      assertThat(monster.getHp()).isEqualTo((short) 80);
+      // default
+      assertThat(monster.getMana()).isEqualTo((short) 150);
+
+      assertThat(monster.getName()).isEqualTo("MyMonster");
+      assertThat(monster.getColor()).isEqualTo((Integer) Color.Blue);
+      // monster.friendly() // can't access, deprecated
+
+        Vec3T pos = monster.getPos();
+      assertThat(pos.getX()).isEqualTo(1.0f);
+      assertThat(pos.getY()).isEqualTo(2.0f);
+      assertThat(pos.getZ()).isEqualTo(3.0f);
+      assertThat(pos.getTest1()).isEqualTo(3.0);
+      // issue: int != byte
+      assertThat(pos.getTest2()).isEqualTo((int) Color.Green);
+      TestT t = pos.getTest3();
+      assertThat(t.getA()).isEqualTo((short) 5);
+      assertThat(t.getB()).isEqualTo((byte) 6);
+
+      assertThat(monster.getTest().getType()).isEqualTo((byte) Any.Monster);
+      MonsterT monster2 = (MonsterT) monster.getTest().getValue();
+      assertThat(monster2 != null).isTrue();
+      assertThat(monster2.getName()).isEqualTo("Fred");
+
+      int[] inv = monster.getInventory();
+      assertThat(inv.length).isEqualTo(5);
+      int[] expInv = {0, 1, 2, 3, 4};
+        for (int i = 0; i < inv.length; i++)
+          assertThat(expInv[i]).isEqualTo(inv[i]);
+
+        TestT[] test4 = monster.getTest4();
+        TestT test_0 = test4[0];
+        TestT test_1 = test4[1];
+      assertThat(test4.length).isEqualTo(2);
+      assertThat(test_0.getA()).isEqualTo((short) 10);
+      assertThat(test_0.getB()).isEqualTo((byte) 20);
+      assertThat(test_1.getA()).isEqualTo((short) 30);
+      assertThat(test_1.getB()).isEqualTo((byte) 40);
+
+      String[] testarrayofstring = monster.getTestarrayofstring();
+      assertThat(testarrayofstring.length).isEqualTo(2);
+      assertThat(testarrayofstring[0]).isEqualTo("test1");
+      assertThat(testarrayofstring[1]).isEqualTo("test2");
+
+      MonsterT[] testarrayoftables = monster.getTestarrayoftables();
+      assertThat(testarrayoftables.length).isEqualTo(0);
+
+      MonsterT enemy = monster.getEnemy();
+      assertThat(enemy != null).isTrue();
+      assertThat(enemy.getName()).isEqualTo("Fred");
+
+      int[] testnestedflatbuffer = monster.getTestnestedflatbuffer();
+      assertThat(testnestedflatbuffer.length).isEqualTo(0);
+
+      assertThat(monster.getTestempty() == null).isTrue();
+
+      assertThat(monster.getTestbool()).isTrue();
+
+      boolean[] testarrayofbools = monster.getTestarrayofbools();
+      assertThat(testarrayofbools.length).isEqualTo(3);
+      assertThat(testarrayofbools[0]).isTrue();
+      assertThat(testarrayofbools[1]).isFalse();
+      assertThat(testarrayofbools[2]).isTrue();
+
+      assertThat(monster.getTestf()).isEqualTo(3.14159f);
+      assertThat(monster.getTestf2()).isEqualTo(3.0f);
+      assertThat(monster.getTestf3()).isEqualTo(0.0f);
+      assertThat(monster.getTestf3()).isEqualTo(0.0f);
+
+      AbilityT[] testarrayofsortedstruct = monster.getTestarrayofsortedstruct();
+      assertThat(testarrayofsortedstruct.length).isEqualTo(3);
+      assertThat(testarrayofsortedstruct[0].getId()).isEqualTo((long) 0);
+      assertThat(testarrayofsortedstruct[1].getId()).isEqualTo((long) 1);
+      assertThat(testarrayofsortedstruct[2].getId()).isEqualTo((long) 5);
+      assertThat(testarrayofsortedstruct[0].getDistance()).isEqualTo((long) 45);
+      assertThat(testarrayofsortedstruct[1].getDistance()).isEqualTo((long) 21);
+      assertThat(testarrayofsortedstruct[2].getDistance()).isEqualTo((long) 12);
+
+      int[] flex = monster.getFlex();
+      assertThat(flex.length).isEqualTo(0);
+
+      long[] vectorOfLongs = monster.getVectorOfLongs();
+      assertThat(vectorOfLongs.length).isEqualTo(5);
+      long l = 1;
+        for (int i = 0; i < vectorOfLongs.length; i++) {
+          assertThat(vectorOfLongs[i]).isEqualTo(l);
+          l *= 100;
+        }
+
+        double[] vectorOfDoubles = monster.getVectorOfDoubles();
+      assertThat(vectorOfDoubles.length).isEqualTo(3);
+      assertThat(vectorOfDoubles[0]).isEqualTo(-1.7976931348623157E308);
+      assertThat(vectorOfDoubles[1]).isEqualTo(0.0);
+      assertThat(vectorOfDoubles[2]).isEqualTo(1.7976931348623157E308);
+
+      assertThat(monster.getParentNamespaceTest() == null).isTrue();
+      ReferrableT[] vectorOfReferrables = monster.getVectorOfReferrables();
+      assertThat(vectorOfReferrables.length).isEqualTo(0);
+
+      assertThat(monster.getSignedEnum()).isEqualTo((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);
+    }
+}
diff --git a/java/src/test/java/MyGame b/java/src/test/java/MyGame
new file mode 120000
index 0000000..0ba918e
--- /dev/null
+++ b/java/src/test/java/MyGame
@@ -0,0 +1 @@
+../../../../tests/MyGame
\ No newline at end of file
diff --git a/java/src/test/java/NamespaceA b/java/src/test/java/NamespaceA
new file mode 120000
index 0000000..37a8d89
--- /dev/null
+++ b/java/src/test/java/NamespaceA
@@ -0,0 +1 @@
+../../../../tests/namespace_test/NamespaceA
\ No newline at end of file
diff --git a/java/src/test/java/NamespaceC b/java/src/test/java/NamespaceC
new file mode 120000
index 0000000..c1e44a8
--- /dev/null
+++ b/java/src/test/java/NamespaceC
@@ -0,0 +1 @@
+../../../../tests/namespace_test/NamespaceC
\ No newline at end of file
diff --git a/java/src/test/java/optional_scalars b/java/src/test/java/optional_scalars
new file mode 120000
index 0000000..44a35f9
--- /dev/null
+++ b/java/src/test/java/optional_scalars
@@ -0,0 +1 @@
+../../../../tests/optional_scalars
\ No newline at end of file
diff --git a/java/src/test/java/union_vector b/java/src/test/java/union_vector
new file mode 120000
index 0000000..cc82221
--- /dev/null
+++ b/java/src/test/java/union_vector
@@ -0,0 +1 @@
+../../../../tests/union_vector
\ No newline at end of file
diff --git a/java/src/test/resources/monsterdata_test.mon b/java/src/test/resources/monsterdata_test.mon
new file mode 100644
index 0000000..da0ed86
--- /dev/null
+++ b/java/src/test/resources/monsterdata_test.mon
Binary files differ