Squashed 'third_party/flatbuffers/' content from commit acc9990ab

Change-Id: I48550d40d78fea996ebe74e9723a5d1f910de491
git-subtree-dir: third_party/flatbuffers
git-subtree-split: acc9990abd2206491480291b0f85f925110102ea
diff --git a/tests/DartTest.sh b/tests/DartTest.sh
new file mode 100755
index 0000000..6ce72cc
--- /dev/null
+++ b/tests/DartTest.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+#
+# Copyright 2016 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.
+
+pushd "$(dirname $0)" >/dev/null
+
+command -v pub >/dev/null 2>&1 || { echo >&2 "Dart tests require `pub` but it's not installed.  Aborting."; exit 1; }
+command -v dart >/dev/null 2>&1 || { echo >&2 "Dart tests require dart to be in path but it's not installed.  Aborting."; exit 1; }
+# output required files to the dart folder so that pub will be able to 
+# distribute them and more people can more easily run the dart tests
+../flatc --dart -I include_test -o ../dart/test monster_test.fbs 
+cp monsterdata_test.mon ../dart/test
+
+cd ../dart
+
+# update packages
+pub get
+# Execute the sample.
+dart test/flat_buffers_test.dart
+
+# cleanup
+rm ../dart/test/monsterdata_test.mon
diff --git a/tests/FlatBuffers.Benchmarks/FlatBufferBuilderBenchmark.cs b/tests/FlatBuffers.Benchmarks/FlatBufferBuilderBenchmark.cs
new file mode 100644
index 0000000..1df5ac3
--- /dev/null
+++ b/tests/FlatBuffers.Benchmarks/FlatBufferBuilderBenchmark.cs
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+
+using BenchmarkDotNet.Attributes;
+using MyGame.Example;
+
+namespace FlatBuffers.Benchmarks
+{
+    //[EtwProfiler] - needs elevated privileges
+    [MemoryDiagnoser]
+    public class FlatBufferBuilderBenchmark
+    {
+        private const int NumberOfRows = 10_000;
+
+        [Benchmark]
+        public void BuildNestedMonster()
+        {
+            const string nestedMonsterName = "NestedMonsterName";
+            const short nestedMonsterHp = 600;
+            const short nestedMonsterMana = 1024;
+
+            for (int i = 0; i < NumberOfRows; i++)
+            {
+                // Create nested buffer as a Monster type
+                var fbb1 = new FlatBufferBuilder(16);
+                var str1 = fbb1.CreateString(nestedMonsterName);
+                Monster.StartMonster(fbb1);
+                Monster.AddName(fbb1, str1);
+                Monster.AddHp(fbb1, nestedMonsterHp);
+                Monster.AddMana(fbb1, nestedMonsterMana);
+                var monster1 = Monster.EndMonster(fbb1);
+                Monster.FinishMonsterBuffer(fbb1, monster1);
+                var fbb1Bytes = fbb1.SizedByteArray();
+                fbb1 = null;
+
+                // Create a Monster which has the first buffer as a nested buffer
+                var fbb2 = new FlatBufferBuilder(16);
+                var str2 = fbb2.CreateString("My Monster");
+                var nestedBuffer = Monster.CreateTestnestedflatbufferVector(fbb2, fbb1Bytes);
+                Monster.StartMonster(fbb2);
+                Monster.AddName(fbb2, str2);
+                Monster.AddHp(fbb2, 50);
+                Monster.AddMana(fbb2, 32);
+                Monster.AddTestnestedflatbuffer(fbb2, nestedBuffer);
+                var monster = Monster.EndMonster(fbb2);
+                Monster.FinishMonsterBuffer(fbb2, monster);
+            }
+        }
+
+        [Benchmark]
+        public void BuildMonster()
+        {
+            for (int i = 0; i < NumberOfRows; i++)
+            {
+                var builder = new FlatBufferBuilder(16);
+                var str1 = builder.CreateString("MonsterName");
+                Monster.StartMonster(builder);
+                Monster.AddName(builder, str1);
+                Monster.AddHp(builder, 600);
+                Monster.AddMana(builder, 1024);
+                Monster.AddColor(builder, Color.Blue);
+                Monster.AddTestbool(builder, true);
+                Monster.AddTestf(builder, 0.3f);
+                Monster.AddTestf2(builder, 0.2f);
+                Monster.AddTestf3(builder, 0.1f);
+
+                var monster1 = Monster.EndMonster(builder);
+                Monster.FinishMonsterBuffer(builder, monster1);
+            }
+        }
+
+        [Benchmark]
+        public void TestTables()
+        {
+            FlatBufferBuilder builder = new FlatBufferBuilder(1024 * 1024 * 32);
+            for (int x = 0; x < 500000; ++x)
+            {
+                var offset = builder.CreateString("T");
+                builder.StartObject(4);
+                builder.AddDouble(3.2);
+                builder.AddDouble(4.2);
+                builder.AddDouble(5.2);
+                builder.AddOffset(offset.Value);
+                builder.EndObject();
+            }
+        }
+    }
+}
diff --git a/tests/FlatBuffers.Benchmarks/FlatBuffers.Benchmarks.csproj b/tests/FlatBuffers.Benchmarks/FlatBuffers.Benchmarks.csproj
new file mode 100644
index 0000000..b900384
--- /dev/null
+++ b/tests/FlatBuffers.Benchmarks/FlatBuffers.Benchmarks.csproj
@@ -0,0 +1,21 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>netcoreapp2.1</TargetFramework>
+    <LangVersion>latest</LangVersion>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <DefineConstants>$(DefineConstants);UNSAFE_BYTEBUFFER;BYTEBUFFER_NO_BOUNDS_CHECK;ENABLE_SPAN_T</DefineConstants>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="BenchmarkDotNet" Version="0.11.3" />
+    <PackageReference Include="BenchmarkDotNet.Diagnostics.Windows" Version="0.11.3" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <Compile Include="..\..\net\FlatBuffers\*.cs" Link="FlatBuffers\%(FileName).cs" />
+    <Compile Include="..\MyGame\**\*.cs" Link="MyGame\Example\%(FileName).cs" />
+  </ItemGroup>
+
+</Project>
diff --git a/tests/FlatBuffers.Benchmarks/Program.cs b/tests/FlatBuffers.Benchmarks/Program.cs
new file mode 100644
index 0000000..9e63b4b
--- /dev/null
+++ b/tests/FlatBuffers.Benchmarks/Program.cs
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+using BenchmarkDotNet.Running;
+
+namespace FlatBuffers.Benchmarks
+{
+    public static class Program
+    {
+        public static void Main(string[] args)
+        {
+            BenchmarkSwitcher
+                .FromAssembly(typeof(Program).Assembly)
+                .Run(args);
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/FlatBuffers.Test/Assert.cs b/tests/FlatBuffers.Test/Assert.cs
new file mode 100644
index 0000000..488c338
--- /dev/null
+++ b/tests/FlatBuffers.Test/Assert.cs
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace FlatBuffers.Test
+{
+
+    public class AssertFailedException : Exception
+    {
+        private readonly object _expected;
+        private readonly object _actual;
+
+        public AssertFailedException(object expected, object actual)
+        {
+            _expected = expected;
+            _actual = actual;
+        }
+
+        public override string Message
+        {
+            get { return string.Format("Expected {0} but saw {1}", _expected, _actual); }
+        }
+    }
+
+    public class AssertArrayFailedException : Exception
+    {
+        private readonly int _index;
+        private readonly object _expected;
+        private readonly object _actual;
+
+        public AssertArrayFailedException(int index, object expected, object actual)
+        {
+            _index = index;
+            _expected = expected;
+            _actual = actual;
+        }
+
+        public override string Message
+        {
+            get { return string.Format("Expected {0} at index {1} but saw {2}", _expected, _index, _actual); }
+        }
+    }
+
+    public class AssertUnexpectedThrowException : Exception
+    {
+        private readonly object _expected;
+
+        public AssertUnexpectedThrowException(object expected)
+        {
+            _expected = expected;
+        }
+
+        public override string Message
+        {
+            get { return string.Format("Expected exception of type {0}", _expected); }
+        }
+    }
+
+    public static class Assert
+    {
+        public static void AreEqual<T>(T expected, T actual)
+        {
+            if (!expected.Equals(actual))
+            {
+                throw new AssertFailedException(expected, actual);
+            }
+        }
+
+        public static void ArrayEqual<T>(T[] expected, T[] actual)
+        {
+            if (expected.Length != actual.Length)
+            {
+                throw new AssertFailedException(expected, actual);
+            }
+
+            for(var i = 0; i < expected.Length; ++i)
+            {
+                if (!expected[i].Equals(actual[i]))
+                {
+                    throw new AssertArrayFailedException(i, expected, actual);
+                }
+            }
+        }
+
+        public static void IsTrue(bool value)
+        {
+            if (!value)
+            {
+                throw new AssertFailedException(true, value);
+            }
+        }
+
+        public static void IsFalse(bool value)
+        {
+            if (value)
+            {
+                throw new AssertFailedException(false, value);
+            }
+        }
+
+        public static void Throws<T>(Action action) where T : Exception
+        {
+            var caught = false;
+            try
+            {
+                action();
+            }
+            catch (T)
+            {
+                caught = true;
+            }
+
+            if (!caught)
+            {
+                throw new AssertUnexpectedThrowException(typeof (T));
+            }
+        }
+    }
+}
diff --git a/tests/FlatBuffers.Test/ByteBufferTests.cs b/tests/FlatBuffers.Test/ByteBufferTests.cs
new file mode 100644
index 0000000..1c33a2f
--- /dev/null
+++ b/tests/FlatBuffers.Test/ByteBufferTests.cs
@@ -0,0 +1,612 @@
+/*
+ * 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.
+ */
+
+using System;
+
+namespace FlatBuffers.Test
+{
+    [FlatBuffersTestClass]
+    public class ByteBufferTests
+    {
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_Length_MatchesBufferLength()
+        {
+            var buffer = new byte[1000];
+            var uut = new ByteBuffer(buffer);
+            Assert.AreEqual(buffer.Length, uut.Length);
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_PutBytePopulatesBufferAtZeroOffset()
+        {
+            var buffer = new byte[1];
+            var uut = new ByteBuffer(buffer);
+            uut.PutByte(0, (byte)99);
+
+            Assert.AreEqual((byte)99, buffer[0]);
+        }
+
+#if !BYTEBUFFER_NO_BOUNDS_CHECK
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_PutByteCannotPutAtOffsetPastLength()
+        {
+            var uut = new ByteBuffer(1);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutByte(1, 99));
+        }
+#endif
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_PutShortPopulatesBufferCorrectly()
+        {
+            var buffer = new byte[2];
+            var uut = new ByteBuffer(buffer);
+            uut.PutShort(0, (short)1);
+
+            // Ensure Endianness was written correctly
+            Assert.AreEqual((byte)1, buffer[0]);
+            Assert.AreEqual((byte)0, buffer[1]);
+        }
+
+#if !BYTEBUFFER_NO_BOUNDS_CHECK
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_PutShortCannotPutAtOffsetPastLength()
+        {
+            var uut = new ByteBuffer(2);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutShort(2, 99));
+        }
+#endif
+
+#if !BYTEBUFFER_NO_BOUNDS_CHECK
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_PutShortChecksLength()
+        {
+            var uut = new ByteBuffer(1);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutShort(0, 99));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_PutShortChecksLengthAndOffset()
+        {
+            var uut = new ByteBuffer(2);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutShort(1, 99));
+        }
+#endif
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_PutIntPopulatesBufferCorrectly()
+        {
+            var buffer = new byte[4];
+            var uut = new ByteBuffer(buffer);
+            uut.PutInt(0, 0x0A0B0C0D);
+
+            // Ensure Endianness was written correctly
+            Assert.AreEqual(0x0D, buffer[0]);
+            Assert.AreEqual(0x0C, buffer[1]);
+            Assert.AreEqual(0x0B, buffer[2]);
+            Assert.AreEqual(0x0A, buffer[3]);
+        }
+
+#if !BYTEBUFFER_NO_BOUNDS_CHECK
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_PutIntCannotPutAtOffsetPastLength()
+        {
+            var uut = new ByteBuffer(4);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutInt(2, 0x0A0B0C0D));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_PutIntChecksLength()
+        {
+            var uut = new ByteBuffer(1);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutInt(0, 0x0A0B0C0D));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_PutIntChecksLengthAndOffset()
+        {
+            var uut = new ByteBuffer(4);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutInt(2, 0x0A0B0C0D));
+        }
+#endif
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_PutLongPopulatesBufferCorrectly()
+        {
+            var buffer = new byte[8];
+            var uut = new ByteBuffer(buffer);
+            uut.PutLong(0, 0x010203040A0B0C0D);
+
+            // Ensure Endianness was written correctly
+            Assert.AreEqual(0x0D, buffer[0]);
+            Assert.AreEqual(0x0C, buffer[1]);
+            Assert.AreEqual(0x0B, buffer[2]);
+            Assert.AreEqual(0x0A, buffer[3]);
+            Assert.AreEqual(0x04, buffer[4]);
+            Assert.AreEqual(0x03, buffer[5]);
+            Assert.AreEqual(0x02, buffer[6]);
+            Assert.AreEqual(0x01, buffer[7]);
+        }
+
+#if !BYTEBUFFER_NO_BOUNDS_CHECK
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_PutLongCannotPutAtOffsetPastLength()
+        {
+            var uut = new ByteBuffer(8);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutLong(2, 0x010203040A0B0C0D));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_PutLongChecksLength()
+        {
+            var uut = new ByteBuffer(1);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutLong(0, 0x010203040A0B0C0D));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_PutLongChecksLengthAndOffset()
+        {
+            var uut = new ByteBuffer(8);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutLong(2, 0x010203040A0B0C0D));
+        }
+#endif
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_GetByteReturnsCorrectData()
+        {
+            var buffer = new byte[1];
+            buffer[0] = 99;
+            var uut = new ByteBuffer(buffer);
+            Assert.AreEqual((byte)99, uut.Get(0));
+        }
+
+#if !BYTEBUFFER_NO_BOUNDS_CHECK
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_GetByteChecksOffset()
+        {
+            var uut = new ByteBuffer(1);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.Get(1));
+        }
+#endif
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_GetShortReturnsCorrectData()
+        {
+            var buffer = new byte[2];
+            buffer[0] = 1;
+            buffer[1] = 0;
+            var uut = new ByteBuffer(buffer);
+            Assert.AreEqual(1, uut.GetShort(0));
+        }
+
+#if !BYTEBUFFER_NO_BOUNDS_CHECK
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_GetShortChecksOffset()
+        {
+            var uut = new ByteBuffer(2);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetShort(2));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_GetShortChecksLength()
+        {
+            var uut = new ByteBuffer(2);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetShort(1));
+        }
+#endif
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_GetIntReturnsCorrectData()
+        {
+            var buffer = new byte[4];
+            buffer[0] = 0x0D;
+            buffer[1] = 0x0C;
+            buffer[2] = 0x0B;
+            buffer[3] = 0x0A;
+            var uut = new ByteBuffer(buffer);
+            Assert.AreEqual(0x0A0B0C0D, uut.GetInt(0));
+        }
+
+#if !BYTEBUFFER_NO_BOUNDS_CHECK
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_GetIntChecksOffset()
+        {
+            var uut = new ByteBuffer(4);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetInt(4));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_GetIntChecksLength()
+        {
+            var uut = new ByteBuffer(2);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetInt(0));
+        }
+#endif
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_GetLongReturnsCorrectData()
+        {
+            var buffer = new byte[8];
+            buffer[0] = 0x0D;
+            buffer[1] = 0x0C;
+            buffer[2] = 0x0B;
+            buffer[3] = 0x0A;
+            buffer[4] = 0x04;
+            buffer[5] = 0x03;
+            buffer[6] = 0x02;
+            buffer[7] = 0x01;
+            var uut = new ByteBuffer(buffer);
+            Assert.AreEqual(0x010203040A0B0C0D, uut.GetLong(0));
+        }
+
+#if !BYTEBUFFER_NO_BOUNDS_CHECK
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_GetLongChecksOffset()
+        {
+            var uut = new ByteBuffer(8);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetLong(8));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_GetLongChecksLength()
+        {
+            var uut = new ByteBuffer(7);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetLong(0));
+        }
+#endif
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_ReverseBytesUshort()
+        {
+            const ushort original = (ushort)0x1234U;
+            var reverse = ByteBuffer.ReverseBytes(original);
+            Assert.AreEqual(0x3412U, reverse);
+
+            var rereverse = ByteBuffer.ReverseBytes(reverse);
+            Assert.AreEqual(original, rereverse);
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_ReverseBytesUint()
+        {
+            const uint original = 0x12345678;
+            var reverse = ByteBuffer.ReverseBytes(original);
+            Assert.AreEqual(0x78563412U, reverse);
+
+            var rereverse = ByteBuffer.ReverseBytes(reverse);
+            Assert.AreEqual(original, rereverse);
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_ReverseBytesUlong()
+        {
+            const ulong original = 0x1234567890ABCDEFUL;
+            var reverse = ByteBuffer.ReverseBytes(original);
+            Assert.AreEqual(0xEFCDAB9078563412UL, reverse);
+
+            var rereverse = ByteBuffer.ReverseBytes(reverse);
+            Assert.AreEqual(original, rereverse);
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_ToFullArray_MatchesBuffer()
+        {
+            var buffer = new byte[4];
+            buffer[0] = 0x0D;
+            buffer[1] = 0x0C;
+            buffer[2] = 0x0B;
+            buffer[3] = 0x0A;
+            var uut = new ByteBuffer(buffer);
+            Assert.ArrayEqual(buffer, uut.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_ToSizedArray_MatchesBuffer()
+        {
+            var buffer = new byte[4];
+            buffer[0] = 0x0D;
+            buffer[1] = 0x0C;
+            buffer[2] = 0x0B;
+            buffer[3] = 0x0A;
+            var uut = new ByteBuffer(buffer);
+            Assert.ArrayEqual(buffer, uut.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_Duplicate_MatchesBuffer()
+        {
+            var buffer = new byte[4];
+            buffer[0] = 0x0D;
+            buffer[1] = 0x0C;
+            buffer[2] = 0x0B;
+            buffer[3] = 0x0A;
+            var uut = new ByteBuffer(buffer);
+            Assert.AreEqual(0x0A0B0C0D, uut.GetInt(0));
+
+            // Advance by two bytes
+            uut.Position = 2; uut = uut.Duplicate();
+            Assert.AreEqual(0x0A0B, uut.GetShort(2));
+
+            // Advance by one more byte
+            uut.Position = 1; uut = uut.Duplicate();
+            Assert.AreEqual(0x0A, uut.Get(3));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_To_Array_Float()
+        {
+            const int len = 9;
+
+            // Construct the data array
+            var fData = new float[len];
+            fData[0] = 1.0079F;
+            fData[1] = 4.0026F;
+            fData[2] = 6.941F;
+            fData[3] = 9.0122F;
+            fData[4] = 10.811F;
+            fData[5] = 12.0107F;
+            fData[6] = 14.0067F;
+            fData[7] = 15.9994F;
+            fData[8] = 18.9984F;
+
+            // Tranfer it to a byte array
+            var buffer = new byte[sizeof(float) * fData.Length];
+            Buffer.BlockCopy(fData, 0, buffer, 0, buffer.Length);
+
+            // Create the Byte Buffer from byte array
+            var uut = new ByteBuffer(buffer);
+
+            // Get the full array back out and ensure they are equivalent
+            var bbArray = uut.ToArray<float>(0, len);
+            Assert.ArrayEqual(fData, bbArray);
+
+            // Get a portion of the full array back out and ensure the
+            // subrange agrees
+            var bbArray2 = uut.ToArray<float>(4, len - 1);
+            Assert.AreEqual(bbArray2.Length, len - 1);
+            for (int i = 1; i < len - 1; i++)
+            {
+                Assert.AreEqual(fData[i], bbArray2[i - 1]);
+            }
+
+            // Get a sub portion of the full array back out and ensure the
+            // subrange agrees
+            var bbArray3 = uut.ToArray<float>(8, len - 4);
+            Assert.AreEqual(bbArray3.Length, len - 4);
+            for (int i = 2; i < len - 4; i++)
+            {
+                Assert.AreEqual(fData[i], bbArray3[i - 2]);
+            }
+        }
+
+        public void ByteBuffer_Put_Array_Helper<T>(T[] data, int typeSize)
+            where T : struct
+        {
+            // Create the Byte Buffer
+            var uut = new ByteBuffer(1024);
+
+            // Put the data into the buffer and make sure the offset is
+            // calculated correctly
+            int nOffset = uut.Put(1024, data);
+            Assert.AreEqual(1024 - typeSize * data.Length, nOffset);
+
+            // Get the full array back out and ensure they are equivalent
+            var bbArray = uut.ToArray<T>(nOffset, data.Length);
+            Assert.ArrayEqual(data, bbArray);
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_Put_Array_Float()
+        {
+            const int len = 9;
+
+            // Construct the data array
+            var data = new float[len];
+            data[0] = 1.0079F;
+            data[1] = 4.0026F;
+            data[2] = 6.941F;
+            data[3] = 9.0122F;
+            data[4] = 10.811F;
+            data[5] = 12.0107F;
+            data[6] = 14.0067F;
+            data[7] = 15.9994F;
+            data[8] = 18.9984F;
+
+            ByteBuffer_Put_Array_Helper(data, sizeof(float));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_Put_Array_Double()
+        {
+            const int len = 9;
+
+            // Construct the data array
+            var data = new double[len];
+            data[0] = 1.0079;
+            data[1] = 4.0026;
+            data[2] = 6.941;
+            data[3] = 9.0122;
+            data[4] = 10.811;
+            data[5] = 12.0107;
+            data[6] = 14.0067;
+            data[7] = 15.9994;
+            data[8] = 18.9984;
+
+            ByteBuffer_Put_Array_Helper(data, sizeof(double));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_Put_Array_Int()
+        {
+            const int len = 9;
+
+            // Construct the data array
+            var data = new int[len];
+            data[0] = 1;
+            data[1] = 4;
+            data[2] = 6;
+            data[3] = 9;
+            data[4] = 10;
+            data[5] = 12;
+            data[6] = 14;
+            data[7] = 15;
+            data[8] = 18;
+
+            ByteBuffer_Put_Array_Helper(data, sizeof(int));
+        }
+
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_Put_Array_UInt()
+        {
+            const int len = 9;
+
+            // Construct the data array
+            var data = new uint[len];
+            data[0] = 1;
+            data[1] = 4;
+            data[2] = 6;
+            data[3] = 9;
+            data[4] = 10;
+            data[5] = 12;
+            data[6] = 14;
+            data[7] = 15;
+            data[8] = 18;
+
+            ByteBuffer_Put_Array_Helper(data, sizeof(uint));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_Put_Array_Bool()
+        {
+            const int len = 9;
+
+            // Construct the data array
+            var data = new bool[len];
+            data[0] = true;
+            data[1] = true;
+            data[2] = false;
+            data[3] = true;
+            data[4] = false;
+            data[5] = true;
+            data[6] = true;
+            data[7] = true;
+            data[8] = false;
+
+            ByteBuffer_Put_Array_Helper(data, sizeof(bool));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_Put_Array_Long()
+        {
+            const int len = 9;
+
+            // Construct the data array
+            var data = new long[len];
+            data[0] = 1;
+            data[1] = 4;
+            data[2] = 6;
+            data[3] = 9;
+            data[4] = 10;
+            data[5] = 12;
+            data[6] = 14;
+            data[7] = 15;
+            data[8] = 18;
+
+            ByteBuffer_Put_Array_Helper(data, sizeof(long));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_Put_Array_Byte()
+        {
+            const int len = 9;
+
+            // Construct the data array
+            var data = new byte[len];
+            data[0] = 1;
+            data[1] = 4;
+            data[2] = 6;
+            data[3] = 9;
+            data[4] = 10;
+            data[5] = 12;
+            data[6] = 14;
+            data[7] = 15;
+            data[8] = 18;
+
+            ByteBuffer_Put_Array_Helper(data, sizeof(byte));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_Put_Array_SByte()
+        {
+            const int len = 9;
+
+            // Construct the data array
+            var data = new sbyte[len];
+            data[0] = 1;
+            data[1] = 4;
+            data[2] = 6;
+            data[3] = 9;
+            data[4] = 10;
+            data[5] = 12;
+            data[6] = 14;
+            data[7] = 15;
+            data[8] = 18;
+
+            ByteBuffer_Put_Array_Helper(data, sizeof(sbyte));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_Put_Array_Null_Throws()
+        {
+            // Create the Byte Buffer
+            var uut = new ByteBuffer(1024);
+
+            // create a null array and try to put it into the buffer
+            float[] data = null;
+            Assert.Throws<ArgumentNullException>(() => uut.Put(1024, data));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_Put_Array_Empty_Throws()
+        {
+            // Create the Byte Buffer
+            var uut = new ByteBuffer(1024);
+
+            // create an array of length == 0, and try to put it into the buffer
+            float[] data = new float[0];
+            Assert.Throws<ArgumentException>(() => uut.Put(1024, data));
+        }
+
+        private struct dummyStruct
+        {
+            int a;
+            float b;
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_Put_Array_IncorrectType_Throws()
+        {
+            // Create the Byte Buffer
+            var uut = new ByteBuffer(1024);
+
+            // Create an array of dummy structures that shouldn't be
+            // able to be put into the buffer
+            var data = new dummyStruct[10];
+            Assert.Throws<ArgumentException>(() => uut.Put(1024, data));
+        }
+    }
+}
diff --git a/tests/FlatBuffers.Test/FlatBufferBuilderTests.cs b/tests/FlatBuffers.Test/FlatBufferBuilderTests.cs
new file mode 100644
index 0000000..d2f49f7
--- /dev/null
+++ b/tests/FlatBuffers.Test/FlatBufferBuilderTests.cs
@@ -0,0 +1,354 @@
+/*
+ * Copyright 2016 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.
+ */
+
+using System;
+
+namespace FlatBuffers.Test
+{
+    [FlatBuffersTestClass]
+    public class FlatBufferBuilderTests
+    {
+        private FlatBufferBuilder CreateBuffer(bool forceDefaults = true)
+        {
+            var fbb = new FlatBufferBuilder(16) {ForceDefaults = forceDefaults};
+            fbb.StartTable(1);
+            return fbb;
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WithForceDefaults_WhenAddBool_AndDefaultValue_OffsetIncreasesBySize()
+        {
+            var fbb = CreateBuffer();
+            var storedOffset = fbb.Offset;
+            fbb.AddBool(0, false, false);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(sizeof(bool), endOffset-storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WithForceDefaults_WhenAddSByte_AndDefaultValue_OffsetIncreasesBySize()
+        {
+            var fbb = CreateBuffer();
+            var storedOffset = fbb.Offset;
+            fbb.AddSbyte(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(sizeof(sbyte), endOffset - storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WithForceDefaults_WhenAddByte_AndDefaultValue_OffsetIncreasesBySize()
+        {
+            var fbb = CreateBuffer();
+            var storedOffset = fbb.Offset;
+            fbb.AddByte(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(sizeof(byte), endOffset - storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WithForceDefaults_WhenAddShort_AndDefaultValue_OffsetIncreasesBySize()
+        {
+            var fbb = CreateBuffer();
+            var storedOffset = fbb.Offset;
+            fbb.AddShort(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(sizeof(short), endOffset - storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WithForceDefaults_WhenAddUShort_AndDefaultValue_OffsetIncreasesBySize()
+        {
+            var fbb = CreateBuffer();
+            var storedOffset = fbb.Offset;
+            fbb.AddUshort(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(sizeof(ushort), endOffset - storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WithForceDefaults_WhenAddInt_AndDefaultValue_OffsetIncreasesBySize()
+        {
+            var fbb = CreateBuffer();
+            var storedOffset = fbb.Offset;
+            fbb.AddInt(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(sizeof(int), endOffset - storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WithForceDefaults_WhenAddUInt_AndDefaultValue_OffsetIncreasesBySize()
+        {
+            var fbb = CreateBuffer();
+            var storedOffset = fbb.Offset;
+            fbb.AddUint(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(sizeof(uint), endOffset - storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WithForceDefaults_WhenAddLong_AndDefaultValue_OffsetIncreasesBySize()
+        {
+            var fbb = CreateBuffer();
+            var storedOffset = fbb.Offset;
+            fbb.AddLong(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(sizeof(long), endOffset - storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WithForceDefaults_WhenAddULong_AndDefaultValue_OffsetIncreasesBySize()
+        {
+            var fbb = CreateBuffer();
+            var storedOffset = fbb.Offset;
+            fbb.AddUlong(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(sizeof(ulong), endOffset - storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WithForceDefaults_WhenAddFloat_AndDefaultValue_OffsetIncreasesBySize()
+        {
+            var fbb = CreateBuffer();
+            var storedOffset = fbb.Offset;
+            fbb.AddFloat(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(sizeof(float), endOffset - storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WithForceDefaults_WhenAddDouble_AndDefaultValue_OffsetIncreasesBySize()
+        {
+            var fbb = CreateBuffer();
+            var storedOffset = fbb.Offset;
+            fbb.AddDouble(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(sizeof(double), endOffset - storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WhenAddBool_AndDefaultValue_OffsetIsUnchanged()
+        {
+            var fbb = CreateBuffer(false);
+            var storedOffset = fbb.Offset;
+            fbb.AddBool(0, false, false);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(endOffset, storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WhenAddSByte_AndDefaultValue_OffsetIsUnchanged()
+        {
+            var fbb = CreateBuffer(false);
+            var storedOffset = fbb.Offset;
+            fbb.AddSbyte(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(endOffset, storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WhenAddByte_AndDefaultValue_OffsetIsUnchanged()
+        {
+            var fbb = CreateBuffer(false);
+            var storedOffset = fbb.Offset;
+            fbb.AddByte(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(endOffset, storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WhenAddShort_AndDefaultValue_OffsetIsUnchanged()
+        {
+            var fbb = CreateBuffer(false);
+            var storedOffset = fbb.Offset;
+            fbb.AddShort(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(endOffset, storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WhenAddUShort_AndDefaultValue_OffsetIsUnchanged()
+        {
+            var fbb = CreateBuffer(false);
+            var storedOffset = fbb.Offset;
+            fbb.AddUshort(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(endOffset, storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WhenAddInt_AndDefaultValue_OffsetIsUnchanged()
+        {
+            var fbb = CreateBuffer(false);
+            var storedOffset = fbb.Offset;
+            fbb.AddInt(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(endOffset, storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WhenAddUInt_AndDefaultValue_OffsetIsUnchanged()
+        {
+            var fbb = CreateBuffer(false);
+            var storedOffset = fbb.Offset;
+            fbb.AddUint(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(endOffset, storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WhenAddLong_AndDefaultValue_OffsetIsUnchanged()
+        {
+            var fbb = CreateBuffer(false);
+            var storedOffset = fbb.Offset;
+            fbb.AddLong(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(endOffset, storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WhenAddULong_AndDefaultValue_OffsetIsUnchanged()
+        {
+            var fbb = CreateBuffer(false);
+            var storedOffset = fbb.Offset;
+            fbb.AddUlong(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(endOffset, storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WhenAddFloat_AndDefaultValue_OffsetIsUnchanged()
+        {
+            var fbb = CreateBuffer(false);
+            var storedOffset = fbb.Offset;
+            fbb.AddFloat(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(endOffset, storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WhenAddDouble_AndDefaultValue_OffsetIsUnchanged()
+        {
+            var fbb = CreateBuffer(false);
+            var storedOffset = fbb.Offset;
+            fbb.AddDouble(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(endOffset, storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_Add_Array_Float()
+        {
+            var fbb = CreateBuffer(false);
+            var storedOffset = fbb.Offset;
+
+            const int len = 9;
+
+            // Construct the data array
+            var data = new float[len];
+            data[0] = 1.0079F;
+            data[1] = 4.0026F;
+            data[2] = 6.941F;
+            data[3] = 9.0122F;
+            data[4] = 10.811F;
+            data[5] = 12.0107F;
+            data[6] = 14.0067F;
+            data[7] = 15.9994F;
+            data[8] = 18.9984F;
+
+            fbb.Add(data);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(endOffset, storedOffset + sizeof(float) * data.Length);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_Add_Array_Bool()
+        {
+            var fbb = CreateBuffer(false);
+            var storedOffset = fbb.Offset;
+
+            const int len = 9;
+
+            // Construct the data array
+            var data = new bool[len];
+            data[0] = true;
+            data[1] = true;
+            data[2] = false;
+            data[3] = true;
+            data[4] = false;
+            data[5] = true;
+            data[6] = true;
+            data[7] = true;
+            data[8] = false;
+
+            fbb.Add(data);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(endOffset, storedOffset + sizeof(bool) * data.Length);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_Add_Array_Double()
+        {
+            var fbb = CreateBuffer(false);
+            var storedOffset = fbb.Offset;
+
+            const int len = 9;
+
+            // Construct the data array
+            var data = new double[len];
+            data[0] = 1.0079;
+            data[1] = 4.0026;
+            data[2] = 6.941;
+            data[3] = 9.0122;
+            data[4] = 10.811;
+            data[5] = 12.0107;
+            data[6] = 14.0067;
+            data[7] = 15.9994;
+            data[8] = 18.9984;
+
+            fbb.Add(data);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(endOffset, storedOffset + sizeof(double) * data.Length);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_Add_Array_Null_Throws()
+        {
+            var fbb = CreateBuffer(false);
+
+            // Construct the data array
+            float[] data = null;
+
+            Assert.Throws<ArgumentNullException>(() => fbb.Add(data));
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_Add_Array_Empty_Noop()
+        {
+            var fbb = CreateBuffer(false);
+
+            var storedOffset = fbb.Offset;
+
+            // Construct an empty data array
+            float[] data = new float[0];
+            fbb.Add(data);
+
+            // Make sure the offset didn't change since nothing
+            // was really added
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(endOffset, storedOffset);
+        }
+    }
+}
diff --git a/tests/FlatBuffers.Test/FlatBuffers.Test.csproj b/tests/FlatBuffers.Test/FlatBuffers.Test.csproj
new file mode 100644
index 0000000..d698d20
--- /dev/null
+++ b/tests/FlatBuffers.Test/FlatBuffers.Test.csproj
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{9DB0B5E7-757E-4BD1-A5F6-279390331254}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>FlatBuffers.Test</RootNamespace>
+    <AssemblyName>FlatBuffers.Test</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup>
+    <StartupObject />
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(UnsafeByteBuffer)' == 'true'">
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <DefineConstants>$(DefineConstants);UNSAFE_BYTEBUFFER</DefineConstants>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="..\..\net\FlatBuffers\ByteBuffer.cs">
+      <Link>FlatBuffers\ByteBuffer.cs</Link>
+    </Compile>
+    <Compile Include="..\..\net\FlatBuffers\ByteBufferUtil.cs">
+      <Link>FlatBuffers\ByteBufferUtil.cs</Link>
+    </Compile>
+    <Compile Include="..\..\net\FlatBuffers\IFlatbufferObject.cs">
+      <Link>FlatBuffers\IFlatbufferObject.cs</Link>
+    </Compile>
+    <Compile Include="..\..\net\FlatBuffers\Offset.cs">
+      <Link>FlatBuffers\Offset.cs</Link>
+    </Compile>
+    <Compile Include="..\..\net\FlatBuffers\FlatBufferBuilder.cs">
+      <Link>FlatBuffers\FlatBufferBuilder.cs</Link>
+    </Compile>
+    <Compile Include="..\..\net\FlatBuffers\FlatBufferConstants.cs">
+      <Link>FlatBuffers\FlatBufferConstants.cs</Link>
+    </Compile>
+    <Compile Include="..\..\net\FlatBuffers\Struct.cs">
+      <Link>FlatBuffers\Struct.cs</Link>
+    </Compile>
+    <Compile Include="..\..\net\FlatBuffers\Table.cs">
+      <Link>FlatBuffers\Table.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\Example\Any.cs">
+      <Link>MyGame\Example\Any.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\Example\AnyAmbiguousAliases.cs">
+      <Link>MyGame\Example\AnyAmbiguousAliases.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\Example\AnyUniqueAliases.cs">
+      <Link>MyGame\Example\AnyUniqueAliases.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\Example\Color.cs">
+      <Link>MyGame\Example\Color.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\Example\Monster.cs">
+      <Link>MyGame\Example\Monster.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\Example\Referrable.cs">
+      <Link>MyGame\Example\Referrable.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\Example\Stat.cs">
+      <Link>MyGame\Example\Stat.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\Example\Test.cs">
+      <Link>MyGame\Example\Test.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\Example\TestSimpleTableWithEnum.cs">
+      <Link>MyGame\Example\TestSimpleTableWithEnum.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\Example\Vec3.cs">
+      <Link>MyGame\Example\Vec3.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\Example\Ability.cs">
+      <Link>MyGame\Example\Ability.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\Example\ArrayTable.cs">
+      <Link>MyGame\Example\ArrayTable.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\Example\ArrayStruct.cs">
+      <Link>MyGame\Example\ArrayStruct.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\Example\NestedStruct.cs">
+      <Link>MyGame\Example\NestedStruct.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\Example\TestEnum.cs">
+      <Link>MyGame\Example\TestEnum.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\InParentNamespace.cs">
+      <Link>MyGame\InParentNamespace.cs</Link>
+    </Compile>
+    <Compile Include="..\namespace_test\NamespaceA\NamespaceB\EnumInNestedNS.cs">
+      <Link>NamespaceA\NamespaceB\EnumInNestedNS.cs</Link>
+    </Compile>
+    <Compile Include="..\namespace_test\NamespaceA\NamespaceB\StructInNestedNS.cs">
+      <Link>NamespaceA\NamespaceB\StructInNestedNS.cs</Link>
+    </Compile>
+    <Compile Include="..\namespace_test\NamespaceA\NamespaceB\TableInNestedNS.cs">
+      <Link>NamespaceA\NamespaceB\TableInNestedNS.cs</Link>
+    </Compile>
+    <Compile Include="..\namespace_test\NamespaceA\TableInFirstNS.cs">
+      <Link>NamespaceA\TableInFirstNS.cs</Link>
+    </Compile>
+    <Compile Include="Assert.cs" />
+    <Compile Include="ByteBufferTests.cs" />
+    <Compile Include="FlatBufferBuilderTests.cs" />
+    <Compile Include="FlatBuffersFuzzTests.cs" />
+    <Compile Include="FlatBuffersTestClassAttribute.cs" />
+    <Compile Include="FlatBuffersTestMethodAttribute.cs" />
+    <Compile Include="FuzzTestData.cs" />
+    <Compile Include="Lcg.cs" />
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="FlatBuffersExampleTests.cs" />
+    <Compile Include="TestTable.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="..\monsterdata_test.mon">
+      <Link>Resources\monsterdata_test.mon</Link>
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
diff --git a/tests/FlatBuffers.Test/FlatBuffersExampleTests.cs b/tests/FlatBuffers.Test/FlatBuffersExampleTests.cs
new file mode 100644
index 0000000..b09119c
--- /dev/null
+++ b/tests/FlatBuffers.Test/FlatBuffersExampleTests.cs
@@ -0,0 +1,387 @@
+/*
+ * 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.
+ */
+
+using System.IO;
+using System.Text;
+using MyGame.Example;
+
+namespace FlatBuffers.Test
+{
+    [FlatBuffersTestClass]
+    public class FlatBuffersExampleTests
+    {
+        public void RunTests()
+        {
+            CanCreateNewFlatBufferFromScratch();
+            CanReadCppGeneratedWireFile();
+            TestEnums();
+        }
+
+        [FlatBuffersTestMethod]
+        public void CanCreateNewFlatBufferFromScratch()
+        {
+            CanCreateNewFlatBufferFromScratch(true);
+            CanCreateNewFlatBufferFromScratch(false);
+        }
+
+        private void CanCreateNewFlatBufferFromScratch(bool sizePrefix)
+        {
+            // Second, let's create a FlatBuffer from scratch in C#, and test it also.
+            // We use an initial size of 1 to exercise the reallocation algorithm,
+            // normally a size larger than the typical FlatBuffer you generate would be
+            // better for performance.
+            var fbb = new FlatBufferBuilder(1);
+
+            StringOffset[] names = { fbb.CreateString("Frodo"), fbb.CreateString("Barney"), fbb.CreateString("Wilma") };
+            Offset<Monster>[] off = new Offset<Monster>[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);
+            var sortMons = Monster.CreateSortedVectorOfMonster(fbb, off);
+
+            // We set up the same values as monsterdata.json:
+
+            var str = fbb.CreateString("MyMonster");
+            var test1 = fbb.CreateString("test1");
+            var test2 = fbb.CreateString("test2");
+
+
+            Monster.StartInventoryVector(fbb, 5);
+            for (int i = 4; i >= 0; i--)
+            {
+                fbb.AddByte((byte)i);
+            }
+            var inv = fbb.EndVector();
+
+            var fred = fbb.CreateString("Fred");
+            Monster.StartMonster(fbb);
+            Monster.AddName(fbb, fred);
+            var mon2 = Monster.EndMonster(fbb);
+
+            Monster.StartTest4Vector(fbb, 2);
+            MyGame.Example.Test.CreateTest(fbb, (short)10, (sbyte)20);
+            MyGame.Example.Test.CreateTest(fbb, (short)30, (sbyte)40);
+            var test4 = fbb.EndVector();
+
+            Monster.StartTestarrayofstringVector(fbb, 2);
+            fbb.AddOffset(test2.Value);
+            fbb.AddOffset(test1.Value);
+            var testArrayOfString = fbb.EndVector();
+
+            Monster.StartMonster(fbb);
+            Monster.AddPos(fbb, Vec3.CreateVec3(fbb, 1.0f, 2.0f, 3.0f, 3.0,
+                                                     Color.Green, (short)5, (sbyte)6));
+            Monster.AddHp(fbb, (short)80);
+            Monster.AddName(fbb, str);
+            Monster.AddInventory(fbb, inv);
+            Monster.AddTestType(fbb, Any.Monster);
+            Monster.AddTest(fbb, mon2.Value);
+            Monster.AddTest4(fbb, test4);
+            Monster.AddTestarrayofstring(fbb, testArrayOfString);
+            Monster.AddTestbool(fbb, true);
+            Monster.AddTestarrayoftables(fbb, sortMons);
+            var mon = Monster.EndMonster(fbb);
+
+            if (sizePrefix)
+            {
+                Monster.FinishSizePrefixedMonsterBuffer(fbb, mon);
+            }
+            else
+            {
+                Monster.FinishMonsterBuffer(fbb, mon);
+            }
+
+            // Dump to output directory so we can inspect later, if needed
+#if ENABLE_SPAN_T
+            var data = fbb.DataBuffer.ToSizedArray();
+            string filename = @"Resources/monsterdata_cstest" + (sizePrefix ? "_sp" : "") + ".mon";
+            File.WriteAllBytes(filename, data);
+#else
+            using (var ms = fbb.DataBuffer.ToMemoryStream(fbb.DataBuffer.Position, fbb.Offset))
+            {
+                var data = ms.ToArray();
+                string filename = @"Resources/monsterdata_cstest" + (sizePrefix ? "_sp" : "") + ".mon";
+                File.WriteAllBytes(filename, data);
+            }
+#endif
+
+            // Remove the size prefix if necessary for further testing
+            ByteBuffer dataBuffer = fbb.DataBuffer;
+            if (sizePrefix)
+            {
+                Assert.AreEqual(ByteBufferUtil.GetSizePrefix(dataBuffer) + FlatBufferConstants.SizePrefixLength,
+                                dataBuffer.Length - dataBuffer.Position);
+                dataBuffer = ByteBufferUtil.RemoveSizePrefix(dataBuffer);
+            }
+
+            // Now assert the buffer
+            TestBuffer(dataBuffer);
+
+            //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
+            Assert.AreEqual(monster.MutateMana((short)10), false);
+            Assert.AreEqual(monster.Mana, (short)150);
+
+            // Accessing a vector of sorted by the key tables
+            Assert.AreEqual(monster.Testarrayoftables(0).Value.Name, "Barney");
+            Assert.AreEqual(monster.Testarrayoftables(1).Value.Name, "Frodo");
+            Assert.AreEqual(monster.Testarrayoftables(2).Value.Name, "Wilma");
+
+            // Example of searching for a table by the key
+            Assert.IsTrue(monster.TestarrayoftablesByKey("Frodo") != null);
+            Assert.IsTrue(monster.TestarrayoftablesByKey("Barney") != null);
+            Assert.IsTrue(monster.TestarrayoftablesByKey("Wilma") != null);
+
+            // testType is an existing field and mutating it should succeed
+            Assert.AreEqual(monster.TestType, Any.Monster);
+            Assert.AreEqual(monster.MutateTestType(Any.NONE), true);
+            Assert.AreEqual(monster.TestType, Any.NONE);
+            Assert.AreEqual(monster.MutateTestType(Any.Monster), true);
+            Assert.AreEqual(monster.TestType, Any.Monster);
+
+            //mutate the inventory vector
+            Assert.AreEqual(monster.MutateInventory(0, 1), true);
+            Assert.AreEqual(monster.MutateInventory(1, 2), true);
+            Assert.AreEqual(monster.MutateInventory(2, 3), true);
+            Assert.AreEqual(monster.MutateInventory(3, 4), true);
+            Assert.AreEqual(monster.MutateInventory(4, 5), true);
+
+            for (int i = 0; i < monster.InventoryLength; i++)
+            {
+                Assert.AreEqual(monster.Inventory(i), i + 1);
+            }
+
+            //reverse mutation
+            Assert.AreEqual(monster.MutateInventory(0, 0), true);
+            Assert.AreEqual(monster.MutateInventory(1, 1), true);
+            Assert.AreEqual(monster.MutateInventory(2, 2), true);
+            Assert.AreEqual(monster.MutateInventory(3, 3), true);
+            Assert.AreEqual(monster.MutateInventory(4, 4), true);
+
+            // get a struct field and edit one of its fields
+            Vec3 pos = (Vec3)monster.Pos;
+            Assert.AreEqual(pos.X, 1.0f);
+            pos.MutateX(55.0f);
+            Assert.AreEqual(pos.X, 55.0f);
+            pos.MutateX(1.0f);
+            Assert.AreEqual(pos.X, 1.0f);
+
+            TestBuffer(dataBuffer);
+        }
+
+        private void TestBuffer(ByteBuffer bb)
+        {
+            Monster monster = Monster.GetRootAsMonster(bb);
+
+            Assert.AreEqual(80, monster.Hp);
+            Assert.AreEqual(150, monster.Mana);
+            Assert.AreEqual("MyMonster", monster.Name);
+
+            var pos = monster.Pos.Value;
+            Assert.AreEqual(1.0f, pos.X);
+            Assert.AreEqual(2.0f, pos.Y);
+            Assert.AreEqual(3.0f, pos.Z);
+
+            Assert.AreEqual(3.0f, pos.Test1);
+            Assert.AreEqual(Color.Green, pos.Test2);
+            var t = (MyGame.Example.Test)pos.Test3;
+            Assert.AreEqual((short)5, t.A);
+            Assert.AreEqual((sbyte)6, t.B);
+
+            Assert.AreEqual(Any.Monster, monster.TestType);
+
+            var monster2 = monster.Test<Monster>().Value;
+            Assert.AreEqual("Fred", monster2.Name);
+
+
+            Assert.AreEqual(5, monster.InventoryLength);
+            var invsum = 0;
+            for (var i = 0; i < monster.InventoryLength; i++)
+            {
+                invsum += monster.Inventory(i);
+            }
+            Assert.AreEqual(10, invsum);
+
+            // Get the inventory as an array and subtract the
+            // sum to get it back to 0
+            var inventoryArray = monster.GetInventoryArray();
+            Assert.AreEqual(5, inventoryArray.Length);
+            foreach(var inv in inventoryArray)
+            {
+                invsum -= inv;
+            }
+            Assert.AreEqual(0, invsum);
+
+            var test0 = monster.Test4(0).Value;
+            var test1 = monster.Test4(1).Value;
+            Assert.AreEqual(2, monster.Test4Length);
+
+            Assert.AreEqual(100, test0.A + test0.B + test1.A + test1.B);
+
+            Assert.AreEqual(2, monster.TestarrayofstringLength);
+            Assert.AreEqual("test1", monster.Testarrayofstring(0));
+            Assert.AreEqual("test2", monster.Testarrayofstring(1));
+
+            Assert.AreEqual(true, monster.Testbool);
+
+#if ENABLE_SPAN_T
+            var nameBytes = monster.GetNameBytes();
+            Assert.AreEqual("MyMonster", Encoding.UTF8.GetString(nameBytes.ToArray(), 0, nameBytes.Length));
+
+            if (0 == monster.TestarrayofboolsLength)
+            {
+                Assert.IsFalse(monster.GetTestarrayofboolsBytes().Length != 0);
+            }
+            else
+            {
+                Assert.IsTrue(monster.GetTestarrayofboolsBytes().Length != 0);
+            }
+#else
+            var nameBytes = monster.GetNameBytes().Value;
+            Assert.AreEqual("MyMonster", Encoding.UTF8.GetString(nameBytes.Array, nameBytes.Offset, nameBytes.Count));
+
+            if (0 == monster.TestarrayofboolsLength)
+            {
+                Assert.IsFalse(monster.GetTestarrayofboolsBytes().HasValue);
+            }
+            else
+            {
+                Assert.IsTrue(monster.GetTestarrayofboolsBytes().HasValue);
+            }
+#endif
+        }
+
+        [FlatBuffersTestMethod]
+        public void CanReadCppGeneratedWireFile()
+        {
+            var data = File.ReadAllBytes(@"Resources/monsterdata_test.mon");
+            var bb = new ByteBuffer(data);
+            TestBuffer(bb);
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestEnums()
+        {
+            Assert.AreEqual("Red", Color.Red.ToString());
+            Assert.AreEqual("Blue", Color.Blue.ToString());
+            Assert.AreEqual("NONE", Any.NONE.ToString());
+            Assert.AreEqual("Monster", Any.Monster.ToString());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestNestedFlatBuffer()
+        {
+            const string nestedMonsterName = "NestedMonsterName";
+            const short nestedMonsterHp = 600;
+            const short nestedMonsterMana = 1024;
+            // Create nested buffer as a Monster type
+            var fbb1 = new FlatBufferBuilder(16);
+            var str1 = fbb1.CreateString(nestedMonsterName);
+            Monster.StartMonster(fbb1);
+            Monster.AddName(fbb1, str1);
+            Monster.AddHp(fbb1, nestedMonsterHp);
+            Monster.AddMana(fbb1, nestedMonsterMana);
+            var monster1 = Monster.EndMonster(fbb1);
+            Monster.FinishMonsterBuffer(fbb1, monster1);
+            var fbb1Bytes = fbb1.SizedByteArray();
+            fbb1 = null;
+
+            // Create a Monster which has the first buffer as a nested buffer
+            var fbb2 = new FlatBufferBuilder(16);
+            var str2 = fbb2.CreateString("My Monster");
+            var nestedBuffer = Monster.CreateTestnestedflatbufferVector(fbb2, fbb1Bytes);
+            Monster.StartMonster(fbb2);
+            Monster.AddName(fbb2, str2);
+            Monster.AddHp(fbb2, 50);
+            Monster.AddMana(fbb2, 32);
+            Monster.AddTestnestedflatbuffer(fbb2, nestedBuffer);
+            var monster = Monster.EndMonster(fbb2);
+            Monster.FinishMonsterBuffer(fbb2, monster);
+
+            // Now test the data extracted from the nested buffer
+            var mons = Monster.GetRootAsMonster(fbb2.DataBuffer);
+            var nestedMonster = mons.GetTestnestedflatbufferAsMonster().Value;
+
+            Assert.AreEqual(nestedMonsterMana, nestedMonster.Mana);
+            Assert.AreEqual(nestedMonsterHp, nestedMonster.Hp);
+            Assert.AreEqual(nestedMonsterName, nestedMonster.Name);
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestFixedLenghtArrays()
+        {
+            FlatBufferBuilder builder = new FlatBufferBuilder(100);
+
+            float   a;
+            int[]   b = new int[15];
+            sbyte   c;
+            int[,]  d_a = new int[2, 2];
+            TestEnum[]  d_b = new TestEnum[2];
+            TestEnum[,] d_c = new TestEnum[2, 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;
+
+            Offset<ArrayStruct> arrayOffset = ArrayStruct.CreateArrayStruct(
+                builder, a, b, c, d_a, d_b, d_c);
+
+            // Create a table with the ArrayStruct.
+            ArrayTable.StartArrayTable(builder);
+            ArrayTable.AddA(builder, arrayOffset);
+            Offset<ArrayTable> tableOffset = ArrayTable.EndArrayTable(builder);
+
+            ArrayTable.FinishArrayTableBuffer(builder, tableOffset);
+
+            ArrayTable table = ArrayTable.GetRootAsArrayTable(builder.DataBuffer);
+
+            Assert.AreEqual(table.A?.A, 0.5f);
+            for (int i = 0; i < 15; i++) Assert.AreEqual(table.A?.B(i), i);
+            Assert.AreEqual(table.A?.C, (sbyte)1);
+            Assert.AreEqual(table.A?.D(0).A(0), 1);
+            Assert.AreEqual(table.A?.D(0).A(1), 2);
+            Assert.AreEqual(table.A?.D(1).A(0), 3);
+            Assert.AreEqual(table.A?.D(1).A(1), 4);
+            Assert.AreEqual(table.A?.D(0).B, TestEnum.B);
+            Assert.AreEqual(table.A?.D(1).B, TestEnum.C);
+            Assert.AreEqual(table.A?.D(0).C(0), TestEnum.A);
+            Assert.AreEqual(table.A?.D(0).C(1), TestEnum.B);
+            Assert.AreEqual(table.A?.D(1).C(0), TestEnum.C);
+            Assert.AreEqual(table.A?.D(1).C(1), TestEnum.B);
+        }
+    }
+}
diff --git a/tests/FlatBuffers.Test/FlatBuffersFuzzTests.cs b/tests/FlatBuffers.Test/FlatBuffersFuzzTests.cs
new file mode 100644
index 0000000..b6c60ea
--- /dev/null
+++ b/tests/FlatBuffers.Test/FlatBuffersFuzzTests.cs
@@ -0,0 +1,811 @@
+/*
+ * Copyright 2015 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.
+ */
+
+using System;
+
+namespace FlatBuffers.Test
+{
+    [FlatBuffersTestClass]
+    public class FlatBuffersFuzzTests
+    {
+        private readonly Lcg _lcg = new Lcg();
+
+        [FlatBuffersTestMethod]
+        public void TestObjects()
+        {
+            CheckObjects(11, 100);
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestNumbers()
+        {
+            var builder = new FlatBufferBuilder(1);
+            Assert.ArrayEqual(new byte[] { 0 }, builder.DataBuffer.ToFullArray());
+            builder.AddBool(true);
+            Assert.ArrayEqual(new byte[] { 1 }, builder.DataBuffer.ToFullArray());
+            builder.AddSbyte(-127);
+            Assert.ArrayEqual(new byte[] { 129, 1 }, builder.DataBuffer.ToFullArray());
+            builder.AddByte(255);
+            Assert.ArrayEqual(new byte[] { 0, 255, 129, 1 }, builder.DataBuffer.ToFullArray()); // First pad
+            builder.AddShort(-32222);
+            Assert.ArrayEqual(new byte[] { 0, 0, 0x22, 0x82, 0, 255, 129, 1 }, builder.DataBuffer.ToFullArray()); // Second pad
+            builder.AddUshort(0xFEEE);
+            Assert.ArrayEqual(new byte[] { 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1 }, builder.DataBuffer.ToFullArray()); // no pad
+            builder.AddInt(-53687092);
+            Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1 }, builder.DataBuffer.ToFullArray()); // third pad
+            builder.AddUint(0x98765432);
+            Assert.ArrayEqual(new byte[] { 0x32, 0x54, 0x76, 0x98, 204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1 }, builder.DataBuffer.ToFullArray()); // no pad
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestNumbers64()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.AddUlong(0x1122334455667788);
+            Assert.ArrayEqual(new byte[] { 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 }, builder.DataBuffer.ToFullArray());
+
+            builder = new FlatBufferBuilder(1);
+            builder.AddLong(0x1122334455667788);
+            Assert.ArrayEqual(new byte[] { 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 }, builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestVector_1xUInt8()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartVector(sizeof(byte), 1, 1);
+            Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }, builder.DataBuffer.ToFullArray());
+            builder.AddByte(1);
+            Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 1, 0, 0, 0 }, builder.DataBuffer.ToFullArray());
+            builder.EndVector();
+            Assert.ArrayEqual(new byte[] { 1, 0, 0, 0, 1, 0, 0, 0 }, builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestVector_2xUint8()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartVector(sizeof(byte), 2, 1);
+            Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }, builder.DataBuffer.ToFullArray());
+            builder.AddByte(1);
+            Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 0, 1, 0, 0 }, builder.DataBuffer.ToFullArray());
+            builder.AddByte(2);
+            Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 2, 1, 0, 0 }, builder.DataBuffer.ToFullArray());
+            builder.EndVector();
+            Assert.ArrayEqual(new byte[] { 2, 0, 0, 0, 2, 1, 0, 0 }, builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestVector_1xUInt16()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartVector(sizeof(ushort), 1, 1);
+            Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }, builder.DataBuffer.ToFullArray());
+            builder.AddUshort(1);
+            Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 1, 0, 0, 0 }, builder.DataBuffer.ToFullArray());
+            builder.EndVector();
+            Assert.ArrayEqual(new byte[] { 1, 0, 0, 0, 1, 0, 0, 0 }, builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestVector_2xUInt16()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartVector(sizeof(ushort), 2, 1);
+            Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }, builder.DataBuffer.ToFullArray());
+            builder.AddUshort(0xABCD);
+            Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 0, 0, 0xCD, 0xAB }, builder.DataBuffer.ToFullArray());
+            builder.AddUshort(0xDCBA);
+            Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 0xBA, 0xDC, 0xCD, 0xAB }, builder.DataBuffer.ToFullArray());
+            builder.EndVector();
+            Assert.ArrayEqual(new byte[] { 2, 0, 0, 0, 0xBA, 0xDC, 0xCD, 0xAB }, builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestCreateAsciiString()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.CreateString("foo");
+            Assert.ArrayEqual(new byte[] { 3, 0, 0, 0, (byte)'f', (byte)'o', (byte)'o', 0 }, builder.DataBuffer.ToFullArray());
+
+            builder.CreateString("moop");
+            Assert.ArrayEqual(new byte[]
+            {
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0,  // Padding to 32 bytes
+                4, 0, 0, 0,
+                (byte)'m', (byte)'o', (byte)'o', (byte)'p',
+                0, 0, 0, 0, // zero terminator with 3 byte pad
+                3, 0, 0, 0,
+                (byte)'f', (byte)'o', (byte)'o', 0
+            }, builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestCreateSharedAsciiString()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.CreateSharedString("foo");
+            Assert.ArrayEqual(new byte[] { 3, 0, 0, 0, (byte)'f', (byte)'o', (byte)'o', 0 }, builder.DataBuffer.ToFullArray());
+
+            builder.CreateSharedString("foo");
+            Assert.ArrayEqual(new byte[] { 3, 0, 0, 0, (byte)'f', (byte)'o', (byte)'o', 0 }, builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestCreateArbitarytring()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.CreateString("\x01\x02\x03");
+            Assert.ArrayEqual(new byte[]
+            {
+                3, 0, 0, 0,
+                0x01, 0x02, 0x03, 0
+            }, builder.DataBuffer.ToFullArray()); // No padding
+            builder.CreateString("\x04\x05\x06\x07");
+            Assert.ArrayEqual(new byte[]
+            {
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0,  // Padding to 32 bytes
+                4, 0, 0, 0,
+                0x04, 0x05, 0x06, 0x07,
+                0, 0, 0, 0, // zero terminator with 3 byte pad
+                3, 0, 0, 0,
+                0x01, 0x02, 0x03, 0
+            }, builder.DataBuffer.ToFullArray()); // No padding
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestEmptyVTable()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartTable(0);
+            Assert.ArrayEqual(new byte[] { 0 }, builder.DataBuffer.ToFullArray());
+            builder.EndTable();
+            Assert.ArrayEqual(new byte[]
+            {
+                4, 0, 4, 0,
+                4, 0, 0, 0
+            },
+                builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestVTableWithOneBool()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartTable(1);
+            Assert.ArrayEqual(new byte[] { 0 }, builder.DataBuffer.ToFullArray());
+            builder.AddBool(0, true, false);
+            builder.EndTable();
+            Assert.ArrayEqual(new byte[]
+            {
+                0, 0, // padding to 16 bytes
+                6, 0, // vtable bytes
+                8, 0, // object length inc vtable offset
+                7, 0, // start of bool value
+                6, 0, 0, 0, // int32 offset for start of vtable
+                0, 0, 0, // padding
+                1, // value 0
+            },
+                builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestVTableWithOneBool_DefaultValue()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartTable(1);
+            Assert.ArrayEqual(new byte[] { 0 }, builder.DataBuffer.ToFullArray());
+            builder.AddBool(0, false, false);
+            builder.EndTable();
+            Assert.ArrayEqual(new byte[]
+            {
+                // No padding.
+                4, 0, // vtable bytes
+                4, 0, // end of object from here
+                // entry 0 is not stored (trimmed end of vtable)
+                4, 0, 0, 0, // int32 offset for start of vtable
+            },
+                builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestVTableWithOneInt16()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartTable(1);
+            Assert.ArrayEqual(new byte[] { 0 }, builder.DataBuffer.ToFullArray());
+            builder.AddShort(0, 0x789A, 0);
+            builder.EndTable();
+            Assert.ArrayEqual(new byte[]
+            {
+                0, 0, // padding to 16 bytes
+                6, 0, // vtable bytes
+                8, 0, // object length inc vtable offset
+                6, 0, // start of int16 value
+                6, 0, 0, 0, // int32 offset for start of vtable
+                0, 0, // padding
+                0x9A, 0x78, //value 0
+            },
+                builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestVTableWithTwoInt16()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartTable(2);
+            Assert.ArrayEqual(new byte[] { 0 }, builder.DataBuffer.ToFullArray());
+            builder.AddShort(0, 0x3456, 0);
+            builder.AddShort(1, 0x789A, 0);
+            builder.EndTable();
+            Assert.ArrayEqual(new byte[]
+            {
+                8, 0, // vtable bytes
+                8, 0, // object length inc vtable offset
+                6, 0, // start of int16 value 0
+                4, 0, // start of int16 value 1
+                8, 0, 0, 0, // int32 offset for start of vtable
+                0x9A, 0x78, // value 1
+                0x56, 0x34, // value 0
+            },
+                builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestVTableWithInt16AndBool()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartTable(2);
+            Assert.ArrayEqual(new byte[] { 0 }, builder.DataBuffer.ToFullArray());
+            builder.AddShort(0, 0x3456, 0);
+            builder.AddBool(1, true, false);
+            builder.EndTable();
+            Assert.ArrayEqual(new byte[]
+            {
+                8, 0, // vtable bytes
+                8, 0, // object length inc vtable offset
+                6, 0, // start of int16 value 0
+                5, 0, // start of bool value 1
+                8, 0, 0, 0, // int32 offset for start of vtable
+                0, 1, // padding + value 1
+                0x56, 0x34, // value 0
+            },
+                builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestVTableWithEmptyVector()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartVector(sizeof(byte), 0, 1);
+            var vecEnd = builder.EndVector();
+
+            builder.StartTable(1);
+
+            builder.AddOffset(0, vecEnd.Value, 0);
+            builder.EndTable();
+            Assert.ArrayEqual(new byte[]
+            {
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0,       // Padding to 32 bytes
+                6, 0, // vtable bytes
+                8, 0, // object length inc vtable offset
+                4, 0, // start of vector offset value 0
+                6, 0, 0, 0, // int32 offset for start of vtable
+                4, 0, 0, 0,
+                0, 0, 0, 0,
+            },
+                builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestVTableWithEmptyVectorAndScalars()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartVector(sizeof(byte), 0, 1);
+            var vecEnd = builder.EndVector();
+
+            builder.StartTable(2);
+            builder.AddShort(0, 55, 0);
+            builder.AddOffset(1, vecEnd.Value, 0);
+            builder.EndTable();
+            Assert.ArrayEqual(new byte[]
+            {
+                0, 0, 0, 0,
+                0, 0, 0, 0, // Padding to 32 bytes
+                8, 0, // vtable bytes
+                12, 0, // object length inc vtable offset
+                10, 0,     // offset to int16 value 0
+                4, 0, // start of vector offset value 1
+                8, 0, 0, 0, // int32 offset for start of vtable
+                8, 0, 0, 0, // value 1
+                0, 0, 55, 0, // value 0
+                0, 0, 0, 0, // length of vector (not in sctruc)
+            },
+                builder.DataBuffer.ToFullArray());
+        }
+
+
+        [FlatBuffersTestMethod]
+        public void TestVTableWith_1xInt16_and_Vector_or_2xInt16()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartVector(sizeof(short), 2, 1);
+            builder.AddShort(0x1234);
+            builder.AddShort(0x5678);
+            var vecEnd = builder.EndVector();
+
+            builder.StartTable(2);
+            builder.AddOffset(1, vecEnd.Value, 0);
+            builder.AddShort(0, 55, 0);
+            builder.EndTable();
+            Assert.ArrayEqual(new byte[]
+            {
+                0, 0, 0, 0, // Padding to 32 bytes
+                8, 0, // vtable bytes
+                12, 0, // object length
+                6, 0,     // start of value 0 from end of vtable
+                8, 0,     // start of value 1 from end of buffer
+                8, 0, 0, 0, // int32 offset for start of vtable
+                0, 0, 55, 0,    // padding + value 0
+                4, 0, 0, 0, // position of vector from here
+                2, 0, 0, 0, // length of vector
+                0x78, 0x56,       // vector value 0
+                0x34, 0x12,       // vector value 1
+            },
+                builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestVTableWithAStruct_of_int8_int16_int32()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartTable(1);
+            builder.Prep(4+4+4, 0);
+            builder.AddSbyte(55);
+            builder.Pad(3);
+            builder.AddShort(0x1234);
+            builder.Pad(2);
+            builder.AddInt(0x12345678);
+            var structStart = builder.Offset;
+            builder.AddStruct(0, structStart, 0);
+            builder.EndTable();
+            Assert.ArrayEqual(new byte[]
+            {
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, // Padding to 32 bytes
+                6, 0, // vtable bytes
+                16, 0, // object length
+                4, 0,     // start of struct from here
+                6, 0, 0, 0, // int32 offset for start of vtable
+                0x78, 0x56, 0x34, 0x12,  // struct value 2
+                0x00, 0x00, 0x34, 0x12, // struct value 1
+                0x00, 0x00, 0x00, 55, // struct value 0
+            },
+                builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestVTableWithAVectorOf_2xStructOf_2xInt8()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartVector(sizeof(byte)*2, 2, 1);
+            builder.AddByte(33);
+            builder.AddByte(44);
+            builder.AddByte(55);
+            builder.AddByte(66);
+            var vecEnd = builder.EndVector();
+
+            builder.StartTable(1);
+            builder.AddOffset(0, vecEnd.Value, 0);
+            builder.EndTable();
+
+            Assert.ArrayEqual(new byte[]
+            {
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, // Padding to 32 bytes
+                6, 0, // vtable bytes
+                8, 0, // object length
+                4, 0,     // offset of vector offset
+                6, 0, 0, 0, // int32 offset for start of vtable
+                4, 0, 0, 0, // Vector start offset
+                2, 0, 0, 0, // Vector len
+                66, // vector 1, 1
+                55, // vector 1, 0
+                44, // vector 0, 1
+                33, // vector 0, 0
+            },
+                builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestVTableWithSomeElements()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartTable(2);
+            builder.AddByte(0, 33, 0);
+            builder.AddShort(1, 66, 0);
+            var off = builder.EndTable();
+            builder.Finish(off);
+
+            byte[] padded = new byte[]
+            {
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0, //Padding to 32 bytes
+                12, 0, 0, 0,     // root of table, pointing to vtable offset
+                8, 0, // vtable bytes
+                8, 0, // object length
+                7, 0, // start of value 0
+                4, 0, // start of value 1
+                8, 0, 0, 0, // int32 offset for start of vtable
+                66, 0, // value 1
+                0, 33, // value 0
+
+            };
+            Assert.ArrayEqual(padded, builder.DataBuffer.ToFullArray());
+
+            // no padding in sized array
+            byte[] unpadded = new byte[padded.Length - 12];
+            Buffer.BlockCopy(padded, 12, unpadded, 0, unpadded.Length);
+            Assert.ArrayEqual(unpadded, builder.DataBuffer.ToSizedArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestTwoFinishTable()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartTable(2);
+            builder.AddByte(0, 33, 0);
+            builder.AddByte(1, 44, 0);
+            var off0 = builder.EndTable();
+            builder.Finish(off0);
+
+            builder.StartTable(3);
+            builder.AddByte(0, 55, 0);
+            builder.AddByte(1, 66, 0);
+            builder.AddByte(2, 77, 0);
+            var off1 = builder.EndTable();
+            builder.Finish(off1);
+
+            Assert.ArrayEqual(new byte[]
+            {
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0,       // padding to 64 bytes
+                16, 0, 0, 0,     // root of table, pointing to vtable offset (obj1)
+                0, 0, // padding
+
+                10, 0, // vtable bytes
+                8, 0, // object length
+                7, 0, // start of value 0
+                6, 0, // start of value 1
+                5, 0, // start of value 2
+                10, 0, 0, 0, // int32 offset for start of vtable
+                0, // pad
+                77, // values 2, 1, 0
+                66,
+                55,
+
+                12, 0, 0, 0,     // root of table, pointing to vtable offset (obj0)
+                8, 0, // vtable bytes
+                8, 0, // object length
+                7, 0, // start of value 0
+                6, 0, // start of value 1
+                8, 0, 0, 0, // int32 offset for start of vtable
+                0, 0, // pad
+                44, // value 1, 0
+                33,
+            },
+                builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestBunchOfBools()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartTable(8);
+            for (var i = 0; i < 8; i++)
+            {
+                builder.AddBool(i, true, false);
+            }
+            var off = builder.EndTable();
+            builder.Finish(off);
+
+            byte[] padded = new byte[]
+            {
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0,       // padding to 64 bytes
+
+                24, 0, 0, 0,     // root of table, pointing to vtable offset (obj0)
+                20, 0, // vtable bytes
+                12, 0, // object length
+                11, 0, // start of value 0
+                10, 0, // start of value 1
+                9, 0, // start of value 2
+                8, 0, // start of value 3
+                7, 0, // start of value 4
+                6, 0, // start of value 5
+                5, 0, // start of value 6
+                4, 0, // start of value 7
+
+                20, 0, 0, 0, // int32 offset for start of vtable
+
+                1, 1, 1, 1,  // values
+                1, 1, 1, 1,
+
+            };
+            Assert.ArrayEqual(padded, builder.DataBuffer.ToFullArray());
+
+            // no padding in sized array
+            byte[] unpadded = new byte[padded.Length - 28];
+            Buffer.BlockCopy(padded, 28, unpadded, 0, unpadded.Length);
+            Assert.ArrayEqual(unpadded, builder.DataBuffer.ToSizedArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestBunchOfBoolsSizePrefixed()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartTable(8);
+            for (var i = 0; i < 8; i++)
+            {
+                builder.AddBool(i, true, false);
+            }
+            var off = builder.EndTable();
+            builder.FinishSizePrefixed(off);
+
+            byte[] padded = new byte[]
+            {
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0,      // padding to 64 bytes
+
+                36, 0, 0, 0,     // size prefix
+                24, 0, 0, 0,     // root of table, pointing to vtable offset (obj0)
+                20, 0, // vtable bytes
+                12, 0, // object length
+                11, 0, // start of value 0
+                10, 0, // start of value 1
+                9, 0, // start of value 2
+                8, 0, // start of value 3
+                7, 0, // start of value 4
+                6, 0, // start of value 5
+                5, 0, // start of value 6
+                4, 0, // start of value 7
+
+                20, 0, 0, 0, // int32 offset for start of vtable
+
+                1, 1, 1, 1,  // values
+                1, 1, 1, 1,
+
+            };
+            Assert.ArrayEqual(padded, builder.DataBuffer.ToFullArray());
+
+            // no padding in sized array
+            byte[] unpadded = new byte[padded.Length - 24];
+            Buffer.BlockCopy(padded, 24, unpadded, 0, unpadded.Length);
+            Assert.ArrayEqual(unpadded, builder.DataBuffer.ToSizedArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestWithFloat()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartTable(1);
+            builder.AddFloat(0, 1, 0);
+            builder.EndTable();
+
+
+            Assert.ArrayEqual(new byte[]
+            {
+                0, 0,
+                6, 0, // vtable bytes
+                8, 0, // object length
+                4, 0, // start of value 0
+                6, 0, 0, 0, // int32 offset for start of vtable
+                0, 0, 128, 63,  // value
+
+            },
+                builder.DataBuffer.ToFullArray());
+        }
+
+        private void CheckObjects(int fieldCount, int objectCount)
+        {
+            _lcg.Reset();
+
+            const int testValuesMax = 11;
+
+            var builder = new FlatBufferBuilder(1);
+
+            var objects = new int[objectCount];
+
+            for (var i = 0; i < objectCount; ++i)
+            {
+                builder.StartTable(fieldCount);
+
+                for (var j = 0; j < fieldCount; ++j)
+                {
+                    var fieldType = _lcg.Next()%testValuesMax;
+
+                    switch (fieldType)
+                    {
+                        case 0:
+                        {
+                            builder.AddBool(j, FuzzTestData.BoolValue, false);
+                            break;
+                        }
+                        case 1:
+                        {
+                            builder.AddSbyte(j, FuzzTestData.Int8Value, 0);
+                            break;
+                        }
+                        case 2:
+                        {
+                            builder.AddByte(j, FuzzTestData.UInt8Value, 0);
+                            break;
+                        }
+                        case 3:
+                        {
+                            builder.AddShort(j, FuzzTestData.Int16Value, 0);
+                            break;
+                        }
+                        case 4:
+                        {
+                            builder.AddUshort(j, FuzzTestData.UInt16Value, 0);
+                            break;
+                        }
+                        case 5:
+                        {
+                            builder.AddInt(j, FuzzTestData.Int32Value, 0);
+                            break;
+                        }
+                        case 6:
+                        {
+                            builder.AddUint(j, FuzzTestData.UInt32Value, 0);
+                            break;
+                        }
+                        case 7:
+                        {
+                            builder.AddLong(j, FuzzTestData.Int64Value, 0);
+                            break;
+                        }
+                        case 8:
+                        {
+                            builder.AddUlong(j, FuzzTestData.UInt64Value, 0);
+                            break;
+                        }
+                        case 9:
+                        {
+                            builder.AddFloat(j, FuzzTestData.Float32Value, 0);
+                            break;
+                        }
+                        case 10:
+                        {
+                            builder.AddDouble(j, FuzzTestData.Float64Value, 0);
+                            break;
+                        }
+                        default:
+                            throw new Exception("Unreachable");
+                    }
+
+                }
+
+                var offset = builder.EndTable();
+
+                // Store the object offset
+                objects[i] = offset;
+            }
+
+            _lcg.Reset();
+
+            // Test all objects are readable and return expected values...
+            for (var i = 0; i < objectCount; ++i)
+            {
+                var table = new TestTable(builder.DataBuffer, builder.DataBuffer.Length - objects[i]);
+
+                for (var j = 0; j < fieldCount; ++j)
+                {
+                    var fieldType = _lcg.Next() % testValuesMax;
+                    var fc = 2 + j; // 2 == VtableMetadataFields
+                    var f = fc * 2;
+
+                    switch (fieldType)
+                    {
+                        case 0:
+                        {
+                            Assert.AreEqual(FuzzTestData.BoolValue, table.GetSlot(f, false));
+                            break;
+                        }
+                        case 1:
+                        {
+                            Assert.AreEqual(FuzzTestData.Int8Value, table.GetSlot(f, (sbyte)0));
+                            break;
+                        }
+                        case 2:
+                        {
+                            Assert.AreEqual(FuzzTestData.UInt8Value, table.GetSlot(f, (byte)0));
+                            break;
+                        }
+                        case 3:
+                        {
+                            Assert.AreEqual(FuzzTestData.Int16Value, table.GetSlot(f, (short)0));
+                            break;
+                        }
+                        case 4:
+                        {
+                            Assert.AreEqual(FuzzTestData.UInt16Value, table.GetSlot(f, (ushort)0));
+                            break;
+                        }
+                        case 5:
+                        {
+                            Assert.AreEqual(FuzzTestData.Int32Value, table.GetSlot(f, (int)0));
+                            break;
+                        }
+                        case 6:
+                        {
+                            Assert.AreEqual(FuzzTestData.UInt32Value, table.GetSlot(f, (uint)0));
+                            break;
+                        }
+                        case 7:
+                        {
+                            Assert.AreEqual(FuzzTestData.Int64Value, table.GetSlot(f, (long)0));
+                            break;
+                        }
+                        case 8:
+                        {
+                            Assert.AreEqual(FuzzTestData.UInt64Value, table.GetSlot(f, (ulong)0));
+                            break;
+                        }
+                        case 9:
+                        {
+                            Assert.AreEqual(FuzzTestData.Float32Value, table.GetSlot(f, (float)0));
+                            break;
+                        }
+                        case 10:
+                        {
+                            Assert.AreEqual(FuzzTestData.Float64Value, table.GetSlot(f, (double)0));
+                            break;
+                        }
+                        default:
+                            throw new Exception("Unreachable");
+                    }
+
+                }
+
+            }
+
+        }
+    }
+}
diff --git a/tests/FlatBuffers.Test/FlatBuffersTestClassAttribute.cs b/tests/FlatBuffers.Test/FlatBuffersTestClassAttribute.cs
new file mode 100644
index 0000000..f31e38b
--- /dev/null
+++ b/tests/FlatBuffers.Test/FlatBuffersTestClassAttribute.cs
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2016 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace FlatBuffers.Test
+{
+    [AttributeUsage(AttributeTargets.Class)]
+    public class FlatBuffersTestClassAttribute : Attribute
+    {
+    }
+}
diff --git a/tests/FlatBuffers.Test/FlatBuffersTestMethodAttribute.cs b/tests/FlatBuffers.Test/FlatBuffersTestMethodAttribute.cs
new file mode 100644
index 0000000..989dae5
--- /dev/null
+++ b/tests/FlatBuffers.Test/FlatBuffersTestMethodAttribute.cs
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2016 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.
+ */
+
+ using System;
+
+namespace FlatBuffers.Test
+{
+    [AttributeUsage(AttributeTargets.Method)]
+    public class FlatBuffersTestMethodAttribute : Attribute
+    {
+    }
+}
\ No newline at end of file
diff --git a/tests/FlatBuffers.Test/FuzzTestData.cs b/tests/FlatBuffers.Test/FuzzTestData.cs
new file mode 100644
index 0000000..119e44e
--- /dev/null
+++ b/tests/FlatBuffers.Test/FuzzTestData.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2016 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.
+ */
+
+using System;
+
+namespace FlatBuffers.Test
+{
+    internal static class FuzzTestData
+    {
+        private static readonly byte[] _overflowInt32 = new byte[] {0x83, 0x33, 0x33, 0x33};
+        private static readonly byte[] _overflowInt64 = new byte[] { 0x84, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 };
+
+        public static readonly bool BoolValue = true;
+        public static readonly  sbyte Int8Value = -127;        // 0x81
+        public static readonly  byte UInt8Value = 255;         // 0xFF
+        public static readonly  short Int16Value = -32222;     // 0x8222;
+        public static readonly  ushort UInt16Value = 65262;      // 0xFEEE
+        public static readonly int Int32Value = BitConverter.ToInt32(_overflowInt32, 0);
+        public static readonly uint UInt32Value = 0xFDDDDDDD;
+        public static readonly long Int64Value = BitConverter.ToInt64(_overflowInt64, 0);
+        public static readonly ulong UInt64Value = 0xFCCCCCCCCCCCCCCC;
+        public static readonly float Float32Value = 3.14159f;
+        public static readonly double Float64Value = 3.14159265359;
+    }
+}
\ No newline at end of file
diff --git a/tests/FlatBuffers.Test/Lcg.cs b/tests/FlatBuffers.Test/Lcg.cs
new file mode 100644
index 0000000..c329ed8
--- /dev/null
+++ b/tests/FlatBuffers.Test/Lcg.cs
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2016 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.
+ */
+
+namespace FlatBuffers.Test
+{
+    /// <summary>
+    /// Lcg Pseudo RNG
+    /// </summary>
+    internal sealed class Lcg
+    {
+        private const uint InitialValue = 10000;
+        private uint _state;
+
+        public Lcg()
+        {
+            _state = InitialValue;
+        }
+
+        public uint Next()
+        {
+            return (_state = 69069 * _state + 362437);
+        }
+
+        public void Reset()
+        {
+            _state = InitialValue;
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/FlatBuffers.Test/NetTest.sh b/tests/FlatBuffers.Test/NetTest.sh
new file mode 100644
index 0000000..3822b49
--- /dev/null
+++ b/tests/FlatBuffers.Test/NetTest.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# Testing C# on Linux using Mono.
+
+mcs -debug -out:./fbnettest.exe \
+  ../../net/FlatBuffers/*.cs ../MyGame/Example/*.cs ../MyGame/*.cs ../union_vector/*.cs \
+  FlatBuffersTestClassAttribute.cs FlatBuffersTestMethodAttribute.cs Assert.cs FlatBuffersExampleTests.cs Program.cs ByteBufferTests.cs FlatBufferBuilderTests.cs FlatBuffersFuzzTests.cs FuzzTestData.cs Lcg.cs TestTable.cs
+mono --debug ./fbnettest.exe
+rm fbnettest.exe
+rm Resources/monsterdata_cstest.mon
+rm Resources/monsterdata_cstest_sp.mon
+
+# Repeat with unsafe versions
+
+mcs -debug -out:./fbnettest.exe \
+  -unsafe -d:UNSAFE_BYTEBUFFER \
+  ../../net/FlatBuffers/*.cs ../MyGame/Example/*.cs ../MyGame/*.cs ../union_vector/*.cs\
+  FlatBuffersTestClassAttribute.cs FlatBuffersTestMethodAttribute.cs Assert.cs FlatBuffersExampleTests.cs Program.cs ByteBufferTests.cs FlatBufferBuilderTests.cs FlatBuffersFuzzTests.cs FuzzTestData.cs Lcg.cs TestTable.cs
+mono --debug ./fbnettest.exe
+rm fbnettest.exe
+rm Resources/monsterdata_cstest.mon
+rm Resources/monsterdata_cstest_sp.mon
+
diff --git a/tests/FlatBuffers.Test/Program.cs b/tests/FlatBuffers.Test/Program.cs
new file mode 100644
index 0000000..f8cec4e
--- /dev/null
+++ b/tests/FlatBuffers.Test/Program.cs
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+
+namespace FlatBuffers.Test
+{
+    static class Program
+    {
+        public static int Main(string[] args)
+        {
+            var testResults = new List<bool>();
+
+            var testClasses = Assembly.GetExecutingAssembly().GetExportedTypes()
+                .Where(t => t.IsClass && t.GetCustomAttributes(typeof (FlatBuffersTestClassAttribute), false).Length > 0);
+
+            foreach (var testClass in testClasses)
+            {
+                var methods = testClass.GetMethods(BindingFlags.Public |
+                                                         BindingFlags.Instance)
+                          .Where(m => m.GetCustomAttributes(typeof(FlatBuffersTestMethodAttribute), false).Length > 0);
+
+                var inst = Activator.CreateInstance(testClass);
+
+                foreach (var method in methods)
+                {
+                    try
+                    {
+                        method.Invoke(inst, new object[] { });
+                        testResults.Add(true);
+                    }
+                    catch (Exception ex)
+                    {
+                        Console.WriteLine("{0}: FAILED when invoking {1} with error {2}",
+                            testClass.Name ,method.Name, ex.GetBaseException());
+                        testResults.Add(false);
+                    }
+                }
+            }
+
+            var failedCount = testResults.Count(i => i == false);
+
+            Console.WriteLine("{0} tests run, {1} failed", testResults.Count, failedCount);
+
+            if (failedCount > 0)
+            {
+                return -1;
+            }
+            return 0;
+        }
+    }
+}
diff --git a/tests/FlatBuffers.Test/Properties/AssemblyInfo.cs b/tests/FlatBuffers.Test/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..2e33f08
--- /dev/null
+++ b/tests/FlatBuffers.Test/Properties/AssemblyInfo.cs
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("FlatBuffers.Test")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("FlatBuffers.Test")]
+[assembly: AssemblyCopyright("Copyright (c) 2014  Google Inc")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components.  If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("a1d58a51-3e74-4ae9-aac7-5a399c9eed1a")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/tests/FlatBuffers.Test/Resources/monsterdata_test.mon b/tests/FlatBuffers.Test/Resources/monsterdata_test.mon
new file mode 100644
index 0000000..3f83972
--- /dev/null
+++ b/tests/FlatBuffers.Test/Resources/monsterdata_test.mon
Binary files differ
diff --git a/tests/FlatBuffers.Test/TestTable.cs b/tests/FlatBuffers.Test/TestTable.cs
new file mode 100644
index 0000000..4f663f0
--- /dev/null
+++ b/tests/FlatBuffers.Test/TestTable.cs
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2016 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.
+ */
+
+namespace FlatBuffers.Test
+{
+    /// <summary>
+    /// A test Table object that gives easy access to the slot data
+    /// </summary>
+    internal struct TestTable
+    {
+        Table t;
+
+        public TestTable(ByteBuffer bb, int pos)
+        {
+          t = new Table(pos, bb);
+        }
+
+        public bool GetSlot(int slot, bool def)
+        {
+            var off = t.__offset(slot);
+
+            if (off == 0)
+            {
+                return def;
+            }
+            return t.bb.GetSbyte(t.bb_pos + off) != 0;
+        }
+
+        public sbyte GetSlot(int slot, sbyte def)
+        {
+            var off = t.__offset(slot);
+
+            if (off == 0)
+            {
+                return def;
+            }
+            return t.bb.GetSbyte(t.bb_pos + off);
+        }
+
+        public byte GetSlot(int slot, byte def)
+        {
+            var off = t.__offset(slot);
+
+            if (off == 0)
+            {
+                return def;
+            }
+            return t.bb.Get(t.bb_pos + off);
+        }
+
+        public short GetSlot(int slot, short def)
+        {
+            var off = t.__offset(slot);
+
+            if (off == 0)
+            {
+                return def;
+            }
+            return t.bb.GetShort(t.bb_pos + off);
+        }
+
+        public ushort GetSlot(int slot, ushort def)
+        {
+            var off = t.__offset(slot);
+
+            if (off == 0)
+            {
+                return def;
+            }
+            return t.bb.GetUshort(t.bb_pos + off);
+        }
+
+        public int GetSlot(int slot, int def)
+        {
+            var off = t.__offset(slot);
+
+            if (off == 0)
+            {
+                return def;
+            }
+            return t.bb.GetInt(t.bb_pos + off);
+        }
+
+        public uint GetSlot(int slot, uint def)
+        {
+            var off = t.__offset(slot);
+
+            if (off == 0)
+            {
+                return def;
+            }
+            return t.bb.GetUint(t.bb_pos + off);
+        }
+
+        public long GetSlot(int slot, long def)
+        {
+            var off = t.__offset(slot);
+
+            if (off == 0)
+            {
+                return def;
+            }
+            return t.bb.GetLong(t.bb_pos + off);
+        }
+
+        public ulong GetSlot(int slot, ulong def)
+        {
+            var off = t.__offset(slot);
+
+            if (off == 0)
+            {
+                return def;
+            }
+            return t.bb.GetUlong(t.bb_pos + off);
+        }
+
+        public float GetSlot(int slot, float def)
+        {
+            var off = t.__offset(slot);
+
+            if (off == 0)
+            {
+                return def;
+            }
+            return t.bb.GetFloat(t.bb_pos + off);
+        }
+
+        public double GetSlot(int slot, double def)
+        {
+            var off = t.__offset(slot);
+
+            if (off == 0)
+            {
+                return def;
+            }
+            return t.bb.GetDouble(t.bb_pos + off);
+        }
+    }
+}
diff --git a/tests/GoTest.sh b/tests/GoTest.sh
new file mode 100755
index 0000000..e69f0d8
--- /dev/null
+++ b/tests/GoTest.sh
@@ -0,0 +1,75 @@
+#!/bin/bash -eu
+#
+# 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.
+
+pushd "$(dirname $0)" >/dev/null
+test_dir="$(pwd)"
+go_path=${test_dir}/go_gen
+go_src=${go_path}/src
+
+# Emit Go code for the example schema in the test dir:
+../flatc -g -I include_test monster_test.fbs
+
+# Go requires a particular layout of files in order to link multiple packages.
+# Copy flatbuffer Go files to their own package directories to compile the
+# test binary:
+mkdir -p ${go_src}/MyGame/Example
+mkdir -p ${go_src}/MyGame/Example2
+mkdir -p ${go_src}/github.com/google/flatbuffers/go
+mkdir -p ${go_src}/flatbuffers_test
+
+cp -a MyGame/*.go ./go_gen/src/MyGame/
+cp -a MyGame/Example/*.go ./go_gen/src/MyGame/Example/
+cp -a MyGame/Example2/*.go ./go_gen/src/MyGame/Example2/
+# do not compile the gRPC generated files, which are not tested by go_test.go
+# below, but have their own test.
+rm ./go_gen/src/MyGame/Example/*_grpc.go
+cp -a ../go/* ./go_gen/src/github.com/google/flatbuffers/go
+cp -a ./go_test.go ./go_gen/src/flatbuffers_test/
+
+# Run tests with necessary flags.
+# Developers may wish to see more detail by appending the verbosity flag
+# -test.v to arguments for this command, as in:
+#   go -test -test.v ...
+# Developers may also wish to run benchmarks, which may be achieved with the
+# flag -test.bench and the wildcard regexp ".":
+#   go -test -test.bench=. ...
+GOPATH=${go_path} go test flatbuffers_test \
+                     --test.coverpkg=github.com/google/flatbuffers/go \
+                     --cpp_data=${test_dir}/monsterdata_test.mon \
+                     --out_data=${test_dir}/monsterdata_go_wire.mon \
+                     --test.bench=. \
+                     --test.benchtime=3s \
+                     --fuzz=true \
+                     --fuzz_fields=4 \
+                     --fuzz_objects=10000
+
+GO_TEST_RESULT=$?
+rm -rf ${go_path}/{pkg,src}
+if [[ $GO_TEST_RESULT  == 0 ]]; then
+    echo "OK: Go tests passed."
+else
+    echo "KO: Go tests failed."
+    exit 1
+fi
+
+NOT_FMT_FILES=$(gofmt -l MyGame)
+if [[ ${NOT_FMT_FILES} != "" ]]; then
+    echo "These files are not well gofmt'ed:"
+    echo
+    echo "${NOT_FMT_FILES}"
+    # enable this when enums are properly formated
+    # exit 1
+fi
diff --git a/tests/JavaScriptTest.js b/tests/JavaScriptTest.js
new file mode 100644
index 0000000..7116daa
--- /dev/null
+++ b/tests/JavaScriptTest.js
@@ -0,0 +1,369 @@
+// Run this using JavaScriptTest.sh
+var assert = require('assert');
+var fs = require('fs');
+
+var flatbuffers = require('../js/flatbuffers').flatbuffers;
+var MyGame = require(process.argv[2]).MyGame;
+
+function main() {
+
+  // First, let's test reading a FlatBuffer generated by C++ code:
+  // This file was generated from monsterdata_test.json
+  var data = new Uint8Array(fs.readFileSync('monsterdata_test.mon'));
+
+  // Now test it:
+
+  var bb = new flatbuffers.ByteBuffer(data);
+  testBuffer(bb);
+
+  // Second, let's create a FlatBuffer from scratch in JavaScript, and test it also.
+  // We use an initial size of 1 to exercise the reallocation algorithm,
+  // normally a size larger than the typical FlatBuffer you generate would be
+  // better for performance.
+  var fbb = new flatbuffers.Builder(1);
+  createMonster(fbb);
+  serializeAndTest(fbb);
+
+  // clear the builder, repeat tests
+  var clearIterations = 100;
+  var startingCapacity = fbb.bb.capacity();
+  for (var i = 0; i < clearIterations; i++) {
+    fbb.clear();
+    createMonster(fbb);
+    serializeAndTest(fbb);
+  }
+  // the capacity of our buffer shouldn't increase with the same size payload
+  assert.strictEqual(fbb.bb.capacity(), startingCapacity);
+
+  test64bit();
+  testUnicode();
+  fuzzTest1();
+
+  console.log('FlatBuffers test: completed successfully');
+}
+
+function createMonster(fbb) {
+  // We set up the same values as monsterdata.json:
+
+  var str = fbb.createString('MyMonster');
+
+  var inv = MyGame.Example.Monster.createInventoryVector(fbb, [0, 1, 2, 3, 4]);
+
+  var fred = fbb.createString('Fred');
+  MyGame.Example.Monster.startMonster(fbb);
+  MyGame.Example.Monster.addName(fbb, fred);
+  var mon2 = MyGame.Example.Monster.endMonster(fbb);
+
+  MyGame.Example.Monster.startTest4Vector(fbb, 2);
+  MyGame.Example.Test.createTest(fbb, 10, 20);
+  MyGame.Example.Test.createTest(fbb, 30, 40);
+  var test4 = fbb.endVector();
+
+  var testArrayOfString = MyGame.Example.Monster.createTestarrayofstringVector(fbb, [
+    fbb.createString('test1'),
+    fbb.createString('test2')
+  ]);
+
+  MyGame.Example.Monster.startMonster(fbb);
+  MyGame.Example.Monster.addPos(fbb, MyGame.Example.Vec3.createVec3(fbb, 1, 2, 3, 3, MyGame.Example.Color.Green, 5, 6));
+  MyGame.Example.Monster.addHp(fbb, 80);
+  MyGame.Example.Monster.addName(fbb, str);
+  MyGame.Example.Monster.addInventory(fbb, inv);
+  MyGame.Example.Monster.addTestType(fbb, MyGame.Example.Any.Monster);
+  MyGame.Example.Monster.addTest(fbb, mon2);
+  MyGame.Example.Monster.addTest4(fbb, test4);
+  MyGame.Example.Monster.addTestarrayofstring(fbb, testArrayOfString);
+  MyGame.Example.Monster.addTestbool(fbb, true);
+  var mon = MyGame.Example.Monster.endMonster(fbb);
+
+  MyGame.Example.Monster.finishMonsterBuffer(fbb, mon);
+}
+
+function serializeAndTest(fbb) {
+  // 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
+  // JavaScript code. They are functionally equivalent though.
+
+  fs.writeFileSync('monsterdata_javascript_wire.mon', new Buffer(fbb.asUint8Array()));
+
+  // Tests mutation first.  This will verify that we did not trample any other
+  // part of the byte buffer.
+  testMutation(fbb.dataBuffer());
+
+  testBuffer(fbb.dataBuffer());
+}
+
+function testMutation(bb) {
+  var monster = MyGame.Example.Monster.getRootAsMonster(bb);
+
+  monster.mutate_hp(120);
+  assert.strictEqual(monster.hp(), 120);
+
+  monster.mutate_hp(80);
+  assert.strictEqual(monster.hp(), 80);
+
+  var manaRes = monster.mutate_mana(10);
+  assert.strictEqual(manaRes, false);  // Field was NOT present, because default value.
+
+  // TODO: There is not the availability to mutate structs or vectors.
+}
+
+function testBuffer(bb) {
+  assert.ok(MyGame.Example.Monster.bufferHasIdentifier(bb));
+
+  var monster = MyGame.Example.Monster.getRootAsMonster(bb);
+
+  assert.strictEqual(monster.hp(), 80);
+  assert.strictEqual(monster.mana(), 150); // default
+
+  assert.strictEqual(monster.name(), 'MyMonster');
+
+  var pos = monster.pos();
+  assert.strictEqual(pos.x(), 1);
+  assert.strictEqual(pos.y(), 2);
+  assert.strictEqual(pos.z(), 3);
+  assert.strictEqual(pos.test1(), 3);
+  assert.strictEqual(pos.test2(), MyGame.Example.Color.Green);
+  var t = pos.test3();
+  assert.strictEqual(t.a(), 5);
+  assert.strictEqual(t.b(), 6);
+
+  assert.strictEqual(monster.testType(), MyGame.Example.Any.Monster);
+  var monster2 = new MyGame.Example.Monster();
+  assert.strictEqual(monster.test(monster2) != null, true);
+  assert.strictEqual(monster2.name(), 'Fred');
+
+  assert.strictEqual(monster.inventoryLength(), 5);
+  var invsum = 0;
+  for (var i = 0; i < monster.inventoryLength(); i++) {
+    invsum += monster.inventory(i);
+  }
+  assert.strictEqual(invsum, 10);
+
+  var invsum2 = 0;
+  var invArr = monster.inventoryArray();
+  for (var i = 0; i < invArr.length; i++) {
+    invsum2 += invArr[i];
+  }
+  assert.strictEqual(invsum2, 10);
+
+  var test_0 = monster.test4(0);
+  var test_1 = monster.test4(1);
+  assert.strictEqual(monster.test4Length(), 2);
+  assert.strictEqual(test_0.a() + test_0.b() + test_1.a() + test_1.b(), 100);
+
+  assert.strictEqual(monster.testarrayofstringLength(), 2);
+  assert.strictEqual(monster.testarrayofstring(0), 'test1');
+  assert.strictEqual(monster.testarrayofstring(1), 'test2');
+
+  assert.strictEqual(monster.testbool(), true);
+}
+
+function test64bit() {
+  var fbb = new flatbuffers.Builder();
+  var required = fbb.createString('required');
+
+  MyGame.Example.Stat.startStat(fbb);
+  var stat2 = MyGame.Example.Stat.endStat(fbb);
+
+  MyGame.Example.Monster.startMonster(fbb);
+  MyGame.Example.Monster.addName(fbb, required);
+  MyGame.Example.Monster.addTestempty(fbb, stat2);
+  var mon2 = MyGame.Example.Monster.endMonster(fbb);
+
+  MyGame.Example.Stat.startStat(fbb);
+  // 2541551405100253985 = 0x87654321(low part) + 0x23456789 * 0x100000000(high part);
+  MyGame.Example.Stat.addVal(fbb, new flatbuffers.Long(0x87654321, 0x23456789));    // the low part is Uint32
+  var stat = MyGame.Example.Stat.endStat(fbb);
+
+  MyGame.Example.Monster.startMonster(fbb);
+  MyGame.Example.Monster.addName(fbb, required);
+  MyGame.Example.Monster.addEnemy(fbb, mon2);
+  MyGame.Example.Monster.addTestempty(fbb, stat);
+  var mon = MyGame.Example.Monster.endMonster(fbb);
+
+  MyGame.Example.Monster.finishMonsterBuffer(fbb, mon);
+  var bytes = fbb.asUint8Array();
+
+  ////////////////////////////////////////////////////////////////
+
+  var bb = new flatbuffers.ByteBuffer(bytes);
+  assert.ok(MyGame.Example.Monster.bufferHasIdentifier(bb));
+  var mon = MyGame.Example.Monster.getRootAsMonster(bb);
+
+  var stat = mon.testempty();
+  assert.strictEqual(stat != null, true);
+  assert.strictEqual(stat.val() != null, true);
+  assert.strictEqual(stat.val().toFloat64(), 2541551405100253985);
+
+  var mon2 = mon.enemy();
+  assert.strictEqual(mon2 != null, true);
+  stat = mon2.testempty();
+  assert.strictEqual(stat != null, true);
+  assert.strictEqual(stat.val() != null, true);
+  assert.strictEqual(stat.val().low, 0); // default value
+  assert.strictEqual(stat.val().high, 0);
+}
+
+function testUnicode() {
+  var correct = fs.readFileSync('unicode_test.mon');
+  var json = JSON.parse(fs.readFileSync('unicode_test.json', 'utf8'));
+
+  // Test reading
+  function testReadingUnicode(bb) {
+    var monster = MyGame.Example.Monster.getRootAsMonster(bb);
+    assert.strictEqual(monster.name(), json.name);
+    assert.deepEqual(new Buffer(monster.name(flatbuffers.Encoding.UTF8_BYTES)), new Buffer(json.name));
+    assert.strictEqual(monster.testarrayoftablesLength(), json.testarrayoftables.length);
+    json.testarrayoftables.forEach(function(table, i) {
+      var value = monster.testarrayoftables(i);
+      assert.strictEqual(value.name(), table.name);
+      assert.deepEqual(new Buffer(value.name(flatbuffers.Encoding.UTF8_BYTES)), new Buffer(table.name));
+    });
+    assert.strictEqual(monster.testarrayofstringLength(), json.testarrayofstring.length);
+    json.testarrayofstring.forEach(function(string, i) {
+      assert.strictEqual(monster.testarrayofstring(i), string);
+      assert.deepEqual(new Buffer(monster.testarrayofstring(i, flatbuffers.Encoding.UTF8_BYTES)), new Buffer(string));
+    });
+  }
+  testReadingUnicode(new flatbuffers.ByteBuffer(new Uint8Array(correct)));
+
+  // Test writing
+  var fbb = new flatbuffers.Builder();
+  var name = fbb.createString(json.name);
+  var testarrayoftablesOffsets = json.testarrayoftables.map(function(table) {
+    var name = fbb.createString(new Uint8Array(new Buffer(table.name)));
+    MyGame.Example.Monster.startMonster(fbb);
+    MyGame.Example.Monster.addName(fbb, name);
+    return MyGame.Example.Monster.endMonster(fbb);
+  });
+  var testarrayoftablesOffset = MyGame.Example.Monster.createTestarrayoftablesVector(fbb,
+    testarrayoftablesOffsets);
+  var testarrayofstringOffset = MyGame.Example.Monster.createTestarrayofstringVector(fbb,
+    json.testarrayofstring.map(function(string) { return fbb.createString(string); }));
+  MyGame.Example.Monster.startMonster(fbb);
+  MyGame.Example.Monster.addTestarrayofstring(fbb, testarrayofstringOffset);
+  MyGame.Example.Monster.addTestarrayoftables(fbb, testarrayoftablesOffset);
+  MyGame.Example.Monster.addName(fbb, name);
+  MyGame.Example.Monster.finishSizePrefixedMonsterBuffer(fbb, MyGame.Example.Monster.endMonster(fbb));
+  var bb = new flatbuffers.ByteBuffer(fbb.asUint8Array())
+  bb.setPosition(4);
+  testReadingUnicode(bb);
+}
+
+var __imul = Math.imul ? Math.imul : function(a, b) {
+  var ah = a >> 16 & 65535;
+  var bh = b >> 16 & 65535;
+  var al = a & 65535;
+  var bl = b & 65535;
+  return al * bl + (ah * bl + al * bh << 16) | 0;
+};
+
+// Include simple random number generator to ensure results will be the
+// same cross platform.
+// http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator
+var lcg_seed = 48271;
+
+function lcg_rand() {
+  return lcg_seed = (__imul(lcg_seed, 279470273) >>> 0) % 4294967291;
+}
+
+function lcg_reset() {
+  lcg_seed = 48271;
+}
+
+// Converts a Field ID to a virtual table offset.
+function fieldIndexToOffset(field_id) {
+  // Should correspond to what EndTable() below builds up.
+  var fixed_fields = 2;  // Vtable size and Object Size.
+  return (field_id + fixed_fields) * 2;
+}
+
+// Low level stress/fuzz test: serialize/deserialize a variety of
+// different kinds of data in different combinations
+function fuzzTest1() {
+
+  // Values we're testing against: chosen to ensure no bits get chopped
+  // off anywhere, and also be different from eachother.
+  var bool_val   = true;
+  var char_val   = -127;  // 0x81
+  var uchar_val  = 0xFF;
+  var short_val  = -32222; // 0x8222;
+  var ushort_val = 0xFEEE;
+  var int_val    = 0x83333333 | 0;
+  var uint_val   = 0xFDDDDDDD;
+  var long_val   = new flatbuffers.Long(0x44444444, 0x84444444);
+  var ulong_val  = new flatbuffers.Long(0xCCCCCCCC, 0xFCCCCCCC);
+  var float_val  = new Float32Array([3.14159])[0];
+  var double_val = 3.14159265359;
+
+  var test_values_max = 11;
+  var fields_per_object = 4;
+  var num_fuzz_objects = 10000;  // The higher, the more thorough :)
+
+  var builder = new flatbuffers.Builder();
+
+  lcg_reset();  // Keep it deterministic.
+
+  var objects = [];
+
+  // Generate num_fuzz_objects random objects each consisting of
+  // fields_per_object fields, each of a random type.
+  for (var i = 0; i < num_fuzz_objects; i++) {
+    builder.startObject(fields_per_object);
+    for (var f = 0; f < fields_per_object; f++) {
+      var choice = lcg_rand() % test_values_max;
+      switch (choice) {
+        case 0:  builder.addFieldInt8(f, bool_val,   0); break;
+        case 1:  builder.addFieldInt8(f, char_val,   0); break;
+        case 2:  builder.addFieldInt8(f, uchar_val,  0); break;
+        case 3:  builder.addFieldInt16(f, short_val,  0); break;
+        case 4:  builder.addFieldInt16(f, ushort_val, 0); break;
+        case 5:  builder.addFieldInt32(f, int_val,    0); break;
+        case 6:  builder.addFieldInt32(f, uint_val,   0); break;
+        case 7:  builder.addFieldInt64(f, long_val,   flatbuffers.Long.ZERO); break;
+        case 8:  builder.addFieldInt64(f, ulong_val,  flatbuffers.Long.ZERO); break;
+        case 9:  builder.addFieldFloat32(f, float_val,  0); break;
+        case 10: builder.addFieldFloat64(f, double_val, 0); break;
+      }
+    }
+    objects.push(builder.endObject());
+  }
+  builder.prep(8, 0);  // Align whole buffer.
+
+  lcg_reset();  // Reset.
+
+  builder.finish(objects[objects.length - 1]);
+  var bytes = new Uint8Array(builder.asUint8Array());
+  var view = new DataView(bytes.buffer);
+
+  // Test that all objects we generated are readable and return the
+  // expected values. We generate random objects in the same order
+  // so this is deterministic.
+  for (var i = 0; i < num_fuzz_objects; i++) {
+    var offset = bytes.length - objects[i];
+    for (var f = 0; f < fields_per_object; f++) {
+      var choice = lcg_rand() % test_values_max;
+      var vtable_offset = fieldIndexToOffset(f);
+      var vtable = offset - view.getInt32(offset, true);
+      assert.ok(vtable_offset < view.getInt16(vtable, true));
+      var field_offset = offset + view.getInt16(vtable + vtable_offset, true);
+      switch (choice) {
+        case 0:  assert.strictEqual(!!view.getInt8(field_offset), bool_val); break;
+        case 1:  assert.strictEqual(view.getInt8(field_offset), char_val); break;
+        case 2:  assert.strictEqual(view.getUint8(field_offset), uchar_val); break;
+        case 3:  assert.strictEqual(view.getInt16(field_offset, true), short_val); break;
+        case 4:  assert.strictEqual(view.getUint16(field_offset, true), ushort_val); break;
+        case 5:  assert.strictEqual(view.getInt32(field_offset, true), int_val); break;
+        case 6:  assert.strictEqual(view.getUint32(field_offset, true), uint_val); break;
+        case 7:  assert.strictEqual(view.getInt32(field_offset, true), long_val.low); assert.strictEqual(view.getInt32(field_offset + 4, true), long_val.high); break;
+        case 8:  assert.strictEqual(view.getInt32(field_offset, true), ulong_val.low); assert.strictEqual(view.getInt32(field_offset + 4, true), ulong_val.high); break;
+        case 9:  assert.strictEqual(view.getFloat32(field_offset, true), float_val); break;
+        case 10: assert.strictEqual(view.getFloat64(field_offset, true), double_val); break;
+      }
+    }
+  }
+}
+
+main();
diff --git a/tests/JavaScriptTest.sh b/tests/JavaScriptTest.sh
new file mode 100755
index 0000000..c0286a0
--- /dev/null
+++ b/tests/JavaScriptTest.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+#
+# Copyright 2016 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.
+
+pushd "$(dirname $0)" >/dev/null
+../flatc -b -I include_test monster_test.fbs unicode_test.json
+node JavaScriptTest ./monster_test_generated
diff --git a/tests/JavaScriptUnionVectorTest.js b/tests/JavaScriptUnionVectorTest.js
new file mode 100644
index 0000000..d79669f
--- /dev/null
+++ b/tests/JavaScriptUnionVectorTest.js
@@ -0,0 +1,57 @@
+var assert = require('assert');
+
+var flatbuffers = require('../js/flatbuffers').flatbuffers;
+var Test = require(process.argv[2]);
+
+function main() {
+  var fbb = new flatbuffers.Builder();
+
+  var charTypes = [
+    Test.Character.Belle,
+    Test.Character.MuLan,
+    Test.Character.BookFan,
+  ];
+
+  Test.Attacker.startAttacker(fbb);
+  Test.Attacker.addSwordAttackDamage(fbb, 5);
+  var attackerOffset = Test.Attacker.endAttacker(fbb);
+
+  var charTypesOffset = Test.Movie.createCharactersTypeVector(fbb, charTypes);
+  var charsOffset = Test.Movie.createCharactersVector(
+    fbb,
+    [
+      Test.BookReader.createBookReader(fbb, 7),
+      attackerOffset,
+      Test.BookReader.createBookReader(fbb, 2),
+    ]
+  );
+
+  Test.Movie.startMovie(fbb);
+  Test.Movie.addCharactersType(fbb, charTypesOffset);
+  Test.Movie.addCharacters(fbb, charsOffset);
+  Test.Movie.finishMovieBuffer(fbb, Test.Movie.endMovie(fbb));
+
+  var buf = new flatbuffers.ByteBuffer(fbb.asUint8Array());
+
+  var movie = Test.Movie.getRootAsMovie(buf);
+
+  assert.strictEqual(movie.charactersTypeLength(), charTypes.length);
+  assert.strictEqual(movie.charactersLength(), movie.charactersTypeLength());
+
+  for (var i = 0; i < charTypes.length; ++i) {
+    assert.strictEqual(movie.charactersType(i), charTypes[i]);
+  }
+
+  var bookReader7 = movie.characters(0, new Test.BookReader());
+  assert.strictEqual(bookReader7.booksRead(), 7);
+
+  var attacker = movie.characters(1, new Test.Attacker());
+  assert.strictEqual(attacker.swordAttackDamage(), 5);
+
+  var bookReader2 = movie.characters(2, new Test.BookReader());
+  assert.strictEqual(bookReader2.booksRead(), 2);
+
+  console.log('FlatBuffers union vector test: completed successfully');
+}
+
+main();
diff --git a/tests/JavaTest.bat b/tests/JavaTest.bat
new file mode 100644
index 0000000..921815a
--- /dev/null
+++ b/tests/JavaTest.bat
@@ -0,0 +1,21 @@
+@echo off
+rem Copyright 2014 Google Inc. All rights reserved.
+rem
+rem Licensed under the Apache License, Version 2.0 (the "License");
+rem you may not use this file except in compliance with the License.
+rem You may obtain a copy of the License at
+rem
+rem     http://www.apache.org/licenses/LICENSE-2.0
+rem
+rem Unless required by applicable law or agreed to in writing, software
+rem distributed under the License is distributed on an "AS IS" BASIS,
+rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+rem See the License for the specific language governing permissions and
+rem limitations under the License.
+
+rem Compile then run the Java test.
+
+set batch_file_dir=%~d0%~p0
+
+javac -g -classpath %batch_file_dir%\..\java;%batch_file_dir%;%batch_file_dir%\namespace_test;%batch_file_dir%\union_vector JavaTest.java
+java -classpath %batch_file_dir%\..\java;%batch_file_dir%;%batch_file_dir%\namespace_test;%batch_file_dir%\union_vector JavaTest
diff --git a/tests/JavaTest.java b/tests/JavaTest.java
new file mode 100644
index 0000000..6505767
--- /dev/null
+++ b/tests/JavaTest.java
@@ -0,0 +1,517 @@
+/*
+ * 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.
+ */
+
+import java.io.*;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.channels.FileChannel;
+import MyGame.Example.*;
+import NamespaceA.*;
+import NamespaceA.NamespaceB.*;
+import com.google.flatbuffers.ByteBufferUtil;
+import static com.google.flatbuffers.Constants.*;
+import com.google.flatbuffers.FlatBufferBuilder;
+import MyGame.MonsterExtra;
+
+class JavaTest {
+    public static void main(String[] args) {
+
+        // First, let's test reading a FlatBuffer generated by C++ code:
+        // This file was generated from monsterdata_test.json
+
+        byte[] data = null;
+        File file = new File("monsterdata_test.mon");
+        RandomAccessFile f = null;
+        try {
+            f = new RandomAccessFile(file, "r");
+            data = new byte[(int)f.length()];
+            f.readFully(data);
+            f.close();
+        } catch(java.io.IOException e) {
+            System.out.println("FlatBuffers test: couldn't read file");
+            return;
+        }
+
+        // Now test it:
+
+        ByteBuffer bb = ByteBuffer.wrap(data);
+        TestBuffer(bb);
+
+        // Second, let's create a FlatBuffer from scratch in Java, and test it also.
+        // We use an initial size of 1 to exercise the reallocation algorithm,
+        // normally a size larger than the typical FlatBuffer you generate would be
+        // better for performance.
+        FlatBufferBuilder fbb = new FlatBufferBuilder(1);
+
+        TestBuilderBasics(fbb, true);
+        TestBuilderBasics(fbb, false);
+
+        TestExtendedBuffer(fbb.dataBuffer().asReadOnlyBuffer());
+
+        TestNamespaceNesting();
+
+        TestNestedFlatBuffer();
+
+        TestCreateByteVector();
+
+        TestCreateUninitializedVector();
+
+        TestByteBufferFactory();
+
+        TestSizedInputStream();
+
+        TestVectorOfUnions();
+
+        TestFixedLengthArrays();
+
+        System.out.println("FlatBuffers test: completed successfully");
+    }
+
+    static void TestEnums() {
+      TestEq(Color.name(Color.Red), "Red");
+      TestEq(Color.name(Color.Blue), "Blue");
+      TestEq(Any.name(Any.NONE), "NONE");
+      TestEq(Any.name(Any.Monster), "Monster");
+    }
+
+    static void TestBuffer(ByteBuffer bb) {
+        TestEq(Monster.MonsterBufferHasIdentifier(bb), true);
+
+        Monster monster = Monster.getRootAsMonster(bb);
+
+        TestEq(monster.hp(), (short)80);
+        TestEq(monster.mana(), (short)150);  // default
+
+        TestEq(monster.name(), "MyMonster");
+        // monster.friendly() // can't access, deprecated
+
+        Vec3 pos = monster.pos();
+        TestEq(pos.x(), 1.0f);
+        TestEq(pos.y(), 2.0f);
+        TestEq(pos.z(), 3.0f);
+        TestEq(pos.test1(), 3.0);
+        // issue: int != byte
+        TestEq(pos.test2(), (int) Color.Green);
+        Test t = pos.test3();
+        TestEq(t.a(), (short)5);
+        TestEq(t.b(), (byte)6);
+
+        TestEq(monster.testType(), (byte)Any.Monster);
+        Monster monster2 = new Monster();
+        TestEq(monster.test(monster2) != null, true);
+        TestEq(monster2.name(), "Fred");
+
+        TestEq(monster.inventoryLength(), 5);
+        int invsum = 0;
+        for (int i = 0; i < monster.inventoryLength(); i++)
+            invsum += monster.inventory(i);
+        TestEq(invsum, 10);
+
+        // Alternative way of accessing a vector:
+        ByteBuffer ibb = monster.inventoryAsByteBuffer();
+        invsum = 0;
+        while (ibb.position() < ibb.limit())
+            invsum += ibb.get();
+        TestEq(invsum, 10);
+
+        Test test_0 = monster.test4(0);
+        Test test_1 = monster.test4(1);
+        TestEq(monster.test4Length(), 2);
+        TestEq(test_0.a() + test_0.b() + test_1.a() + test_1.b(), 100);
+
+        TestEq(monster.testarrayofstringLength(), 2);
+        TestEq(monster.testarrayofstring(0),"test1");
+        TestEq(monster.testarrayofstring(1),"test2");
+
+        TestEq(monster.testbool(), true);
+    }
+
+    // this method checks additional fields not present in the binary buffer read from file
+    // these new tests are performed on top of the regular tests
+    static void TestExtendedBuffer(ByteBuffer bb) {
+        TestBuffer(bb);
+
+        Monster monster = Monster.getRootAsMonster(bb);
+
+        TestEq(monster.testhashu32Fnv1(), Integer.MAX_VALUE + 1L);
+    }
+
+    static void TestNamespaceNesting() {
+        // reference / manipulate these to verify compilation
+        FlatBufferBuilder fbb = new FlatBufferBuilder(1);
+
+        TableInNestedNS.startTableInNestedNS(fbb);
+        TableInNestedNS.addFoo(fbb, 1234);
+        int nestedTableOff = TableInNestedNS.endTableInNestedNS(fbb);
+
+        TableInFirstNS.startTableInFirstNS(fbb);
+        TableInFirstNS.addFooTable(fbb, nestedTableOff);
+        int off = TableInFirstNS.endTableInFirstNS(fbb);
+    }
+
+    static void TestNestedFlatBuffer() {
+        final String nestedMonsterName = "NestedMonsterName";
+        final short nestedMonsterHp = 600;
+        final short nestedMonsterMana = 1024;
+
+        FlatBufferBuilder fbb1 = new FlatBufferBuilder(16);
+        int str1 = fbb1.createString(nestedMonsterName);
+        Monster.startMonster(fbb1);
+        Monster.addName(fbb1, str1);
+        Monster.addHp(fbb1, nestedMonsterHp);
+        Monster.addMana(fbb1, nestedMonsterMana);
+        int monster1 = Monster.endMonster(fbb1);
+        Monster.finishMonsterBuffer(fbb1, monster1);
+        byte[] fbb1Bytes = fbb1.sizedByteArray();
+        fbb1 = null;
+
+        FlatBufferBuilder fbb2 = new FlatBufferBuilder(16);
+        int str2 = fbb2.createString("My Monster");
+        int nestedBuffer = Monster.createTestnestedflatbufferVector(fbb2, fbb1Bytes);
+        Monster.startMonster(fbb2);
+        Monster.addName(fbb2, str2);
+        Monster.addHp(fbb2, (short)50);
+        Monster.addMana(fbb2, (short)32);
+        Monster.addTestnestedflatbuffer(fbb2, nestedBuffer);
+        int monster = Monster.endMonster(fbb2);
+        Monster.finishMonsterBuffer(fbb2, monster);
+
+        // Now test the data extracted from the nested buffer
+        Monster mons = Monster.getRootAsMonster(fbb2.dataBuffer());
+        Monster nestedMonster = mons.testnestedflatbufferAsMonster();
+
+        TestEq(nestedMonsterMana, nestedMonster.mana());
+        TestEq(nestedMonsterHp, nestedMonster.hp());
+        TestEq(nestedMonsterName, nestedMonster.name());
+    }
+
+    static void TestCreateByteVector() {
+        FlatBufferBuilder fbb = new FlatBufferBuilder(16);
+        int str = fbb.createString("MyMonster");
+        byte[] inventory = new byte[] { 0, 1, 2, 3, 4 };
+        int vec = fbb.createByteVector(inventory);
+        Monster.startMonster(fbb);
+        Monster.addInventory(fbb, vec);
+        Monster.addName(fbb, str);
+        int monster1 = Monster.endMonster(fbb);
+        Monster.finishMonsterBuffer(fbb, monster1);
+        Monster monsterObject = Monster.getRootAsMonster(fbb.dataBuffer());
+
+        TestEq(monsterObject.inventory(1), (int)inventory[1]);
+        TestEq(monsterObject.inventoryLength(), inventory.length);
+        TestEq(ByteBuffer.wrap(inventory), monsterObject.inventoryAsByteBuffer());
+    }
+
+    static void TestCreateUninitializedVector() {
+        FlatBufferBuilder fbb = new FlatBufferBuilder(16);
+        int str = fbb.createString("MyMonster");
+        byte[] inventory = new byte[] { 0, 1, 2, 3, 4 };
+        ByteBuffer bb = fbb.createUnintializedVector(1, inventory.length, 1);
+        for (byte i:inventory) {
+            bb.put(i);
+        }
+        int vec = fbb.endVector();
+        Monster.startMonster(fbb);
+        Monster.addInventory(fbb, vec);
+        Monster.addName(fbb, str);
+        int monster1 = Monster.endMonster(fbb);
+        Monster.finishMonsterBuffer(fbb, monster1);
+        Monster monsterObject = Monster.getRootAsMonster(fbb.dataBuffer());
+
+        TestEq(monsterObject.inventory(1), (int)inventory[1]);
+        TestEq(monsterObject.inventoryLength(), inventory.length);
+        TestEq(ByteBuffer.wrap(inventory), monsterObject.inventoryAsByteBuffer());
+    }
+
+    static void TestByteBufferFactory() {
+        final class MappedByteBufferFactory extends FlatBufferBuilder.ByteBufferFactory {
+            @Override
+            public ByteBuffer newByteBuffer(int capacity) {
+                ByteBuffer bb;
+                try {
+                    bb =  new RandomAccessFile("javatest.bin", "rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 0, capacity).order(ByteOrder.LITTLE_ENDIAN);
+                } catch(Throwable e) {
+                    System.out.println("FlatBuffers test: couldn't map ByteBuffer to a file");
+                    bb = null;
+                }
+                return bb;
+            }
+        }
+
+        FlatBufferBuilder fbb = new FlatBufferBuilder(1, new MappedByteBufferFactory());
+
+        TestBuilderBasics(fbb, false);
+    }
+
+    static void TestSizedInputStream() {
+        // Test on default FlatBufferBuilder that uses HeapByteBuffer
+        FlatBufferBuilder fbb = new FlatBufferBuilder(1);
+
+        TestBuilderBasics(fbb, false);
+
+        InputStream in = fbb.sizedInputStream();
+        byte[] array = fbb.sizedByteArray();
+        int count = 0;
+        int currentVal = 0;
+
+        while (currentVal != -1 && count < array.length) {
+            try {
+                currentVal = in.read();
+            } catch(java.io.IOException e) {
+                System.out.println("FlatBuffers test: couldn't read from InputStream");
+                return;
+            }
+            TestEq((byte)currentVal, array[count]);
+            count++;
+        }
+        TestEq(count, array.length);
+    }
+
+    static void TestBuilderBasics(FlatBufferBuilder fbb, boolean sizePrefix) {
+        int[] names = {fbb.createString("Frodo"), fbb.createString("Barney"), fbb.createString("Wilma")};
+        int[] off = new int[3];
+        Monster.startMonster(fbb);
+        Monster.addName(fbb, names[0]);
+        off[0] = Monster.endMonster(fbb);
+        Monster.startMonster(fbb);
+        Monster.addName(fbb, names[1]);
+        off[1] = Monster.endMonster(fbb);
+        Monster.startMonster(fbb);
+        Monster.addName(fbb, names[2]);
+        off[2] = Monster.endMonster(fbb);
+        int sortMons = fbb.createSortedVectorOfTables(new Monster(), off);
+
+        // We set up the same values as monsterdata.json:
+
+        int str = fbb.createString("MyMonster");
+
+        int inv = Monster.createInventoryVector(fbb, new byte[] { 0, 1, 2, 3, 4 });
+
+        int fred = fbb.createString("Fred");
+        Monster.startMonster(fbb);
+        Monster.addName(fbb, fred);
+        int mon2 = Monster.endMonster(fbb);
+
+        Monster.startTest4Vector(fbb, 2);
+        Test.createTest(fbb, (short)10, (byte)20);
+        Test.createTest(fbb, (short)30, (byte)40);
+        int test4 = fbb.endVector();
+
+        int testArrayOfString = Monster.createTestarrayofstringVector(fbb, new int[] {
+                fbb.createString("test1"),
+                fbb.createString("test2")
+        });
+
+        Monster.startMonster(fbb);
+        Monster.addPos(fbb, Vec3.createVec3(fbb, 1.0f, 2.0f, 3.0f, 3.0,
+                Color.Green, (short)5, (byte)6));
+        Monster.addHp(fbb, (short)80);
+        Monster.addName(fbb, str);
+        Monster.addInventory(fbb, inv);
+        Monster.addTestType(fbb, (byte)Any.Monster);
+        Monster.addTest(fbb, mon2);
+        Monster.addTest4(fbb, test4);
+        Monster.addTestarrayofstring(fbb, testArrayOfString);
+        Monster.addTestbool(fbb, true);
+        Monster.addTesthashu32Fnv1(fbb, Integer.MAX_VALUE + 1L);
+        Monster.addTestarrayoftables(fbb, sortMons);
+        int mon = Monster.endMonster(fbb);
+
+        if (sizePrefix) {
+            Monster.finishSizePrefixedMonsterBuffer(fbb, mon);
+        } else {
+            Monster.finishMonsterBuffer(fbb, mon);
+        }
+
+        // Write the result to a file for debugging purposes:
+        // Note that the binaries are not necessarily identical, since the JSON
+        // parser may serialize in a slightly different order than the above
+        // Java code. They are functionally equivalent though.
+
+        try {
+            String filename = "monsterdata_java_wire" + (sizePrefix ? "_sp" : "") + ".mon";
+            FileChannel fc = new FileOutputStream(filename).getChannel();
+            fc.write(fbb.dataBuffer().duplicate());
+            fc.close();
+        } catch(java.io.IOException e) {
+            System.out.println("FlatBuffers test: couldn't write file");
+            return;
+        }
+
+        // Test it:
+        ByteBuffer dataBuffer = fbb.dataBuffer();
+        if (sizePrefix) {
+            TestEq(ByteBufferUtil.getSizePrefix(dataBuffer) + SIZE_PREFIX_LENGTH,
+                   dataBuffer.remaining());
+            dataBuffer = ByteBufferUtil.removeSizePrefix(dataBuffer);
+        }
+        TestExtendedBuffer(dataBuffer);
+
+        // Make sure it also works with read only ByteBuffers. This is slower,
+        // since creating strings incurs an additional copy
+        // (see Table.__string).
+        TestExtendedBuffer(dataBuffer.asReadOnlyBuffer());
+
+        TestEnums();
+
+        //Attempt to mutate Monster fields and check whether the buffer has been mutated properly
+        // revert to original values after testing
+        Monster monster = Monster.getRootAsMonster(dataBuffer);
+
+        // mana is optional and does not exist in the buffer so the mutation should fail
+        // the mana field should retain its default value
+        TestEq(monster.mutateMana((short)10), false);
+        TestEq(monster.mana(), (short)150);
+
+        // Accessing a vector of sorted by the key tables
+        TestEq(monster.testarrayoftables(0).name(), "Barney");
+        TestEq(monster.testarrayoftables(1).name(), "Frodo");
+        TestEq(monster.testarrayoftables(2).name(), "Wilma");
+
+        // Example of searching for a table by the key
+        TestEq(monster.testarrayoftablesByKey("Frodo").name(), "Frodo");
+        TestEq(monster.testarrayoftablesByKey("Barney").name(), "Barney");
+        TestEq(monster.testarrayoftablesByKey("Wilma").name(), "Wilma");
+
+        // testType is an existing field and mutating it should succeed
+        TestEq(monster.testType(), (byte)Any.Monster);
+        TestEq(monster.mutateTestType(Any.NONE), true);
+        TestEq(monster.testType(), (byte)Any.NONE);
+        TestEq(monster.mutateTestType(Any.Monster), true);
+        TestEq(monster.testType(), (byte)Any.Monster);
+
+        //mutate the inventory vector
+        TestEq(monster.mutateInventory(0, 1), true);
+        TestEq(monster.mutateInventory(1, 2), true);
+        TestEq(monster.mutateInventory(2, 3), true);
+        TestEq(monster.mutateInventory(3, 4), true);
+        TestEq(monster.mutateInventory(4, 5), true);
+
+        for (int i = 0; i < monster.inventoryLength(); i++) {
+            TestEq(monster.inventory(i), i + 1);
+        }
+
+        //reverse mutation
+        TestEq(monster.mutateInventory(0, 0), true);
+        TestEq(monster.mutateInventory(1, 1), true);
+        TestEq(monster.mutateInventory(2, 2), true);
+        TestEq(monster.mutateInventory(3, 3), true);
+        TestEq(monster.mutateInventory(4, 4), true);
+
+        // get a struct field and edit one of its fields
+        Vec3 pos = monster.pos();
+        TestEq(pos.x(), 1.0f);
+        pos.mutateX(55.0f);
+        TestEq(pos.x(), 55.0f);
+        pos.mutateX(1.0f);
+        TestEq(pos.x(), 1.0f);
+    }
+
+    static void TestVectorOfUnions() {
+        final FlatBufferBuilder fbb = new FlatBufferBuilder();
+
+        final int swordAttackDamage = 1;
+
+        final int[] characterVector = new int[] {
+            Attacker.createAttacker(fbb, swordAttackDamage),
+        };
+
+        final byte[] characterTypeVector = new byte[]{
+            Character.MuLan,
+        };
+
+        Movie.finishMovieBuffer(
+            fbb,
+            Movie.createMovie(
+                fbb,
+                (byte)0,
+                (byte)0,
+                Movie.createCharactersTypeVector(fbb, characterTypeVector),
+                Movie.createCharactersVector(fbb, characterVector)
+            )
+        );
+
+        final Movie movie = Movie.getRootAsMovie(fbb.dataBuffer());
+
+        TestEq(movie.charactersTypeLength(), characterTypeVector.length);
+        TestEq(movie.charactersLength(), characterVector.length);
+
+        TestEq(movie.charactersType(0), characterTypeVector[0]);
+
+        TestEq(((Attacker)movie.characters(new Attacker(), 0)).swordAttackDamage(), swordAttackDamage);
+    }
+
+    static void TestFixedLengthArrays() {
+        FlatBufferBuilder builder = new FlatBufferBuilder(0);
+
+        float       a;
+        int[]       b = new int[15];
+        byte        c;
+        int[][]     d_a = new int[2][2];
+        byte[]      d_b = new byte[2];
+        byte[][]    d_c = new byte[2][2];
+
+        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;
+
+        int arrayOffset = ArrayStruct.createArrayStruct(builder,
+            a, b, c, d_a, d_b, d_c);
+
+        // Create a table with the ArrayStruct.
+        ArrayTable.startArrayTable(builder);
+        ArrayTable.addA(builder, arrayOffset);
+        int tableOffset = ArrayTable.endArrayTable(builder);
+
+        ArrayTable.finishArrayTableBuffer(builder, tableOffset);
+
+        ArrayTable table = ArrayTable.getRootAsArrayTable(builder.dataBuffer());
+        NestedStruct nested = new NestedStruct();
+
+        TestEq(table.a().a(), 0.5f);
+        for (int i = 0; i < 15; i++) TestEq(table.a().b(i), i);
+        TestEq(table.a().c(), (byte)1);
+        TestEq(table.a().d(nested, 0).a(0), 1);
+        TestEq(table.a().d(nested, 0).a(1), 2);
+        TestEq(table.a().d(nested, 1).a(0), 3);
+        TestEq(table.a().d(nested, 1).a(1), 4);
+        TestEq(table.a().d(nested, 0).b(), TestEnum.B);
+        TestEq(table.a().d(nested, 1).b(), TestEnum.C);
+        TestEq(table.a().d(nested, 0).c(0), TestEnum.A);
+        TestEq(table.a().d(nested, 0).c(1), TestEnum.B);
+        TestEq(table.a().d(nested, 1).c(0), TestEnum.C);
+        TestEq(table.a().d(nested, 1).c(1), TestEnum.B);
+    }
+
+    static <T> void TestEq(T a, T b) {
+        if (!a.equals(b)) {
+            System.out.println("" + a.getClass().getName() + " " + b.getClass().getName());
+            System.out.println("FlatBuffers test FAILED: \'" + a + "\' != \'" + b + "\'");
+            assert false;
+            System.exit(1);
+        }
+    }
+}
diff --git a/tests/JavaTest.sh b/tests/JavaTest.sh
new file mode 100755
index 0000000..58d8442
--- /dev/null
+++ b/tests/JavaTest.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+#
+# 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.
+
+set -o errexit
+
+echo Compile then run the Java test.
+
+java -version
+
+testdir="$(readlink -fn "$(dirname "$0")")"
+
+targetdir="${testdir}/target"
+
+if [[ -e "${targetdir}" ]]; then
+    echo "cleaning target"
+    rm -rf "${targetdir}"
+fi
+
+mkdir -v "${targetdir}"
+
+if ! find "${testdir}/../java" -type f -name "*.class" -delete; then
+    echo "failed to clean .class files from java directory" >&2
+    exit 1
+fi
+
+javac -d "${targetdir}" -classpath "${testdir}/../java:${testdir}:${testdir}/namespace_test:${testdir}/union_vector" "${testdir}/JavaTest.java"
+
+(cd "${testdir}" && java -classpath "${targetdir}" JavaTest )
+
+rm -rf "${targetdir}"
diff --git a/tests/KotlinTest.kt b/tests/KotlinTest.kt
new file mode 100644
index 0000000..07f0465
--- /dev/null
+++ b/tests/KotlinTest.kt
@@ -0,0 +1,460 @@
+/*
+ * 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.
+ */
+
+import MyGame.Example.*
+import com.google.flatbuffers.ByteBufferUtil
+import com.google.flatbuffers.FlatBufferBuilder
+import NamespaceA.*
+import NamespaceA.NamespaceB.*
+import NamespaceA.NamespaceB.TableInNestedNS
+import java.io.File
+import java.io.FileOutputStream
+import java.io.InputStream
+import java.io.RandomAccessFile
+import java.nio.ByteBuffer
+import java.nio.ByteOrder
+import java.nio.channels.FileChannel
+
+import com.google.flatbuffers.Constants.SIZE_PREFIX_LENGTH
+
+@kotlin.ExperimentalUnsignedTypes
+class KotlinTest {
+
+  companion object {
+    @JvmStatic
+    fun main(args: Array<String>) {
+
+        // First, let's test reading a FlatBuffer generated by C++ code:
+        // This file was generated from monsterdata_test.json
+
+        val data = RandomAccessFile(File("monsterdata_test.mon"), "r").use {
+            val temp = ByteArray(it.length().toInt())
+            it.readFully(temp)
+            temp
+        }
+
+        // Now test it:
+
+        val bb = ByteBuffer.wrap(data)
+        TestBuffer(bb)
+
+        // Second, let's create a FlatBuffer from scratch in Java, and test it also.
+        // We use an initial size of 1 to exercise the reallocation algorithm,
+        // normally a size larger than the typical FlatBuffer you generate would be
+        // better for performance.
+        val fbb = FlatBufferBuilder(1)
+
+        TestBuilderBasics(fbb, true)
+        TestBuilderBasics(fbb, false)
+
+        TestExtendedBuffer(fbb.dataBuffer().asReadOnlyBuffer())
+
+        TestNamespaceNesting()
+
+        TestNestedFlatBuffer()
+
+        TestCreateByteVector()
+
+        TestCreateUninitializedVector()
+
+        TestByteBufferFactory()
+
+        TestSizedInputStream()
+
+        TestVectorOfUnions()
+
+        println("FlatBuffers test: completed successfully")
+    }
+
+    fun TestEnums() {
+        assert(Color.name(Color.Red.toInt()) == "Red")
+        assert(Color.name(Color.Blue.toInt()) == "Blue")
+        assert(Any_.name(Any_.NONE.toInt()) == "NONE")
+        assert(Any_.name(Any_.Monster.toInt()) == "Monster")
+    }
+
+    fun TestBuffer(bb: ByteBuffer) {
+        assert(Monster.MonsterBufferHasIdentifier(bb) == true)
+
+        val monster = Monster.getRootAsMonster(bb)
+
+        assert(monster.hp == 80.toShort())
+        assert(monster.mana == 150.toShort())  // default
+
+        assert(monster.name == "MyMonster")
+        // monster.friendly() // can't access, deprecated
+
+        val pos = monster.pos!!
+        assert(pos.x == 1.0f)
+        assert(pos.y == 2.0f)
+        assert(pos.z == 3.0f)
+        assert(pos.test1 == 3.0)
+        // issue: int != byte
+        assert(pos.test2 == Color.Green)
+        val t = pos.test3!!
+        assert(t.a == 5.toShort())
+        assert(t.b == 6.toByte())
+
+        assert(monster.testType == Any_.Monster)
+        val monster2 = Monster()
+        assert(monster.test(monster2) != null == true)
+        assert(monster2.name == "Fred")
+
+        assert(monster.inventoryLength == 5)
+        var invsum = 0u
+        for (i in 0 until monster.inventoryLength)
+            invsum += monster.inventory(i)
+        assert(invsum == 10u)
+
+        // Alternative way of accessing a vector:
+        val ibb = monster.inventoryAsByteBuffer
+        invsum = 0u
+        while (ibb.position() < ibb.limit())
+            invsum += ibb.get().toUInt()
+        assert(invsum == 10u)
+
+
+        val test_0 = monster.test4(0)!!
+        val test_1 = monster.test4(1)!!
+        assert(monster.test4Length == 2)
+        assert(test_0.a + test_0.b + test_1.a + test_1.b == 100)
+
+        assert(monster.testarrayofstringLength == 2)
+        assert(monster.testarrayofstring(0) == "test1")
+        assert(monster.testarrayofstring(1) == "test2")
+
+        assert(monster.testbool == true)
+    }
+
+    // this method checks additional fields not present in the binary buffer read from file
+    // these new tests are performed on top of the regular tests
+    fun TestExtendedBuffer(bb: ByteBuffer) {
+        TestBuffer(bb)
+
+        val monster = Monster.getRootAsMonster(bb)
+
+        assert(monster.testhashu32Fnv1 == (1u + Integer.MAX_VALUE.toUInt()))
+    }
+
+    fun TestNamespaceNesting() {
+        // reference / manipulate these to verify compilation
+        val fbb = FlatBufferBuilder(1)
+
+        TableInNestedNS.startTableInNestedNS(fbb)
+        TableInNestedNS.addFoo(fbb, 1234)
+        val nestedTableOff = TableInNestedNS.endTableInNestedNS(fbb)
+
+        TableInFirstNS.startTableInFirstNS(fbb)
+        TableInFirstNS.addFooTable(fbb, nestedTableOff)
+    }
+
+    fun TestNestedFlatBuffer() {
+        val nestedMonsterName = "NestedMonsterName"
+        val nestedMonsterHp: Short = 600
+        val nestedMonsterMana: Short = 1024
+
+        var fbb1: FlatBufferBuilder? = FlatBufferBuilder(16)
+        val str1 = fbb1!!.createString(nestedMonsterName)
+        Monster.startMonster(fbb1)
+        Monster.addName(fbb1, str1)
+        Monster.addHp(fbb1, nestedMonsterHp)
+        Monster.addMana(fbb1, nestedMonsterMana)
+        val monster1 = Monster.endMonster(fbb1)
+        Monster.finishMonsterBuffer(fbb1, monster1)
+        val fbb1Bytes = fbb1.sizedByteArray()
+        
+        val fbb2 = FlatBufferBuilder(16)
+        val str2 = fbb2.createString("My Monster")
+        val nestedBuffer = Monster.createTestnestedflatbufferVector(fbb2, fbb1Bytes.asUByteArray())
+        Monster.startMonster(fbb2)
+        Monster.addName(fbb2, str2)
+        Monster.addHp(fbb2, 50.toShort())
+        Monster.addMana(fbb2, 32.toShort())
+        Monster.addTestnestedflatbuffer(fbb2, nestedBuffer)
+        val monster = Monster.endMonster(fbb2)
+        Monster.finishMonsterBuffer(fbb2, monster)
+
+        // Now test the data extracted from the nested buffer
+        val mons = Monster.getRootAsMonster(fbb2.dataBuffer())
+        val nestedMonster = mons.testnestedflatbufferAsMonster!!
+
+        assert(nestedMonsterMana == nestedMonster.mana)
+        assert(nestedMonsterHp == nestedMonster.hp)
+        assert(nestedMonsterName == nestedMonster.name)
+    }
+
+    fun TestCreateByteVector() {
+        val fbb = FlatBufferBuilder(16)
+        val str = fbb.createString("MyMonster")
+        val inventory = byteArrayOf(0, 1, 2, 3, 4)
+        val vec = fbb.createByteVector(inventory)
+        Monster.startMonster(fbb)
+        Monster.addInventory(fbb, vec)
+        Monster.addName(fbb, str)
+        val monster1 = Monster.endMonster(fbb)
+        Monster.finishMonsterBuffer(fbb, monster1)
+        val monsterObject = Monster.getRootAsMonster(fbb.dataBuffer())
+
+        assert(monsterObject.inventory(1) == inventory[1].toUByte())
+        assert(monsterObject.inventoryLength == inventory.size)
+        assert(ByteBuffer.wrap(inventory) == monsterObject.inventoryAsByteBuffer)
+    }
+
+    fun TestCreateUninitializedVector() {
+        val fbb = FlatBufferBuilder(16)
+        val str = fbb.createString("MyMonster")
+        val inventory = byteArrayOf(0, 1, 2, 3, 4)
+        val bb = fbb.createUnintializedVector(1, inventory.size, 1)
+        for (i in inventory) {
+            bb.put(i)
+        }
+        val vec = fbb.endVector()
+        Monster.startMonster(fbb)
+        Monster.addInventory(fbb, vec)
+        Monster.addName(fbb, str)
+        val monster1 = Monster.endMonster(fbb)
+        Monster.finishMonsterBuffer(fbb, monster1)
+        val monsterObject = Monster.getRootAsMonster(fbb.dataBuffer())
+
+        assert(monsterObject.inventory(1) == inventory[1].toUByte())
+        assert(monsterObject.inventoryLength == inventory.size)
+        assert(ByteBuffer.wrap(inventory) == monsterObject.inventoryAsByteBuffer)
+    }
+
+    fun TestByteBufferFactory() {
+        class MappedByteBufferFactory : FlatBufferBuilder.ByteBufferFactory() {
+            override fun newByteBuffer(capacity: Int): ByteBuffer? {
+                var bb: ByteBuffer?
+                try {
+                    bb = RandomAccessFile("javatest.bin", "rw").channel.map(
+                        FileChannel.MapMode.READ_WRITE,
+                        0,
+                        capacity.toLong()
+                    ).order(ByteOrder.LITTLE_ENDIAN)
+                } catch (e: Throwable) {
+                    println("FlatBuffers test: couldn't map ByteBuffer to a file")
+                    bb = null
+                }
+
+                return bb
+            }
+        }
+
+        val fbb = FlatBufferBuilder(1, MappedByteBufferFactory())
+
+        TestBuilderBasics(fbb, false)
+    }
+
+    fun TestSizedInputStream() {
+        // Test on default FlatBufferBuilder that uses HeapByteBuffer
+        val fbb = FlatBufferBuilder(1)
+
+        TestBuilderBasics(fbb, false)
+
+        val `in` = fbb.sizedInputStream()
+        val array = fbb.sizedByteArray()
+        var count = 0
+        var currentVal = 0
+
+        while (currentVal != -1 && count < array.size) {
+            try {
+                currentVal = `in`.read()
+            } catch (e: java.io.IOException) {
+                println("FlatBuffers test: couldn't read from InputStream")
+                return
+            }
+
+            assert(currentVal.toByte() == array[count])
+            count++
+        }
+        assert(count == array.size)
+    }
+
+    fun TestBuilderBasics(fbb: FlatBufferBuilder, sizePrefix: Boolean) {
+        val names = intArrayOf(fbb.createString("Frodo"), fbb.createString("Barney"), fbb.createString("Wilma"))
+        val off = IntArray(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)
+        val sortMons = fbb.createSortedVectorOfTables(Monster(), off)
+
+        // We set up the same values as monsterdata.json:
+
+        val str = fbb.createString("MyMonster")
+
+        val inv = Monster.createInventoryVector(fbb, byteArrayOf(0, 1, 2, 3, 4).asUByteArray())
+
+        val fred = fbb.createString("Fred")
+        Monster.startMonster(fbb)
+        Monster.addName(fbb, fred)
+        val mon2 = Monster.endMonster(fbb)
+
+        Monster.startTest4Vector(fbb, 2)
+        Test.createTest(fbb, 10.toShort(), 20.toByte())
+        Test.createTest(fbb, 30.toShort(), 40.toByte())
+        val test4 = fbb.endVector()
+
+        val testArrayOfString =
+            Monster.createTestarrayofstringVector(fbb, intArrayOf(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, 5.toShort(), 6.toByte()
+            )
+        )
+        Monster.addHp(fbb, 80.toShort())
+        Monster.addName(fbb, str)
+        Monster.addInventory(fbb, inv)
+        Monster.addTestType(fbb, Any_.Monster)
+        Monster.addTest(fbb, mon2)
+        Monster.addTest4(fbb, test4)
+        Monster.addTestarrayofstring(fbb, testArrayOfString)
+        Monster.addTestbool(fbb, true)
+        Monster.addTesthashu32Fnv1(fbb, UInt.MAX_VALUE + 1u)
+        Monster.addTestarrayoftables(fbb, sortMons)
+        val 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 {
+            val filename = "monsterdata_java_wire" + (if (sizePrefix) "_sp" else "") + ".mon"
+            val fc = FileOutputStream(filename).channel
+            fc.write(fbb.dataBuffer().duplicate())
+            fc.close()
+        } catch (e: java.io.IOException) {
+            println("FlatBuffers test: couldn't write file")
+            return
+        }
+
+        // Test it:
+        var dataBuffer = fbb.dataBuffer()
+        if (sizePrefix) {
+            assert(
+                ByteBufferUtil.getSizePrefix(dataBuffer) + SIZE_PREFIX_LENGTH ==
+                dataBuffer.remaining()
+            )
+            dataBuffer = ByteBufferUtil.removeSizePrefix(dataBuffer)
+        }
+        TestExtendedBuffer(dataBuffer)
+
+        // Make sure it also works with read only ByteBuffers. This is slower,
+        // since creating strings incurs an additional copy
+        // (see Table.__string).
+        TestExtendedBuffer(dataBuffer.asReadOnlyBuffer())
+
+        TestEnums()
+
+        //Attempt to mutate Monster fields and check whether the buffer has been mutated properly
+        // revert to original values after testing
+        val 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
+        assert(monster.mutateMana(10.toShort()) == false)
+        assert(monster.mana == 150.toShort())
+
+        // Accessing a vector of sorted by the key tables
+        assert(monster.testarrayoftables(0)!!.name == "Barney")
+        assert(monster.testarrayoftables(1)!!.name == "Frodo")
+        assert(monster.testarrayoftables(2)!!.name == "Wilma")
+
+        // Example of searching for a table by the key
+        assert(monster.testarrayoftablesByKey("Frodo")!!.name == "Frodo")
+        assert(monster.testarrayoftablesByKey("Barney")!!.name == "Barney")
+        assert(monster.testarrayoftablesByKey("Wilma")!!.name == "Wilma")
+
+        // testType is an existing field and mutating it should succeed
+        assert(monster.testType == Any_.Monster)
+        assert(monster.mutateTestType(Any_.NONE) == true)
+        assert(monster.testType == Any_.NONE)
+        assert(monster.mutateTestType(Any_.Monster) == true)
+        assert(monster.testType == Any_.Monster)
+
+        //mutate the inventory vector
+        assert(monster.mutateInventory(0, 1u) == true)
+        assert(monster.mutateInventory(1, 2u) == true)
+        assert(monster.mutateInventory(2, 3u) == true)
+        assert(monster.mutateInventory(3, 4u) == true)
+        assert(monster.mutateInventory(4, 5u) == true)
+
+        for (i in 0 until monster.inventoryLength) {
+            assert(monster.inventory(i) == (i.toUByte() + 1u).toUByte())
+        }
+
+        //reverse mutation
+        assert(monster.mutateInventory(0, 0u) == true)
+        assert(monster.mutateInventory(1, 1u) == true)
+        assert(monster.mutateInventory(2, 2u) == true)
+        assert(monster.mutateInventory(3, 3u) == true)
+        assert(monster.mutateInventory(4, 4u) == true)
+
+        // get a struct field and edit one of its fields
+        val pos = monster.pos!!
+        assert(pos.x == 1.0f)
+        pos.mutateX(55.0f)
+        assert(pos.x == 55.0f)
+        pos.mutateX(1.0f)
+        assert(pos.x == 1.0f)
+    }
+
+    fun TestVectorOfUnions() {
+        val fbb = FlatBufferBuilder()
+
+        val swordAttackDamage = 1
+
+        val characterVector = intArrayOf(Attacker.createAttacker(fbb, swordAttackDamage))
+
+        val characterTypeVector = ubyteArrayOf(Character_.MuLan)
+
+        Movie.finishMovieBuffer(
+            fbb,
+            Movie.createMovie(
+                fbb,
+                0u,
+                0,
+                Movie.createCharactersTypeVector(fbb, characterTypeVector),
+                Movie.createCharactersVector(fbb, characterVector)
+            )
+        )
+
+        val movie = Movie.getRootAsMovie(fbb.dataBuffer())
+
+        assert(movie.charactersTypeLength == characterTypeVector.size)
+        assert(movie.charactersLength == characterVector.size)
+
+        assert(movie.charactersType(0) == characterTypeVector[0])
+
+        assert((movie.characters(Attacker(), 0) as Attacker).swordAttackDamage == swordAttackDamage)
+    }
+}
+  }
diff --git a/tests/KotlinTest.sh b/tests/KotlinTest.sh
new file mode 100755
index 0000000..709e68c
--- /dev/null
+++ b/tests/KotlinTest.sh
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+# 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.
+
+echo Compile then run the Kotlin test.
+
+testdir=$(dirname $0)
+targetdir="${testdir}/kotlin"
+
+if [[ -e "${targetdir}" ]]; then
+    echo "cleaning target"
+    rm -rf "${targetdir}"
+fi
+
+mkdir -v "${targetdir}"
+
+if ! find "${testdir}/../java" -type f -name "*.class" -delete; then
+    echo "failed to clean .class files from java directory" >&2
+    exit 1
+fi
+
+all_kt_files=`find . -name "*.kt" -print`
+
+# Compile java FlatBuffer library 
+javac ${testdir}/../java/com/google/flatbuffers/*.java -d $targetdir
+# Compile Kotlin files
+kotlinc $all_kt_files -classpath $targetdir -include-runtime -d $targetdir
+# Make jar
+jar cvf ${testdir}/kotlin_test.jar -C $targetdir . > /dev/null
+# Run test
+kotlin -cp ${testdir}/kotlin_test.jar KotlinTest
+# clean up
+rm -rf $targetdir
+rm ${testdir}/kotlin_test.jar
diff --git a/tests/LuaTest.bat b/tests/LuaTest.bat
new file mode 100644
index 0000000..2bbf1d0
--- /dev/null
+++ b/tests/LuaTest.bat
@@ -0,0 +1,6 @@
+set buildtype=Release
+if "%1"=="-b" set buildtype=%2
+
+..\%buildtype%\flatc.exe --lua -I include_test monster_test.fbs
+
+lua53.exe luatest.lua
\ No newline at end of file
diff --git a/tests/LuaTest.sh b/tests/LuaTest.sh
new file mode 100755
index 0000000..eb70e8a
--- /dev/null
+++ b/tests/LuaTest.sh
@@ -0,0 +1,22 @@
+#!/bin/bash -eu
+#
+# Copyright 2019 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.
+
+pushd "$(dirname $0)" >/dev/null
+test_dir="$(pwd)"
+
+${test_dir}/../flatc --lua -I include_test monster_test.fbs
+
+lua5.3 luatest.lua
diff --git a/tests/MyGame/Example/Ability.cs b/tests/MyGame/Example/Ability.cs
new file mode 100644
index 0000000..8315985
--- /dev/null
+++ b/tests/MyGame/Example/Ability.cs
@@ -0,0 +1,32 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct Ability : IFlatbufferObject
+{
+  private Struct __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
+  public Ability __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public uint Id { get { return __p.bb.GetUint(__p.bb_pos + 0); } }
+  public void MutateId(uint id) { __p.bb.PutUint(__p.bb_pos + 0, id); }
+  public uint Distance { get { return __p.bb.GetUint(__p.bb_pos + 4); } }
+  public void MutateDistance(uint distance) { __p.bb.PutUint(__p.bb_pos + 4, distance); }
+
+  public static Offset<MyGame.Example.Ability> CreateAbility(FlatBufferBuilder builder, uint Id, uint Distance) {
+    builder.Prep(4, 8);
+    builder.PutUint(Distance);
+    builder.PutUint(Id);
+    return new Offset<MyGame.Example.Ability>(builder.Offset);
+  }
+};
+
+
+}
diff --git a/tests/MyGame/Example/Ability.go b/tests/MyGame/Example/Ability.go
new file mode 100644
index 0000000..a56b445
--- /dev/null
+++ b/tests/MyGame/Example/Ability.go
@@ -0,0 +1,41 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package Example
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+)
+
+type Ability struct {
+	_tab flatbuffers.Struct
+}
+
+func (rcv *Ability) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *Ability) Table() flatbuffers.Table {
+	return rcv._tab.Table
+}
+
+func (rcv *Ability) Id() uint32 {
+	return rcv._tab.GetUint32(rcv._tab.Pos + flatbuffers.UOffsetT(0))
+}
+func (rcv *Ability) MutateId(n uint32) bool {
+	return rcv._tab.MutateUint32(rcv._tab.Pos+flatbuffers.UOffsetT(0), n)
+}
+
+func (rcv *Ability) Distance() uint32 {
+	return rcv._tab.GetUint32(rcv._tab.Pos + flatbuffers.UOffsetT(4))
+}
+func (rcv *Ability) MutateDistance(n uint32) bool {
+	return rcv._tab.MutateUint32(rcv._tab.Pos+flatbuffers.UOffsetT(4), n)
+}
+
+func CreateAbility(builder *flatbuffers.Builder, id uint32, distance uint32) flatbuffers.UOffsetT {
+	builder.Prep(4, 8)
+	builder.PrependUint32(distance)
+	builder.PrependUint32(id)
+	return builder.Offset()
+}
diff --git a/tests/MyGame/Example/Ability.java b/tests/MyGame/Example/Ability.java
new file mode 100644
index 0000000..1a8ef03
--- /dev/null
+++ b/tests/MyGame/Example/Ability.java
@@ -0,0 +1,27 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class Ability extends Struct {
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public Ability __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public long id() { return (long)bb.getInt(bb_pos + 0) & 0xFFFFFFFFL; }
+  public void mutateId(long id) { bb.putInt(bb_pos + 0, (int)id); }
+  public long distance() { return (long)bb.getInt(bb_pos + 4) & 0xFFFFFFFFL; }
+  public void mutateDistance(long distance) { bb.putInt(bb_pos + 4, (int)distance); }
+
+  public static int createAbility(FlatBufferBuilder builder, long id, long distance) {
+    builder.prep(4, 8);
+    builder.putInt((int)distance);
+    builder.putInt((int)id);
+    return builder.offset();
+  }
+}
+
diff --git a/tests/MyGame/Example/Ability.kt b/tests/MyGame/Example/Ability.kt
new file mode 100644
index 0000000..1b644d6
--- /dev/null
+++ b/tests/MyGame/Example/Ability.kt
@@ -0,0 +1,32 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Ability : Struct() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : Ability {
+        __init(_i, _bb)
+        return this
+    }
+    val id : UInt get() = bb.getInt(bb_pos + 0).toUInt()
+    fun mutateId(id: UInt) : ByteBuffer = bb.putInt(bb_pos + 0, id.toInt())
+    val distance : UInt get() = bb.getInt(bb_pos + 4).toUInt()
+    fun mutateDistance(distance: UInt) : ByteBuffer = bb.putInt(bb_pos + 4, distance.toInt())
+    companion object {
+        fun createAbility(builder: FlatBufferBuilder, id: UInt, distance: UInt) : Int {
+            builder.prep(4, 8)
+            builder.putInt(distance.toInt())
+            builder.putInt(id.toInt())
+            return builder.offset()
+        }
+    }
+}
diff --git a/tests/MyGame/Example/Ability.lua b/tests/MyGame/Example/Ability.lua
new file mode 100644
index 0000000..7fb664a
--- /dev/null
+++ b/tests/MyGame/Example/Ability.lua
@@ -0,0 +1,31 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Example
+
+local flatbuffers = require('flatbuffers')
+
+local Ability = {} -- the module
+local Ability_mt = {} -- the class metatable
+
+function Ability.New()
+    local o = {}
+    setmetatable(o, {__index = Ability_mt})
+    return o
+end
+function Ability_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function Ability_mt:Id()
+    return self.view:Get(flatbuffers.N.Uint32, self.view.pos + 0)
+end
+function Ability_mt:Distance()
+    return self.view:Get(flatbuffers.N.Uint32, self.view.pos + 4)
+end
+function Ability.CreateAbility(builder, id, distance)
+    builder:Prep(4, 8)
+    builder:PrependUint32(distance)
+    builder:PrependUint32(id)
+    return builder:Offset()
+end
+
+return Ability -- return the module
\ No newline at end of file
diff --git a/tests/MyGame/Example/Ability.php b/tests/MyGame/Example/Ability.php
new file mode 100644
index 0000000..c09eca3
--- /dev/null
+++ b/tests/MyGame/Example/Ability.php
@@ -0,0 +1,52 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace MyGame\Example;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class Ability extends Struct
+{
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return Ability
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    /**
+     * @return uint
+     */
+    public function GetId()
+    {
+        return $this->bb->getUint($this->bb_pos + 0);
+    }
+
+    /**
+     * @return uint
+     */
+    public function GetDistance()
+    {
+        return $this->bb->getUint($this->bb_pos + 4);
+    }
+
+
+    /**
+     * @return int offset
+     */
+    public static function createAbility(FlatBufferBuilder $builder, $id, $distance)
+    {
+        $builder->prep(4, 8);
+        $builder->putUint($distance);
+        $builder->putUint($id);
+        return $builder->offset();
+    }
+}
diff --git a/tests/MyGame/Example/Ability.py b/tests/MyGame/Example/Ability.py
new file mode 100644
index 0000000..3c4776e
--- /dev/null
+++ b/tests/MyGame/Example/Ability.py
@@ -0,0 +1,23 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+import flatbuffers
+
+class Ability(object):
+    __slots__ = ['_tab']
+
+    # Ability
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # Ability
+    def Id(self): return self._tab.Get(flatbuffers.number_types.Uint32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(0))
+    # Ability
+    def Distance(self): return self._tab.Get(flatbuffers.number_types.Uint32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(4))
+
+def CreateAbility(builder, id, distance):
+    builder.Prep(4, 8)
+    builder.PrependUint32(distance)
+    builder.PrependUint32(id)
+    return builder.Offset()
diff --git a/tests/MyGame/Example/Any.cs b/tests/MyGame/Example/Any.cs
new file mode 100644
index 0000000..f95c6bc
--- /dev/null
+++ b/tests/MyGame/Example/Any.cs
@@ -0,0 +1,17 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+public enum Any : byte
+{
+  NONE = 0,
+  Monster = 1,
+  TestSimpleTableWithEnum = 2,
+  MyGame_Example2_Monster = 3,
+};
+
+
+}
diff --git a/tests/MyGame/Example/Any.go b/tests/MyGame/Example/Any.go
new file mode 100644
index 0000000..8d9067e
--- /dev/null
+++ b/tests/MyGame/Example/Any.go
@@ -0,0 +1,35 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package Example
+
+import "strconv"
+
+type Any byte
+
+const (
+	AnyNONE                    Any = 0
+	AnyMonster                 Any = 1
+	AnyTestSimpleTableWithEnum Any = 2
+	AnyMyGame_Example2_Monster Any = 3
+)
+
+var EnumNamesAny = map[Any]string{
+	AnyNONE:                    "NONE",
+	AnyMonster:                 "Monster",
+	AnyTestSimpleTableWithEnum: "TestSimpleTableWithEnum",
+	AnyMyGame_Example2_Monster: "MyGame_Example2_Monster",
+}
+
+var EnumValuesAny = map[string]Any{
+	"NONE":                    AnyNONE,
+	"Monster":                 AnyMonster,
+	"TestSimpleTableWithEnum": AnyTestSimpleTableWithEnum,
+	"MyGame_Example2_Monster": AnyMyGame_Example2_Monster,
+}
+
+func (v Any) String() string {
+	if s, ok := EnumNamesAny[v]; ok {
+		return s
+	}
+	return "Any(" + strconv.FormatInt(int64(v), 10) + ")"
+}
diff --git a/tests/MyGame/Example/Any.java b/tests/MyGame/Example/Any.java
new file mode 100644
index 0000000..6e4fb76
--- /dev/null
+++ b/tests/MyGame/Example/Any.java
@@ -0,0 +1,16 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+public final class Any {
+  private Any() { }
+  public static final byte NONE = 0;
+  public static final byte Monster = 1;
+  public static final byte TestSimpleTableWithEnum = 2;
+  public static final byte MyGame_Example2_Monster = 3;
+
+  public static final String[] names = { "NONE", "Monster", "TestSimpleTableWithEnum", "MyGame_Example2_Monster", };
+
+  public static String name(int e) { return names[e]; }
+}
+
diff --git a/tests/MyGame/Example/Any.kt b/tests/MyGame/Example/Any.kt
new file mode 100644
index 0000000..f1a4dfe
--- /dev/null
+++ b/tests/MyGame/Example/Any.kt
@@ -0,0 +1,16 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Any_ private constructor() {
+    companion object {
+        const val NONE: UByte = 0u
+        const val Monster: UByte = 1u
+        const val TestSimpleTableWithEnum: UByte = 2u
+        const val MyGameExample2Monster: UByte = 3u
+        val names : Array<String> = arrayOf("NONE", "Monster", "TestSimpleTableWithEnum", "MyGame_Example2_Monster")
+        fun name(e: Int) : String = names[e]
+    }
+}
diff --git a/tests/MyGame/Example/Any.lua b/tests/MyGame/Example/Any.lua
new file mode 100644
index 0000000..03225ba
--- /dev/null
+++ b/tests/MyGame/Example/Any.lua
@@ -0,0 +1,12 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Example
+
+local Any = {
+    NONE = 0,
+    Monster = 1,
+    TestSimpleTableWithEnum = 2,
+    MyGame_Example2_Monster = 3,
+}
+
+return Any -- return the module
\ No newline at end of file
diff --git a/tests/MyGame/Example/Any.php b/tests/MyGame/Example/Any.php
new file mode 100644
index 0000000..929caaf
--- /dev/null
+++ b/tests/MyGame/Example/Any.php
@@ -0,0 +1,27 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace MyGame\Example;
+
+class Any
+{
+    const NONE = 0;
+    const Monster = 1;
+    const TestSimpleTableWithEnum = 2;
+    const MyGame_Example2_Monster = 3;
+
+    private static $names = array(
+        Any::NONE=>"NONE",
+        Any::Monster=>"Monster",
+        Any::TestSimpleTableWithEnum=>"TestSimpleTableWithEnum",
+        Any::MyGame_Example2_Monster=>"MyGame_Example2_Monster",
+    );
+
+    public static function Name($e)
+    {
+        if (!isset(self::$names[$e])) {
+            throw new \Exception();
+        }
+        return self::$names[$e];
+    }
+}
diff --git a/tests/MyGame/Example/Any.py b/tests/MyGame/Example/Any.py
new file mode 100644
index 0000000..f1b8d51
--- /dev/null
+++ b/tests/MyGame/Example/Any.py
@@ -0,0 +1,10 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+class Any(object):
+    NONE = 0
+    Monster = 1
+    TestSimpleTableWithEnum = 2
+    MyGame_Example2_Monster = 3
+
diff --git a/tests/MyGame/Example/AnyAmbiguousAliases.cs b/tests/MyGame/Example/AnyAmbiguousAliases.cs
new file mode 100644
index 0000000..c727b88
--- /dev/null
+++ b/tests/MyGame/Example/AnyAmbiguousAliases.cs
@@ -0,0 +1,17 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+public enum AnyAmbiguousAliases : byte
+{
+  NONE = 0,
+  M1 = 1,
+  M2 = 2,
+  M3 = 3,
+};
+
+
+}
diff --git a/tests/MyGame/Example/AnyAmbiguousAliases.go b/tests/MyGame/Example/AnyAmbiguousAliases.go
new file mode 100644
index 0000000..b9c3793
--- /dev/null
+++ b/tests/MyGame/Example/AnyAmbiguousAliases.go
@@ -0,0 +1,35 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package Example
+
+import "strconv"
+
+type AnyAmbiguousAliases byte
+
+const (
+	AnyAmbiguousAliasesNONE AnyAmbiguousAliases = 0
+	AnyAmbiguousAliasesM1   AnyAmbiguousAliases = 1
+	AnyAmbiguousAliasesM2   AnyAmbiguousAliases = 2
+	AnyAmbiguousAliasesM3   AnyAmbiguousAliases = 3
+)
+
+var EnumNamesAnyAmbiguousAliases = map[AnyAmbiguousAliases]string{
+	AnyAmbiguousAliasesNONE: "NONE",
+	AnyAmbiguousAliasesM1:   "M1",
+	AnyAmbiguousAliasesM2:   "M2",
+	AnyAmbiguousAliasesM3:   "M3",
+}
+
+var EnumValuesAnyAmbiguousAliases = map[string]AnyAmbiguousAliases{
+	"NONE": AnyAmbiguousAliasesNONE,
+	"M1":   AnyAmbiguousAliasesM1,
+	"M2":   AnyAmbiguousAliasesM2,
+	"M3":   AnyAmbiguousAliasesM3,
+}
+
+func (v AnyAmbiguousAliases) String() string {
+	if s, ok := EnumNamesAnyAmbiguousAliases[v]; ok {
+		return s
+	}
+	return "AnyAmbiguousAliases(" + strconv.FormatInt(int64(v), 10) + ")"
+}
diff --git a/tests/MyGame/Example/AnyAmbiguousAliases.java b/tests/MyGame/Example/AnyAmbiguousAliases.java
new file mode 100644
index 0000000..b8a6870
--- /dev/null
+++ b/tests/MyGame/Example/AnyAmbiguousAliases.java
@@ -0,0 +1,16 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+public final class AnyAmbiguousAliases {
+  private AnyAmbiguousAliases() { }
+  public static final byte NONE = 0;
+  public static final byte M1 = 1;
+  public static final byte M2 = 2;
+  public static final byte M3 = 3;
+
+  public static final String[] names = { "NONE", "M1", "M2", "M3", };
+
+  public static String name(int e) { return names[e]; }
+}
+
diff --git a/tests/MyGame/Example/AnyAmbiguousAliases.kt b/tests/MyGame/Example/AnyAmbiguousAliases.kt
new file mode 100644
index 0000000..cee13c5
--- /dev/null
+++ b/tests/MyGame/Example/AnyAmbiguousAliases.kt
@@ -0,0 +1,16 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class AnyAmbiguousAliases private constructor() {
+    companion object {
+        const val NONE: UByte = 0u
+        const val M1: UByte = 1u
+        const val M2: UByte = 2u
+        const val M3: UByte = 3u
+        val names : Array<String> = arrayOf("NONE", "M1", "M2", "M3")
+        fun name(e: Int) : String = names[e]
+    }
+}
diff --git a/tests/MyGame/Example/AnyAmbiguousAliases.lua b/tests/MyGame/Example/AnyAmbiguousAliases.lua
new file mode 100644
index 0000000..dbe474b
--- /dev/null
+++ b/tests/MyGame/Example/AnyAmbiguousAliases.lua
@@ -0,0 +1,12 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Example
+
+local AnyAmbiguousAliases = {
+    NONE = 0,
+    M1 = 1,
+    M2 = 2,
+    M3 = 3,
+}
+
+return AnyAmbiguousAliases -- return the module
\ No newline at end of file
diff --git a/tests/MyGame/Example/AnyAmbiguousAliases.php b/tests/MyGame/Example/AnyAmbiguousAliases.php
new file mode 100644
index 0000000..13d318a
--- /dev/null
+++ b/tests/MyGame/Example/AnyAmbiguousAliases.php
@@ -0,0 +1,27 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace MyGame\Example;
+
+class AnyAmbiguousAliases
+{
+    const NONE = 0;
+    const M1 = 1;
+    const M2 = 2;
+    const M3 = 3;
+
+    private static $names = array(
+        AnyAmbiguousAliases::NONE=>"NONE",
+        AnyAmbiguousAliases::M1=>"M1",
+        AnyAmbiguousAliases::M2=>"M2",
+        AnyAmbiguousAliases::M3=>"M3",
+    );
+
+    public static function Name($e)
+    {
+        if (!isset(self::$names[$e])) {
+            throw new \Exception();
+        }
+        return self::$names[$e];
+    }
+}
diff --git a/tests/MyGame/Example/AnyAmbiguousAliases.py b/tests/MyGame/Example/AnyAmbiguousAliases.py
new file mode 100644
index 0000000..de6e9d0
--- /dev/null
+++ b/tests/MyGame/Example/AnyAmbiguousAliases.py
@@ -0,0 +1,10 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+class AnyAmbiguousAliases(object):
+    NONE = 0
+    M1 = 1
+    M2 = 2
+    M3 = 3
+
diff --git a/tests/MyGame/Example/AnyUniqueAliases.cs b/tests/MyGame/Example/AnyUniqueAliases.cs
new file mode 100644
index 0000000..42a3e0b
--- /dev/null
+++ b/tests/MyGame/Example/AnyUniqueAliases.cs
@@ -0,0 +1,17 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+public enum AnyUniqueAliases : byte
+{
+  NONE = 0,
+  M = 1,
+  TS = 2,
+  M2 = 3,
+};
+
+
+}
diff --git a/tests/MyGame/Example/AnyUniqueAliases.go b/tests/MyGame/Example/AnyUniqueAliases.go
new file mode 100644
index 0000000..23d8649
--- /dev/null
+++ b/tests/MyGame/Example/AnyUniqueAliases.go
@@ -0,0 +1,35 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package Example
+
+import "strconv"
+
+type AnyUniqueAliases byte
+
+const (
+	AnyUniqueAliasesNONE AnyUniqueAliases = 0
+	AnyUniqueAliasesM    AnyUniqueAliases = 1
+	AnyUniqueAliasesTS   AnyUniqueAliases = 2
+	AnyUniqueAliasesM2   AnyUniqueAliases = 3
+)
+
+var EnumNamesAnyUniqueAliases = map[AnyUniqueAliases]string{
+	AnyUniqueAliasesNONE: "NONE",
+	AnyUniqueAliasesM:    "M",
+	AnyUniqueAliasesTS:   "TS",
+	AnyUniqueAliasesM2:   "M2",
+}
+
+var EnumValuesAnyUniqueAliases = map[string]AnyUniqueAliases{
+	"NONE": AnyUniqueAliasesNONE,
+	"M":    AnyUniqueAliasesM,
+	"TS":   AnyUniqueAliasesTS,
+	"M2":   AnyUniqueAliasesM2,
+}
+
+func (v AnyUniqueAliases) String() string {
+	if s, ok := EnumNamesAnyUniqueAliases[v]; ok {
+		return s
+	}
+	return "AnyUniqueAliases(" + strconv.FormatInt(int64(v), 10) + ")"
+}
diff --git a/tests/MyGame/Example/AnyUniqueAliases.java b/tests/MyGame/Example/AnyUniqueAliases.java
new file mode 100644
index 0000000..1f32945
--- /dev/null
+++ b/tests/MyGame/Example/AnyUniqueAliases.java
@@ -0,0 +1,16 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+public final class AnyUniqueAliases {
+  private AnyUniqueAliases() { }
+  public static final byte NONE = 0;
+  public static final byte M = 1;
+  public static final byte TS = 2;
+  public static final byte M2 = 3;
+
+  public static final String[] names = { "NONE", "M", "TS", "M2", };
+
+  public static String name(int e) { return names[e]; }
+}
+
diff --git a/tests/MyGame/Example/AnyUniqueAliases.kt b/tests/MyGame/Example/AnyUniqueAliases.kt
new file mode 100644
index 0000000..1902d5d
--- /dev/null
+++ b/tests/MyGame/Example/AnyUniqueAliases.kt
@@ -0,0 +1,16 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class AnyUniqueAliases private constructor() {
+    companion object {
+        const val NONE: UByte = 0u
+        const val M: UByte = 1u
+        const val TS: UByte = 2u
+        const val M2: UByte = 3u
+        val names : Array<String> = arrayOf("NONE", "M", "TS", "M2")
+        fun name(e: Int) : String = names[e]
+    }
+}
diff --git a/tests/MyGame/Example/AnyUniqueAliases.lua b/tests/MyGame/Example/AnyUniqueAliases.lua
new file mode 100644
index 0000000..9bfeb80
--- /dev/null
+++ b/tests/MyGame/Example/AnyUniqueAliases.lua
@@ -0,0 +1,12 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Example
+
+local AnyUniqueAliases = {
+    NONE = 0,
+    M = 1,
+    TS = 2,
+    M2 = 3,
+}
+
+return AnyUniqueAliases -- return the module
\ No newline at end of file
diff --git a/tests/MyGame/Example/AnyUniqueAliases.php b/tests/MyGame/Example/AnyUniqueAliases.php
new file mode 100644
index 0000000..830d8b5
--- /dev/null
+++ b/tests/MyGame/Example/AnyUniqueAliases.php
@@ -0,0 +1,27 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace MyGame\Example;
+
+class AnyUniqueAliases
+{
+    const NONE = 0;
+    const M = 1;
+    const TS = 2;
+    const M2 = 3;
+
+    private static $names = array(
+        AnyUniqueAliases::NONE=>"NONE",
+        AnyUniqueAliases::M=>"M",
+        AnyUniqueAliases::TS=>"TS",
+        AnyUniqueAliases::M2=>"M2",
+    );
+
+    public static function Name($e)
+    {
+        if (!isset(self::$names[$e])) {
+            throw new \Exception();
+        }
+        return self::$names[$e];
+    }
+}
diff --git a/tests/MyGame/Example/AnyUniqueAliases.py b/tests/MyGame/Example/AnyUniqueAliases.py
new file mode 100644
index 0000000..a6da355
--- /dev/null
+++ b/tests/MyGame/Example/AnyUniqueAliases.py
@@ -0,0 +1,10 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+class AnyUniqueAliases(object):
+    NONE = 0
+    M = 1
+    TS = 2
+    M2 = 3
+
diff --git a/tests/MyGame/Example/ArrayStruct.cs b/tests/MyGame/Example/ArrayStruct.cs
new file mode 100644
index 0000000..28815e7
--- /dev/null
+++ b/tests/MyGame/Example/ArrayStruct.cs
@@ -0,0 +1,50 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct ArrayStruct : IFlatbufferObject
+{
+  private Struct __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
+  public ArrayStruct __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public float A { get { return __p.bb.GetFloat(__p.bb_pos + 0); } }
+  public void MutateA(float a) { __p.bb.PutFloat(__p.bb_pos + 0, a); }
+  public int B(int j) { return __p.bb.GetInt(__p.bb_pos + 4 + j * 4); }
+  public void MutateB(int j, int b) { __p.bb.PutInt(__p.bb_pos + 4 + j * 4, b); }
+  public sbyte C { get { return __p.bb.GetSbyte(__p.bb_pos + 64); } }
+  public void MutateC(sbyte c) { __p.bb.PutSbyte(__p.bb_pos + 64, c); }
+  public MyGame.Example.NestedStruct D(int j) { return (new MyGame.Example.NestedStruct()).__assign(__p.bb_pos + 68 + j * 12, __p.bb); }
+
+  public static Offset<MyGame.Example.ArrayStruct> CreateArrayStruct(FlatBufferBuilder builder, float A, int[] B, sbyte C, int[,] d_A, MyGame.Example.TestEnum[] d_B, MyGame.Example.TestEnum[,] d_C) {
+    builder.Prep(4, 92);
+    for (int _idx0 = 2; _idx0 > 0; _idx0--) {
+      builder.Prep(4, 12);
+      builder.Pad(1);
+      for (int _idx1 = 2; _idx1 > 0; _idx1--) {
+        builder.PutSbyte((sbyte)d_C[_idx0-1,_idx1-1]);
+      }
+      builder.PutSbyte((sbyte)d_B[_idx0-1]);
+      for (int _idx1 = 2; _idx1 > 0; _idx1--) {
+        builder.PutInt(d_A[_idx0-1,_idx1-1]);
+      }
+    }
+    builder.Pad(3);
+    builder.PutSbyte(C);
+    for (int _idx0 = 15; _idx0 > 0; _idx0--) {
+      builder.PutInt(B[_idx0-1]);
+    }
+    builder.PutFloat(A);
+    return new Offset<MyGame.Example.ArrayStruct>(builder.Offset);
+  }
+};
+
+
+}
diff --git a/tests/MyGame/Example/ArrayStruct.java b/tests/MyGame/Example/ArrayStruct.java
new file mode 100644
index 0000000..0098c55
--- /dev/null
+++ b/tests/MyGame/Example/ArrayStruct.java
@@ -0,0 +1,45 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class ArrayStruct extends Struct {
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public ArrayStruct __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public float a() { return bb.getFloat(bb_pos + 0); }
+  public void mutateA(float a) { bb.putFloat(bb_pos + 0, a); }
+  public int b(int j) { return bb.getInt(bb_pos + 4 + j * 4); }
+  public void mutateB(int j, int b) { bb.putInt(bb_pos + 4 + j * 4, b); }
+  public byte c() { return bb.get(bb_pos + 64); }
+  public void mutateC(byte c) { bb.put(bb_pos + 64, c); }
+  public MyGame.Example.NestedStruct d(MyGame.Example.NestedStruct obj, int j) { return obj.__assign(bb_pos + 68 + j * 12, bb); }
+
+  public static int createArrayStruct(FlatBufferBuilder builder, float a, int[] b, byte c, int[][] d_a, byte[] d_b, byte[][] d_c) {
+    builder.prep(4, 92);
+    for (int _idx0 = 2; _idx0 > 0; _idx0--) {
+      builder.prep(4, 12);
+      builder.pad(1);
+      for (int _idx1 = 2; _idx1 > 0; _idx1--) {
+        builder.putByte(d_c[_idx0-1][_idx1-1]);
+      }
+      builder.putByte(d_b[_idx0-1]);
+      for (int _idx1 = 2; _idx1 > 0; _idx1--) {
+        builder.putInt(d_a[_idx0-1][_idx1-1]);
+      }
+    }
+    builder.pad(3);
+    builder.putByte(c);
+    for (int _idx0 = 15; _idx0 > 0; _idx0--) {
+      builder.putInt(b[_idx0-1]);
+    }
+    builder.putFloat(a);
+    return builder.offset();
+  }
+}
+
diff --git a/tests/MyGame/Example/ArrayStruct.py b/tests/MyGame/Example/ArrayStruct.py
new file mode 100644
index 0000000..79dda31
--- /dev/null
+++ b/tests/MyGame/Example/ArrayStruct.py
@@ -0,0 +1,41 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+import flatbuffers
+
+class ArrayStruct(object):
+    __slots__ = ['_tab']
+
+    # ArrayStruct
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # ArrayStruct
+    def A(self): return self._tab.Get(flatbuffers.number_types.Float32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(0))
+    # ArrayStruct
+    def B(self): return [self._tab.Get(flatbuffers.number_types.Int32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(4 + i * 4)) for i in range(15)]
+    # ArrayStruct
+    def C(self): return self._tab.Get(flatbuffers.number_types.Int8Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(64))
+    # ArrayStruct
+    def D(self, obj, i):
+        obj.Init(self._tab.Bytes, self._tab.Pos + 68 + i * 12)
+        return obj
+
+
+def CreateArrayStruct(builder, a, b, c, d_a, d_b, d_c):
+    builder.Prep(4, 92)
+    for _idx0 in range(2 , 0, -1):
+        builder.Prep(4, 12)
+        builder.Pad(1)
+        for _idx1 in range(2 , 0, -1):
+            builder.PrependInt8(d_c[_idx0-1][_idx1-1])
+        builder.PrependInt8(d_b[_idx0-1])
+        for _idx1 in range(2 , 0, -1):
+            builder.PrependInt32(d_a[_idx0-1][_idx1-1])
+    builder.Pad(3)
+    builder.PrependInt8(c)
+    for _idx0 in range(15 , 0, -1):
+        builder.PrependInt32(b[_idx0-1])
+    builder.PrependFloat32(a)
+    return builder.Offset()
diff --git a/tests/MyGame/Example/ArrayTable.cs b/tests/MyGame/Example/ArrayTable.cs
new file mode 100644
index 0000000..e303211
--- /dev/null
+++ b/tests/MyGame/Example/ArrayTable.cs
@@ -0,0 +1,35 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct ArrayTable : IFlatbufferObject
+{
+  private Table __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_11_1(); }
+  public static ArrayTable GetRootAsArrayTable(ByteBuffer _bb) { return GetRootAsArrayTable(_bb, new ArrayTable()); }
+  public static ArrayTable GetRootAsArrayTable(ByteBuffer _bb, ArrayTable obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public static bool ArrayTableBufferHasIdentifier(ByteBuffer _bb) { return Table.__has_identifier(_bb, "ARRT"); }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+  public ArrayTable __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public MyGame.Example.ArrayStruct? A { get { int o = __p.__offset(4); return o != 0 ? (MyGame.Example.ArrayStruct?)(new MyGame.Example.ArrayStruct()).__assign(o + __p.bb_pos, __p.bb) : null; } }
+
+  public static void StartArrayTable(FlatBufferBuilder builder) { builder.StartTable(1); }
+  public static void AddA(FlatBufferBuilder builder, Offset<MyGame.Example.ArrayStruct> aOffset) { builder.AddStruct(0, aOffset.Value, 0); }
+  public static Offset<MyGame.Example.ArrayTable> EndArrayTable(FlatBufferBuilder builder) {
+    int o = builder.EndTable();
+    return new Offset<MyGame.Example.ArrayTable>(o);
+  }
+  public static void FinishArrayTableBuffer(FlatBufferBuilder builder, Offset<MyGame.Example.ArrayTable> offset) { builder.Finish(offset.Value, "ARRT"); }
+  public static void FinishSizePrefixedArrayTableBuffer(FlatBufferBuilder builder, Offset<MyGame.Example.ArrayTable> offset) { builder.FinishSizePrefixed(offset.Value, "ARRT"); }
+};
+
+
+}
diff --git a/tests/MyGame/Example/ArrayTable.java b/tests/MyGame/Example/ArrayTable.java
new file mode 100644
index 0000000..74ce86a
--- /dev/null
+++ b/tests/MyGame/Example/ArrayTable.java
@@ -0,0 +1,31 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class ArrayTable extends Table {
+  public static void ValidateVersion() { Constants.FLATBUFFERS_1_11_1(); }
+  public static ArrayTable getRootAsArrayTable(ByteBuffer _bb) { return getRootAsArrayTable(_bb, new ArrayTable()); }
+  public static ArrayTable getRootAsArrayTable(ByteBuffer _bb, ArrayTable obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public static boolean ArrayTableBufferHasIdentifier(ByteBuffer _bb) { return __has_identifier(_bb, "ARRT"); }
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public ArrayTable __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public MyGame.Example.ArrayStruct a() { return a(new MyGame.Example.ArrayStruct()); }
+  public MyGame.Example.ArrayStruct a(MyGame.Example.ArrayStruct obj) { int o = __offset(4); return o != 0 ? obj.__assign(o + bb_pos, bb) : null; }
+
+  public static void startArrayTable(FlatBufferBuilder builder) { builder.startTable(1); }
+  public static void addA(FlatBufferBuilder builder, int aOffset) { builder.addStruct(0, aOffset, 0); }
+  public static int endArrayTable(FlatBufferBuilder builder) {
+    int o = builder.endTable();
+    return o;
+  }
+  public static void finishArrayTableBuffer(FlatBufferBuilder builder, int offset) { builder.finish(offset, "ARRT"); }
+  public static void finishSizePrefixedArrayTableBuffer(FlatBufferBuilder builder, int offset) { builder.finishSizePrefixed(offset, "ARRT"); }
+}
+
diff --git a/tests/MyGame/Example/ArrayTable.py b/tests/MyGame/Example/ArrayTable.py
new file mode 100644
index 0000000..6d583f9
--- /dev/null
+++ b/tests/MyGame/Example/ArrayTable.py
@@ -0,0 +1,38 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+import flatbuffers
+
+class ArrayTable(object):
+    __slots__ = ['_tab']
+
+    @classmethod
+    def GetRootAsArrayTable(cls, buf, offset):
+        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
+        x = ArrayTable()
+        x.Init(buf, n + offset)
+        return x
+
+    @classmethod
+    def ArrayTableBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
+        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x41\x52\x52\x54", size_prefixed=size_prefixed)
+
+    # ArrayTable
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # ArrayTable
+    def A(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+        if o != 0:
+            x = o + self._tab.Pos
+            from .ArrayStruct import ArrayStruct
+            obj = ArrayStruct()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+def ArrayTableStart(builder): builder.StartObject(1)
+def ArrayTableAddA(builder, a): builder.PrependStructSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(a), 0)
+def ArrayTableEnd(builder): return builder.EndObject()
diff --git a/tests/MyGame/Example/Color.cs b/tests/MyGame/Example/Color.cs
new file mode 100644
index 0000000..5981cf8
--- /dev/null
+++ b/tests/MyGame/Example/Color.cs
@@ -0,0 +1,21 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+/// Composite components of Monster color.
+[System.FlagsAttribute]
+public enum Color : byte
+{
+  Red = 1,
+  /// \brief color Green
+  /// Green is bit_flag with value (1u << 1)
+  Green = 2,
+  /// \brief color Blue (1u << 3)
+  Blue = 8,
+};
+
+
+}
diff --git a/tests/MyGame/Example/Color.go b/tests/MyGame/Example/Color.go
new file mode 100644
index 0000000..9570ae4
--- /dev/null
+++ b/tests/MyGame/Example/Color.go
@@ -0,0 +1,36 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package Example
+
+import "strconv"
+
+/// Composite components of Monster color.
+type Color byte
+
+const (
+	ColorRed   Color = 1
+	/// \brief color Green
+	/// Green is bit_flag with value (1u << 1)
+	ColorGreen Color = 2
+	/// \brief color Blue (1u << 3)
+	ColorBlue  Color = 8
+)
+
+var EnumNamesColor = map[Color]string{
+	ColorRed:   "Red",
+	ColorGreen: "Green",
+	ColorBlue:  "Blue",
+}
+
+var EnumValuesColor = map[string]Color{
+	"Red":   ColorRed,
+	"Green": ColorGreen,
+	"Blue":  ColorBlue,
+}
+
+func (v Color) String() string {
+	if s, ok := EnumNamesColor[v]; ok {
+		return s
+	}
+	return "Color(" + strconv.FormatInt(int64(v), 10) + ")"
+}
diff --git a/tests/MyGame/Example/Color.java b/tests/MyGame/Example/Color.java
new file mode 100644
index 0000000..0563c0a
--- /dev/null
+++ b/tests/MyGame/Example/Color.java
@@ -0,0 +1,25 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+/**
+ * Composite components of Monster color.
+ */
+public final class Color {
+  private Color() { }
+  public static final byte Red = 1;
+  /**
+   * \brief color Green
+   * Green is bit_flag with value (1u << 1)
+   */
+  public static final byte Green = 2;
+  /**
+   * \brief color Blue (1u << 3)
+   */
+  public static final byte Blue = 8;
+
+  public static final String[] names = { "Red", "Green", "", "", "", "", "", "Blue", };
+
+  public static String name(int e) { return names[e - Red]; }
+}
+
diff --git a/tests/MyGame/Example/Color.kt b/tests/MyGame/Example/Color.kt
new file mode 100644
index 0000000..4c27ba3
--- /dev/null
+++ b/tests/MyGame/Example/Color.kt
@@ -0,0 +1,25 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+/**
+ * Composite components of Monster color.
+ */
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Color private constructor() {
+    companion object {
+        const val Red: UByte = 1u
+        /**
+         * \brief color Green
+         * Green is bit_flag with value (1u << 1)
+         */
+        const val Green: UByte = 2u
+        /**
+         * \brief color Blue (1u << 3)
+         */
+        const val Blue: UByte = 8u
+        val names : Array<String> = arrayOf("Red", "Green", "", "", "", "", "", "Blue")
+        fun name(e: Int) : String = names[e - Red.toInt()]
+    }
+}
diff --git a/tests/MyGame/Example/Color.lua b/tests/MyGame/Example/Color.lua
new file mode 100644
index 0000000..d4d2cbc
--- /dev/null
+++ b/tests/MyGame/Example/Color.lua
@@ -0,0 +1,15 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Example
+
+-- Composite components of Monster color.
+local Color = {
+    Red = 1,
+    -- \brief color Green
+    -- Green is bit_flag with value (1u << 1)
+    Green = 2,
+    -- \brief color Blue (1u << 3)
+    Blue = 8,
+}
+
+return Color -- return the module
\ No newline at end of file
diff --git a/tests/MyGame/Example/Color.php b/tests/MyGame/Example/Color.php
new file mode 100644
index 0000000..8c32922
--- /dev/null
+++ b/tests/MyGame/Example/Color.php
@@ -0,0 +1,29 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace MyGame\Example;
+
+/// Composite components of Monster color.
+class Color
+{
+    const Red = 1;
+    /// \brief color Green
+    /// Green is bit_flag with value (1u << 1)
+    const Green = 2;
+    /// \brief color Blue (1u << 3)
+    const Blue = 8;
+
+    private static $names = array(
+        Color::Red=>"Red",
+        Color::Green=>"Green",
+        Color::Blue=>"Blue",
+    );
+
+    public static function Name($e)
+    {
+        if (!isset(self::$names[$e])) {
+            throw new \Exception();
+        }
+        return self::$names[$e];
+    }
+}
diff --git a/tests/MyGame/Example/Color.py b/tests/MyGame/Example/Color.py
new file mode 100644
index 0000000..55aa821
--- /dev/null
+++ b/tests/MyGame/Example/Color.py
@@ -0,0 +1,13 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+# Composite components of Monster color.
+class Color(object):
+    Red = 1
+    # \brief color Green
+    # Green is bit_flag with value (1u << 1)
+    Green = 2
+    # \brief color Blue (1u << 3)
+    Blue = 8
+
diff --git a/tests/MyGame/Example/Monster.cs b/tests/MyGame/Example/Monster.cs
new file mode 100644
index 0000000..5dc669e
--- /dev/null
+++ b/tests/MyGame/Example/Monster.cs
@@ -0,0 +1,324 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+using global::System;
+using global::FlatBuffers;
+
+/// an example documentation comment: monster object
+public struct Monster : IFlatbufferObject
+{
+  private Table __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_11_1(); }
+  public static Monster GetRootAsMonster(ByteBuffer _bb) { return GetRootAsMonster(_bb, new Monster()); }
+  public static Monster GetRootAsMonster(ByteBuffer _bb, Monster obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public static bool MonsterBufferHasIdentifier(ByteBuffer _bb) { return Table.__has_identifier(_bb, "MONS"); }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+  public Monster __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public MyGame.Example.Vec3? Pos { get { int o = __p.__offset(4); return o != 0 ? (MyGame.Example.Vec3?)(new MyGame.Example.Vec3()).__assign(o + __p.bb_pos, __p.bb) : null; } }
+  public short Mana { get { int o = __p.__offset(6); return o != 0 ? __p.bb.GetShort(o + __p.bb_pos) : (short)150; } }
+  public bool MutateMana(short mana) { int o = __p.__offset(6); if (o != 0) { __p.bb.PutShort(o + __p.bb_pos, mana); return true; } else { return false; } }
+  public short Hp { get { int o = __p.__offset(8); return o != 0 ? __p.bb.GetShort(o + __p.bb_pos) : (short)100; } }
+  public bool MutateHp(short hp) { int o = __p.__offset(8); if (o != 0) { __p.bb.PutShort(o + __p.bb_pos, hp); return true; } else { return false; } }
+  public string Name { get { int o = __p.__offset(10); return o != 0 ? __p.__string(o + __p.bb_pos) : null; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetNameBytes() { return __p.__vector_as_span(10); }
+#else
+  public ArraySegment<byte>? GetNameBytes() { return __p.__vector_as_arraysegment(10); }
+#endif
+  public byte[] GetNameArray() { return __p.__vector_as_array<byte>(10); }
+  public byte Inventory(int j) { int o = __p.__offset(14); return o != 0 ? __p.bb.Get(__p.__vector(o) + j * 1) : (byte)0; }
+  public int InventoryLength { get { int o = __p.__offset(14); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetInventoryBytes() { return __p.__vector_as_span(14); }
+#else
+  public ArraySegment<byte>? GetInventoryBytes() { return __p.__vector_as_arraysegment(14); }
+#endif
+  public byte[] GetInventoryArray() { return __p.__vector_as_array<byte>(14); }
+  public bool MutateInventory(int j, byte inventory) { int o = __p.__offset(14); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, inventory); return true; } else { return false; } }
+  public MyGame.Example.Color Color { get { int o = __p.__offset(16); return o != 0 ? (MyGame.Example.Color)__p.bb.Get(o + __p.bb_pos) : MyGame.Example.Color.Blue; } }
+  public bool MutateColor(MyGame.Example.Color color) { int o = __p.__offset(16); if (o != 0) { __p.bb.Put(o + __p.bb_pos, (byte)color); return true; } else { return false; } }
+  public MyGame.Example.Any TestType { get { int o = __p.__offset(18); return o != 0 ? (MyGame.Example.Any)__p.bb.Get(o + __p.bb_pos) : MyGame.Example.Any.NONE; } }
+  public bool MutateTestType(MyGame.Example.Any test_type) { int o = __p.__offset(18); if (o != 0) { __p.bb.Put(o + __p.bb_pos, (byte)test_type); return true; } else { return false; } }
+  public TTable? Test<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(20); return o != 0 ? (TTable?)__p.__union<TTable>(o) : null; }
+  public MyGame.Example.Test? Test4(int j) { int o = __p.__offset(22); return o != 0 ? (MyGame.Example.Test?)(new MyGame.Example.Test()).__assign(__p.__vector(o) + j * 4, __p.bb) : null; }
+  public int Test4Length { get { int o = __p.__offset(22); return o != 0 ? __p.__vector_len(o) : 0; } }
+  public string Testarrayofstring(int j) { int o = __p.__offset(24); return o != 0 ? __p.__string(__p.__vector(o) + j * 4) : null; }
+  public int TestarrayofstringLength { get { int o = __p.__offset(24); return o != 0 ? __p.__vector_len(o) : 0; } }
+  /// an example documentation comment: this will end up in the generated code
+  /// multiline too
+  public MyGame.Example.Monster? Testarrayoftables(int j) { int o = __p.__offset(26); return o != 0 ? (MyGame.Example.Monster?)(new MyGame.Example.Monster()).__assign(__p.__indirect(__p.__vector(o) + j * 4), __p.bb) : null; }
+  public int TestarrayoftablesLength { get { int o = __p.__offset(26); return o != 0 ? __p.__vector_len(o) : 0; } }
+  public MyGame.Example.Monster? TestarrayoftablesByKey(string key) { int o = __p.__offset(26); return o != 0 ? MyGame.Example.Monster.__lookup_by_key(__p.__vector(o), key, __p.bb) : null; }
+  public MyGame.Example.Monster? Enemy { get { int o = __p.__offset(28); return o != 0 ? (MyGame.Example.Monster?)(new MyGame.Example.Monster()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
+  public byte Testnestedflatbuffer(int j) { int o = __p.__offset(30); return o != 0 ? __p.bb.Get(__p.__vector(o) + j * 1) : (byte)0; }
+  public int TestnestedflatbufferLength { get { int o = __p.__offset(30); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetTestnestedflatbufferBytes() { return __p.__vector_as_span(30); }
+#else
+  public ArraySegment<byte>? GetTestnestedflatbufferBytes() { return __p.__vector_as_arraysegment(30); }
+#endif
+  public byte[] GetTestnestedflatbufferArray() { return __p.__vector_as_array<byte>(30); }
+  public MyGame.Example.Monster? GetTestnestedflatbufferAsMonster() { int o = __p.__offset(30); return o != 0 ? (MyGame.Example.Monster?)(new MyGame.Example.Monster()).__assign(__p.__indirect(__p.__vector(o)), __p.bb) : null; }
+  public bool MutateTestnestedflatbuffer(int j, byte testnestedflatbuffer) { int o = __p.__offset(30); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, testnestedflatbuffer); return true; } else { return false; } }
+  public MyGame.Example.Stat? Testempty { get { int o = __p.__offset(32); return o != 0 ? (MyGame.Example.Stat?)(new MyGame.Example.Stat()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
+  public bool Testbool { get { int o = __p.__offset(34); return o != 0 ? 0!=__p.bb.Get(o + __p.bb_pos) : (bool)false; } }
+  public bool MutateTestbool(bool testbool) { int o = __p.__offset(34); if (o != 0) { __p.bb.Put(o + __p.bb_pos, (byte)(testbool ? 1 : 0)); return true; } else { return false; } }
+  public int Testhashs32Fnv1 { get { int o = __p.__offset(36); return o != 0 ? __p.bb.GetInt(o + __p.bb_pos) : (int)0; } }
+  public bool MutateTesthashs32Fnv1(int testhashs32_fnv1) { int o = __p.__offset(36); if (o != 0) { __p.bb.PutInt(o + __p.bb_pos, testhashs32_fnv1); return true; } else { return false; } }
+  public uint Testhashu32Fnv1 { get { int o = __p.__offset(38); return o != 0 ? __p.bb.GetUint(o + __p.bb_pos) : (uint)0; } }
+  public bool MutateTesthashu32Fnv1(uint testhashu32_fnv1) { int o = __p.__offset(38); if (o != 0) { __p.bb.PutUint(o + __p.bb_pos, testhashu32_fnv1); return true; } else { return false; } }
+  public long Testhashs64Fnv1 { get { int o = __p.__offset(40); return o != 0 ? __p.bb.GetLong(o + __p.bb_pos) : (long)0; } }
+  public bool MutateTesthashs64Fnv1(long testhashs64_fnv1) { int o = __p.__offset(40); if (o != 0) { __p.bb.PutLong(o + __p.bb_pos, testhashs64_fnv1); return true; } else { return false; } }
+  public ulong Testhashu64Fnv1 { get { int o = __p.__offset(42); return o != 0 ? __p.bb.GetUlong(o + __p.bb_pos) : (ulong)0; } }
+  public bool MutateTesthashu64Fnv1(ulong testhashu64_fnv1) { int o = __p.__offset(42); if (o != 0) { __p.bb.PutUlong(o + __p.bb_pos, testhashu64_fnv1); return true; } else { return false; } }
+  public int Testhashs32Fnv1a { get { int o = __p.__offset(44); return o != 0 ? __p.bb.GetInt(o + __p.bb_pos) : (int)0; } }
+  public bool MutateTesthashs32Fnv1a(int testhashs32_fnv1a) { int o = __p.__offset(44); if (o != 0) { __p.bb.PutInt(o + __p.bb_pos, testhashs32_fnv1a); return true; } else { return false; } }
+  public uint Testhashu32Fnv1a { get { int o = __p.__offset(46); return o != 0 ? __p.bb.GetUint(o + __p.bb_pos) : (uint)0; } }
+  public bool MutateTesthashu32Fnv1a(uint testhashu32_fnv1a) { int o = __p.__offset(46); if (o != 0) { __p.bb.PutUint(o + __p.bb_pos, testhashu32_fnv1a); return true; } else { return false; } }
+  public long Testhashs64Fnv1a { get { int o = __p.__offset(48); return o != 0 ? __p.bb.GetLong(o + __p.bb_pos) : (long)0; } }
+  public bool MutateTesthashs64Fnv1a(long testhashs64_fnv1a) { int o = __p.__offset(48); if (o != 0) { __p.bb.PutLong(o + __p.bb_pos, testhashs64_fnv1a); return true; } else { return false; } }
+  public ulong Testhashu64Fnv1a { get { int o = __p.__offset(50); return o != 0 ? __p.bb.GetUlong(o + __p.bb_pos) : (ulong)0; } }
+  public bool MutateTesthashu64Fnv1a(ulong testhashu64_fnv1a) { int o = __p.__offset(50); if (o != 0) { __p.bb.PutUlong(o + __p.bb_pos, testhashu64_fnv1a); return true; } else { return false; } }
+  public bool Testarrayofbools(int j) { int o = __p.__offset(52); return o != 0 ? 0!=__p.bb.Get(__p.__vector(o) + j * 1) : false; }
+  public int TestarrayofboolsLength { get { int o = __p.__offset(52); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetTestarrayofboolsBytes() { return __p.__vector_as_span(52); }
+#else
+  public ArraySegment<byte>? GetTestarrayofboolsBytes() { return __p.__vector_as_arraysegment(52); }
+#endif
+  public bool[] GetTestarrayofboolsArray() { return __p.__vector_as_array<bool>(52); }
+  public bool MutateTestarrayofbools(int j, bool testarrayofbools) { int o = __p.__offset(52); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, (byte)(testarrayofbools ? 1 : 0)); return true; } else { return false; } }
+  public float Testf { get { int o = __p.__offset(54); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)3.14159f; } }
+  public bool MutateTestf(float testf) { int o = __p.__offset(54); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, testf); return true; } else { return false; } }
+  public float Testf2 { get { int o = __p.__offset(56); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)3.0f; } }
+  public bool MutateTestf2(float testf2) { int o = __p.__offset(56); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, testf2); return true; } else { return false; } }
+  public float Testf3 { get { int o = __p.__offset(58); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)0.0f; } }
+  public bool MutateTestf3(float testf3) { int o = __p.__offset(58); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, testf3); return true; } else { return false; } }
+  public string Testarrayofstring2(int j) { int o = __p.__offset(60); return o != 0 ? __p.__string(__p.__vector(o) + j * 4) : null; }
+  public int Testarrayofstring2Length { get { int o = __p.__offset(60); return o != 0 ? __p.__vector_len(o) : 0; } }
+  public MyGame.Example.Ability? Testarrayofsortedstruct(int j) { int o = __p.__offset(62); return o != 0 ? (MyGame.Example.Ability?)(new MyGame.Example.Ability()).__assign(__p.__vector(o) + j * 8, __p.bb) : null; }
+  public int TestarrayofsortedstructLength { get { int o = __p.__offset(62); return o != 0 ? __p.__vector_len(o) : 0; } }
+  public byte Flex(int j) { int o = __p.__offset(64); return o != 0 ? __p.bb.Get(__p.__vector(o) + j * 1) : (byte)0; }
+  public int FlexLength { get { int o = __p.__offset(64); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetFlexBytes() { return __p.__vector_as_span(64); }
+#else
+  public ArraySegment<byte>? GetFlexBytes() { return __p.__vector_as_arraysegment(64); }
+#endif
+  public byte[] GetFlexArray() { return __p.__vector_as_array<byte>(64); }
+  public bool MutateFlex(int j, byte flex) { int o = __p.__offset(64); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, flex); return true; } else { return false; } }
+  public MyGame.Example.Test? Test5(int j) { int o = __p.__offset(66); return o != 0 ? (MyGame.Example.Test?)(new MyGame.Example.Test()).__assign(__p.__vector(o) + j * 4, __p.bb) : null; }
+  public int Test5Length { get { int o = __p.__offset(66); return o != 0 ? __p.__vector_len(o) : 0; } }
+  public long VectorOfLongs(int j) { int o = __p.__offset(68); return o != 0 ? __p.bb.GetLong(__p.__vector(o) + j * 8) : (long)0; }
+  public int VectorOfLongsLength { get { int o = __p.__offset(68); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetVectorOfLongsBytes() { return __p.__vector_as_span(68); }
+#else
+  public ArraySegment<byte>? GetVectorOfLongsBytes() { return __p.__vector_as_arraysegment(68); }
+#endif
+  public long[] GetVectorOfLongsArray() { return __p.__vector_as_array<long>(68); }
+  public bool MutateVectorOfLongs(int j, long vector_of_longs) { int o = __p.__offset(68); if (o != 0) { __p.bb.PutLong(__p.__vector(o) + j * 8, vector_of_longs); return true; } else { return false; } }
+  public double VectorOfDoubles(int j) { int o = __p.__offset(70); return o != 0 ? __p.bb.GetDouble(__p.__vector(o) + j * 8) : (double)0; }
+  public int VectorOfDoublesLength { get { int o = __p.__offset(70); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetVectorOfDoublesBytes() { return __p.__vector_as_span(70); }
+#else
+  public ArraySegment<byte>? GetVectorOfDoublesBytes() { return __p.__vector_as_arraysegment(70); }
+#endif
+  public double[] GetVectorOfDoublesArray() { return __p.__vector_as_array<double>(70); }
+  public bool MutateVectorOfDoubles(int j, double vector_of_doubles) { int o = __p.__offset(70); if (o != 0) { __p.bb.PutDouble(__p.__vector(o) + j * 8, vector_of_doubles); return true; } else { return false; } }
+  public MyGame.InParentNamespace? ParentNamespaceTest { get { int o = __p.__offset(72); return o != 0 ? (MyGame.InParentNamespace?)(new MyGame.InParentNamespace()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
+  public MyGame.Example.Referrable? VectorOfReferrables(int j) { int o = __p.__offset(74); return o != 0 ? (MyGame.Example.Referrable?)(new MyGame.Example.Referrable()).__assign(__p.__indirect(__p.__vector(o) + j * 4), __p.bb) : null; }
+  public int VectorOfReferrablesLength { get { int o = __p.__offset(74); return o != 0 ? __p.__vector_len(o) : 0; } }
+  public MyGame.Example.Referrable? VectorOfReferrablesByKey(ulong key) { int o = __p.__offset(74); return o != 0 ? MyGame.Example.Referrable.__lookup_by_key(__p.__vector(o), key, __p.bb) : null; }
+  public ulong SingleWeakReference { get { int o = __p.__offset(76); return o != 0 ? __p.bb.GetUlong(o + __p.bb_pos) : (ulong)0; } }
+  public bool MutateSingleWeakReference(ulong single_weak_reference) { int o = __p.__offset(76); if (o != 0) { __p.bb.PutUlong(o + __p.bb_pos, single_weak_reference); return true; } else { return false; } }
+  public ulong VectorOfWeakReferences(int j) { int o = __p.__offset(78); return o != 0 ? __p.bb.GetUlong(__p.__vector(o) + j * 8) : (ulong)0; }
+  public int VectorOfWeakReferencesLength { get { int o = __p.__offset(78); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetVectorOfWeakReferencesBytes() { return __p.__vector_as_span(78); }
+#else
+  public ArraySegment<byte>? GetVectorOfWeakReferencesBytes() { return __p.__vector_as_arraysegment(78); }
+#endif
+  public ulong[] GetVectorOfWeakReferencesArray() { return __p.__vector_as_array<ulong>(78); }
+  public bool MutateVectorOfWeakReferences(int j, ulong vector_of_weak_references) { int o = __p.__offset(78); if (o != 0) { __p.bb.PutUlong(__p.__vector(o) + j * 8, vector_of_weak_references); return true; } else { return false; } }
+  public MyGame.Example.Referrable? VectorOfStrongReferrables(int j) { int o = __p.__offset(80); return o != 0 ? (MyGame.Example.Referrable?)(new MyGame.Example.Referrable()).__assign(__p.__indirect(__p.__vector(o) + j * 4), __p.bb) : null; }
+  public int VectorOfStrongReferrablesLength { get { int o = __p.__offset(80); return o != 0 ? __p.__vector_len(o) : 0; } }
+  public MyGame.Example.Referrable? VectorOfStrongReferrablesByKey(ulong key) { int o = __p.__offset(80); return o != 0 ? MyGame.Example.Referrable.__lookup_by_key(__p.__vector(o), key, __p.bb) : null; }
+  public ulong CoOwningReference { get { int o = __p.__offset(82); return o != 0 ? __p.bb.GetUlong(o + __p.bb_pos) : (ulong)0; } }
+  public bool MutateCoOwningReference(ulong co_owning_reference) { int o = __p.__offset(82); if (o != 0) { __p.bb.PutUlong(o + __p.bb_pos, co_owning_reference); return true; } else { return false; } }
+  public ulong VectorOfCoOwningReferences(int j) { int o = __p.__offset(84); return o != 0 ? __p.bb.GetUlong(__p.__vector(o) + j * 8) : (ulong)0; }
+  public int VectorOfCoOwningReferencesLength { get { int o = __p.__offset(84); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetVectorOfCoOwningReferencesBytes() { return __p.__vector_as_span(84); }
+#else
+  public ArraySegment<byte>? GetVectorOfCoOwningReferencesBytes() { return __p.__vector_as_arraysegment(84); }
+#endif
+  public ulong[] GetVectorOfCoOwningReferencesArray() { return __p.__vector_as_array<ulong>(84); }
+  public bool MutateVectorOfCoOwningReferences(int j, ulong vector_of_co_owning_references) { int o = __p.__offset(84); if (o != 0) { __p.bb.PutUlong(__p.__vector(o) + j * 8, vector_of_co_owning_references); return true; } else { return false; } }
+  public ulong NonOwningReference { get { int o = __p.__offset(86); return o != 0 ? __p.bb.GetUlong(o + __p.bb_pos) : (ulong)0; } }
+  public bool MutateNonOwningReference(ulong non_owning_reference) { int o = __p.__offset(86); if (o != 0) { __p.bb.PutUlong(o + __p.bb_pos, non_owning_reference); return true; } else { return false; } }
+  public ulong VectorOfNonOwningReferences(int j) { int o = __p.__offset(88); return o != 0 ? __p.bb.GetUlong(__p.__vector(o) + j * 8) : (ulong)0; }
+  public int VectorOfNonOwningReferencesLength { get { int o = __p.__offset(88); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetVectorOfNonOwningReferencesBytes() { return __p.__vector_as_span(88); }
+#else
+  public ArraySegment<byte>? GetVectorOfNonOwningReferencesBytes() { return __p.__vector_as_arraysegment(88); }
+#endif
+  public ulong[] GetVectorOfNonOwningReferencesArray() { return __p.__vector_as_array<ulong>(88); }
+  public bool MutateVectorOfNonOwningReferences(int j, ulong vector_of_non_owning_references) { int o = __p.__offset(88); if (o != 0) { __p.bb.PutUlong(__p.__vector(o) + j * 8, vector_of_non_owning_references); return true; } else { return false; } }
+  public MyGame.Example.AnyUniqueAliases AnyUniqueType { get { int o = __p.__offset(90); return o != 0 ? (MyGame.Example.AnyUniqueAliases)__p.bb.Get(o + __p.bb_pos) : MyGame.Example.AnyUniqueAliases.NONE; } }
+  public bool MutateAnyUniqueType(MyGame.Example.AnyUniqueAliases any_unique_type) { int o = __p.__offset(90); if (o != 0) { __p.bb.Put(o + __p.bb_pos, (byte)any_unique_type); return true; } else { return false; } }
+  public TTable? AnyUnique<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(92); return o != 0 ? (TTable?)__p.__union<TTable>(o) : null; }
+  public MyGame.Example.AnyAmbiguousAliases AnyAmbiguousType { get { int o = __p.__offset(94); return o != 0 ? (MyGame.Example.AnyAmbiguousAliases)__p.bb.Get(o + __p.bb_pos) : MyGame.Example.AnyAmbiguousAliases.NONE; } }
+  public bool MutateAnyAmbiguousType(MyGame.Example.AnyAmbiguousAliases any_ambiguous_type) { int o = __p.__offset(94); if (o != 0) { __p.bb.Put(o + __p.bb_pos, (byte)any_ambiguous_type); return true; } else { return false; } }
+  public TTable? AnyAmbiguous<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(96); return o != 0 ? (TTable?)__p.__union<TTable>(o) : null; }
+  public MyGame.Example.Color VectorOfEnums(int j) { int o = __p.__offset(98); return o != 0 ? (MyGame.Example.Color)__p.bb.Get(__p.__vector(o) + j * 1) : (MyGame.Example.Color)0; }
+  public int VectorOfEnumsLength { get { int o = __p.__offset(98); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetVectorOfEnumsBytes() { return __p.__vector_as_span(98); }
+#else
+  public ArraySegment<byte>? GetVectorOfEnumsBytes() { return __p.__vector_as_arraysegment(98); }
+#endif
+  public MyGame.Example.Color[] GetVectorOfEnumsArray() { return __p.__vector_as_array<MyGame.Example.Color>(98); }
+  public bool MutateVectorOfEnums(int j, MyGame.Example.Color vector_of_enums) { int o = __p.__offset(98); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, (byte)vector_of_enums); return true; } else { return false; } }
+
+  public static void StartMonster(FlatBufferBuilder builder) { builder.StartTable(48); }
+  public static void AddPos(FlatBufferBuilder builder, Offset<MyGame.Example.Vec3> posOffset) { builder.AddStruct(0, posOffset.Value, 0); }
+  public static void AddMana(FlatBufferBuilder builder, short mana) { builder.AddShort(1, mana, 150); }
+  public static void AddHp(FlatBufferBuilder builder, short hp) { builder.AddShort(2, hp, 100); }
+  public static void AddName(FlatBufferBuilder builder, StringOffset nameOffset) { builder.AddOffset(3, nameOffset.Value, 0); }
+  public static void AddInventory(FlatBufferBuilder builder, VectorOffset inventoryOffset) { builder.AddOffset(5, inventoryOffset.Value, 0); }
+  public static VectorOffset CreateInventoryVector(FlatBufferBuilder builder, byte[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddByte(data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateInventoryVectorBlock(FlatBufferBuilder builder, byte[] data) { builder.StartVector(1, data.Length, 1); builder.Add(data); return builder.EndVector(); }
+  public static void StartInventoryVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); }
+  public static void AddColor(FlatBufferBuilder builder, MyGame.Example.Color color) { builder.AddByte(6, (byte)color, 8); }
+  public static void AddTestType(FlatBufferBuilder builder, MyGame.Example.Any testType) { builder.AddByte(7, (byte)testType, 0); }
+  public static void AddTest(FlatBufferBuilder builder, int testOffset) { builder.AddOffset(8, testOffset, 0); }
+  public static void AddTest4(FlatBufferBuilder builder, VectorOffset test4Offset) { builder.AddOffset(9, test4Offset.Value, 0); }
+  public static void StartTest4Vector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 2); }
+  public static void AddTestarrayofstring(FlatBufferBuilder builder, VectorOffset testarrayofstringOffset) { builder.AddOffset(10, testarrayofstringOffset.Value, 0); }
+  public static VectorOffset CreateTestarrayofstringVector(FlatBufferBuilder builder, StringOffset[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
+  public static VectorOffset CreateTestarrayofstringVectorBlock(FlatBufferBuilder builder, StringOffset[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
+  public static void StartTestarrayofstringVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
+  public static void AddTestarrayoftables(FlatBufferBuilder builder, VectorOffset testarrayoftablesOffset) { builder.AddOffset(11, testarrayoftablesOffset.Value, 0); }
+  public static VectorOffset CreateTestarrayoftablesVector(FlatBufferBuilder builder, Offset<MyGame.Example.Monster>[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
+  public static VectorOffset CreateTestarrayoftablesVectorBlock(FlatBufferBuilder builder, Offset<MyGame.Example.Monster>[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
+  public static void StartTestarrayoftablesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
+  public static void AddEnemy(FlatBufferBuilder builder, Offset<MyGame.Example.Monster> enemyOffset) { builder.AddOffset(12, enemyOffset.Value, 0); }
+  public static void AddTestnestedflatbuffer(FlatBufferBuilder builder, VectorOffset testnestedflatbufferOffset) { builder.AddOffset(13, testnestedflatbufferOffset.Value, 0); }
+  public static VectorOffset CreateTestnestedflatbufferVector(FlatBufferBuilder builder, byte[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddByte(data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateTestnestedflatbufferVectorBlock(FlatBufferBuilder builder, byte[] data) { builder.StartVector(1, data.Length, 1); builder.Add(data); return builder.EndVector(); }
+  public static void StartTestnestedflatbufferVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); }
+  public static void AddTestempty(FlatBufferBuilder builder, Offset<MyGame.Example.Stat> testemptyOffset) { builder.AddOffset(14, testemptyOffset.Value, 0); }
+  public static void AddTestbool(FlatBufferBuilder builder, bool testbool) { builder.AddBool(15, testbool, false); }
+  public static void AddTesthashs32Fnv1(FlatBufferBuilder builder, int testhashs32Fnv1) { builder.AddInt(16, testhashs32Fnv1, 0); }
+  public static void AddTesthashu32Fnv1(FlatBufferBuilder builder, uint testhashu32Fnv1) { builder.AddUint(17, testhashu32Fnv1, 0); }
+  public static void AddTesthashs64Fnv1(FlatBufferBuilder builder, long testhashs64Fnv1) { builder.AddLong(18, testhashs64Fnv1, 0); }
+  public static void AddTesthashu64Fnv1(FlatBufferBuilder builder, ulong testhashu64Fnv1) { builder.AddUlong(19, testhashu64Fnv1, 0); }
+  public static void AddTesthashs32Fnv1a(FlatBufferBuilder builder, int testhashs32Fnv1a) { builder.AddInt(20, testhashs32Fnv1a, 0); }
+  public static void AddTesthashu32Fnv1a(FlatBufferBuilder builder, uint testhashu32Fnv1a) { builder.AddUint(21, testhashu32Fnv1a, 0); }
+  public static void AddTesthashs64Fnv1a(FlatBufferBuilder builder, long testhashs64Fnv1a) { builder.AddLong(22, testhashs64Fnv1a, 0); }
+  public static void AddTesthashu64Fnv1a(FlatBufferBuilder builder, ulong testhashu64Fnv1a) { builder.AddUlong(23, testhashu64Fnv1a, 0); }
+  public static void AddTestarrayofbools(FlatBufferBuilder builder, VectorOffset testarrayofboolsOffset) { builder.AddOffset(24, testarrayofboolsOffset.Value, 0); }
+  public static VectorOffset CreateTestarrayofboolsVector(FlatBufferBuilder builder, bool[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddBool(data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateTestarrayofboolsVectorBlock(FlatBufferBuilder builder, bool[] data) { builder.StartVector(1, data.Length, 1); builder.Add(data); return builder.EndVector(); }
+  public static void StartTestarrayofboolsVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); }
+  public static void AddTestf(FlatBufferBuilder builder, float testf) { builder.AddFloat(25, testf, 3.14159f); }
+  public static void AddTestf2(FlatBufferBuilder builder, float testf2) { builder.AddFloat(26, testf2, 3.0f); }
+  public static void AddTestf3(FlatBufferBuilder builder, float testf3) { builder.AddFloat(27, testf3, 0.0f); }
+  public static void AddTestarrayofstring2(FlatBufferBuilder builder, VectorOffset testarrayofstring2Offset) { builder.AddOffset(28, testarrayofstring2Offset.Value, 0); }
+  public static VectorOffset CreateTestarrayofstring2Vector(FlatBufferBuilder builder, StringOffset[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
+  public static VectorOffset CreateTestarrayofstring2VectorBlock(FlatBufferBuilder builder, StringOffset[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
+  public static void StartTestarrayofstring2Vector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
+  public static void AddTestarrayofsortedstruct(FlatBufferBuilder builder, VectorOffset testarrayofsortedstructOffset) { builder.AddOffset(29, testarrayofsortedstructOffset.Value, 0); }
+  public static void StartTestarrayofsortedstructVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 4); }
+  public static void AddFlex(FlatBufferBuilder builder, VectorOffset flexOffset) { builder.AddOffset(30, flexOffset.Value, 0); }
+  public static VectorOffset CreateFlexVector(FlatBufferBuilder builder, byte[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddByte(data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateFlexVectorBlock(FlatBufferBuilder builder, byte[] data) { builder.StartVector(1, data.Length, 1); builder.Add(data); return builder.EndVector(); }
+  public static void StartFlexVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); }
+  public static void AddTest5(FlatBufferBuilder builder, VectorOffset test5Offset) { builder.AddOffset(31, test5Offset.Value, 0); }
+  public static void StartTest5Vector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 2); }
+  public static void AddVectorOfLongs(FlatBufferBuilder builder, VectorOffset vectorOfLongsOffset) { builder.AddOffset(32, vectorOfLongsOffset.Value, 0); }
+  public static VectorOffset CreateVectorOfLongsVector(FlatBufferBuilder builder, long[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddLong(data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateVectorOfLongsVectorBlock(FlatBufferBuilder builder, long[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
+  public static void StartVectorOfLongsVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
+  public static void AddVectorOfDoubles(FlatBufferBuilder builder, VectorOffset vectorOfDoublesOffset) { builder.AddOffset(33, vectorOfDoublesOffset.Value, 0); }
+  public static VectorOffset CreateVectorOfDoublesVector(FlatBufferBuilder builder, double[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddDouble(data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateVectorOfDoublesVectorBlock(FlatBufferBuilder builder, double[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
+  public static void StartVectorOfDoublesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
+  public static void AddParentNamespaceTest(FlatBufferBuilder builder, Offset<MyGame.InParentNamespace> parentNamespaceTestOffset) { builder.AddOffset(34, parentNamespaceTestOffset.Value, 0); }
+  public static void AddVectorOfReferrables(FlatBufferBuilder builder, VectorOffset vectorOfReferrablesOffset) { builder.AddOffset(35, vectorOfReferrablesOffset.Value, 0); }
+  public static VectorOffset CreateVectorOfReferrablesVector(FlatBufferBuilder builder, Offset<MyGame.Example.Referrable>[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
+  public static VectorOffset CreateVectorOfReferrablesVectorBlock(FlatBufferBuilder builder, Offset<MyGame.Example.Referrable>[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
+  public static void StartVectorOfReferrablesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
+  public static void AddSingleWeakReference(FlatBufferBuilder builder, ulong singleWeakReference) { builder.AddUlong(36, singleWeakReference, 0); }
+  public static void AddVectorOfWeakReferences(FlatBufferBuilder builder, VectorOffset vectorOfWeakReferencesOffset) { builder.AddOffset(37, vectorOfWeakReferencesOffset.Value, 0); }
+  public static VectorOffset CreateVectorOfWeakReferencesVector(FlatBufferBuilder builder, ulong[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddUlong(data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateVectorOfWeakReferencesVectorBlock(FlatBufferBuilder builder, ulong[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
+  public static void StartVectorOfWeakReferencesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
+  public static void AddVectorOfStrongReferrables(FlatBufferBuilder builder, VectorOffset vectorOfStrongReferrablesOffset) { builder.AddOffset(38, vectorOfStrongReferrablesOffset.Value, 0); }
+  public static VectorOffset CreateVectorOfStrongReferrablesVector(FlatBufferBuilder builder, Offset<MyGame.Example.Referrable>[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
+  public static VectorOffset CreateVectorOfStrongReferrablesVectorBlock(FlatBufferBuilder builder, Offset<MyGame.Example.Referrable>[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
+  public static void StartVectorOfStrongReferrablesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
+  public static void AddCoOwningReference(FlatBufferBuilder builder, ulong coOwningReference) { builder.AddUlong(39, coOwningReference, 0); }
+  public static void AddVectorOfCoOwningReferences(FlatBufferBuilder builder, VectorOffset vectorOfCoOwningReferencesOffset) { builder.AddOffset(40, vectorOfCoOwningReferencesOffset.Value, 0); }
+  public static VectorOffset CreateVectorOfCoOwningReferencesVector(FlatBufferBuilder builder, ulong[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddUlong(data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateVectorOfCoOwningReferencesVectorBlock(FlatBufferBuilder builder, ulong[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
+  public static void StartVectorOfCoOwningReferencesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
+  public static void AddNonOwningReference(FlatBufferBuilder builder, ulong nonOwningReference) { builder.AddUlong(41, nonOwningReference, 0); }
+  public static void AddVectorOfNonOwningReferences(FlatBufferBuilder builder, VectorOffset vectorOfNonOwningReferencesOffset) { builder.AddOffset(42, vectorOfNonOwningReferencesOffset.Value, 0); }
+  public static VectorOffset CreateVectorOfNonOwningReferencesVector(FlatBufferBuilder builder, ulong[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddUlong(data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateVectorOfNonOwningReferencesVectorBlock(FlatBufferBuilder builder, ulong[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
+  public static void StartVectorOfNonOwningReferencesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
+  public static void AddAnyUniqueType(FlatBufferBuilder builder, MyGame.Example.AnyUniqueAliases anyUniqueType) { builder.AddByte(43, (byte)anyUniqueType, 0); }
+  public static void AddAnyUnique(FlatBufferBuilder builder, int anyUniqueOffset) { builder.AddOffset(44, anyUniqueOffset, 0); }
+  public static void AddAnyAmbiguousType(FlatBufferBuilder builder, MyGame.Example.AnyAmbiguousAliases anyAmbiguousType) { builder.AddByte(45, (byte)anyAmbiguousType, 0); }
+  public static void AddAnyAmbiguous(FlatBufferBuilder builder, int anyAmbiguousOffset) { builder.AddOffset(46, anyAmbiguousOffset, 0); }
+  public static void AddVectorOfEnums(FlatBufferBuilder builder, VectorOffset vectorOfEnumsOffset) { builder.AddOffset(47, vectorOfEnumsOffset.Value, 0); }
+  public static VectorOffset CreateVectorOfEnumsVector(FlatBufferBuilder builder, MyGame.Example.Color[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddByte((byte)data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateVectorOfEnumsVectorBlock(FlatBufferBuilder builder, MyGame.Example.Color[] data) { builder.StartVector(1, data.Length, 1); builder.Add(data); return builder.EndVector(); }
+  public static void StartVectorOfEnumsVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); }
+  public static Offset<MyGame.Example.Monster> EndMonster(FlatBufferBuilder builder) {
+    int o = builder.EndTable();
+    builder.Required(o, 10);  // name
+    return new Offset<MyGame.Example.Monster>(o);
+  }
+  public static void FinishMonsterBuffer(FlatBufferBuilder builder, Offset<MyGame.Example.Monster> offset) { builder.Finish(offset.Value, "MONS"); }
+  public static void FinishSizePrefixedMonsterBuffer(FlatBufferBuilder builder, Offset<MyGame.Example.Monster> offset) { builder.FinishSizePrefixed(offset.Value, "MONS"); }
+
+  public static VectorOffset CreateSortedVectorOfMonster(FlatBufferBuilder builder, Offset<Monster>[] offsets) {
+    Array.Sort(offsets, (Offset<Monster> o1, Offset<Monster> o2) => Table.CompareStrings(Table.__offset(10, o1.Value, builder.DataBuffer), Table.__offset(10, o2.Value, builder.DataBuffer), builder.DataBuffer));
+    return builder.CreateVectorOfTables(offsets);
+  }
+
+  public static Monster? __lookup_by_key(int vectorLocation, string key, ByteBuffer bb) {
+    byte[] byteKey = System.Text.Encoding.UTF8.GetBytes(key);
+    int span = bb.GetInt(vectorLocation - 4);
+    int start = 0;
+    while (span != 0) {
+      int middle = span / 2;
+      int tableOffset = Table.__indirect(vectorLocation + 4 * (start + middle), bb);
+      int comp = Table.CompareStrings(Table.__offset(10, bb.Length - tableOffset, bb), byteKey, bb);
+      if (comp > 0) {
+        span = middle;
+      } else if (comp < 0) {
+        middle++;
+        start += middle;
+        span -= middle;
+      } else {
+        return new Monster().__assign(tableOffset, bb);
+      }
+    }
+    return null;
+  }
+};
+
+
+}
diff --git a/tests/MyGame/Example/Monster.go b/tests/MyGame/Example/Monster.go
new file mode 100644
index 0000000..dabb596
--- /dev/null
+++ b/tests/MyGame/Example/Monster.go
@@ -0,0 +1,1018 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package Example
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+
+	MyGame "MyGame"
+)
+
+/// an example documentation comment: monster object
+type Monster struct {
+	_tab flatbuffers.Table
+}
+
+func GetRootAsMonster(buf []byte, offset flatbuffers.UOffsetT) *Monster {
+	n := flatbuffers.GetUOffsetT(buf[offset:])
+	x := &Monster{}
+	x.Init(buf, n+offset)
+	return x
+}
+
+func (rcv *Monster) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *Monster) Table() flatbuffers.Table {
+	return rcv._tab
+}
+
+func (rcv *Monster) Pos(obj *Vec3) *Vec3 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
+	if o != 0 {
+		x := o + rcv._tab.Pos
+		if obj == nil {
+			obj = new(Vec3)
+		}
+		obj.Init(rcv._tab.Bytes, x)
+		return obj
+	}
+	return nil
+}
+
+func (rcv *Monster) Mana() int16 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
+	if o != 0 {
+		return rcv._tab.GetInt16(o + rcv._tab.Pos)
+	}
+	return 150
+}
+
+func (rcv *Monster) MutateMana(n int16) bool {
+	return rcv._tab.MutateInt16Slot(6, n)
+}
+
+func (rcv *Monster) Hp() int16 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(8))
+	if o != 0 {
+		return rcv._tab.GetInt16(o + rcv._tab.Pos)
+	}
+	return 100
+}
+
+func (rcv *Monster) MutateHp(n int16) bool {
+	return rcv._tab.MutateInt16Slot(8, n)
+}
+
+func (rcv *Monster) Name() []byte {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(10))
+	if o != 0 {
+		return rcv._tab.ByteVector(o + rcv._tab.Pos)
+	}
+	return nil
+}
+
+func (rcv *Monster) Inventory(j int) byte {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(14))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.GetByte(a + flatbuffers.UOffsetT(j*1))
+	}
+	return 0
+}
+
+func (rcv *Monster) InventoryLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(14))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) InventoryBytes() []byte {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(14))
+	if o != 0 {
+		return rcv._tab.ByteVector(o + rcv._tab.Pos)
+	}
+	return nil
+}
+
+func (rcv *Monster) MutateInventory(j int, n byte) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(14))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.MutateByte(a+flatbuffers.UOffsetT(j*1), n)
+	}
+	return false
+}
+
+func (rcv *Monster) Color() Color {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(16))
+	if o != 0 {
+		return Color(rcv._tab.GetByte(o + rcv._tab.Pos))
+	}
+	return 8
+}
+
+func (rcv *Monster) MutateColor(n Color) bool {
+	return rcv._tab.MutateByteSlot(16, byte(n))
+}
+
+func (rcv *Monster) TestType() Any {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(18))
+	if o != 0 {
+		return Any(rcv._tab.GetByte(o + rcv._tab.Pos))
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateTestType(n Any) bool {
+	return rcv._tab.MutateByteSlot(18, byte(n))
+}
+
+func (rcv *Monster) Test(obj *flatbuffers.Table) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(20))
+	if o != 0 {
+		rcv._tab.Union(obj, o)
+		return true
+	}
+	return false
+}
+
+func (rcv *Monster) Test4(obj *Test, j int) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(22))
+	if o != 0 {
+		x := rcv._tab.Vector(o)
+		x += flatbuffers.UOffsetT(j) * 4
+		obj.Init(rcv._tab.Bytes, x)
+		return true
+	}
+	return false
+}
+
+func (rcv *Monster) Test4Length() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(22))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) Testarrayofstring(j int) []byte {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(24))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.ByteVector(a + flatbuffers.UOffsetT(j*4))
+	}
+	return nil
+}
+
+func (rcv *Monster) TestarrayofstringLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(24))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+/// an example documentation comment: this will end up in the generated code
+/// multiline too
+func (rcv *Monster) Testarrayoftables(obj *Monster, j int) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(26))
+	if o != 0 {
+		x := rcv._tab.Vector(o)
+		x += flatbuffers.UOffsetT(j) * 4
+		x = rcv._tab.Indirect(x)
+		obj.Init(rcv._tab.Bytes, x)
+		return true
+	}
+	return false
+}
+
+func (rcv *Monster) TestarrayoftablesLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(26))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+/// an example documentation comment: this will end up in the generated code
+/// multiline too
+func (rcv *Monster) Enemy(obj *Monster) *Monster {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(28))
+	if o != 0 {
+		x := rcv._tab.Indirect(o + rcv._tab.Pos)
+		if obj == nil {
+			obj = new(Monster)
+		}
+		obj.Init(rcv._tab.Bytes, x)
+		return obj
+	}
+	return nil
+}
+
+func (rcv *Monster) Testnestedflatbuffer(j int) byte {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(30))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.GetByte(a + flatbuffers.UOffsetT(j*1))
+	}
+	return 0
+}
+
+func (rcv *Monster) TestnestedflatbufferLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(30))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) TestnestedflatbufferBytes() []byte {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(30))
+	if o != 0 {
+		return rcv._tab.ByteVector(o + rcv._tab.Pos)
+	}
+	return nil
+}
+
+func (rcv *Monster) MutateTestnestedflatbuffer(j int, n byte) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(30))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.MutateByte(a+flatbuffers.UOffsetT(j*1), n)
+	}
+	return false
+}
+
+func (rcv *Monster) Testempty(obj *Stat) *Stat {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(32))
+	if o != 0 {
+		x := rcv._tab.Indirect(o + rcv._tab.Pos)
+		if obj == nil {
+			obj = new(Stat)
+		}
+		obj.Init(rcv._tab.Bytes, x)
+		return obj
+	}
+	return nil
+}
+
+func (rcv *Monster) Testbool() bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(34))
+	if o != 0 {
+		return rcv._tab.GetBool(o + rcv._tab.Pos)
+	}
+	return false
+}
+
+func (rcv *Monster) MutateTestbool(n bool) bool {
+	return rcv._tab.MutateBoolSlot(34, n)
+}
+
+func (rcv *Monster) Testhashs32Fnv1() int32 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(36))
+	if o != 0 {
+		return rcv._tab.GetInt32(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateTesthashs32Fnv1(n int32) bool {
+	return rcv._tab.MutateInt32Slot(36, n)
+}
+
+func (rcv *Monster) Testhashu32Fnv1() uint32 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(38))
+	if o != 0 {
+		return rcv._tab.GetUint32(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateTesthashu32Fnv1(n uint32) bool {
+	return rcv._tab.MutateUint32Slot(38, n)
+}
+
+func (rcv *Monster) Testhashs64Fnv1() int64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(40))
+	if o != 0 {
+		return rcv._tab.GetInt64(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateTesthashs64Fnv1(n int64) bool {
+	return rcv._tab.MutateInt64Slot(40, n)
+}
+
+func (rcv *Monster) Testhashu64Fnv1() uint64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(42))
+	if o != 0 {
+		return rcv._tab.GetUint64(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateTesthashu64Fnv1(n uint64) bool {
+	return rcv._tab.MutateUint64Slot(42, n)
+}
+
+func (rcv *Monster) Testhashs32Fnv1a() int32 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(44))
+	if o != 0 {
+		return rcv._tab.GetInt32(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateTesthashs32Fnv1a(n int32) bool {
+	return rcv._tab.MutateInt32Slot(44, n)
+}
+
+func (rcv *Monster) Testhashu32Fnv1a() uint32 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(46))
+	if o != 0 {
+		return rcv._tab.GetUint32(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateTesthashu32Fnv1a(n uint32) bool {
+	return rcv._tab.MutateUint32Slot(46, n)
+}
+
+func (rcv *Monster) Testhashs64Fnv1a() int64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(48))
+	if o != 0 {
+		return rcv._tab.GetInt64(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateTesthashs64Fnv1a(n int64) bool {
+	return rcv._tab.MutateInt64Slot(48, n)
+}
+
+func (rcv *Monster) Testhashu64Fnv1a() uint64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(50))
+	if o != 0 {
+		return rcv._tab.GetUint64(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateTesthashu64Fnv1a(n uint64) bool {
+	return rcv._tab.MutateUint64Slot(50, n)
+}
+
+func (rcv *Monster) Testarrayofbools(j int) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(52))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.GetBool(a + flatbuffers.UOffsetT(j*1))
+	}
+	return false
+}
+
+func (rcv *Monster) TestarrayofboolsLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(52))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateTestarrayofbools(j int, n bool) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(52))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.MutateBool(a+flatbuffers.UOffsetT(j*1), n)
+	}
+	return false
+}
+
+func (rcv *Monster) Testf() float32 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(54))
+	if o != 0 {
+		return rcv._tab.GetFloat32(o + rcv._tab.Pos)
+	}
+	return 3.14159
+}
+
+func (rcv *Monster) MutateTestf(n float32) bool {
+	return rcv._tab.MutateFloat32Slot(54, n)
+}
+
+func (rcv *Monster) Testf2() float32 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(56))
+	if o != 0 {
+		return rcv._tab.GetFloat32(o + rcv._tab.Pos)
+	}
+	return 3.0
+}
+
+func (rcv *Monster) MutateTestf2(n float32) bool {
+	return rcv._tab.MutateFloat32Slot(56, n)
+}
+
+func (rcv *Monster) Testf3() float32 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(58))
+	if o != 0 {
+		return rcv._tab.GetFloat32(o + rcv._tab.Pos)
+	}
+	return 0.0
+}
+
+func (rcv *Monster) MutateTestf3(n float32) bool {
+	return rcv._tab.MutateFloat32Slot(58, n)
+}
+
+func (rcv *Monster) Testarrayofstring2(j int) []byte {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(60))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.ByteVector(a + flatbuffers.UOffsetT(j*4))
+	}
+	return nil
+}
+
+func (rcv *Monster) Testarrayofstring2Length() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(60))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) Testarrayofsortedstruct(obj *Ability, j int) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(62))
+	if o != 0 {
+		x := rcv._tab.Vector(o)
+		x += flatbuffers.UOffsetT(j) * 8
+		obj.Init(rcv._tab.Bytes, x)
+		return true
+	}
+	return false
+}
+
+func (rcv *Monster) TestarrayofsortedstructLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(62))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) Flex(j int) byte {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(64))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.GetByte(a + flatbuffers.UOffsetT(j*1))
+	}
+	return 0
+}
+
+func (rcv *Monster) FlexLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(64))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) FlexBytes() []byte {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(64))
+	if o != 0 {
+		return rcv._tab.ByteVector(o + rcv._tab.Pos)
+	}
+	return nil
+}
+
+func (rcv *Monster) MutateFlex(j int, n byte) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(64))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.MutateByte(a+flatbuffers.UOffsetT(j*1), n)
+	}
+	return false
+}
+
+func (rcv *Monster) Test5(obj *Test, j int) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(66))
+	if o != 0 {
+		x := rcv._tab.Vector(o)
+		x += flatbuffers.UOffsetT(j) * 4
+		obj.Init(rcv._tab.Bytes, x)
+		return true
+	}
+	return false
+}
+
+func (rcv *Monster) Test5Length() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(66))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) VectorOfLongs(j int) int64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(68))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.GetInt64(a + flatbuffers.UOffsetT(j*8))
+	}
+	return 0
+}
+
+func (rcv *Monster) VectorOfLongsLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(68))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateVectorOfLongs(j int, n int64) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(68))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.MutateInt64(a+flatbuffers.UOffsetT(j*8), n)
+	}
+	return false
+}
+
+func (rcv *Monster) VectorOfDoubles(j int) float64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(70))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.GetFloat64(a + flatbuffers.UOffsetT(j*8))
+	}
+	return 0
+}
+
+func (rcv *Monster) VectorOfDoublesLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(70))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateVectorOfDoubles(j int, n float64) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(70))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.MutateFloat64(a+flatbuffers.UOffsetT(j*8), n)
+	}
+	return false
+}
+
+func (rcv *Monster) ParentNamespaceTest(obj *MyGame.InParentNamespace) *MyGame.InParentNamespace {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(72))
+	if o != 0 {
+		x := rcv._tab.Indirect(o + rcv._tab.Pos)
+		if obj == nil {
+			obj = new(MyGame.InParentNamespace)
+		}
+		obj.Init(rcv._tab.Bytes, x)
+		return obj
+	}
+	return nil
+}
+
+func (rcv *Monster) VectorOfReferrables(obj *Referrable, j int) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(74))
+	if o != 0 {
+		x := rcv._tab.Vector(o)
+		x += flatbuffers.UOffsetT(j) * 4
+		x = rcv._tab.Indirect(x)
+		obj.Init(rcv._tab.Bytes, x)
+		return true
+	}
+	return false
+}
+
+func (rcv *Monster) VectorOfReferrablesLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(74))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) SingleWeakReference() uint64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(76))
+	if o != 0 {
+		return rcv._tab.GetUint64(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateSingleWeakReference(n uint64) bool {
+	return rcv._tab.MutateUint64Slot(76, n)
+}
+
+func (rcv *Monster) VectorOfWeakReferences(j int) uint64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(78))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.GetUint64(a + flatbuffers.UOffsetT(j*8))
+	}
+	return 0
+}
+
+func (rcv *Monster) VectorOfWeakReferencesLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(78))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateVectorOfWeakReferences(j int, n uint64) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(78))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.MutateUint64(a+flatbuffers.UOffsetT(j*8), n)
+	}
+	return false
+}
+
+func (rcv *Monster) VectorOfStrongReferrables(obj *Referrable, j int) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(80))
+	if o != 0 {
+		x := rcv._tab.Vector(o)
+		x += flatbuffers.UOffsetT(j) * 4
+		x = rcv._tab.Indirect(x)
+		obj.Init(rcv._tab.Bytes, x)
+		return true
+	}
+	return false
+}
+
+func (rcv *Monster) VectorOfStrongReferrablesLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(80))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) CoOwningReference() uint64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(82))
+	if o != 0 {
+		return rcv._tab.GetUint64(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateCoOwningReference(n uint64) bool {
+	return rcv._tab.MutateUint64Slot(82, n)
+}
+
+func (rcv *Monster) VectorOfCoOwningReferences(j int) uint64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(84))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.GetUint64(a + flatbuffers.UOffsetT(j*8))
+	}
+	return 0
+}
+
+func (rcv *Monster) VectorOfCoOwningReferencesLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(84))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateVectorOfCoOwningReferences(j int, n uint64) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(84))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.MutateUint64(a+flatbuffers.UOffsetT(j*8), n)
+	}
+	return false
+}
+
+func (rcv *Monster) NonOwningReference() uint64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(86))
+	if o != 0 {
+		return rcv._tab.GetUint64(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateNonOwningReference(n uint64) bool {
+	return rcv._tab.MutateUint64Slot(86, n)
+}
+
+func (rcv *Monster) VectorOfNonOwningReferences(j int) uint64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(88))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.GetUint64(a + flatbuffers.UOffsetT(j*8))
+	}
+	return 0
+}
+
+func (rcv *Monster) VectorOfNonOwningReferencesLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(88))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateVectorOfNonOwningReferences(j int, n uint64) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(88))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.MutateUint64(a+flatbuffers.UOffsetT(j*8), n)
+	}
+	return false
+}
+
+func (rcv *Monster) AnyUniqueType() AnyUniqueAliases {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(90))
+	if o != 0 {
+		return AnyUniqueAliases(rcv._tab.GetByte(o + rcv._tab.Pos))
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateAnyUniqueType(n AnyUniqueAliases) bool {
+	return rcv._tab.MutateByteSlot(90, byte(n))
+}
+
+func (rcv *Monster) AnyUnique(obj *flatbuffers.Table) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(92))
+	if o != 0 {
+		rcv._tab.Union(obj, o)
+		return true
+	}
+	return false
+}
+
+func (rcv *Monster) AnyAmbiguousType() AnyAmbiguousAliases {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(94))
+	if o != 0 {
+		return AnyAmbiguousAliases(rcv._tab.GetByte(o + rcv._tab.Pos))
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateAnyAmbiguousType(n AnyAmbiguousAliases) bool {
+	return rcv._tab.MutateByteSlot(94, byte(n))
+}
+
+func (rcv *Monster) AnyAmbiguous(obj *flatbuffers.Table) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(96))
+	if o != 0 {
+		rcv._tab.Union(obj, o)
+		return true
+	}
+	return false
+}
+
+func (rcv *Monster) VectorOfEnums(j int) Color {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(98))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return Color(rcv._tab.GetByte(a + flatbuffers.UOffsetT(j*1)))
+	}
+	return 0
+}
+
+func (rcv *Monster) VectorOfEnumsLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(98))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) VectorOfEnumsBytes() []byte {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(98))
+	if o != 0 {
+		return rcv._tab.ByteVector(o + rcv._tab.Pos)
+	}
+	return nil
+}
+
+func (rcv *Monster) MutateVectorOfEnums(j int, n Color) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(98))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.MutateByte(a+flatbuffers.UOffsetT(j*1), byte(n))
+	}
+	return false
+}
+
+func MonsterStart(builder *flatbuffers.Builder) {
+	builder.StartObject(48)
+}
+func MonsterAddPos(builder *flatbuffers.Builder, pos flatbuffers.UOffsetT) {
+	builder.PrependStructSlot(0, flatbuffers.UOffsetT(pos), 0)
+}
+func MonsterAddMana(builder *flatbuffers.Builder, mana int16) {
+	builder.PrependInt16Slot(1, mana, 150)
+}
+func MonsterAddHp(builder *flatbuffers.Builder, hp int16) {
+	builder.PrependInt16Slot(2, hp, 100)
+}
+func MonsterAddName(builder *flatbuffers.Builder, name flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(3, flatbuffers.UOffsetT(name), 0)
+}
+func MonsterAddInventory(builder *flatbuffers.Builder, inventory flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(5, flatbuffers.UOffsetT(inventory), 0)
+}
+func MonsterStartInventoryVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(1, numElems, 1)
+}
+func MonsterAddColor(builder *flatbuffers.Builder, color Color) {
+	builder.PrependByteSlot(6, byte(color), 8)
+}
+func MonsterAddTestType(builder *flatbuffers.Builder, testType Any) {
+	builder.PrependByteSlot(7, byte(testType), 0)
+}
+func MonsterAddTest(builder *flatbuffers.Builder, test flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(8, flatbuffers.UOffsetT(test), 0)
+}
+func MonsterAddTest4(builder *flatbuffers.Builder, test4 flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(9, flatbuffers.UOffsetT(test4), 0)
+}
+func MonsterStartTest4Vector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(4, numElems, 2)
+}
+func MonsterAddTestarrayofstring(builder *flatbuffers.Builder, testarrayofstring flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(10, flatbuffers.UOffsetT(testarrayofstring), 0)
+}
+func MonsterStartTestarrayofstringVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(4, numElems, 4)
+}
+func MonsterAddTestarrayoftables(builder *flatbuffers.Builder, testarrayoftables flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(11, flatbuffers.UOffsetT(testarrayoftables), 0)
+}
+func MonsterStartTestarrayoftablesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(4, numElems, 4)
+}
+func MonsterAddEnemy(builder *flatbuffers.Builder, enemy flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(12, flatbuffers.UOffsetT(enemy), 0)
+}
+func MonsterAddTestnestedflatbuffer(builder *flatbuffers.Builder, testnestedflatbuffer flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(13, flatbuffers.UOffsetT(testnestedflatbuffer), 0)
+}
+func MonsterStartTestnestedflatbufferVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(1, numElems, 1)
+}
+func MonsterAddTestempty(builder *flatbuffers.Builder, testempty flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(14, flatbuffers.UOffsetT(testempty), 0)
+}
+func MonsterAddTestbool(builder *flatbuffers.Builder, testbool bool) {
+	builder.PrependBoolSlot(15, testbool, false)
+}
+func MonsterAddTesthashs32Fnv1(builder *flatbuffers.Builder, testhashs32Fnv1 int32) {
+	builder.PrependInt32Slot(16, testhashs32Fnv1, 0)
+}
+func MonsterAddTesthashu32Fnv1(builder *flatbuffers.Builder, testhashu32Fnv1 uint32) {
+	builder.PrependUint32Slot(17, testhashu32Fnv1, 0)
+}
+func MonsterAddTesthashs64Fnv1(builder *flatbuffers.Builder, testhashs64Fnv1 int64) {
+	builder.PrependInt64Slot(18, testhashs64Fnv1, 0)
+}
+func MonsterAddTesthashu64Fnv1(builder *flatbuffers.Builder, testhashu64Fnv1 uint64) {
+	builder.PrependUint64Slot(19, testhashu64Fnv1, 0)
+}
+func MonsterAddTesthashs32Fnv1a(builder *flatbuffers.Builder, testhashs32Fnv1a int32) {
+	builder.PrependInt32Slot(20, testhashs32Fnv1a, 0)
+}
+func MonsterAddTesthashu32Fnv1a(builder *flatbuffers.Builder, testhashu32Fnv1a uint32) {
+	builder.PrependUint32Slot(21, testhashu32Fnv1a, 0)
+}
+func MonsterAddTesthashs64Fnv1a(builder *flatbuffers.Builder, testhashs64Fnv1a int64) {
+	builder.PrependInt64Slot(22, testhashs64Fnv1a, 0)
+}
+func MonsterAddTesthashu64Fnv1a(builder *flatbuffers.Builder, testhashu64Fnv1a uint64) {
+	builder.PrependUint64Slot(23, testhashu64Fnv1a, 0)
+}
+func MonsterAddTestarrayofbools(builder *flatbuffers.Builder, testarrayofbools flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(24, flatbuffers.UOffsetT(testarrayofbools), 0)
+}
+func MonsterStartTestarrayofboolsVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(1, numElems, 1)
+}
+func MonsterAddTestf(builder *flatbuffers.Builder, testf float32) {
+	builder.PrependFloat32Slot(25, testf, 3.14159)
+}
+func MonsterAddTestf2(builder *flatbuffers.Builder, testf2 float32) {
+	builder.PrependFloat32Slot(26, testf2, 3.0)
+}
+func MonsterAddTestf3(builder *flatbuffers.Builder, testf3 float32) {
+	builder.PrependFloat32Slot(27, testf3, 0.0)
+}
+func MonsterAddTestarrayofstring2(builder *flatbuffers.Builder, testarrayofstring2 flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(28, flatbuffers.UOffsetT(testarrayofstring2), 0)
+}
+func MonsterStartTestarrayofstring2Vector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(4, numElems, 4)
+}
+func MonsterAddTestarrayofsortedstruct(builder *flatbuffers.Builder, testarrayofsortedstruct flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(29, flatbuffers.UOffsetT(testarrayofsortedstruct), 0)
+}
+func MonsterStartTestarrayofsortedstructVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(8, numElems, 4)
+}
+func MonsterAddFlex(builder *flatbuffers.Builder, flex flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(30, flatbuffers.UOffsetT(flex), 0)
+}
+func MonsterStartFlexVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(1, numElems, 1)
+}
+func MonsterAddTest5(builder *flatbuffers.Builder, test5 flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(31, flatbuffers.UOffsetT(test5), 0)
+}
+func MonsterStartTest5Vector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(4, numElems, 2)
+}
+func MonsterAddVectorOfLongs(builder *flatbuffers.Builder, vectorOfLongs flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(32, flatbuffers.UOffsetT(vectorOfLongs), 0)
+}
+func MonsterStartVectorOfLongsVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(8, numElems, 8)
+}
+func MonsterAddVectorOfDoubles(builder *flatbuffers.Builder, vectorOfDoubles flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(33, flatbuffers.UOffsetT(vectorOfDoubles), 0)
+}
+func MonsterStartVectorOfDoublesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(8, numElems, 8)
+}
+func MonsterAddParentNamespaceTest(builder *flatbuffers.Builder, parentNamespaceTest flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(34, flatbuffers.UOffsetT(parentNamespaceTest), 0)
+}
+func MonsterAddVectorOfReferrables(builder *flatbuffers.Builder, vectorOfReferrables flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(35, flatbuffers.UOffsetT(vectorOfReferrables), 0)
+}
+func MonsterStartVectorOfReferrablesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(4, numElems, 4)
+}
+func MonsterAddSingleWeakReference(builder *flatbuffers.Builder, singleWeakReference uint64) {
+	builder.PrependUint64Slot(36, singleWeakReference, 0)
+}
+func MonsterAddVectorOfWeakReferences(builder *flatbuffers.Builder, vectorOfWeakReferences flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(37, flatbuffers.UOffsetT(vectorOfWeakReferences), 0)
+}
+func MonsterStartVectorOfWeakReferencesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(8, numElems, 8)
+}
+func MonsterAddVectorOfStrongReferrables(builder *flatbuffers.Builder, vectorOfStrongReferrables flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(38, flatbuffers.UOffsetT(vectorOfStrongReferrables), 0)
+}
+func MonsterStartVectorOfStrongReferrablesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(4, numElems, 4)
+}
+func MonsterAddCoOwningReference(builder *flatbuffers.Builder, coOwningReference uint64) {
+	builder.PrependUint64Slot(39, coOwningReference, 0)
+}
+func MonsterAddVectorOfCoOwningReferences(builder *flatbuffers.Builder, vectorOfCoOwningReferences flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(40, flatbuffers.UOffsetT(vectorOfCoOwningReferences), 0)
+}
+func MonsterStartVectorOfCoOwningReferencesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(8, numElems, 8)
+}
+func MonsterAddNonOwningReference(builder *flatbuffers.Builder, nonOwningReference uint64) {
+	builder.PrependUint64Slot(41, nonOwningReference, 0)
+}
+func MonsterAddVectorOfNonOwningReferences(builder *flatbuffers.Builder, vectorOfNonOwningReferences flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(42, flatbuffers.UOffsetT(vectorOfNonOwningReferences), 0)
+}
+func MonsterStartVectorOfNonOwningReferencesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(8, numElems, 8)
+}
+func MonsterAddAnyUniqueType(builder *flatbuffers.Builder, anyUniqueType AnyUniqueAliases) {
+	builder.PrependByteSlot(43, byte(anyUniqueType), 0)
+}
+func MonsterAddAnyUnique(builder *flatbuffers.Builder, anyUnique flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(44, flatbuffers.UOffsetT(anyUnique), 0)
+}
+func MonsterAddAnyAmbiguousType(builder *flatbuffers.Builder, anyAmbiguousType AnyAmbiguousAliases) {
+	builder.PrependByteSlot(45, byte(anyAmbiguousType), 0)
+}
+func MonsterAddAnyAmbiguous(builder *flatbuffers.Builder, anyAmbiguous flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(46, flatbuffers.UOffsetT(anyAmbiguous), 0)
+}
+func MonsterAddVectorOfEnums(builder *flatbuffers.Builder, vectorOfEnums flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(47, flatbuffers.UOffsetT(vectorOfEnums), 0)
+}
+func MonsterStartVectorOfEnumsVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(1, numElems, 1)
+}
+func MonsterEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+	return builder.EndObject()
+}
diff --git a/tests/MyGame/Example/Monster.java b/tests/MyGame/Example/Monster.java
new file mode 100644
index 0000000..34d7983
--- /dev/null
+++ b/tests/MyGame/Example/Monster.java
@@ -0,0 +1,276 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+/**
+ * an example documentation comment: monster object
+ */
+public final class Monster extends Table {
+  public static void ValidateVersion() { Constants.FLATBUFFERS_1_11_1(); }
+  public static Monster getRootAsMonster(ByteBuffer _bb) { return getRootAsMonster(_bb, new Monster()); }
+  public static Monster getRootAsMonster(ByteBuffer _bb, Monster obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public static boolean MonsterBufferHasIdentifier(ByteBuffer _bb) { return __has_identifier(_bb, "MONS"); }
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public Monster __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public MyGame.Example.Vec3 pos() { return pos(new MyGame.Example.Vec3()); }
+  public MyGame.Example.Vec3 pos(MyGame.Example.Vec3 obj) { int o = __offset(4); return o != 0 ? obj.__assign(o + bb_pos, bb) : null; }
+  public short mana() { int o = __offset(6); return o != 0 ? bb.getShort(o + bb_pos) : 150; }
+  public boolean mutateMana(short mana) { int o = __offset(6); if (o != 0) { bb.putShort(o + bb_pos, mana); return true; } else { return false; } }
+  public short hp() { int o = __offset(8); return o != 0 ? bb.getShort(o + bb_pos) : 100; }
+  public boolean mutateHp(short hp) { int o = __offset(8); if (o != 0) { bb.putShort(o + bb_pos, hp); return true; } else { return false; } }
+  public String name() { int o = __offset(10); return o != 0 ? __string(o + bb_pos) : null; }
+  public ByteBuffer nameAsByteBuffer() { return __vector_as_bytebuffer(10, 1); }
+  public ByteBuffer nameInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 10, 1); }
+  public int inventory(int j) { int o = __offset(14); return o != 0 ? bb.get(__vector(o) + j * 1) & 0xFF : 0; }
+  public int inventoryLength() { int o = __offset(14); return o != 0 ? __vector_len(o) : 0; }
+  public ByteBuffer inventoryAsByteBuffer() { return __vector_as_bytebuffer(14, 1); }
+  public ByteBuffer inventoryInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 14, 1); }
+  public boolean mutateInventory(int j, int inventory) { int o = __offset(14); if (o != 0) { bb.put(__vector(o) + j * 1, (byte)inventory); return true; } else { return false; } }
+  public int color() { int o = __offset(16); return o != 0 ? bb.get(o + bb_pos) & 0xFF : 8; }
+  public boolean mutateColor(int color) { int o = __offset(16); if (o != 0) { bb.put(o + bb_pos, (byte)color); return true; } else { return false; } }
+  public byte testType() { int o = __offset(18); return o != 0 ? bb.get(o + bb_pos) : 0; }
+  public boolean mutateTestType(byte test_type) { int o = __offset(18); if (o != 0) { bb.put(o + bb_pos, test_type); return true; } else { return false; } }
+  public Table test(Table obj) { int o = __offset(20); return o != 0 ? __union(obj, o) : null; }
+  public MyGame.Example.Test test4(int j) { return test4(new MyGame.Example.Test(), j); }
+  public MyGame.Example.Test test4(MyGame.Example.Test obj, int j) { int o = __offset(22); return o != 0 ? obj.__assign(__vector(o) + j * 4, bb) : null; }
+  public int test4Length() { int o = __offset(22); return o != 0 ? __vector_len(o) : 0; }
+  public String testarrayofstring(int j) { int o = __offset(24); return o != 0 ? __string(__vector(o) + j * 4) : null; }
+  public int testarrayofstringLength() { int o = __offset(24); return o != 0 ? __vector_len(o) : 0; }
+  /**
+   * an example documentation comment: this will end up in the generated code
+   * multiline too
+   */
+  public MyGame.Example.Monster testarrayoftables(int j) { return testarrayoftables(new MyGame.Example.Monster(), j); }
+  public MyGame.Example.Monster testarrayoftables(MyGame.Example.Monster obj, int j) { int o = __offset(26); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; }
+  public int testarrayoftablesLength() { int o = __offset(26); return o != 0 ? __vector_len(o) : 0; }
+  public MyGame.Example.Monster testarrayoftablesByKey(String key) { int o = __offset(26); return o != 0 ? MyGame.Example.Monster.__lookup_by_key(null, __vector(o), key, bb) : null; }
+  public MyGame.Example.Monster testarrayoftablesByKey(MyGame.Example.Monster obj, String key) { int o = __offset(26); return o != 0 ? MyGame.Example.Monster.__lookup_by_key(obj, __vector(o), key, bb) : null; }
+  public MyGame.Example.Monster enemy() { return enemy(new MyGame.Example.Monster()); }
+  public MyGame.Example.Monster enemy(MyGame.Example.Monster obj) { int o = __offset(28); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; }
+  public int testnestedflatbuffer(int j) { int o = __offset(30); return o != 0 ? bb.get(__vector(o) + j * 1) & 0xFF : 0; }
+  public int testnestedflatbufferLength() { int o = __offset(30); return o != 0 ? __vector_len(o) : 0; }
+  public ByteBuffer testnestedflatbufferAsByteBuffer() { return __vector_as_bytebuffer(30, 1); }
+  public ByteBuffer testnestedflatbufferInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 30, 1); }
+  public MyGame.Example.Monster testnestedflatbufferAsMonster() { return testnestedflatbufferAsMonster(new MyGame.Example.Monster()); }
+  public MyGame.Example.Monster testnestedflatbufferAsMonster(MyGame.Example.Monster obj) { int o = __offset(30); return o != 0 ? obj.__assign(__indirect(__vector(o)), bb) : null; }
+  public boolean mutateTestnestedflatbuffer(int j, int testnestedflatbuffer) { int o = __offset(30); if (o != 0) { bb.put(__vector(o) + j * 1, (byte)testnestedflatbuffer); return true; } else { return false; } }
+  public MyGame.Example.Stat testempty() { return testempty(new MyGame.Example.Stat()); }
+  public MyGame.Example.Stat testempty(MyGame.Example.Stat obj) { int o = __offset(32); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; }
+  public boolean testbool() { int o = __offset(34); return o != 0 ? 0!=bb.get(o + bb_pos) : false; }
+  public boolean mutateTestbool(boolean testbool) { int o = __offset(34); if (o != 0) { bb.put(o + bb_pos, (byte)(testbool ? 1 : 0)); return true; } else { return false; } }
+  public int testhashs32Fnv1() { int o = __offset(36); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
+  public boolean mutateTesthashs32Fnv1(int testhashs32_fnv1) { int o = __offset(36); if (o != 0) { bb.putInt(o + bb_pos, testhashs32_fnv1); return true; } else { return false; } }
+  public long testhashu32Fnv1() { int o = __offset(38); return o != 0 ? (long)bb.getInt(o + bb_pos) & 0xFFFFFFFFL : 0L; }
+  public boolean mutateTesthashu32Fnv1(long testhashu32_fnv1) { int o = __offset(38); if (o != 0) { bb.putInt(o + bb_pos, (int)testhashu32_fnv1); return true; } else { return false; } }
+  public long testhashs64Fnv1() { int o = __offset(40); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
+  public boolean mutateTesthashs64Fnv1(long testhashs64_fnv1) { int o = __offset(40); if (o != 0) { bb.putLong(o + bb_pos, testhashs64_fnv1); return true; } else { return false; } }
+  public long testhashu64Fnv1() { int o = __offset(42); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
+  public boolean mutateTesthashu64Fnv1(long testhashu64_fnv1) { int o = __offset(42); if (o != 0) { bb.putLong(o + bb_pos, testhashu64_fnv1); return true; } else { return false; } }
+  public int testhashs32Fnv1a() { int o = __offset(44); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
+  public boolean mutateTesthashs32Fnv1a(int testhashs32_fnv1a) { int o = __offset(44); if (o != 0) { bb.putInt(o + bb_pos, testhashs32_fnv1a); return true; } else { return false; } }
+  public long testhashu32Fnv1a() { int o = __offset(46); return o != 0 ? (long)bb.getInt(o + bb_pos) & 0xFFFFFFFFL : 0L; }
+  public boolean mutateTesthashu32Fnv1a(long testhashu32_fnv1a) { int o = __offset(46); if (o != 0) { bb.putInt(o + bb_pos, (int)testhashu32_fnv1a); return true; } else { return false; } }
+  public long testhashs64Fnv1a() { int o = __offset(48); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
+  public boolean mutateTesthashs64Fnv1a(long testhashs64_fnv1a) { int o = __offset(48); if (o != 0) { bb.putLong(o + bb_pos, testhashs64_fnv1a); return true; } else { return false; } }
+  public long testhashu64Fnv1a() { int o = __offset(50); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
+  public boolean mutateTesthashu64Fnv1a(long testhashu64_fnv1a) { int o = __offset(50); if (o != 0) { bb.putLong(o + bb_pos, testhashu64_fnv1a); return true; } else { return false; } }
+  public boolean testarrayofbools(int j) { int o = __offset(52); return o != 0 ? 0!=bb.get(__vector(o) + j * 1) : false; }
+  public int testarrayofboolsLength() { int o = __offset(52); return o != 0 ? __vector_len(o) : 0; }
+  public ByteBuffer testarrayofboolsAsByteBuffer() { return __vector_as_bytebuffer(52, 1); }
+  public ByteBuffer testarrayofboolsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 52, 1); }
+  public boolean mutateTestarrayofbools(int j, boolean testarrayofbools) { int o = __offset(52); if (o != 0) { bb.put(__vector(o) + j * 1, (byte)(testarrayofbools ? 1 : 0)); return true; } else { return false; } }
+  public float testf() { int o = __offset(54); return o != 0 ? bb.getFloat(o + bb_pos) : 3.14159f; }
+  public boolean mutateTestf(float testf) { int o = __offset(54); if (o != 0) { bb.putFloat(o + bb_pos, testf); return true; } else { return false; } }
+  public float testf2() { int o = __offset(56); return o != 0 ? bb.getFloat(o + bb_pos) : 3.0f; }
+  public boolean mutateTestf2(float testf2) { int o = __offset(56); if (o != 0) { bb.putFloat(o + bb_pos, testf2); return true; } else { return false; } }
+  public float testf3() { int o = __offset(58); return o != 0 ? bb.getFloat(o + bb_pos) : 0.0f; }
+  public boolean mutateTestf3(float testf3) { int o = __offset(58); if (o != 0) { bb.putFloat(o + bb_pos, testf3); return true; } else { return false; } }
+  public String testarrayofstring2(int j) { int o = __offset(60); return o != 0 ? __string(__vector(o) + j * 4) : null; }
+  public int testarrayofstring2Length() { int o = __offset(60); return o != 0 ? __vector_len(o) : 0; }
+  public MyGame.Example.Ability testarrayofsortedstruct(int j) { return testarrayofsortedstruct(new MyGame.Example.Ability(), j); }
+  public MyGame.Example.Ability testarrayofsortedstruct(MyGame.Example.Ability obj, int j) { int o = __offset(62); return o != 0 ? obj.__assign(__vector(o) + j * 8, bb) : null; }
+  public int testarrayofsortedstructLength() { int o = __offset(62); return o != 0 ? __vector_len(o) : 0; }
+  public int flex(int j) { int o = __offset(64); return o != 0 ? bb.get(__vector(o) + j * 1) & 0xFF : 0; }
+  public int flexLength() { int o = __offset(64); return o != 0 ? __vector_len(o) : 0; }
+  public ByteBuffer flexAsByteBuffer() { return __vector_as_bytebuffer(64, 1); }
+  public ByteBuffer flexInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 64, 1); }
+  public boolean mutateFlex(int j, int flex) { int o = __offset(64); if (o != 0) { bb.put(__vector(o) + j * 1, (byte)flex); return true; } else { return false; } }
+  public MyGame.Example.Test test5(int j) { return test5(new MyGame.Example.Test(), j); }
+  public MyGame.Example.Test test5(MyGame.Example.Test obj, int j) { int o = __offset(66); return o != 0 ? obj.__assign(__vector(o) + j * 4, bb) : null; }
+  public int test5Length() { int o = __offset(66); return o != 0 ? __vector_len(o) : 0; }
+  public long vectorOfLongs(int j) { int o = __offset(68); return o != 0 ? bb.getLong(__vector(o) + j * 8) : 0; }
+  public int vectorOfLongsLength() { int o = __offset(68); return o != 0 ? __vector_len(o) : 0; }
+  public ByteBuffer vectorOfLongsAsByteBuffer() { return __vector_as_bytebuffer(68, 8); }
+  public ByteBuffer vectorOfLongsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 68, 8); }
+  public boolean mutateVectorOfLongs(int j, long vector_of_longs) { int o = __offset(68); if (o != 0) { bb.putLong(__vector(o) + j * 8, vector_of_longs); return true; } else { return false; } }
+  public double vectorOfDoubles(int j) { int o = __offset(70); return o != 0 ? bb.getDouble(__vector(o) + j * 8) : 0; }
+  public int vectorOfDoublesLength() { int o = __offset(70); return o != 0 ? __vector_len(o) : 0; }
+  public ByteBuffer vectorOfDoublesAsByteBuffer() { return __vector_as_bytebuffer(70, 8); }
+  public ByteBuffer vectorOfDoublesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 70, 8); }
+  public boolean mutateVectorOfDoubles(int j, double vector_of_doubles) { int o = __offset(70); if (o != 0) { bb.putDouble(__vector(o) + j * 8, vector_of_doubles); return true; } else { return false; } }
+  public MyGame.InParentNamespace parentNamespaceTest() { return parentNamespaceTest(new MyGame.InParentNamespace()); }
+  public MyGame.InParentNamespace parentNamespaceTest(MyGame.InParentNamespace obj) { int o = __offset(72); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; }
+  public MyGame.Example.Referrable vectorOfReferrables(int j) { return vectorOfReferrables(new MyGame.Example.Referrable(), j); }
+  public MyGame.Example.Referrable vectorOfReferrables(MyGame.Example.Referrable obj, int j) { int o = __offset(74); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; }
+  public int vectorOfReferrablesLength() { int o = __offset(74); return o != 0 ? __vector_len(o) : 0; }
+  public MyGame.Example.Referrable vectorOfReferrablesByKey(long key) { int o = __offset(74); return o != 0 ? MyGame.Example.Referrable.__lookup_by_key(null, __vector(o), key, bb) : null; }
+  public MyGame.Example.Referrable vectorOfReferrablesByKey(MyGame.Example.Referrable obj, long key) { int o = __offset(74); return o != 0 ? MyGame.Example.Referrable.__lookup_by_key(obj, __vector(o), key, bb) : null; }
+  public long singleWeakReference() { int o = __offset(76); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
+  public boolean mutateSingleWeakReference(long single_weak_reference) { int o = __offset(76); if (o != 0) { bb.putLong(o + bb_pos, single_weak_reference); return true; } else { return false; } }
+  public long vectorOfWeakReferences(int j) { int o = __offset(78); return o != 0 ? bb.getLong(__vector(o) + j * 8) : 0; }
+  public int vectorOfWeakReferencesLength() { int o = __offset(78); return o != 0 ? __vector_len(o) : 0; }
+  public ByteBuffer vectorOfWeakReferencesAsByteBuffer() { return __vector_as_bytebuffer(78, 8); }
+  public ByteBuffer vectorOfWeakReferencesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 78, 8); }
+  public boolean mutateVectorOfWeakReferences(int j, long vector_of_weak_references) { int o = __offset(78); if (o != 0) { bb.putLong(__vector(o) + j * 8, vector_of_weak_references); return true; } else { return false; } }
+  public MyGame.Example.Referrable vectorOfStrongReferrables(int j) { return vectorOfStrongReferrables(new MyGame.Example.Referrable(), j); }
+  public MyGame.Example.Referrable vectorOfStrongReferrables(MyGame.Example.Referrable obj, int j) { int o = __offset(80); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; }
+  public int vectorOfStrongReferrablesLength() { int o = __offset(80); return o != 0 ? __vector_len(o) : 0; }
+  public MyGame.Example.Referrable vectorOfStrongReferrablesByKey(long key) { int o = __offset(80); return o != 0 ? MyGame.Example.Referrable.__lookup_by_key(null, __vector(o), key, bb) : null; }
+  public MyGame.Example.Referrable vectorOfStrongReferrablesByKey(MyGame.Example.Referrable obj, long key) { int o = __offset(80); return o != 0 ? MyGame.Example.Referrable.__lookup_by_key(obj, __vector(o), key, bb) : null; }
+  public long coOwningReference() { int o = __offset(82); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
+  public boolean mutateCoOwningReference(long co_owning_reference) { int o = __offset(82); if (o != 0) { bb.putLong(o + bb_pos, co_owning_reference); return true; } else { return false; } }
+  public long vectorOfCoOwningReferences(int j) { int o = __offset(84); return o != 0 ? bb.getLong(__vector(o) + j * 8) : 0; }
+  public int vectorOfCoOwningReferencesLength() { int o = __offset(84); return o != 0 ? __vector_len(o) : 0; }
+  public ByteBuffer vectorOfCoOwningReferencesAsByteBuffer() { return __vector_as_bytebuffer(84, 8); }
+  public ByteBuffer vectorOfCoOwningReferencesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 84, 8); }
+  public boolean mutateVectorOfCoOwningReferences(int j, long vector_of_co_owning_references) { int o = __offset(84); if (o != 0) { bb.putLong(__vector(o) + j * 8, vector_of_co_owning_references); return true; } else { return false; } }
+  public long nonOwningReference() { int o = __offset(86); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
+  public boolean mutateNonOwningReference(long non_owning_reference) { int o = __offset(86); if (o != 0) { bb.putLong(o + bb_pos, non_owning_reference); return true; } else { return false; } }
+  public long vectorOfNonOwningReferences(int j) { int o = __offset(88); return o != 0 ? bb.getLong(__vector(o) + j * 8) : 0; }
+  public int vectorOfNonOwningReferencesLength() { int o = __offset(88); return o != 0 ? __vector_len(o) : 0; }
+  public ByteBuffer vectorOfNonOwningReferencesAsByteBuffer() { return __vector_as_bytebuffer(88, 8); }
+  public ByteBuffer vectorOfNonOwningReferencesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 88, 8); }
+  public boolean mutateVectorOfNonOwningReferences(int j, long vector_of_non_owning_references) { int o = __offset(88); if (o != 0) { bb.putLong(__vector(o) + j * 8, vector_of_non_owning_references); return true; } else { return false; } }
+  public byte anyUniqueType() { int o = __offset(90); return o != 0 ? bb.get(o + bb_pos) : 0; }
+  public boolean mutateAnyUniqueType(byte any_unique_type) { int o = __offset(90); if (o != 0) { bb.put(o + bb_pos, any_unique_type); return true; } else { return false; } }
+  public Table anyUnique(Table obj) { int o = __offset(92); return o != 0 ? __union(obj, o) : null; }
+  public byte anyAmbiguousType() { int o = __offset(94); return o != 0 ? bb.get(o + bb_pos) : 0; }
+  public boolean mutateAnyAmbiguousType(byte any_ambiguous_type) { int o = __offset(94); if (o != 0) { bb.put(o + bb_pos, any_ambiguous_type); return true; } else { return false; } }
+  public Table anyAmbiguous(Table obj) { int o = __offset(96); return o != 0 ? __union(obj, o) : null; }
+  public int vectorOfEnums(int j) { int o = __offset(98); return o != 0 ? bb.get(__vector(o) + j * 1) & 0xFF : 0; }
+  public int vectorOfEnumsLength() { int o = __offset(98); return o != 0 ? __vector_len(o) : 0; }
+  public ByteBuffer vectorOfEnumsAsByteBuffer() { return __vector_as_bytebuffer(98, 1); }
+  public ByteBuffer vectorOfEnumsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 98, 1); }
+  public boolean mutateVectorOfEnums(int j, int vector_of_enums) { int o = __offset(98); if (o != 0) { bb.put(__vector(o) + j * 1, (byte)vector_of_enums); return true; } else { return false; } }
+
+  public static void startMonster(FlatBufferBuilder builder) { builder.startTable(48); }
+  public static void addPos(FlatBufferBuilder builder, int posOffset) { builder.addStruct(0, posOffset, 0); }
+  public static void addMana(FlatBufferBuilder builder, short mana) { builder.addShort(1, mana, 150); }
+  public static void addHp(FlatBufferBuilder builder, short hp) { builder.addShort(2, hp, 100); }
+  public static void addName(FlatBufferBuilder builder, int nameOffset) { builder.addOffset(3, nameOffset, 0); }
+  public static void addInventory(FlatBufferBuilder builder, int inventoryOffset) { builder.addOffset(5, inventoryOffset, 0); }
+  public static int createInventoryVector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); }
+  public static void startInventoryVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
+  public static void addColor(FlatBufferBuilder builder, int color) { builder.addByte(6, (byte)color, (byte)8); }
+  public static void addTestType(FlatBufferBuilder builder, byte testType) { builder.addByte(7, testType, 0); }
+  public static void addTest(FlatBufferBuilder builder, int testOffset) { builder.addOffset(8, testOffset, 0); }
+  public static void addTest4(FlatBufferBuilder builder, int test4Offset) { builder.addOffset(9, test4Offset, 0); }
+  public static void startTest4Vector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 2); }
+  public static void addTestarrayofstring(FlatBufferBuilder builder, int testarrayofstringOffset) { builder.addOffset(10, testarrayofstringOffset, 0); }
+  public static int createTestarrayofstringVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
+  public static void startTestarrayofstringVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
+  public static void addTestarrayoftables(FlatBufferBuilder builder, int testarrayoftablesOffset) { builder.addOffset(11, testarrayoftablesOffset, 0); }
+  public static int createTestarrayoftablesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
+  public static void startTestarrayoftablesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
+  public static void addEnemy(FlatBufferBuilder builder, int enemyOffset) { builder.addOffset(12, enemyOffset, 0); }
+  public static void addTestnestedflatbuffer(FlatBufferBuilder builder, int testnestedflatbufferOffset) { builder.addOffset(13, testnestedflatbufferOffset, 0); }
+  public static int createTestnestedflatbufferVector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); }
+  public static void startTestnestedflatbufferVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
+  public static void addTestempty(FlatBufferBuilder builder, int testemptyOffset) { builder.addOffset(14, testemptyOffset, 0); }
+  public static void addTestbool(FlatBufferBuilder builder, boolean testbool) { builder.addBoolean(15, testbool, false); }
+  public static void addTesthashs32Fnv1(FlatBufferBuilder builder, int testhashs32Fnv1) { builder.addInt(16, testhashs32Fnv1, 0); }
+  public static void addTesthashu32Fnv1(FlatBufferBuilder builder, long testhashu32Fnv1) { builder.addInt(17, (int)testhashu32Fnv1, (int)0L); }
+  public static void addTesthashs64Fnv1(FlatBufferBuilder builder, long testhashs64Fnv1) { builder.addLong(18, testhashs64Fnv1, 0L); }
+  public static void addTesthashu64Fnv1(FlatBufferBuilder builder, long testhashu64Fnv1) { builder.addLong(19, testhashu64Fnv1, 0L); }
+  public static void addTesthashs32Fnv1a(FlatBufferBuilder builder, int testhashs32Fnv1a) { builder.addInt(20, testhashs32Fnv1a, 0); }
+  public static void addTesthashu32Fnv1a(FlatBufferBuilder builder, long testhashu32Fnv1a) { builder.addInt(21, (int)testhashu32Fnv1a, (int)0L); }
+  public static void addTesthashs64Fnv1a(FlatBufferBuilder builder, long testhashs64Fnv1a) { builder.addLong(22, testhashs64Fnv1a, 0L); }
+  public static void addTesthashu64Fnv1a(FlatBufferBuilder builder, long testhashu64Fnv1a) { builder.addLong(23, testhashu64Fnv1a, 0L); }
+  public static void addTestarrayofbools(FlatBufferBuilder builder, int testarrayofboolsOffset) { builder.addOffset(24, testarrayofboolsOffset, 0); }
+  public static int createTestarrayofboolsVector(FlatBufferBuilder builder, boolean[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addBoolean(data[i]); return builder.endVector(); }
+  public static void startTestarrayofboolsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
+  public static void addTestf(FlatBufferBuilder builder, float testf) { builder.addFloat(25, testf, 3.14159f); }
+  public static void addTestf2(FlatBufferBuilder builder, float testf2) { builder.addFloat(26, testf2, 3.0f); }
+  public static void addTestf3(FlatBufferBuilder builder, float testf3) { builder.addFloat(27, testf3, 0.0f); }
+  public static void addTestarrayofstring2(FlatBufferBuilder builder, int testarrayofstring2Offset) { builder.addOffset(28, testarrayofstring2Offset, 0); }
+  public static int createTestarrayofstring2Vector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
+  public static void startTestarrayofstring2Vector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
+  public static void addTestarrayofsortedstruct(FlatBufferBuilder builder, int testarrayofsortedstructOffset) { builder.addOffset(29, testarrayofsortedstructOffset, 0); }
+  public static void startTestarrayofsortedstructVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 4); }
+  public static void addFlex(FlatBufferBuilder builder, int flexOffset) { builder.addOffset(30, flexOffset, 0); }
+  public static int createFlexVector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); }
+  public static void startFlexVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
+  public static void addTest5(FlatBufferBuilder builder, int test5Offset) { builder.addOffset(31, test5Offset, 0); }
+  public static void startTest5Vector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 2); }
+  public static void addVectorOfLongs(FlatBufferBuilder builder, int vectorOfLongsOffset) { builder.addOffset(32, vectorOfLongsOffset, 0); }
+  public static int createVectorOfLongsVector(FlatBufferBuilder builder, long[] data) { builder.startVector(8, data.length, 8); for (int i = data.length - 1; i >= 0; i--) builder.addLong(data[i]); return builder.endVector(); }
+  public static void startVectorOfLongsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); }
+  public static void addVectorOfDoubles(FlatBufferBuilder builder, int vectorOfDoublesOffset) { builder.addOffset(33, vectorOfDoublesOffset, 0); }
+  public static int createVectorOfDoublesVector(FlatBufferBuilder builder, double[] data) { builder.startVector(8, data.length, 8); for (int i = data.length - 1; i >= 0; i--) builder.addDouble(data[i]); return builder.endVector(); }
+  public static void startVectorOfDoublesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); }
+  public static void addParentNamespaceTest(FlatBufferBuilder builder, int parentNamespaceTestOffset) { builder.addOffset(34, parentNamespaceTestOffset, 0); }
+  public static void addVectorOfReferrables(FlatBufferBuilder builder, int vectorOfReferrablesOffset) { builder.addOffset(35, vectorOfReferrablesOffset, 0); }
+  public static int createVectorOfReferrablesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
+  public static void startVectorOfReferrablesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
+  public static void addSingleWeakReference(FlatBufferBuilder builder, long singleWeakReference) { builder.addLong(36, singleWeakReference, 0L); }
+  public static void addVectorOfWeakReferences(FlatBufferBuilder builder, int vectorOfWeakReferencesOffset) { builder.addOffset(37, vectorOfWeakReferencesOffset, 0); }
+  public static int createVectorOfWeakReferencesVector(FlatBufferBuilder builder, long[] data) { builder.startVector(8, data.length, 8); for (int i = data.length - 1; i >= 0; i--) builder.addLong(data[i]); return builder.endVector(); }
+  public static void startVectorOfWeakReferencesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); }
+  public static void addVectorOfStrongReferrables(FlatBufferBuilder builder, int vectorOfStrongReferrablesOffset) { builder.addOffset(38, vectorOfStrongReferrablesOffset, 0); }
+  public static int createVectorOfStrongReferrablesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
+  public static void startVectorOfStrongReferrablesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
+  public static void addCoOwningReference(FlatBufferBuilder builder, long coOwningReference) { builder.addLong(39, coOwningReference, 0L); }
+  public static void addVectorOfCoOwningReferences(FlatBufferBuilder builder, int vectorOfCoOwningReferencesOffset) { builder.addOffset(40, vectorOfCoOwningReferencesOffset, 0); }
+  public static int createVectorOfCoOwningReferencesVector(FlatBufferBuilder builder, long[] data) { builder.startVector(8, data.length, 8); for (int i = data.length - 1; i >= 0; i--) builder.addLong(data[i]); return builder.endVector(); }
+  public static void startVectorOfCoOwningReferencesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); }
+  public static void addNonOwningReference(FlatBufferBuilder builder, long nonOwningReference) { builder.addLong(41, nonOwningReference, 0L); }
+  public static void addVectorOfNonOwningReferences(FlatBufferBuilder builder, int vectorOfNonOwningReferencesOffset) { builder.addOffset(42, vectorOfNonOwningReferencesOffset, 0); }
+  public static int createVectorOfNonOwningReferencesVector(FlatBufferBuilder builder, long[] data) { builder.startVector(8, data.length, 8); for (int i = data.length - 1; i >= 0; i--) builder.addLong(data[i]); return builder.endVector(); }
+  public static void startVectorOfNonOwningReferencesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); }
+  public static void addAnyUniqueType(FlatBufferBuilder builder, byte anyUniqueType) { builder.addByte(43, anyUniqueType, 0); }
+  public static void addAnyUnique(FlatBufferBuilder builder, int anyUniqueOffset) { builder.addOffset(44, anyUniqueOffset, 0); }
+  public static void addAnyAmbiguousType(FlatBufferBuilder builder, byte anyAmbiguousType) { builder.addByte(45, anyAmbiguousType, 0); }
+  public static void addAnyAmbiguous(FlatBufferBuilder builder, int anyAmbiguousOffset) { builder.addOffset(46, anyAmbiguousOffset, 0); }
+  public static void addVectorOfEnums(FlatBufferBuilder builder, int vectorOfEnumsOffset) { builder.addOffset(47, vectorOfEnumsOffset, 0); }
+  public static int createVectorOfEnumsVector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); }
+  public static void startVectorOfEnumsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
+  public static int endMonster(FlatBufferBuilder builder) {
+    int o = builder.endTable();
+    builder.required(o, 10);  // name
+    return o;
+  }
+  public static void finishMonsterBuffer(FlatBufferBuilder builder, int offset) { builder.finish(offset, "MONS"); }
+  public static void finishSizePrefixedMonsterBuffer(FlatBufferBuilder builder, int offset) { builder.finishSizePrefixed(offset, "MONS"); }
+
+  @Override
+  protected int keysCompare(Integer o1, Integer o2, ByteBuffer _bb) { return compareStrings(__offset(10, o1, _bb), __offset(10, o2, _bb), _bb); }
+
+  public static Monster __lookup_by_key(Monster obj, int vectorLocation, String key, ByteBuffer bb) {
+    byte[] byteKey = key.getBytes(Table.UTF8_CHARSET.get());
+    int span = bb.getInt(vectorLocation - 4);
+    int start = 0;
+    while (span != 0) {
+      int middle = span / 2;
+      int tableOffset = __indirect(vectorLocation + 4 * (start + middle), bb);
+      int comp = compareStrings(__offset(10, bb.capacity() - tableOffset, bb), byteKey, bb);
+      if (comp > 0) {
+        span = middle;
+      } else if (comp < 0) {
+        middle++;
+        start += middle;
+        span -= middle;
+      } else {
+        return (obj == null ? new Monster() : obj).__assign(tableOffset, bb);
+      }
+    }
+    return null;
+  }
+}
+
diff --git a/tests/MyGame/Example/Monster.kt b/tests/MyGame/Example/Monster.kt
new file mode 100644
index 0000000..71d72b8
--- /dev/null
+++ b/tests/MyGame/Example/Monster.kt
@@ -0,0 +1,974 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+/**
+ * an example documentation comment: monster object
+ */
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Monster : Table() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : Monster {
+        __init(_i, _bb)
+        return this
+    }
+    val pos : MyGame.Example.Vec3? get() = pos(MyGame.Example.Vec3())
+    fun pos(obj: MyGame.Example.Vec3) : MyGame.Example.Vec3? {
+        val o = __offset(4)
+        return if (o != 0) {
+            obj.__assign(o + bb_pos, bb)
+        } else {
+            null
+        }
+    }
+    val mana : Short
+        get() {
+            val o = __offset(6)
+            return if(o != 0) bb.getShort(o + bb_pos) else 150
+        }
+    fun mutateMana(mana: Short) : Boolean {
+        val o = __offset(6)
+        return if (o != 0) {
+            bb.putShort(o + bb_pos, mana)
+            true
+        } else {
+            false
+        }
+    }
+    val hp : Short
+        get() {
+            val o = __offset(8)
+            return if(o != 0) bb.getShort(o + bb_pos) else 100
+        }
+    fun mutateHp(hp: Short) : Boolean {
+        val o = __offset(8)
+        return if (o != 0) {
+            bb.putShort(o + bb_pos, hp)
+            true
+        } else {
+            false
+        }
+    }
+    val name : String?
+        get() {
+            val o = __offset(10)
+            return if (o != 0) __string(o + bb_pos) else null
+        }
+    val nameAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(10, 1)
+    fun nameInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 10, 1)
+    fun inventory(j: Int) : UByte {
+        val o = __offset(14)
+        return if (o != 0) {
+            bb.get(__vector(o) + j * 1).toUByte()
+        } else {
+            0u
+        }
+    }
+    val inventoryLength : Int
+        get() {
+            val o = __offset(14); return if (o != 0) __vector_len(o) else 0
+        }
+    val inventoryAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(14, 1)
+    fun inventoryInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 14, 1)
+    fun mutateInventory(j: Int, inventory: UByte) : Boolean {
+        val o = __offset(14)
+        return if (o != 0) {
+            bb.put(__vector(o) + j * 1, inventory.toByte())
+            true
+        } else {
+            false
+        }
+    }
+    val color : UByte
+        get() {
+            val o = __offset(16)
+            return if(o != 0) bb.get(o + bb_pos).toUByte() else 8u
+        }
+    fun mutateColor(color: UByte) : Boolean {
+        val o = __offset(16)
+        return if (o != 0) {
+            bb.put(o + bb_pos, color.toByte())
+            true
+        } else {
+            false
+        }
+    }
+    val testType : UByte
+        get() {
+            val o = __offset(18)
+            return if(o != 0) bb.get(o + bb_pos).toUByte() else 0u
+        }
+    fun mutateTestType(testType: UByte) : Boolean {
+        val o = __offset(18)
+        return if (o != 0) {
+            bb.put(o + bb_pos, testType.toByte())
+            true
+        } else {
+            false
+        }
+    }
+    fun test(obj: Table) : Table? {
+        val o = __offset(20); return if (o != 0) __union(obj, o) else null
+    }
+    fun test4(j: Int) : MyGame.Example.Test? = test4(MyGame.Example.Test(), j)
+    fun test4(obj: MyGame.Example.Test, j: Int) : MyGame.Example.Test? {
+        val o = __offset(22)
+        return if (o != 0) {
+            obj.__assign(__vector(o) + j * 4, bb)
+        } else {
+            null
+        }
+    }
+    val test4Length : Int
+        get() {
+            val o = __offset(22); return if (o != 0) __vector_len(o) else 0
+        }
+    fun testarrayofstring(j: Int) : String? {
+        val o = __offset(24)
+        return if (o != 0) {
+            __string(__vector(o) + j * 4)
+        } else {
+            null
+        }
+    }
+    val testarrayofstringLength : Int
+        get() {
+            val o = __offset(24); return if (o != 0) __vector_len(o) else 0
+        }
+    /**
+     * an example documentation comment: this will end up in the generated code
+     * multiline too
+     */
+    fun testarrayoftables(j: Int) : MyGame.Example.Monster? = testarrayoftables(MyGame.Example.Monster(), j)
+    fun testarrayoftables(obj: MyGame.Example.Monster, j: Int) : MyGame.Example.Monster? {
+        val o = __offset(26)
+        return if (o != 0) {
+            obj.__assign(__indirect(__vector(o) + j * 4), bb)
+        } else {
+            null
+        }
+    }
+    val testarrayoftablesLength : Int
+        get() {
+            val o = __offset(26); return if (o != 0) __vector_len(o) else 0
+        }
+    fun testarrayoftablesByKey(key: String) : MyGame.Example.Monster? {
+        val o = __offset(26)
+        return if (o != 0) {
+            MyGame.Example.Monster.__lookup_by_key(null, __vector(o), key, bb)
+        } else {
+            null
+        }
+    }
+    fun testarrayoftablesByKey(obj: MyGame.Example.Monster, key: String) : MyGame.Example.Monster? {
+        val o = __offset(26)
+        return if (o != 0) {
+            MyGame.Example.Monster.__lookup_by_key(obj, __vector(o), key, bb)
+        } else {
+            null
+        }
+    }
+    val enemy : MyGame.Example.Monster? get() = enemy(MyGame.Example.Monster())
+    fun enemy(obj: MyGame.Example.Monster) : MyGame.Example.Monster? {
+        val o = __offset(28)
+        return if (o != 0) {
+            obj.__assign(__indirect(o + bb_pos), bb)
+        } else {
+            null
+        }
+    }
+    fun testnestedflatbuffer(j: Int) : UByte {
+        val o = __offset(30)
+        return if (o != 0) {
+            bb.get(__vector(o) + j * 1).toUByte()
+        } else {
+            0u
+        }
+    }
+    val testnestedflatbufferLength : Int
+        get() {
+            val o = __offset(30); return if (o != 0) __vector_len(o) else 0
+        }
+    val testnestedflatbufferAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(30, 1)
+    fun testnestedflatbufferInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 30, 1)
+    val testnestedflatbufferAsMonster : MyGame.Example.Monster? get() = testnestedflatbufferAsMonster(MyGame.Example.Monster())
+    fun testnestedflatbufferAsMonster(obj: MyGame.Example.Monster) : MyGame.Example.Monster? {
+        val o = __offset(30)
+        return if (o != 0) {
+            obj.__assign(__indirect(__vector(o)), bb)
+        } else {
+            null
+        }
+    }
+    fun mutateTestnestedflatbuffer(j: Int, testnestedflatbuffer: UByte) : Boolean {
+        val o = __offset(30)
+        return if (o != 0) {
+            bb.put(__vector(o) + j * 1, testnestedflatbuffer.toByte())
+            true
+        } else {
+            false
+        }
+    }
+    val testempty : MyGame.Example.Stat? get() = testempty(MyGame.Example.Stat())
+    fun testempty(obj: MyGame.Example.Stat) : MyGame.Example.Stat? {
+        val o = __offset(32)
+        return if (o != 0) {
+            obj.__assign(__indirect(o + bb_pos), bb)
+        } else {
+            null
+        }
+    }
+    val testbool : Boolean
+        get() {
+            val o = __offset(34)
+            return if(o != 0) 0.toByte() != bb.get(o + bb_pos) else false
+        }
+    fun mutateTestbool(testbool: Boolean) : Boolean {
+        val o = __offset(34)
+        return if (o != 0) {
+            bb.put(o + bb_pos, (if(testbool) 1 else 0).toByte())
+            true
+        } else {
+            false
+        }
+    }
+    val testhashs32Fnv1 : Int
+        get() {
+            val o = __offset(36)
+            return if(o != 0) bb.getInt(o + bb_pos) else 0
+        }
+    fun mutateTesthashs32Fnv1(testhashs32Fnv1: Int) : Boolean {
+        val o = __offset(36)
+        return if (o != 0) {
+            bb.putInt(o + bb_pos, testhashs32Fnv1)
+            true
+        } else {
+            false
+        }
+    }
+    val testhashu32Fnv1 : UInt
+        get() {
+            val o = __offset(38)
+            return if(o != 0) bb.getInt(o + bb_pos).toUInt() else 0u
+        }
+    fun mutateTesthashu32Fnv1(testhashu32Fnv1: UInt) : Boolean {
+        val o = __offset(38)
+        return if (o != 0) {
+            bb.putInt(o + bb_pos, testhashu32Fnv1.toInt())
+            true
+        } else {
+            false
+        }
+    }
+    val testhashs64Fnv1 : Long
+        get() {
+            val o = __offset(40)
+            return if(o != 0) bb.getLong(o + bb_pos) else 0L
+        }
+    fun mutateTesthashs64Fnv1(testhashs64Fnv1: Long) : Boolean {
+        val o = __offset(40)
+        return if (o != 0) {
+            bb.putLong(o + bb_pos, testhashs64Fnv1)
+            true
+        } else {
+            false
+        }
+    }
+    val testhashu64Fnv1 : ULong
+        get() {
+            val o = __offset(42)
+            return if(o != 0) bb.getLong(o + bb_pos).toULong() else 0UL
+        }
+    fun mutateTesthashu64Fnv1(testhashu64Fnv1: ULong) : Boolean {
+        val o = __offset(42)
+        return if (o != 0) {
+            bb.putLong(o + bb_pos, testhashu64Fnv1.toLong())
+            true
+        } else {
+            false
+        }
+    }
+    val testhashs32Fnv1a : Int
+        get() {
+            val o = __offset(44)
+            return if(o != 0) bb.getInt(o + bb_pos) else 0
+        }
+    fun mutateTesthashs32Fnv1a(testhashs32Fnv1a: Int) : Boolean {
+        val o = __offset(44)
+        return if (o != 0) {
+            bb.putInt(o + bb_pos, testhashs32Fnv1a)
+            true
+        } else {
+            false
+        }
+    }
+    val testhashu32Fnv1a : UInt
+        get() {
+            val o = __offset(46)
+            return if(o != 0) bb.getInt(o + bb_pos).toUInt() else 0u
+        }
+    fun mutateTesthashu32Fnv1a(testhashu32Fnv1a: UInt) : Boolean {
+        val o = __offset(46)
+        return if (o != 0) {
+            bb.putInt(o + bb_pos, testhashu32Fnv1a.toInt())
+            true
+        } else {
+            false
+        }
+    }
+    val testhashs64Fnv1a : Long
+        get() {
+            val o = __offset(48)
+            return if(o != 0) bb.getLong(o + bb_pos) else 0L
+        }
+    fun mutateTesthashs64Fnv1a(testhashs64Fnv1a: Long) : Boolean {
+        val o = __offset(48)
+        return if (o != 0) {
+            bb.putLong(o + bb_pos, testhashs64Fnv1a)
+            true
+        } else {
+            false
+        }
+    }
+    val testhashu64Fnv1a : ULong
+        get() {
+            val o = __offset(50)
+            return if(o != 0) bb.getLong(o + bb_pos).toULong() else 0UL
+        }
+    fun mutateTesthashu64Fnv1a(testhashu64Fnv1a: ULong) : Boolean {
+        val o = __offset(50)
+        return if (o != 0) {
+            bb.putLong(o + bb_pos, testhashu64Fnv1a.toLong())
+            true
+        } else {
+            false
+        }
+    }
+    fun testarrayofbools(j: Int) : Boolean {
+        val o = __offset(52)
+        return if (o != 0) {
+            0.toByte() != bb.get(__vector(o) + j * 1)
+        } else {
+            false
+        }
+    }
+    val testarrayofboolsLength : Int
+        get() {
+            val o = __offset(52); return if (o != 0) __vector_len(o) else 0
+        }
+    val testarrayofboolsAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(52, 1)
+    fun testarrayofboolsInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 52, 1)
+    fun mutateTestarrayofbools(j: Int, testarrayofbools: Boolean) : Boolean {
+        val o = __offset(52)
+        return if (o != 0) {
+            bb.put(__vector(o) + j * 1, (if(testarrayofbools) 1 else 0).toByte())
+            true
+        } else {
+            false
+        }
+    }
+    val testf : Float
+        get() {
+            val o = __offset(54)
+            return if(o != 0) bb.getFloat(o + bb_pos) else 3.14159f
+        }
+    fun mutateTestf(testf: Float) : Boolean {
+        val o = __offset(54)
+        return if (o != 0) {
+            bb.putFloat(o + bb_pos, testf)
+            true
+        } else {
+            false
+        }
+    }
+    val testf2 : Float
+        get() {
+            val o = __offset(56)
+            return if(o != 0) bb.getFloat(o + bb_pos) else 3.0f
+        }
+    fun mutateTestf2(testf2: Float) : Boolean {
+        val o = __offset(56)
+        return if (o != 0) {
+            bb.putFloat(o + bb_pos, testf2)
+            true
+        } else {
+            false
+        }
+    }
+    val testf3 : Float
+        get() {
+            val o = __offset(58)
+            return if(o != 0) bb.getFloat(o + bb_pos) else 0.0f
+        }
+    fun mutateTestf3(testf3: Float) : Boolean {
+        val o = __offset(58)
+        return if (o != 0) {
+            bb.putFloat(o + bb_pos, testf3)
+            true
+        } else {
+            false
+        }
+    }
+    fun testarrayofstring2(j: Int) : String? {
+        val o = __offset(60)
+        return if (o != 0) {
+            __string(__vector(o) + j * 4)
+        } else {
+            null
+        }
+    }
+    val testarrayofstring2Length : Int
+        get() {
+            val o = __offset(60); return if (o != 0) __vector_len(o) else 0
+        }
+    fun testarrayofsortedstruct(j: Int) : MyGame.Example.Ability? = testarrayofsortedstruct(MyGame.Example.Ability(), j)
+    fun testarrayofsortedstruct(obj: MyGame.Example.Ability, j: Int) : MyGame.Example.Ability? {
+        val o = __offset(62)
+        return if (o != 0) {
+            obj.__assign(__vector(o) + j * 8, bb)
+        } else {
+            null
+        }
+    }
+    val testarrayofsortedstructLength : Int
+        get() {
+            val o = __offset(62); return if (o != 0) __vector_len(o) else 0
+        }
+    fun flex(j: Int) : UByte {
+        val o = __offset(64)
+        return if (o != 0) {
+            bb.get(__vector(o) + j * 1).toUByte()
+        } else {
+            0u
+        }
+    }
+    val flexLength : Int
+        get() {
+            val o = __offset(64); return if (o != 0) __vector_len(o) else 0
+        }
+    val flexAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(64, 1)
+    fun flexInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 64, 1)
+    fun mutateFlex(j: Int, flex: UByte) : Boolean {
+        val o = __offset(64)
+        return if (o != 0) {
+            bb.put(__vector(o) + j * 1, flex.toByte())
+            true
+        } else {
+            false
+        }
+    }
+    fun test5(j: Int) : MyGame.Example.Test? = test5(MyGame.Example.Test(), j)
+    fun test5(obj: MyGame.Example.Test, j: Int) : MyGame.Example.Test? {
+        val o = __offset(66)
+        return if (o != 0) {
+            obj.__assign(__vector(o) + j * 4, bb)
+        } else {
+            null
+        }
+    }
+    val test5Length : Int
+        get() {
+            val o = __offset(66); return if (o != 0) __vector_len(o) else 0
+        }
+    fun vectorOfLongs(j: Int) : Long {
+        val o = __offset(68)
+        return if (o != 0) {
+            bb.getLong(__vector(o) + j * 8)
+        } else {
+            0
+        }
+    }
+    val vectorOfLongsLength : Int
+        get() {
+            val o = __offset(68); return if (o != 0) __vector_len(o) else 0
+        }
+    val vectorOfLongsAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(68, 8)
+    fun vectorOfLongsInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 68, 8)
+    fun mutateVectorOfLongs(j: Int, vectorOfLongs: Long) : Boolean {
+        val o = __offset(68)
+        return if (o != 0) {
+            bb.putLong(__vector(o) + j * 8, vectorOfLongs)
+            true
+        } else {
+            false
+        }
+    }
+    fun vectorOfDoubles(j: Int) : Double {
+        val o = __offset(70)
+        return if (o != 0) {
+            bb.getDouble(__vector(o) + j * 8)
+        } else {
+            0.0
+        }
+    }
+    val vectorOfDoublesLength : Int
+        get() {
+            val o = __offset(70); return if (o != 0) __vector_len(o) else 0
+        }
+    val vectorOfDoublesAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(70, 8)
+    fun vectorOfDoublesInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 70, 8)
+    fun mutateVectorOfDoubles(j: Int, vectorOfDoubles: Double) : Boolean {
+        val o = __offset(70)
+        return if (o != 0) {
+            bb.putDouble(__vector(o) + j * 8, vectorOfDoubles)
+            true
+        } else {
+            false
+        }
+    }
+    val parentNamespaceTest : MyGame.InParentNamespace? get() = parentNamespaceTest(MyGame.InParentNamespace())
+    fun parentNamespaceTest(obj: MyGame.InParentNamespace) : MyGame.InParentNamespace? {
+        val o = __offset(72)
+        return if (o != 0) {
+            obj.__assign(__indirect(o + bb_pos), bb)
+        } else {
+            null
+        }
+    }
+    fun vectorOfReferrables(j: Int) : MyGame.Example.Referrable? = vectorOfReferrables(MyGame.Example.Referrable(), j)
+    fun vectorOfReferrables(obj: MyGame.Example.Referrable, j: Int) : MyGame.Example.Referrable? {
+        val o = __offset(74)
+        return if (o != 0) {
+            obj.__assign(__indirect(__vector(o) + j * 4), bb)
+        } else {
+            null
+        }
+    }
+    val vectorOfReferrablesLength : Int
+        get() {
+            val o = __offset(74); return if (o != 0) __vector_len(o) else 0
+        }
+    fun vectorOfReferrablesByKey(key: ULong) : MyGame.Example.Referrable? {
+        val o = __offset(74)
+        return if (o != 0) {
+            MyGame.Example.Referrable.__lookup_by_key(null, __vector(o), key, bb)
+        } else {
+            null
+        }
+    }
+    fun vectorOfReferrablesByKey(obj: MyGame.Example.Referrable, key: ULong) : MyGame.Example.Referrable? {
+        val o = __offset(74)
+        return if (o != 0) {
+            MyGame.Example.Referrable.__lookup_by_key(obj, __vector(o), key, bb)
+        } else {
+            null
+        }
+    }
+    val singleWeakReference : ULong
+        get() {
+            val o = __offset(76)
+            return if(o != 0) bb.getLong(o + bb_pos).toULong() else 0UL
+        }
+    fun mutateSingleWeakReference(singleWeakReference: ULong) : Boolean {
+        val o = __offset(76)
+        return if (o != 0) {
+            bb.putLong(o + bb_pos, singleWeakReference.toLong())
+            true
+        } else {
+            false
+        }
+    }
+    fun vectorOfWeakReferences(j: Int) : ULong {
+        val o = __offset(78)
+        return if (o != 0) {
+            bb.getLong(__vector(o) + j * 8).toULong()
+        } else {
+            0uL
+        }
+    }
+    val vectorOfWeakReferencesLength : Int
+        get() {
+            val o = __offset(78); return if (o != 0) __vector_len(o) else 0
+        }
+    val vectorOfWeakReferencesAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(78, 8)
+    fun vectorOfWeakReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 78, 8)
+    fun mutateVectorOfWeakReferences(j: Int, vectorOfWeakReferences: ULong) : Boolean {
+        val o = __offset(78)
+        return if (o != 0) {
+            bb.putLong(__vector(o) + j * 8, vectorOfWeakReferences.toLong())
+            true
+        } else {
+            false
+        }
+    }
+    fun vectorOfStrongReferrables(j: Int) : MyGame.Example.Referrable? = vectorOfStrongReferrables(MyGame.Example.Referrable(), j)
+    fun vectorOfStrongReferrables(obj: MyGame.Example.Referrable, j: Int) : MyGame.Example.Referrable? {
+        val o = __offset(80)
+        return if (o != 0) {
+            obj.__assign(__indirect(__vector(o) + j * 4), bb)
+        } else {
+            null
+        }
+    }
+    val vectorOfStrongReferrablesLength : Int
+        get() {
+            val o = __offset(80); return if (o != 0) __vector_len(o) else 0
+        }
+    fun vectorOfStrongReferrablesByKey(key: ULong) : MyGame.Example.Referrable? {
+        val o = __offset(80)
+        return if (o != 0) {
+            MyGame.Example.Referrable.__lookup_by_key(null, __vector(o), key, bb)
+        } else {
+            null
+        }
+    }
+    fun vectorOfStrongReferrablesByKey(obj: MyGame.Example.Referrable, key: ULong) : MyGame.Example.Referrable? {
+        val o = __offset(80)
+        return if (o != 0) {
+            MyGame.Example.Referrable.__lookup_by_key(obj, __vector(o), key, bb)
+        } else {
+            null
+        }
+    }
+    val coOwningReference : ULong
+        get() {
+            val o = __offset(82)
+            return if(o != 0) bb.getLong(o + bb_pos).toULong() else 0UL
+        }
+    fun mutateCoOwningReference(coOwningReference: ULong) : Boolean {
+        val o = __offset(82)
+        return if (o != 0) {
+            bb.putLong(o + bb_pos, coOwningReference.toLong())
+            true
+        } else {
+            false
+        }
+    }
+    fun vectorOfCoOwningReferences(j: Int) : ULong {
+        val o = __offset(84)
+        return if (o != 0) {
+            bb.getLong(__vector(o) + j * 8).toULong()
+        } else {
+            0uL
+        }
+    }
+    val vectorOfCoOwningReferencesLength : Int
+        get() {
+            val o = __offset(84); return if (o != 0) __vector_len(o) else 0
+        }
+    val vectorOfCoOwningReferencesAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(84, 8)
+    fun vectorOfCoOwningReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 84, 8)
+    fun mutateVectorOfCoOwningReferences(j: Int, vectorOfCoOwningReferences: ULong) : Boolean {
+        val o = __offset(84)
+        return if (o != 0) {
+            bb.putLong(__vector(o) + j * 8, vectorOfCoOwningReferences.toLong())
+            true
+        } else {
+            false
+        }
+    }
+    val nonOwningReference : ULong
+        get() {
+            val o = __offset(86)
+            return if(o != 0) bb.getLong(o + bb_pos).toULong() else 0UL
+        }
+    fun mutateNonOwningReference(nonOwningReference: ULong) : Boolean {
+        val o = __offset(86)
+        return if (o != 0) {
+            bb.putLong(o + bb_pos, nonOwningReference.toLong())
+            true
+        } else {
+            false
+        }
+    }
+    fun vectorOfNonOwningReferences(j: Int) : ULong {
+        val o = __offset(88)
+        return if (o != 0) {
+            bb.getLong(__vector(o) + j * 8).toULong()
+        } else {
+            0uL
+        }
+    }
+    val vectorOfNonOwningReferencesLength : Int
+        get() {
+            val o = __offset(88); return if (o != 0) __vector_len(o) else 0
+        }
+    val vectorOfNonOwningReferencesAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(88, 8)
+    fun vectorOfNonOwningReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 88, 8)
+    fun mutateVectorOfNonOwningReferences(j: Int, vectorOfNonOwningReferences: ULong) : Boolean {
+        val o = __offset(88)
+        return if (o != 0) {
+            bb.putLong(__vector(o) + j * 8, vectorOfNonOwningReferences.toLong())
+            true
+        } else {
+            false
+        }
+    }
+    val anyUniqueType : UByte
+        get() {
+            val o = __offset(90)
+            return if(o != 0) bb.get(o + bb_pos).toUByte() else 0u
+        }
+    fun mutateAnyUniqueType(anyUniqueType: UByte) : Boolean {
+        val o = __offset(90)
+        return if (o != 0) {
+            bb.put(o + bb_pos, anyUniqueType.toByte())
+            true
+        } else {
+            false
+        }
+    }
+    fun anyUnique(obj: Table) : Table? {
+        val o = __offset(92); return if (o != 0) __union(obj, o) else null
+    }
+    val anyAmbiguousType : UByte
+        get() {
+            val o = __offset(94)
+            return if(o != 0) bb.get(o + bb_pos).toUByte() else 0u
+        }
+    fun mutateAnyAmbiguousType(anyAmbiguousType: UByte) : Boolean {
+        val o = __offset(94)
+        return if (o != 0) {
+            bb.put(o + bb_pos, anyAmbiguousType.toByte())
+            true
+        } else {
+            false
+        }
+    }
+    fun anyAmbiguous(obj: Table) : Table? {
+        val o = __offset(96); return if (o != 0) __union(obj, o) else null
+    }
+    fun vectorOfEnums(j: Int) : UByte {
+        val o = __offset(98)
+        return if (o != 0) {
+            bb.get(__vector(o) + j * 1).toUByte()
+        } else {
+            0u
+        }
+    }
+    val vectorOfEnumsLength : Int
+        get() {
+            val o = __offset(98); return if (o != 0) __vector_len(o) else 0
+        }
+    val vectorOfEnumsAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(98, 1)
+    fun vectorOfEnumsInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 98, 1)
+    fun mutateVectorOfEnums(j: Int, vectorOfEnums: UByte) : Boolean {
+        val o = __offset(98)
+        return if (o != 0) {
+            bb.put(__vector(o) + j * 1, vectorOfEnums.toByte())
+            true
+        } else {
+            false
+        }
+    }
+    override fun keysCompare(o1: Int, o2: Int, _bb: ByteBuffer) : Int {
+         return compareStrings(__offset(10, o1, _bb), __offset(10, o2, _bb), _bb)
+    }
+    companion object {
+        fun validateVersion() = Constants.FLATBUFFERS_1_11_1()
+        fun getRootAsMonster(_bb: ByteBuffer): Monster = getRootAsMonster(_bb, Monster())
+        fun getRootAsMonster(_bb: ByteBuffer, obj: Monster): Monster {
+            _bb.order(ByteOrder.LITTLE_ENDIAN)
+            return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+        }
+        fun MonsterBufferHasIdentifier(_bb: ByteBuffer) : Boolean = __has_identifier(_bb, "MONS")
+        fun startMonster(builder: FlatBufferBuilder) = builder.startTable(48)
+        fun addPos(builder: FlatBufferBuilder, pos: Int) = builder.addStruct(0, pos, 0)
+        fun addMana(builder: FlatBufferBuilder, mana: Short) = builder.addShort(1, mana, 150)
+        fun addHp(builder: FlatBufferBuilder, hp: Short) = builder.addShort(2, hp, 100)
+        fun addName(builder: FlatBufferBuilder, name: Int) = builder.addOffset(3, name, 0)
+        fun addInventory(builder: FlatBufferBuilder, inventory: Int) = builder.addOffset(5, inventory, 0)
+        fun createInventoryVector(builder: FlatBufferBuilder, data: UByteArray) : Int {
+            builder.startVector(1, data.size, 1)
+            for (i in data.size - 1 downTo 0) {
+                builder.addByte(data[i].toByte())
+            }
+            return builder.endVector()
+        }
+        fun startInventoryVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(1, numElems, 1)
+        fun addColor(builder: FlatBufferBuilder, color: UByte) = builder.addByte(6, color.toByte(), 8)
+        fun addTestType(builder: FlatBufferBuilder, testType: UByte) = builder.addByte(7, testType.toByte(), 0)
+        fun addTest(builder: FlatBufferBuilder, test: Int) = builder.addOffset(8, test, 0)
+        fun addTest4(builder: FlatBufferBuilder, test4: Int) = builder.addOffset(9, test4, 0)
+        fun startTest4Vector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(4, numElems, 2)
+        fun addTestarrayofstring(builder: FlatBufferBuilder, testarrayofstring: Int) = builder.addOffset(10, testarrayofstring, 0)
+        fun createTestarrayofstringVector(builder: FlatBufferBuilder, data: IntArray) : Int {
+            builder.startVector(4, data.size, 4)
+            for (i in data.size - 1 downTo 0) {
+                builder.addOffset(data[i])
+            }
+            return builder.endVector()
+        }
+        fun startTestarrayofstringVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(4, numElems, 4)
+        fun addTestarrayoftables(builder: FlatBufferBuilder, testarrayoftables: Int) = builder.addOffset(11, testarrayoftables, 0)
+        fun createTestarrayoftablesVector(builder: FlatBufferBuilder, data: IntArray) : Int {
+            builder.startVector(4, data.size, 4)
+            for (i in data.size - 1 downTo 0) {
+                builder.addOffset(data[i])
+            }
+            return builder.endVector()
+        }
+        fun startTestarrayoftablesVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(4, numElems, 4)
+        fun addEnemy(builder: FlatBufferBuilder, enemy: Int) = builder.addOffset(12, enemy, 0)
+        fun addTestnestedflatbuffer(builder: FlatBufferBuilder, testnestedflatbuffer: Int) = builder.addOffset(13, testnestedflatbuffer, 0)
+        fun createTestnestedflatbufferVector(builder: FlatBufferBuilder, data: UByteArray) : Int {
+            builder.startVector(1, data.size, 1)
+            for (i in data.size - 1 downTo 0) {
+                builder.addByte(data[i].toByte())
+            }
+            return builder.endVector()
+        }
+        fun startTestnestedflatbufferVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(1, numElems, 1)
+        fun addTestempty(builder: FlatBufferBuilder, testempty: Int) = builder.addOffset(14, testempty, 0)
+        fun addTestbool(builder: FlatBufferBuilder, testbool: Boolean) = builder.addBoolean(15, testbool, false)
+        fun addTesthashs32Fnv1(builder: FlatBufferBuilder, testhashs32Fnv1: Int) = builder.addInt(16, testhashs32Fnv1, 0)
+        fun addTesthashu32Fnv1(builder: FlatBufferBuilder, testhashu32Fnv1: UInt) = builder.addInt(17, testhashu32Fnv1.toInt(), 0)
+        fun addTesthashs64Fnv1(builder: FlatBufferBuilder, testhashs64Fnv1: Long) = builder.addLong(18, testhashs64Fnv1, 0L)
+        fun addTesthashu64Fnv1(builder: FlatBufferBuilder, testhashu64Fnv1: ULong) = builder.addLong(19, testhashu64Fnv1.toLong(), 0)
+        fun addTesthashs32Fnv1a(builder: FlatBufferBuilder, testhashs32Fnv1a: Int) = builder.addInt(20, testhashs32Fnv1a, 0)
+        fun addTesthashu32Fnv1a(builder: FlatBufferBuilder, testhashu32Fnv1a: UInt) = builder.addInt(21, testhashu32Fnv1a.toInt(), 0)
+        fun addTesthashs64Fnv1a(builder: FlatBufferBuilder, testhashs64Fnv1a: Long) = builder.addLong(22, testhashs64Fnv1a, 0L)
+        fun addTesthashu64Fnv1a(builder: FlatBufferBuilder, testhashu64Fnv1a: ULong) = builder.addLong(23, testhashu64Fnv1a.toLong(), 0)
+        fun addTestarrayofbools(builder: FlatBufferBuilder, testarrayofbools: Int) = builder.addOffset(24, testarrayofbools, 0)
+        fun createTestarrayofboolsVector(builder: FlatBufferBuilder, data: BooleanArray) : Int {
+            builder.startVector(1, data.size, 1)
+            for (i in data.size - 1 downTo 0) {
+                builder.addBoolean(data[i])
+            }
+            return builder.endVector()
+        }
+        fun startTestarrayofboolsVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(1, numElems, 1)
+        fun addTestf(builder: FlatBufferBuilder, testf: Float) = builder.addFloat(25, testf, 3.14159)
+        fun addTestf2(builder: FlatBufferBuilder, testf2: Float) = builder.addFloat(26, testf2, 3.0)
+        fun addTestf3(builder: FlatBufferBuilder, testf3: Float) = builder.addFloat(27, testf3, 0.0)
+        fun addTestarrayofstring2(builder: FlatBufferBuilder, testarrayofstring2: Int) = builder.addOffset(28, testarrayofstring2, 0)
+        fun createTestarrayofstring2Vector(builder: FlatBufferBuilder, data: IntArray) : Int {
+            builder.startVector(4, data.size, 4)
+            for (i in data.size - 1 downTo 0) {
+                builder.addOffset(data[i])
+            }
+            return builder.endVector()
+        }
+        fun startTestarrayofstring2Vector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(4, numElems, 4)
+        fun addTestarrayofsortedstruct(builder: FlatBufferBuilder, testarrayofsortedstruct: Int) = builder.addOffset(29, testarrayofsortedstruct, 0)
+        fun startTestarrayofsortedstructVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(8, numElems, 4)
+        fun addFlex(builder: FlatBufferBuilder, flex: Int) = builder.addOffset(30, flex, 0)
+        fun createFlexVector(builder: FlatBufferBuilder, data: UByteArray) : Int {
+            builder.startVector(1, data.size, 1)
+            for (i in data.size - 1 downTo 0) {
+                builder.addByte(data[i].toByte())
+            }
+            return builder.endVector()
+        }
+        fun startFlexVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(1, numElems, 1)
+        fun addTest5(builder: FlatBufferBuilder, test5: Int) = builder.addOffset(31, test5, 0)
+        fun startTest5Vector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(4, numElems, 2)
+        fun addVectorOfLongs(builder: FlatBufferBuilder, vectorOfLongs: Int) = builder.addOffset(32, vectorOfLongs, 0)
+        fun createVectorOfLongsVector(builder: FlatBufferBuilder, data: LongArray) : Int {
+            builder.startVector(8, data.size, 8)
+            for (i in data.size - 1 downTo 0) {
+                builder.addLong(data[i])
+            }
+            return builder.endVector()
+        }
+        fun startVectorOfLongsVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(8, numElems, 8)
+        fun addVectorOfDoubles(builder: FlatBufferBuilder, vectorOfDoubles: Int) = builder.addOffset(33, vectorOfDoubles, 0)
+        fun createVectorOfDoublesVector(builder: FlatBufferBuilder, data: DoubleArray) : Int {
+            builder.startVector(8, data.size, 8)
+            for (i in data.size - 1 downTo 0) {
+                builder.addDouble(data[i])
+            }
+            return builder.endVector()
+        }
+        fun startVectorOfDoublesVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(8, numElems, 8)
+        fun addParentNamespaceTest(builder: FlatBufferBuilder, parentNamespaceTest: Int) = builder.addOffset(34, parentNamespaceTest, 0)
+        fun addVectorOfReferrables(builder: FlatBufferBuilder, vectorOfReferrables: Int) = builder.addOffset(35, vectorOfReferrables, 0)
+        fun createVectorOfReferrablesVector(builder: FlatBufferBuilder, data: IntArray) : Int {
+            builder.startVector(4, data.size, 4)
+            for (i in data.size - 1 downTo 0) {
+                builder.addOffset(data[i])
+            }
+            return builder.endVector()
+        }
+        fun startVectorOfReferrablesVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(4, numElems, 4)
+        fun addSingleWeakReference(builder: FlatBufferBuilder, singleWeakReference: ULong) = builder.addLong(36, singleWeakReference.toLong(), 0)
+        fun addVectorOfWeakReferences(builder: FlatBufferBuilder, vectorOfWeakReferences: Int) = builder.addOffset(37, vectorOfWeakReferences, 0)
+        fun createVectorOfWeakReferencesVector(builder: FlatBufferBuilder, data: ULongArray) : Int {
+            builder.startVector(8, data.size, 8)
+            for (i in data.size - 1 downTo 0) {
+                builder.addLong(data[i].toLong())
+            }
+            return builder.endVector()
+        }
+        fun startVectorOfWeakReferencesVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(8, numElems, 8)
+        fun addVectorOfStrongReferrables(builder: FlatBufferBuilder, vectorOfStrongReferrables: Int) = builder.addOffset(38, vectorOfStrongReferrables, 0)
+        fun createVectorOfStrongReferrablesVector(builder: FlatBufferBuilder, data: IntArray) : Int {
+            builder.startVector(4, data.size, 4)
+            for (i in data.size - 1 downTo 0) {
+                builder.addOffset(data[i])
+            }
+            return builder.endVector()
+        }
+        fun startVectorOfStrongReferrablesVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(4, numElems, 4)
+        fun addCoOwningReference(builder: FlatBufferBuilder, coOwningReference: ULong) = builder.addLong(39, coOwningReference.toLong(), 0)
+        fun addVectorOfCoOwningReferences(builder: FlatBufferBuilder, vectorOfCoOwningReferences: Int) = builder.addOffset(40, vectorOfCoOwningReferences, 0)
+        fun createVectorOfCoOwningReferencesVector(builder: FlatBufferBuilder, data: ULongArray) : Int {
+            builder.startVector(8, data.size, 8)
+            for (i in data.size - 1 downTo 0) {
+                builder.addLong(data[i].toLong())
+            }
+            return builder.endVector()
+        }
+        fun startVectorOfCoOwningReferencesVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(8, numElems, 8)
+        fun addNonOwningReference(builder: FlatBufferBuilder, nonOwningReference: ULong) = builder.addLong(41, nonOwningReference.toLong(), 0)
+        fun addVectorOfNonOwningReferences(builder: FlatBufferBuilder, vectorOfNonOwningReferences: Int) = builder.addOffset(42, vectorOfNonOwningReferences, 0)
+        fun createVectorOfNonOwningReferencesVector(builder: FlatBufferBuilder, data: ULongArray) : Int {
+            builder.startVector(8, data.size, 8)
+            for (i in data.size - 1 downTo 0) {
+                builder.addLong(data[i].toLong())
+            }
+            return builder.endVector()
+        }
+        fun startVectorOfNonOwningReferencesVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(8, numElems, 8)
+        fun addAnyUniqueType(builder: FlatBufferBuilder, anyUniqueType: UByte) = builder.addByte(43, anyUniqueType.toByte(), 0)
+        fun addAnyUnique(builder: FlatBufferBuilder, anyUnique: Int) = builder.addOffset(44, anyUnique, 0)
+        fun addAnyAmbiguousType(builder: FlatBufferBuilder, anyAmbiguousType: UByte) = builder.addByte(45, anyAmbiguousType.toByte(), 0)
+        fun addAnyAmbiguous(builder: FlatBufferBuilder, anyAmbiguous: Int) = builder.addOffset(46, anyAmbiguous, 0)
+        fun addVectorOfEnums(builder: FlatBufferBuilder, vectorOfEnums: Int) = builder.addOffset(47, vectorOfEnums, 0)
+        fun createVectorOfEnumsVector(builder: FlatBufferBuilder, data: UByteArray) : Int {
+            builder.startVector(1, data.size, 1)
+            for (i in data.size - 1 downTo 0) {
+                builder.addByte(data[i].toByte())
+            }
+            return builder.endVector()
+        }
+        fun startVectorOfEnumsVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(1, numElems, 1)
+        fun endMonster(builder: FlatBufferBuilder) : Int {
+            val o = builder.endTable()
+                builder.required(o, 10)
+            return o
+        }
+        fun finishMonsterBuffer(builder: FlatBufferBuilder, offset: Int) = builder.finish(offset, "MONS")
+        fun finishSizePrefixedMonsterBuffer(builder: FlatBufferBuilder, offset: Int) = builder.finishSizePrefixed(offset, "MONS")
+        fun __lookup_by_key(obj: Monster?, vectorLocation: Int, key: String, bb: ByteBuffer) : Monster? {
+            val byteKey = key.toByteArray(Table.UTF8_CHARSET.get()!!)
+            var span = bb.getInt(vectorLocation - 4)
+            var start = 0
+            while (span != 0) {
+                var middle = span / 2
+                val tableOffset = __indirect(vectorLocation + 4 * (start + middle), bb)
+                val comp = compareStrings(__offset(10, bb.capacity() - tableOffset, bb), byteKey, bb)
+                when {
+                    comp > 0 -> span = middle
+                    comp < 0 -> {
+                        middle++
+                        start += middle
+                        span -= middle
+                    }
+                    else -> {
+                        return (obj ?: Monster()).__assign(tableOffset, bb)
+                    }
+                }
+            }
+            return null
+        }
+    }
+}
diff --git a/tests/MyGame/Example/Monster.lua b/tests/MyGame/Example/Monster.lua
new file mode 100644
index 0000000..130c903
--- /dev/null
+++ b/tests/MyGame/Example/Monster.lua
@@ -0,0 +1,593 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Example
+
+local flatbuffers = require('flatbuffers')
+
+-- an example documentation comment: monster object
+local Monster = {} -- the module
+local Monster_mt = {} -- the class metatable
+
+function Monster.New()
+    local o = {}
+    setmetatable(o, {__index = Monster_mt})
+    return o
+end
+function Monster.GetRootAsMonster(buf, offset)
+    local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)
+    local o = Monster.New()
+    o:Init(buf, n + offset)
+    return o
+end
+function Monster_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function Monster_mt:Pos()
+    local o = self.view:Offset(4)
+    if o ~= 0 then
+        local x = o + self.view.pos
+        local obj = require('MyGame.Example.Vec3').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function Monster_mt:Mana()
+    local o = self.view:Offset(6)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Int16, o + self.view.pos)
+    end
+    return 150
+end
+function Monster_mt:Hp()
+    local o = self.view:Offset(8)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Int16, o + self.view.pos)
+    end
+    return 100
+end
+function Monster_mt:Name()
+    local o = self.view:Offset(10)
+    if o ~= 0 then
+        return self.view:String(o + self.view.pos)
+    end
+end
+function Monster_mt:Inventory(j)
+    local o = self.view:Offset(14)
+    if o ~= 0 then
+        local a = self.view:Vector(o)
+        return self.view:Get(flatbuffers.N.Uint8, a + ((j-1) * 1))
+    end
+    return 0
+end
+function Monster_mt:InventoryLength()
+    local o = self.view:Offset(14)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:Color()
+    local o = self.view:Offset(16)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint8, o + self.view.pos)
+    end
+    return 8
+end
+function Monster_mt:TestType()
+    local o = self.view:Offset(18)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint8, o + self.view.pos)
+    end
+    return 0
+end
+function Monster_mt:Test()
+    local o = self.view:Offset(20)
+    if o ~= 0 then
+        local obj = flatbuffers.view.New(require('flatbuffers.binaryarray').New(0), 0)
+        self.view:Union(obj, o)
+        return obj
+    end
+end
+function Monster_mt:Test4(j)
+    local o = self.view:Offset(22)
+    if o ~= 0 then
+        local x = self.view:Vector(o)
+        x = x + ((j-1) * 4)
+        local obj = require('MyGame.Example.Test').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function Monster_mt:Test4Length()
+    local o = self.view:Offset(22)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:Testarrayofstring(j)
+    local o = self.view:Offset(24)
+    if o ~= 0 then
+        local a = self.view:Vector(o)
+        return self.view:String(a + ((j-1) * 4))
+    end
+    return ''
+end
+function Monster_mt:TestarrayofstringLength()
+    local o = self.view:Offset(24)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+-- an example documentation comment: this will end up in the generated code
+-- multiline too
+function Monster_mt:Testarrayoftables(j)
+    local o = self.view:Offset(26)
+    if o ~= 0 then
+        local x = self.view:Vector(o)
+        x = x + ((j-1) * 4)
+        x = self.view:Indirect(x)
+        local obj = require('MyGame.Example.Monster').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function Monster_mt:TestarrayoftablesLength()
+    local o = self.view:Offset(26)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:Enemy()
+    local o = self.view:Offset(28)
+    if o ~= 0 then
+        local x = self.view:Indirect(o + self.view.pos)
+        local obj = require('MyGame.Example.Monster').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function Monster_mt:Testnestedflatbuffer(j)
+    local o = self.view:Offset(30)
+    if o ~= 0 then
+        local a = self.view:Vector(o)
+        return self.view:Get(flatbuffers.N.Uint8, a + ((j-1) * 1))
+    end
+    return 0
+end
+function Monster_mt:TestnestedflatbufferLength()
+    local o = self.view:Offset(30)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:Testempty()
+    local o = self.view:Offset(32)
+    if o ~= 0 then
+        local x = self.view:Indirect(o + self.view.pos)
+        local obj = require('MyGame.Example.Stat').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function Monster_mt:Testbool()
+    local o = self.view:Offset(34)
+    if o ~= 0 then
+        return (self.view:Get(flatbuffers.N.Bool, o + self.view.pos) ~= 0)
+    end
+    return false
+end
+function Monster_mt:Testhashs32Fnv1()
+    local o = self.view:Offset(36)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Int32, o + self.view.pos)
+    end
+    return 0
+end
+function Monster_mt:Testhashu32Fnv1()
+    local o = self.view:Offset(38)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint32, o + self.view.pos)
+    end
+    return 0
+end
+function Monster_mt:Testhashs64Fnv1()
+    local o = self.view:Offset(40)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Int64, o + self.view.pos)
+    end
+    return 0
+end
+function Monster_mt:Testhashu64Fnv1()
+    local o = self.view:Offset(42)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint64, o + self.view.pos)
+    end
+    return 0
+end
+function Monster_mt:Testhashs32Fnv1a()
+    local o = self.view:Offset(44)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Int32, o + self.view.pos)
+    end
+    return 0
+end
+function Monster_mt:Testhashu32Fnv1a()
+    local o = self.view:Offset(46)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint32, o + self.view.pos)
+    end
+    return 0
+end
+function Monster_mt:Testhashs64Fnv1a()
+    local o = self.view:Offset(48)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Int64, o + self.view.pos)
+    end
+    return 0
+end
+function Monster_mt:Testhashu64Fnv1a()
+    local o = self.view:Offset(50)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint64, o + self.view.pos)
+    end
+    return 0
+end
+function Monster_mt:Testarrayofbools(j)
+    local o = self.view:Offset(52)
+    if o ~= 0 then
+        local a = self.view:Vector(o)
+        return self.view:Get(flatbuffers.N.Bool, a + ((j-1) * 1))
+    end
+    return 0
+end
+function Monster_mt:TestarrayofboolsLength()
+    local o = self.view:Offset(52)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:Testf()
+    local o = self.view:Offset(54)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Float32, o + self.view.pos)
+    end
+    return 3.14159
+end
+function Monster_mt:Testf2()
+    local o = self.view:Offset(56)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Float32, o + self.view.pos)
+    end
+    return 3.0
+end
+function Monster_mt:Testf3()
+    local o = self.view:Offset(58)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Float32, o + self.view.pos)
+    end
+    return 0.0
+end
+function Monster_mt:Testarrayofstring2(j)
+    local o = self.view:Offset(60)
+    if o ~= 0 then
+        local a = self.view:Vector(o)
+        return self.view:String(a + ((j-1) * 4))
+    end
+    return ''
+end
+function Monster_mt:Testarrayofstring2Length()
+    local o = self.view:Offset(60)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:Testarrayofsortedstruct(j)
+    local o = self.view:Offset(62)
+    if o ~= 0 then
+        local x = self.view:Vector(o)
+        x = x + ((j-1) * 8)
+        local obj = require('MyGame.Example.Ability').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function Monster_mt:TestarrayofsortedstructLength()
+    local o = self.view:Offset(62)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:Flex(j)
+    local o = self.view:Offset(64)
+    if o ~= 0 then
+        local a = self.view:Vector(o)
+        return self.view:Get(flatbuffers.N.Uint8, a + ((j-1) * 1))
+    end
+    return 0
+end
+function Monster_mt:FlexLength()
+    local o = self.view:Offset(64)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:Test5(j)
+    local o = self.view:Offset(66)
+    if o ~= 0 then
+        local x = self.view:Vector(o)
+        x = x + ((j-1) * 4)
+        local obj = require('MyGame.Example.Test').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function Monster_mt:Test5Length()
+    local o = self.view:Offset(66)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:VectorOfLongs(j)
+    local o = self.view:Offset(68)
+    if o ~= 0 then
+        local a = self.view:Vector(o)
+        return self.view:Get(flatbuffers.N.Int64, a + ((j-1) * 8))
+    end
+    return 0
+end
+function Monster_mt:VectorOfLongsLength()
+    local o = self.view:Offset(68)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:VectorOfDoubles(j)
+    local o = self.view:Offset(70)
+    if o ~= 0 then
+        local a = self.view:Vector(o)
+        return self.view:Get(flatbuffers.N.Float64, a + ((j-1) * 8))
+    end
+    return 0
+end
+function Monster_mt:VectorOfDoublesLength()
+    local o = self.view:Offset(70)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:ParentNamespaceTest()
+    local o = self.view:Offset(72)
+    if o ~= 0 then
+        local x = self.view:Indirect(o + self.view.pos)
+        local obj = require('MyGame.InParentNamespace').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function Monster_mt:VectorOfReferrables(j)
+    local o = self.view:Offset(74)
+    if o ~= 0 then
+        local x = self.view:Vector(o)
+        x = x + ((j-1) * 4)
+        x = self.view:Indirect(x)
+        local obj = require('MyGame.Example.Referrable').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function Monster_mt:VectorOfReferrablesLength()
+    local o = self.view:Offset(74)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:SingleWeakReference()
+    local o = self.view:Offset(76)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint64, o + self.view.pos)
+    end
+    return 0
+end
+function Monster_mt:VectorOfWeakReferences(j)
+    local o = self.view:Offset(78)
+    if o ~= 0 then
+        local a = self.view:Vector(o)
+        return self.view:Get(flatbuffers.N.Uint64, a + ((j-1) * 8))
+    end
+    return 0
+end
+function Monster_mt:VectorOfWeakReferencesLength()
+    local o = self.view:Offset(78)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:VectorOfStrongReferrables(j)
+    local o = self.view:Offset(80)
+    if o ~= 0 then
+        local x = self.view:Vector(o)
+        x = x + ((j-1) * 4)
+        x = self.view:Indirect(x)
+        local obj = require('MyGame.Example.Referrable').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function Monster_mt:VectorOfStrongReferrablesLength()
+    local o = self.view:Offset(80)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:CoOwningReference()
+    local o = self.view:Offset(82)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint64, o + self.view.pos)
+    end
+    return 0
+end
+function Monster_mt:VectorOfCoOwningReferences(j)
+    local o = self.view:Offset(84)
+    if o ~= 0 then
+        local a = self.view:Vector(o)
+        return self.view:Get(flatbuffers.N.Uint64, a + ((j-1) * 8))
+    end
+    return 0
+end
+function Monster_mt:VectorOfCoOwningReferencesLength()
+    local o = self.view:Offset(84)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:NonOwningReference()
+    local o = self.view:Offset(86)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint64, o + self.view.pos)
+    end
+    return 0
+end
+function Monster_mt:VectorOfNonOwningReferences(j)
+    local o = self.view:Offset(88)
+    if o ~= 0 then
+        local a = self.view:Vector(o)
+        return self.view:Get(flatbuffers.N.Uint64, a + ((j-1) * 8))
+    end
+    return 0
+end
+function Monster_mt:VectorOfNonOwningReferencesLength()
+    local o = self.view:Offset(88)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:AnyUniqueType()
+    local o = self.view:Offset(90)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint8, o + self.view.pos)
+    end
+    return 0
+end
+function Monster_mt:AnyUnique()
+    local o = self.view:Offset(92)
+    if o ~= 0 then
+        local obj = flatbuffers.view.New(require('flatbuffers.binaryarray').New(0), 0)
+        self.view:Union(obj, o)
+        return obj
+    end
+end
+function Monster_mt:AnyAmbiguousType()
+    local o = self.view:Offset(94)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint8, o + self.view.pos)
+    end
+    return 0
+end
+function Monster_mt:AnyAmbiguous()
+    local o = self.view:Offset(96)
+    if o ~= 0 then
+        local obj = flatbuffers.view.New(require('flatbuffers.binaryarray').New(0), 0)
+        self.view:Union(obj, o)
+        return obj
+    end
+end
+function Monster_mt:VectorOfEnums(j)
+    local o = self.view:Offset(98)
+    if o ~= 0 then
+        local a = self.view:Vector(o)
+        return self.view:Get(flatbuffers.N.Uint8, a + ((j-1) * 1))
+    end
+    return 0
+end
+function Monster_mt:VectorOfEnumsLength()
+    local o = self.view:Offset(98)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster.Start(builder) builder:StartObject(48) end
+function Monster.AddPos(builder, pos) builder:PrependStructSlot(0, pos, 0) end
+function Monster.AddMana(builder, mana) builder:PrependInt16Slot(1, mana, 150) end
+function Monster.AddHp(builder, hp) builder:PrependInt16Slot(2, hp, 100) end
+function Monster.AddName(builder, name) builder:PrependUOffsetTRelativeSlot(3, name, 0) end
+function Monster.AddInventory(builder, inventory) builder:PrependUOffsetTRelativeSlot(5, inventory, 0) end
+function Monster.StartInventoryVector(builder, numElems) return builder:StartVector(1, numElems, 1) end
+function Monster.AddColor(builder, color) builder:PrependUint8Slot(6, color, 8) end
+function Monster.AddTestType(builder, testType) builder:PrependUint8Slot(7, testType, 0) end
+function Monster.AddTest(builder, test) builder:PrependUOffsetTRelativeSlot(8, test, 0) end
+function Monster.AddTest4(builder, test4) builder:PrependUOffsetTRelativeSlot(9, test4, 0) end
+function Monster.StartTest4Vector(builder, numElems) return builder:StartVector(4, numElems, 2) end
+function Monster.AddTestarrayofstring(builder, testarrayofstring) builder:PrependUOffsetTRelativeSlot(10, testarrayofstring, 0) end
+function Monster.StartTestarrayofstringVector(builder, numElems) return builder:StartVector(4, numElems, 4) end
+function Monster.AddTestarrayoftables(builder, testarrayoftables) builder:PrependUOffsetTRelativeSlot(11, testarrayoftables, 0) end
+function Monster.StartTestarrayoftablesVector(builder, numElems) return builder:StartVector(4, numElems, 4) end
+function Monster.AddEnemy(builder, enemy) builder:PrependUOffsetTRelativeSlot(12, enemy, 0) end
+function Monster.AddTestnestedflatbuffer(builder, testnestedflatbuffer) builder:PrependUOffsetTRelativeSlot(13, testnestedflatbuffer, 0) end
+function Monster.StartTestnestedflatbufferVector(builder, numElems) return builder:StartVector(1, numElems, 1) end
+function Monster.AddTestempty(builder, testempty) builder:PrependUOffsetTRelativeSlot(14, testempty, 0) end
+function Monster.AddTestbool(builder, testbool) builder:PrependBoolSlot(15, testbool, 0) end
+function Monster.AddTesthashs32Fnv1(builder, testhashs32Fnv1) builder:PrependInt32Slot(16, testhashs32Fnv1, 0) end
+function Monster.AddTesthashu32Fnv1(builder, testhashu32Fnv1) builder:PrependUint32Slot(17, testhashu32Fnv1, 0) end
+function Monster.AddTesthashs64Fnv1(builder, testhashs64Fnv1) builder:PrependInt64Slot(18, testhashs64Fnv1, 0) end
+function Monster.AddTesthashu64Fnv1(builder, testhashu64Fnv1) builder:PrependUint64Slot(19, testhashu64Fnv1, 0) end
+function Monster.AddTesthashs32Fnv1a(builder, testhashs32Fnv1a) builder:PrependInt32Slot(20, testhashs32Fnv1a, 0) end
+function Monster.AddTesthashu32Fnv1a(builder, testhashu32Fnv1a) builder:PrependUint32Slot(21, testhashu32Fnv1a, 0) end
+function Monster.AddTesthashs64Fnv1a(builder, testhashs64Fnv1a) builder:PrependInt64Slot(22, testhashs64Fnv1a, 0) end
+function Monster.AddTesthashu64Fnv1a(builder, testhashu64Fnv1a) builder:PrependUint64Slot(23, testhashu64Fnv1a, 0) end
+function Monster.AddTestarrayofbools(builder, testarrayofbools) builder:PrependUOffsetTRelativeSlot(24, testarrayofbools, 0) end
+function Monster.StartTestarrayofboolsVector(builder, numElems) return builder:StartVector(1, numElems, 1) end
+function Monster.AddTestf(builder, testf) builder:PrependFloat32Slot(25, testf, 3.14159) end
+function Monster.AddTestf2(builder, testf2) builder:PrependFloat32Slot(26, testf2, 3.0) end
+function Monster.AddTestf3(builder, testf3) builder:PrependFloat32Slot(27, testf3, 0.0) end
+function Monster.AddTestarrayofstring2(builder, testarrayofstring2) builder:PrependUOffsetTRelativeSlot(28, testarrayofstring2, 0) end
+function Monster.StartTestarrayofstring2Vector(builder, numElems) return builder:StartVector(4, numElems, 4) end
+function Monster.AddTestarrayofsortedstruct(builder, testarrayofsortedstruct) builder:PrependUOffsetTRelativeSlot(29, testarrayofsortedstruct, 0) end
+function Monster.StartTestarrayofsortedstructVector(builder, numElems) return builder:StartVector(8, numElems, 4) end
+function Monster.AddFlex(builder, flex) builder:PrependUOffsetTRelativeSlot(30, flex, 0) end
+function Monster.StartFlexVector(builder, numElems) return builder:StartVector(1, numElems, 1) end
+function Monster.AddTest5(builder, test5) builder:PrependUOffsetTRelativeSlot(31, test5, 0) end
+function Monster.StartTest5Vector(builder, numElems) return builder:StartVector(4, numElems, 2) end
+function Monster.AddVectorOfLongs(builder, vectorOfLongs) builder:PrependUOffsetTRelativeSlot(32, vectorOfLongs, 0) end
+function Monster.StartVectorOfLongsVector(builder, numElems) return builder:StartVector(8, numElems, 8) end
+function Monster.AddVectorOfDoubles(builder, vectorOfDoubles) builder:PrependUOffsetTRelativeSlot(33, vectorOfDoubles, 0) end
+function Monster.StartVectorOfDoublesVector(builder, numElems) return builder:StartVector(8, numElems, 8) end
+function Monster.AddParentNamespaceTest(builder, parentNamespaceTest) builder:PrependUOffsetTRelativeSlot(34, parentNamespaceTest, 0) end
+function Monster.AddVectorOfReferrables(builder, vectorOfReferrables) builder:PrependUOffsetTRelativeSlot(35, vectorOfReferrables, 0) end
+function Monster.StartVectorOfReferrablesVector(builder, numElems) return builder:StartVector(4, numElems, 4) end
+function Monster.AddSingleWeakReference(builder, singleWeakReference) builder:PrependUint64Slot(36, singleWeakReference, 0) end
+function Monster.AddVectorOfWeakReferences(builder, vectorOfWeakReferences) builder:PrependUOffsetTRelativeSlot(37, vectorOfWeakReferences, 0) end
+function Monster.StartVectorOfWeakReferencesVector(builder, numElems) return builder:StartVector(8, numElems, 8) end
+function Monster.AddVectorOfStrongReferrables(builder, vectorOfStrongReferrables) builder:PrependUOffsetTRelativeSlot(38, vectorOfStrongReferrables, 0) end
+function Monster.StartVectorOfStrongReferrablesVector(builder, numElems) return builder:StartVector(4, numElems, 4) end
+function Monster.AddCoOwningReference(builder, coOwningReference) builder:PrependUint64Slot(39, coOwningReference, 0) end
+function Monster.AddVectorOfCoOwningReferences(builder, vectorOfCoOwningReferences) builder:PrependUOffsetTRelativeSlot(40, vectorOfCoOwningReferences, 0) end
+function Monster.StartVectorOfCoOwningReferencesVector(builder, numElems) return builder:StartVector(8, numElems, 8) end
+function Monster.AddNonOwningReference(builder, nonOwningReference) builder:PrependUint64Slot(41, nonOwningReference, 0) end
+function Monster.AddVectorOfNonOwningReferences(builder, vectorOfNonOwningReferences) builder:PrependUOffsetTRelativeSlot(42, vectorOfNonOwningReferences, 0) end
+function Monster.StartVectorOfNonOwningReferencesVector(builder, numElems) return builder:StartVector(8, numElems, 8) end
+function Monster.AddAnyUniqueType(builder, anyUniqueType) builder:PrependUint8Slot(43, anyUniqueType, 0) end
+function Monster.AddAnyUnique(builder, anyUnique) builder:PrependUOffsetTRelativeSlot(44, anyUnique, 0) end
+function Monster.AddAnyAmbiguousType(builder, anyAmbiguousType) builder:PrependUint8Slot(45, anyAmbiguousType, 0) end
+function Monster.AddAnyAmbiguous(builder, anyAmbiguous) builder:PrependUOffsetTRelativeSlot(46, anyAmbiguous, 0) end
+function Monster.AddVectorOfEnums(builder, vectorOfEnums) builder:PrependUOffsetTRelativeSlot(47, vectorOfEnums, 0) end
+function Monster.StartVectorOfEnumsVector(builder, numElems) return builder:StartVector(1, numElems, 1) end
+function Monster.End(builder) return builder:EndObject() end
+
+return Monster -- return the module
\ No newline at end of file
diff --git a/tests/MyGame/Example/Monster.php b/tests/MyGame/Example/Monster.php
new file mode 100644
index 0000000..7d6de87b
--- /dev/null
+++ b/tests/MyGame/Example/Monster.php
@@ -0,0 +1,1647 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace MyGame\Example;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+/// an example documentation comment: monster object
+class Monster extends Table
+{
+    /**
+     * @param ByteBuffer $bb
+     * @return Monster
+     */
+    public static function getRootAsMonster(ByteBuffer $bb)
+    {
+        $obj = new Monster();
+        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
+    }
+
+    public static function MonsterIdentifier()
+    {
+        return "MONS";
+    }
+
+    public static function MonsterBufferHasIdentifier(ByteBuffer $buf)
+    {
+        return self::__has_identifier($buf, self::MonsterIdentifier());
+    }
+
+    public static function MonsterExtension()
+    {
+        return "mon";
+    }
+
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return Monster
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    public function getPos()
+    {
+        $obj = new Vec3();
+        $o = $this->__offset(4);
+        return $o != 0 ? $obj->init($o + $this->bb_pos, $this->bb) : 0;
+    }
+
+    /**
+     * @return short
+     */
+    public function getMana()
+    {
+        $o = $this->__offset(6);
+        return $o != 0 ? $this->bb->getShort($o + $this->bb_pos) : 150;
+    }
+
+    /**
+     * @return short
+     */
+    public function getHp()
+    {
+        $o = $this->__offset(8);
+        return $o != 0 ? $this->bb->getShort($o + $this->bb_pos) : 100;
+    }
+
+    public function getName()
+    {
+        $o = $this->__offset(10);
+        return $o != 0 ? $this->__string($o + $this->bb_pos) : null;
+    }
+
+    /**
+     * @param int offset
+     * @return byte
+     */
+    public function getInventory($j)
+    {
+        $o = $this->__offset(14);
+        return $o != 0 ? $this->bb->getByte($this->__vector($o) + $j * 1) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getInventoryLength()
+    {
+        $o = $this->__offset(14);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @return string
+     */
+    public function getInventoryBytes()
+    {
+        return $this->__vector_as_bytes(14);
+    }
+
+    /**
+     * @return byte
+     */
+    public function getColor()
+    {
+        $o = $this->__offset(16);
+        return $o != 0 ? $this->bb->getByte($o + $this->bb_pos) : \MyGame\Example\Color::Blue;
+    }
+
+    /**
+     * @return byte
+     */
+    public function getTestType()
+    {
+        $o = $this->__offset(18);
+        return $o != 0 ? $this->bb->getByte($o + $this->bb_pos) : \MyGame\Example\Any::NONE;
+    }
+
+    /**
+     * @returnint
+     */
+    public function getTest($obj)
+    {
+        $o = $this->__offset(20);
+        return $o != 0 ? $this->__union($obj, $o) : null;
+    }
+
+    /**
+     * @returnVectorOffset
+     */
+    public function getTest4($j)
+    {
+        $o = $this->__offset(22);
+        $obj = new Test();
+        return $o != 0 ? $obj->init($this->__vector($o) + $j *4, $this->bb) : null;
+    }
+
+    /**
+     * @return int
+     */
+    public function getTest4Length()
+    {
+        $o = $this->__offset(22);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @param int offset
+     * @return string
+     */
+    public function getTestarrayofstring($j)
+    {
+        $o = $this->__offset(24);
+        return $o != 0 ? $this->__string($this->__vector($o) + $j * 4) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getTestarrayofstringLength()
+    {
+        $o = $this->__offset(24);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /// an example documentation comment: this will end up in the generated code
+    /// multiline too
+    /**
+     * @returnVectorOffset
+     */
+    public function getTestarrayoftables($j)
+    {
+        $o = $this->__offset(26);
+        $obj = new Monster();
+        return $o != 0 ? $obj->init($this->__indirect($this->__vector($o) + $j * 4), $this->bb) : null;
+    }
+
+    /**
+     * @return int
+     */
+    public function getTestarrayoftablesLength()
+    {
+        $o = $this->__offset(26);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    public function getEnemy()
+    {
+        $obj = new Monster();
+        $o = $this->__offset(28);
+        return $o != 0 ? $obj->init($this->__indirect($o + $this->bb_pos), $this->bb) : 0;
+    }
+
+    /**
+     * @param int offset
+     * @return byte
+     */
+    public function getTestnestedflatbuffer($j)
+    {
+        $o = $this->__offset(30);
+        return $o != 0 ? $this->bb->getByte($this->__vector($o) + $j * 1) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getTestnestedflatbufferLength()
+    {
+        $o = $this->__offset(30);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @return string
+     */
+    public function getTestnestedflatbufferBytes()
+    {
+        return $this->__vector_as_bytes(30);
+    }
+
+    public function getTestempty()
+    {
+        $obj = new Stat();
+        $o = $this->__offset(32);
+        return $o != 0 ? $obj->init($this->__indirect($o + $this->bb_pos), $this->bb) : 0;
+    }
+
+    /**
+     * @return bool
+     */
+    public function getTestbool()
+    {
+        $o = $this->__offset(34);
+        return $o != 0 ? $this->bb->getBool($o + $this->bb_pos) : false;
+    }
+
+    /**
+     * @return int
+     */
+    public function getTesthashs32Fnv1()
+    {
+        $o = $this->__offset(36);
+        return $o != 0 ? $this->bb->getInt($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return uint
+     */
+    public function getTesthashu32Fnv1()
+    {
+        $o = $this->__offset(38);
+        return $o != 0 ? $this->bb->getUint($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return long
+     */
+    public function getTesthashs64Fnv1()
+    {
+        $o = $this->__offset(40);
+        return $o != 0 ? $this->bb->getLong($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return ulong
+     */
+    public function getTesthashu64Fnv1()
+    {
+        $o = $this->__offset(42);
+        return $o != 0 ? $this->bb->getUlong($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getTesthashs32Fnv1a()
+    {
+        $o = $this->__offset(44);
+        return $o != 0 ? $this->bb->getInt($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return uint
+     */
+    public function getTesthashu32Fnv1a()
+    {
+        $o = $this->__offset(46);
+        return $o != 0 ? $this->bb->getUint($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return long
+     */
+    public function getTesthashs64Fnv1a()
+    {
+        $o = $this->__offset(48);
+        return $o != 0 ? $this->bb->getLong($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return ulong
+     */
+    public function getTesthashu64Fnv1a()
+    {
+        $o = $this->__offset(50);
+        return $o != 0 ? $this->bb->getUlong($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @param int offset
+     * @return bool
+     */
+    public function getTestarrayofbools($j)
+    {
+        $o = $this->__offset(52);
+        return $o != 0 ? $this->bb->getBool($this->__vector($o) + $j * 1) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getTestarrayofboolsLength()
+    {
+        $o = $this->__offset(52);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @return float
+     */
+    public function getTestf()
+    {
+        $o = $this->__offset(54);
+        return $o != 0 ? $this->bb->getFloat($o + $this->bb_pos) : 3.14159;
+    }
+
+    /**
+     * @return float
+     */
+    public function getTestf2()
+    {
+        $o = $this->__offset(56);
+        return $o != 0 ? $this->bb->getFloat($o + $this->bb_pos) : 3.0;
+    }
+
+    /**
+     * @return float
+     */
+    public function getTestf3()
+    {
+        $o = $this->__offset(58);
+        return $o != 0 ? $this->bb->getFloat($o + $this->bb_pos) : 0.0;
+    }
+
+    /**
+     * @param int offset
+     * @return string
+     */
+    public function getTestarrayofstring2($j)
+    {
+        $o = $this->__offset(60);
+        return $o != 0 ? $this->__string($this->__vector($o) + $j * 4) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getTestarrayofstring2Length()
+    {
+        $o = $this->__offset(60);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @returnVectorOffset
+     */
+    public function getTestarrayofsortedstruct($j)
+    {
+        $o = $this->__offset(62);
+        $obj = new Ability();
+        return $o != 0 ? $obj->init($this->__vector($o) + $j *8, $this->bb) : null;
+    }
+
+    /**
+     * @return int
+     */
+    public function getTestarrayofsortedstructLength()
+    {
+        $o = $this->__offset(62);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @param int offset
+     * @return byte
+     */
+    public function getFlex($j)
+    {
+        $o = $this->__offset(64);
+        return $o != 0 ? $this->bb->getByte($this->__vector($o) + $j * 1) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getFlexLength()
+    {
+        $o = $this->__offset(64);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @return string
+     */
+    public function getFlexBytes()
+    {
+        return $this->__vector_as_bytes(64);
+    }
+
+    /**
+     * @returnVectorOffset
+     */
+    public function getTest5($j)
+    {
+        $o = $this->__offset(66);
+        $obj = new Test();
+        return $o != 0 ? $obj->init($this->__vector($o) + $j *4, $this->bb) : null;
+    }
+
+    /**
+     * @return int
+     */
+    public function getTest5Length()
+    {
+        $o = $this->__offset(66);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @param int offset
+     * @return long
+     */
+    public function getVectorOfLongs($j)
+    {
+        $o = $this->__offset(68);
+        return $o != 0 ? $this->bb->getLong($this->__vector($o) + $j * 8) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getVectorOfLongsLength()
+    {
+        $o = $this->__offset(68);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @param int offset
+     * @return double
+     */
+    public function getVectorOfDoubles($j)
+    {
+        $o = $this->__offset(70);
+        return $o != 0 ? $this->bb->getDouble($this->__vector($o) + $j * 8) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getVectorOfDoublesLength()
+    {
+        $o = $this->__offset(70);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    public function getParentNamespaceTest()
+    {
+        $obj = new InParentNamespace();
+        $o = $this->__offset(72);
+        return $o != 0 ? $obj->init($this->__indirect($o + $this->bb_pos), $this->bb) : 0;
+    }
+
+    /**
+     * @returnVectorOffset
+     */
+    public function getVectorOfReferrables($j)
+    {
+        $o = $this->__offset(74);
+        $obj = new Referrable();
+        return $o != 0 ? $obj->init($this->__indirect($this->__vector($o) + $j * 4), $this->bb) : null;
+    }
+
+    /**
+     * @return int
+     */
+    public function getVectorOfReferrablesLength()
+    {
+        $o = $this->__offset(74);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @return ulong
+     */
+    public function getSingleWeakReference()
+    {
+        $o = $this->__offset(76);
+        return $o != 0 ? $this->bb->getUlong($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @param int offset
+     * @return ulong
+     */
+    public function getVectorOfWeakReferences($j)
+    {
+        $o = $this->__offset(78);
+        return $o != 0 ? $this->bb->getUlong($this->__vector($o) + $j * 8) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getVectorOfWeakReferencesLength()
+    {
+        $o = $this->__offset(78);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @returnVectorOffset
+     */
+    public function getVectorOfStrongReferrables($j)
+    {
+        $o = $this->__offset(80);
+        $obj = new Referrable();
+        return $o != 0 ? $obj->init($this->__indirect($this->__vector($o) + $j * 4), $this->bb) : null;
+    }
+
+    /**
+     * @return int
+     */
+    public function getVectorOfStrongReferrablesLength()
+    {
+        $o = $this->__offset(80);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @return ulong
+     */
+    public function getCoOwningReference()
+    {
+        $o = $this->__offset(82);
+        return $o != 0 ? $this->bb->getUlong($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @param int offset
+     * @return ulong
+     */
+    public function getVectorOfCoOwningReferences($j)
+    {
+        $o = $this->__offset(84);
+        return $o != 0 ? $this->bb->getUlong($this->__vector($o) + $j * 8) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getVectorOfCoOwningReferencesLength()
+    {
+        $o = $this->__offset(84);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @return ulong
+     */
+    public function getNonOwningReference()
+    {
+        $o = $this->__offset(86);
+        return $o != 0 ? $this->bb->getUlong($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @param int offset
+     * @return ulong
+     */
+    public function getVectorOfNonOwningReferences($j)
+    {
+        $o = $this->__offset(88);
+        return $o != 0 ? $this->bb->getUlong($this->__vector($o) + $j * 8) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getVectorOfNonOwningReferencesLength()
+    {
+        $o = $this->__offset(88);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @return byte
+     */
+    public function getAnyUniqueType()
+    {
+        $o = $this->__offset(90);
+        return $o != 0 ? $this->bb->getByte($o + $this->bb_pos) : \MyGame\Example\AnyUniqueAliases::NONE;
+    }
+
+    /**
+     * @returnint
+     */
+    public function getAnyUnique($obj)
+    {
+        $o = $this->__offset(92);
+        return $o != 0 ? $this->__union($obj, $o) : null;
+    }
+
+    /**
+     * @return byte
+     */
+    public function getAnyAmbiguousType()
+    {
+        $o = $this->__offset(94);
+        return $o != 0 ? $this->bb->getByte($o + $this->bb_pos) : \MyGame\Example\AnyAmbiguousAliases::NONE;
+    }
+
+    /**
+     * @returnint
+     */
+    public function getAnyAmbiguous($obj)
+    {
+        $o = $this->__offset(96);
+        return $o != 0 ? $this->__union($obj, $o) : null;
+    }
+
+    /**
+     * @param int offset
+     * @return byte
+     */
+    public function getVectorOfEnums($j)
+    {
+        $o = $this->__offset(98);
+        return $o != 0 ? $this->bb->getByte($this->__vector($o) + $j * 1) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getVectorOfEnumsLength()
+    {
+        $o = $this->__offset(98);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @return string
+     */
+    public function getVectorOfEnumsBytes()
+    {
+        return $this->__vector_as_bytes(98);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return void
+     */
+    public static function startMonster(FlatBufferBuilder $builder)
+    {
+        $builder->StartObject(48);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return Monster
+     */
+    public static function createMonster(FlatBufferBuilder $builder, $pos, $mana, $hp, $name, $inventory, $color, $test_type, $test, $test4, $testarrayofstring, $testarrayoftables, $enemy, $testnestedflatbuffer, $testempty, $testbool, $testhashs32_fnv1, $testhashu32_fnv1, $testhashs64_fnv1, $testhashu64_fnv1, $testhashs32_fnv1a, $testhashu32_fnv1a, $testhashs64_fnv1a, $testhashu64_fnv1a, $testarrayofbools, $testf, $testf2, $testf3, $testarrayofstring2, $testarrayofsortedstruct, $flex, $test5, $vector_of_longs, $vector_of_doubles, $parent_namespace_test, $vector_of_referrables, $single_weak_reference, $vector_of_weak_references, $vector_of_strong_referrables, $co_owning_reference, $vector_of_co_owning_references, $non_owning_reference, $vector_of_non_owning_references, $any_unique_type, $any_unique, $any_ambiguous_type, $any_ambiguous, $vector_of_enums)
+    {
+        $builder->startObject(48);
+        self::addPos($builder, $pos);
+        self::addMana($builder, $mana);
+        self::addHp($builder, $hp);
+        self::addName($builder, $name);
+        self::addInventory($builder, $inventory);
+        self::addColor($builder, $color);
+        self::addTestType($builder, $test_type);
+        self::addTest($builder, $test);
+        self::addTest4($builder, $test4);
+        self::addTestarrayofstring($builder, $testarrayofstring);
+        self::addTestarrayoftables($builder, $testarrayoftables);
+        self::addEnemy($builder, $enemy);
+        self::addTestnestedflatbuffer($builder, $testnestedflatbuffer);
+        self::addTestempty($builder, $testempty);
+        self::addTestbool($builder, $testbool);
+        self::addTesthashs32Fnv1($builder, $testhashs32_fnv1);
+        self::addTesthashu32Fnv1($builder, $testhashu32_fnv1);
+        self::addTesthashs64Fnv1($builder, $testhashs64_fnv1);
+        self::addTesthashu64Fnv1($builder, $testhashu64_fnv1);
+        self::addTesthashs32Fnv1a($builder, $testhashs32_fnv1a);
+        self::addTesthashu32Fnv1a($builder, $testhashu32_fnv1a);
+        self::addTesthashs64Fnv1a($builder, $testhashs64_fnv1a);
+        self::addTesthashu64Fnv1a($builder, $testhashu64_fnv1a);
+        self::addTestarrayofbools($builder, $testarrayofbools);
+        self::addTestf($builder, $testf);
+        self::addTestf2($builder, $testf2);
+        self::addTestf3($builder, $testf3);
+        self::addTestarrayofstring2($builder, $testarrayofstring2);
+        self::addTestarrayofsortedstruct($builder, $testarrayofsortedstruct);
+        self::addFlex($builder, $flex);
+        self::addTest5($builder, $test5);
+        self::addVectorOfLongs($builder, $vector_of_longs);
+        self::addVectorOfDoubles($builder, $vector_of_doubles);
+        self::addParentNamespaceTest($builder, $parent_namespace_test);
+        self::addVectorOfReferrables($builder, $vector_of_referrables);
+        self::addSingleWeakReference($builder, $single_weak_reference);
+        self::addVectorOfWeakReferences($builder, $vector_of_weak_references);
+        self::addVectorOfStrongReferrables($builder, $vector_of_strong_referrables);
+        self::addCoOwningReference($builder, $co_owning_reference);
+        self::addVectorOfCoOwningReferences($builder, $vector_of_co_owning_references);
+        self::addNonOwningReference($builder, $non_owning_reference);
+        self::addVectorOfNonOwningReferences($builder, $vector_of_non_owning_references);
+        self::addAnyUniqueType($builder, $any_unique_type);
+        self::addAnyUnique($builder, $any_unique);
+        self::addAnyAmbiguousType($builder, $any_ambiguous_type);
+        self::addAnyAmbiguous($builder, $any_ambiguous);
+        self::addVectorOfEnums($builder, $vector_of_enums);
+        $o = $builder->endObject();
+        $builder->required($o, 10);  // name
+        return $o;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addPos(FlatBufferBuilder $builder, $pos)
+    {
+        $builder->addStructX(0, $pos, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param short
+     * @return void
+     */
+    public static function addMana(FlatBufferBuilder $builder, $mana)
+    {
+        $builder->addShortX(1, $mana, 150);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param short
+     * @return void
+     */
+    public static function addHp(FlatBufferBuilder $builder, $hp)
+    {
+        $builder->addShortX(2, $hp, 100);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param StringOffset
+     * @return void
+     */
+    public static function addName(FlatBufferBuilder $builder, $name)
+    {
+        $builder->addOffsetX(3, $name, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addInventory(FlatBufferBuilder $builder, $inventory)
+    {
+        $builder->addOffsetX(5, $inventory, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createInventoryVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(1, count($data), 1);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putByte($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startInventoryVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(1, $numElems, 1);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param byte
+     * @return void
+     */
+    public static function addColor(FlatBufferBuilder $builder, $color)
+    {
+        $builder->addByteX(6, $color, 8);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param byte
+     * @return void
+     */
+    public static function addTestType(FlatBufferBuilder $builder, $testType)
+    {
+        $builder->addByteX(7, $testType, 0);
+    }
+
+    public static function addTest(FlatBufferBuilder $builder, $offset)
+    {
+        $builder->addOffsetX(8, $offset, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addTest4(FlatBufferBuilder $builder, $test4)
+    {
+        $builder->addOffsetX(9, $test4, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createTest4Vector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(4, count($data), 2);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putOffset($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startTest4Vector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(4, $numElems, 2);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addTestarrayofstring(FlatBufferBuilder $builder, $testarrayofstring)
+    {
+        $builder->addOffsetX(10, $testarrayofstring, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createTestarrayofstringVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(4, count($data), 4);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putOffset($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startTestarrayofstringVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(4, $numElems, 4);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addTestarrayoftables(FlatBufferBuilder $builder, $testarrayoftables)
+    {
+        $builder->addOffsetX(11, $testarrayoftables, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createTestarrayoftablesVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(4, count($data), 4);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putOffset($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startTestarrayoftablesVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(4, $numElems, 4);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addEnemy(FlatBufferBuilder $builder, $enemy)
+    {
+        $builder->addOffsetX(12, $enemy, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addTestnestedflatbuffer(FlatBufferBuilder $builder, $testnestedflatbuffer)
+    {
+        $builder->addOffsetX(13, $testnestedflatbuffer, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createTestnestedflatbufferVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(1, count($data), 1);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putByte($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startTestnestedflatbufferVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(1, $numElems, 1);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addTestempty(FlatBufferBuilder $builder, $testempty)
+    {
+        $builder->addOffsetX(14, $testempty, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param bool
+     * @return void
+     */
+    public static function addTestbool(FlatBufferBuilder $builder, $testbool)
+    {
+        $builder->addBoolX(15, $testbool, false);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addTesthashs32Fnv1(FlatBufferBuilder $builder, $testhashs32Fnv1)
+    {
+        $builder->addIntX(16, $testhashs32Fnv1, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param uint
+     * @return void
+     */
+    public static function addTesthashu32Fnv1(FlatBufferBuilder $builder, $testhashu32Fnv1)
+    {
+        $builder->addUintX(17, $testhashu32Fnv1, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param long
+     * @return void
+     */
+    public static function addTesthashs64Fnv1(FlatBufferBuilder $builder, $testhashs64Fnv1)
+    {
+        $builder->addLongX(18, $testhashs64Fnv1, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param ulong
+     * @return void
+     */
+    public static function addTesthashu64Fnv1(FlatBufferBuilder $builder, $testhashu64Fnv1)
+    {
+        $builder->addUlongX(19, $testhashu64Fnv1, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addTesthashs32Fnv1a(FlatBufferBuilder $builder, $testhashs32Fnv1a)
+    {
+        $builder->addIntX(20, $testhashs32Fnv1a, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param uint
+     * @return void
+     */
+    public static function addTesthashu32Fnv1a(FlatBufferBuilder $builder, $testhashu32Fnv1a)
+    {
+        $builder->addUintX(21, $testhashu32Fnv1a, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param long
+     * @return void
+     */
+    public static function addTesthashs64Fnv1a(FlatBufferBuilder $builder, $testhashs64Fnv1a)
+    {
+        $builder->addLongX(22, $testhashs64Fnv1a, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param ulong
+     * @return void
+     */
+    public static function addTesthashu64Fnv1a(FlatBufferBuilder $builder, $testhashu64Fnv1a)
+    {
+        $builder->addUlongX(23, $testhashu64Fnv1a, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addTestarrayofbools(FlatBufferBuilder $builder, $testarrayofbools)
+    {
+        $builder->addOffsetX(24, $testarrayofbools, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createTestarrayofboolsVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(1, count($data), 1);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putBool($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startTestarrayofboolsVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(1, $numElems, 1);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param float
+     * @return void
+     */
+    public static function addTestf(FlatBufferBuilder $builder, $testf)
+    {
+        $builder->addFloatX(25, $testf, 3.14159);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param float
+     * @return void
+     */
+    public static function addTestf2(FlatBufferBuilder $builder, $testf2)
+    {
+        $builder->addFloatX(26, $testf2, 3.0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param float
+     * @return void
+     */
+    public static function addTestf3(FlatBufferBuilder $builder, $testf3)
+    {
+        $builder->addFloatX(27, $testf3, 0.0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addTestarrayofstring2(FlatBufferBuilder $builder, $testarrayofstring2)
+    {
+        $builder->addOffsetX(28, $testarrayofstring2, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createTestarrayofstring2Vector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(4, count($data), 4);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putOffset($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startTestarrayofstring2Vector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(4, $numElems, 4);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addTestarrayofsortedstruct(FlatBufferBuilder $builder, $testarrayofsortedstruct)
+    {
+        $builder->addOffsetX(29, $testarrayofsortedstruct, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createTestarrayofsortedstructVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(8, count($data), 4);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putOffset($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startTestarrayofsortedstructVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(8, $numElems, 4);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addFlex(FlatBufferBuilder $builder, $flex)
+    {
+        $builder->addOffsetX(30, $flex, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createFlexVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(1, count($data), 1);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putByte($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startFlexVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(1, $numElems, 1);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addTest5(FlatBufferBuilder $builder, $test5)
+    {
+        $builder->addOffsetX(31, $test5, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createTest5Vector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(4, count($data), 2);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putOffset($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startTest5Vector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(4, $numElems, 2);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addVectorOfLongs(FlatBufferBuilder $builder, $vectorOfLongs)
+    {
+        $builder->addOffsetX(32, $vectorOfLongs, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createVectorOfLongsVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(8, count($data), 8);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putLong($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startVectorOfLongsVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(8, $numElems, 8);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addVectorOfDoubles(FlatBufferBuilder $builder, $vectorOfDoubles)
+    {
+        $builder->addOffsetX(33, $vectorOfDoubles, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createVectorOfDoublesVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(8, count($data), 8);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putDouble($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startVectorOfDoublesVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(8, $numElems, 8);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addParentNamespaceTest(FlatBufferBuilder $builder, $parentNamespaceTest)
+    {
+        $builder->addOffsetX(34, $parentNamespaceTest, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addVectorOfReferrables(FlatBufferBuilder $builder, $vectorOfReferrables)
+    {
+        $builder->addOffsetX(35, $vectorOfReferrables, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createVectorOfReferrablesVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(4, count($data), 4);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putOffset($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startVectorOfReferrablesVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(4, $numElems, 4);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param ulong
+     * @return void
+     */
+    public static function addSingleWeakReference(FlatBufferBuilder $builder, $singleWeakReference)
+    {
+        $builder->addUlongX(36, $singleWeakReference, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addVectorOfWeakReferences(FlatBufferBuilder $builder, $vectorOfWeakReferences)
+    {
+        $builder->addOffsetX(37, $vectorOfWeakReferences, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createVectorOfWeakReferencesVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(8, count($data), 8);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putUlong($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startVectorOfWeakReferencesVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(8, $numElems, 8);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addVectorOfStrongReferrables(FlatBufferBuilder $builder, $vectorOfStrongReferrables)
+    {
+        $builder->addOffsetX(38, $vectorOfStrongReferrables, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createVectorOfStrongReferrablesVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(4, count($data), 4);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putOffset($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startVectorOfStrongReferrablesVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(4, $numElems, 4);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param ulong
+     * @return void
+     */
+    public static function addCoOwningReference(FlatBufferBuilder $builder, $coOwningReference)
+    {
+        $builder->addUlongX(39, $coOwningReference, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addVectorOfCoOwningReferences(FlatBufferBuilder $builder, $vectorOfCoOwningReferences)
+    {
+        $builder->addOffsetX(40, $vectorOfCoOwningReferences, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createVectorOfCoOwningReferencesVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(8, count($data), 8);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putUlong($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startVectorOfCoOwningReferencesVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(8, $numElems, 8);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param ulong
+     * @return void
+     */
+    public static function addNonOwningReference(FlatBufferBuilder $builder, $nonOwningReference)
+    {
+        $builder->addUlongX(41, $nonOwningReference, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addVectorOfNonOwningReferences(FlatBufferBuilder $builder, $vectorOfNonOwningReferences)
+    {
+        $builder->addOffsetX(42, $vectorOfNonOwningReferences, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createVectorOfNonOwningReferencesVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(8, count($data), 8);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putUlong($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startVectorOfNonOwningReferencesVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(8, $numElems, 8);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param byte
+     * @return void
+     */
+    public static function addAnyUniqueType(FlatBufferBuilder $builder, $anyUniqueType)
+    {
+        $builder->addByteX(43, $anyUniqueType, 0);
+    }
+
+    public static function addAnyUnique(FlatBufferBuilder $builder, $offset)
+    {
+        $builder->addOffsetX(44, $offset, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param byte
+     * @return void
+     */
+    public static function addAnyAmbiguousType(FlatBufferBuilder $builder, $anyAmbiguousType)
+    {
+        $builder->addByteX(45, $anyAmbiguousType, 0);
+    }
+
+    public static function addAnyAmbiguous(FlatBufferBuilder $builder, $offset)
+    {
+        $builder->addOffsetX(46, $offset, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addVectorOfEnums(FlatBufferBuilder $builder, $vectorOfEnums)
+    {
+        $builder->addOffsetX(47, $vectorOfEnums, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createVectorOfEnumsVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(1, count($data), 1);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putByte($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startVectorOfEnumsVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(1, $numElems, 1);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return int table offset
+     */
+    public static function endMonster(FlatBufferBuilder $builder)
+    {
+        $o = $builder->endObject();
+        $builder->required($o, 10);  // name
+        return $o;
+    }
+
+    public static function finishMonsterBuffer(FlatBufferBuilder $builder, $offset)
+    {
+        $builder->finish($offset, "MONS");
+    }
+}
diff --git a/tests/MyGame/Example/Monster.py b/tests/MyGame/Example/Monster.py
new file mode 100644
index 0000000..5baf64d
--- /dev/null
+++ b/tests/MyGame/Example/Monster.py
@@ -0,0 +1,689 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+import flatbuffers
+
+# an example documentation comment: monster object
+class Monster(object):
+    __slots__ = ['_tab']
+
+    @classmethod
+    def GetRootAsMonster(cls, buf, offset):
+        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
+        x = Monster()
+        x.Init(buf, n + offset)
+        return x
+
+    @classmethod
+    def MonsterBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
+        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x53", size_prefixed=size_prefixed)
+
+    # Monster
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # Monster
+    def Pos(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+        if o != 0:
+            x = o + self._tab.Pos
+            from .Vec3 import Vec3
+            obj = Vec3()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+    # Monster
+    def Mana(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Int16Flags, o + self._tab.Pos)
+        return 150
+
+    # Monster
+    def Hp(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Int16Flags, o + self._tab.Pos)
+        return 100
+
+    # Monster
+    def Name(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
+        if o != 0:
+            return self._tab.String(o + self._tab.Pos)
+        return None
+
+    # Monster
+    def Inventory(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
+        return 0
+
+    # Monster
+    def InventoryAsNumpy(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
+        if o != 0:
+            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
+        return 0
+
+    # Monster
+    def InventoryLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def Color(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos)
+        return 8
+
+    # Monster
+    def TestType(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(18))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos)
+        return 0
+
+    # Monster
+    def Test(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(20))
+        if o != 0:
+            from flatbuffers.table import Table
+            obj = Table(bytearray(), 0)
+            self._tab.Union(obj, o)
+            return obj
+        return None
+
+    # Monster
+    def Test4(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
+        if o != 0:
+            x = self._tab.Vector(o)
+            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
+            from .Test import Test
+            obj = Test()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+    # Monster
+    def Test4Length(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def Testarrayofstring(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.String(a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
+        return ""
+
+    # Monster
+    def TestarrayofstringLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # an example documentation comment: this will end up in the generated code
+    # multiline too
+    # Monster
+    def Testarrayoftables(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
+        if o != 0:
+            x = self._tab.Vector(o)
+            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
+            x = self._tab.Indirect(x)
+            from .Monster import Monster
+            obj = Monster()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+    # Monster
+    def TestarrayoftablesLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def Enemy(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(28))
+        if o != 0:
+            x = self._tab.Indirect(o + self._tab.Pos)
+            from .Monster import Monster
+            obj = Monster()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+    # Monster
+    def Testnestedflatbuffer(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(30))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
+        return 0
+
+    # Monster
+    def TestnestedflatbufferAsNumpy(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(30))
+        if o != 0:
+            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
+        return 0
+
+    # Monster
+    def TestnestedflatbufferLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(30))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def Testempty(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(32))
+        if o != 0:
+            x = self._tab.Indirect(o + self._tab.Pos)
+            from .Stat import Stat
+            obj = Stat()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+    # Monster
+    def Testbool(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(34))
+        if o != 0:
+            return bool(self._tab.Get(flatbuffers.number_types.BoolFlags, o + self._tab.Pos))
+        return False
+
+    # Monster
+    def Testhashs32Fnv1(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(36))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
+        return 0
+
+    # Monster
+    def Testhashu32Fnv1(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(38))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint32Flags, o + self._tab.Pos)
+        return 0
+
+    # Monster
+    def Testhashs64Fnv1(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(40))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Int64Flags, o + self._tab.Pos)
+        return 0
+
+    # Monster
+    def Testhashu64Fnv1(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(42))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
+        return 0
+
+    # Monster
+    def Testhashs32Fnv1a(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(44))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
+        return 0
+
+    # Monster
+    def Testhashu32Fnv1a(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(46))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint32Flags, o + self._tab.Pos)
+        return 0
+
+    # Monster
+    def Testhashs64Fnv1a(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(48))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Int64Flags, o + self._tab.Pos)
+        return 0
+
+    # Monster
+    def Testhashu64Fnv1a(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(50))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
+        return 0
+
+    # Monster
+    def Testarrayofbools(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(52))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.Get(flatbuffers.number_types.BoolFlags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
+        return 0
+
+    # Monster
+    def TestarrayofboolsAsNumpy(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(52))
+        if o != 0:
+            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.BoolFlags, o)
+        return 0
+
+    # Monster
+    def TestarrayofboolsLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(52))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def Testf(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(54))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
+        return 3.14159
+
+    # Monster
+    def Testf2(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(56))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
+        return 3.0
+
+    # Monster
+    def Testf3(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(58))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
+        return 0.0
+
+    # Monster
+    def Testarrayofstring2(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(60))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.String(a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
+        return ""
+
+    # Monster
+    def Testarrayofstring2Length(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(60))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def Testarrayofsortedstruct(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(62))
+        if o != 0:
+            x = self._tab.Vector(o)
+            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 8
+            from .Ability import Ability
+            obj = Ability()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+    # Monster
+    def TestarrayofsortedstructLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(62))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def Flex(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(64))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
+        return 0
+
+    # Monster
+    def FlexAsNumpy(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(64))
+        if o != 0:
+            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
+        return 0
+
+    # Monster
+    def FlexLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(64))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def Test5(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(66))
+        if o != 0:
+            x = self._tab.Vector(o)
+            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
+            from .Test import Test
+            obj = Test()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+    # Monster
+    def Test5Length(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(66))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def VectorOfLongs(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(68))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.Get(flatbuffers.number_types.Int64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
+        return 0
+
+    # Monster
+    def VectorOfLongsAsNumpy(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(68))
+        if o != 0:
+            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Int64Flags, o)
+        return 0
+
+    # Monster
+    def VectorOfLongsLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(68))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def VectorOfDoubles(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(70))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.Get(flatbuffers.number_types.Float64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
+        return 0
+
+    # Monster
+    def VectorOfDoublesAsNumpy(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(70))
+        if o != 0:
+            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Float64Flags, o)
+        return 0
+
+    # Monster
+    def VectorOfDoublesLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(70))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def ParentNamespaceTest(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(72))
+        if o != 0:
+            x = self._tab.Indirect(o + self._tab.Pos)
+            from .InParentNamespace import InParentNamespace
+            obj = InParentNamespace()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+    # Monster
+    def VectorOfReferrables(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(74))
+        if o != 0:
+            x = self._tab.Vector(o)
+            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
+            x = self._tab.Indirect(x)
+            from .Referrable import Referrable
+            obj = Referrable()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+    # Monster
+    def VectorOfReferrablesLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(74))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def SingleWeakReference(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(76))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
+        return 0
+
+    # Monster
+    def VectorOfWeakReferences(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(78))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.Get(flatbuffers.number_types.Uint64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
+        return 0
+
+    # Monster
+    def VectorOfWeakReferencesAsNumpy(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(78))
+        if o != 0:
+            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint64Flags, o)
+        return 0
+
+    # Monster
+    def VectorOfWeakReferencesLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(78))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def VectorOfStrongReferrables(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(80))
+        if o != 0:
+            x = self._tab.Vector(o)
+            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
+            x = self._tab.Indirect(x)
+            from .Referrable import Referrable
+            obj = Referrable()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+    # Monster
+    def VectorOfStrongReferrablesLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(80))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def CoOwningReference(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(82))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
+        return 0
+
+    # Monster
+    def VectorOfCoOwningReferences(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(84))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.Get(flatbuffers.number_types.Uint64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
+        return 0
+
+    # Monster
+    def VectorOfCoOwningReferencesAsNumpy(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(84))
+        if o != 0:
+            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint64Flags, o)
+        return 0
+
+    # Monster
+    def VectorOfCoOwningReferencesLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(84))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def NonOwningReference(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(86))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
+        return 0
+
+    # Monster
+    def VectorOfNonOwningReferences(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(88))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.Get(flatbuffers.number_types.Uint64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
+        return 0
+
+    # Monster
+    def VectorOfNonOwningReferencesAsNumpy(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(88))
+        if o != 0:
+            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint64Flags, o)
+        return 0
+
+    # Monster
+    def VectorOfNonOwningReferencesLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(88))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def AnyUniqueType(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(90))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos)
+        return 0
+
+    # Monster
+    def AnyUnique(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(92))
+        if o != 0:
+            from flatbuffers.table import Table
+            obj = Table(bytearray(), 0)
+            self._tab.Union(obj, o)
+            return obj
+        return None
+
+    # Monster
+    def AnyAmbiguousType(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(94))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos)
+        return 0
+
+    # Monster
+    def AnyAmbiguous(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(96))
+        if o != 0:
+            from flatbuffers.table import Table
+            obj = Table(bytearray(), 0)
+            self._tab.Union(obj, o)
+            return obj
+        return None
+
+    # Monster
+    def VectorOfEnums(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(98))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
+        return 0
+
+    # Monster
+    def VectorOfEnumsAsNumpy(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(98))
+        if o != 0:
+            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
+        return 0
+
+    # Monster
+    def VectorOfEnumsLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(98))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+def MonsterStart(builder): builder.StartObject(48)
+def MonsterAddPos(builder, pos): builder.PrependStructSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(pos), 0)
+def MonsterAddMana(builder, mana): builder.PrependInt16Slot(1, mana, 150)
+def MonsterAddHp(builder, hp): builder.PrependInt16Slot(2, hp, 100)
+def MonsterAddName(builder, name): builder.PrependUOffsetTRelativeSlot(3, flatbuffers.number_types.UOffsetTFlags.py_type(name), 0)
+def MonsterAddInventory(builder, inventory): builder.PrependUOffsetTRelativeSlot(5, flatbuffers.number_types.UOffsetTFlags.py_type(inventory), 0)
+def MonsterStartInventoryVector(builder, numElems): return builder.StartVector(1, numElems, 1)
+def MonsterAddColor(builder, color): builder.PrependUint8Slot(6, color, 8)
+def MonsterAddTestType(builder, testType): builder.PrependUint8Slot(7, testType, 0)
+def MonsterAddTest(builder, test): builder.PrependUOffsetTRelativeSlot(8, flatbuffers.number_types.UOffsetTFlags.py_type(test), 0)
+def MonsterAddTest4(builder, test4): builder.PrependUOffsetTRelativeSlot(9, flatbuffers.number_types.UOffsetTFlags.py_type(test4), 0)
+def MonsterStartTest4Vector(builder, numElems): return builder.StartVector(4, numElems, 2)
+def MonsterAddTestarrayofstring(builder, testarrayofstring): builder.PrependUOffsetTRelativeSlot(10, flatbuffers.number_types.UOffsetTFlags.py_type(testarrayofstring), 0)
+def MonsterStartTestarrayofstringVector(builder, numElems): return builder.StartVector(4, numElems, 4)
+def MonsterAddTestarrayoftables(builder, testarrayoftables): builder.PrependUOffsetTRelativeSlot(11, flatbuffers.number_types.UOffsetTFlags.py_type(testarrayoftables), 0)
+def MonsterStartTestarrayoftablesVector(builder, numElems): return builder.StartVector(4, numElems, 4)
+def MonsterAddEnemy(builder, enemy): builder.PrependUOffsetTRelativeSlot(12, flatbuffers.number_types.UOffsetTFlags.py_type(enemy), 0)
+def MonsterAddTestnestedflatbuffer(builder, testnestedflatbuffer): builder.PrependUOffsetTRelativeSlot(13, flatbuffers.number_types.UOffsetTFlags.py_type(testnestedflatbuffer), 0)
+def MonsterStartTestnestedflatbufferVector(builder, numElems): return builder.StartVector(1, numElems, 1)
+def MonsterAddTestempty(builder, testempty): builder.PrependUOffsetTRelativeSlot(14, flatbuffers.number_types.UOffsetTFlags.py_type(testempty), 0)
+def MonsterAddTestbool(builder, testbool): builder.PrependBoolSlot(15, testbool, 0)
+def MonsterAddTesthashs32Fnv1(builder, testhashs32Fnv1): builder.PrependInt32Slot(16, testhashs32Fnv1, 0)
+def MonsterAddTesthashu32Fnv1(builder, testhashu32Fnv1): builder.PrependUint32Slot(17, testhashu32Fnv1, 0)
+def MonsterAddTesthashs64Fnv1(builder, testhashs64Fnv1): builder.PrependInt64Slot(18, testhashs64Fnv1, 0)
+def MonsterAddTesthashu64Fnv1(builder, testhashu64Fnv1): builder.PrependUint64Slot(19, testhashu64Fnv1, 0)
+def MonsterAddTesthashs32Fnv1a(builder, testhashs32Fnv1a): builder.PrependInt32Slot(20, testhashs32Fnv1a, 0)
+def MonsterAddTesthashu32Fnv1a(builder, testhashu32Fnv1a): builder.PrependUint32Slot(21, testhashu32Fnv1a, 0)
+def MonsterAddTesthashs64Fnv1a(builder, testhashs64Fnv1a): builder.PrependInt64Slot(22, testhashs64Fnv1a, 0)
+def MonsterAddTesthashu64Fnv1a(builder, testhashu64Fnv1a): builder.PrependUint64Slot(23, testhashu64Fnv1a, 0)
+def MonsterAddTestarrayofbools(builder, testarrayofbools): builder.PrependUOffsetTRelativeSlot(24, flatbuffers.number_types.UOffsetTFlags.py_type(testarrayofbools), 0)
+def MonsterStartTestarrayofboolsVector(builder, numElems): return builder.StartVector(1, numElems, 1)
+def MonsterAddTestf(builder, testf): builder.PrependFloat32Slot(25, testf, 3.14159)
+def MonsterAddTestf2(builder, testf2): builder.PrependFloat32Slot(26, testf2, 3.0)
+def MonsterAddTestf3(builder, testf3): builder.PrependFloat32Slot(27, testf3, 0.0)
+def MonsterAddTestarrayofstring2(builder, testarrayofstring2): builder.PrependUOffsetTRelativeSlot(28, flatbuffers.number_types.UOffsetTFlags.py_type(testarrayofstring2), 0)
+def MonsterStartTestarrayofstring2Vector(builder, numElems): return builder.StartVector(4, numElems, 4)
+def MonsterAddTestarrayofsortedstruct(builder, testarrayofsortedstruct): builder.PrependUOffsetTRelativeSlot(29, flatbuffers.number_types.UOffsetTFlags.py_type(testarrayofsortedstruct), 0)
+def MonsterStartTestarrayofsortedstructVector(builder, numElems): return builder.StartVector(8, numElems, 4)
+def MonsterAddFlex(builder, flex): builder.PrependUOffsetTRelativeSlot(30, flatbuffers.number_types.UOffsetTFlags.py_type(flex), 0)
+def MonsterStartFlexVector(builder, numElems): return builder.StartVector(1, numElems, 1)
+def MonsterAddTest5(builder, test5): builder.PrependUOffsetTRelativeSlot(31, flatbuffers.number_types.UOffsetTFlags.py_type(test5), 0)
+def MonsterStartTest5Vector(builder, numElems): return builder.StartVector(4, numElems, 2)
+def MonsterAddVectorOfLongs(builder, vectorOfLongs): builder.PrependUOffsetTRelativeSlot(32, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfLongs), 0)
+def MonsterStartVectorOfLongsVector(builder, numElems): return builder.StartVector(8, numElems, 8)
+def MonsterAddVectorOfDoubles(builder, vectorOfDoubles): builder.PrependUOffsetTRelativeSlot(33, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfDoubles), 0)
+def MonsterStartVectorOfDoublesVector(builder, numElems): return builder.StartVector(8, numElems, 8)
+def MonsterAddParentNamespaceTest(builder, parentNamespaceTest): builder.PrependUOffsetTRelativeSlot(34, flatbuffers.number_types.UOffsetTFlags.py_type(parentNamespaceTest), 0)
+def MonsterAddVectorOfReferrables(builder, vectorOfReferrables): builder.PrependUOffsetTRelativeSlot(35, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfReferrables), 0)
+def MonsterStartVectorOfReferrablesVector(builder, numElems): return builder.StartVector(4, numElems, 4)
+def MonsterAddSingleWeakReference(builder, singleWeakReference): builder.PrependUint64Slot(36, singleWeakReference, 0)
+def MonsterAddVectorOfWeakReferences(builder, vectorOfWeakReferences): builder.PrependUOffsetTRelativeSlot(37, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfWeakReferences), 0)
+def MonsterStartVectorOfWeakReferencesVector(builder, numElems): return builder.StartVector(8, numElems, 8)
+def MonsterAddVectorOfStrongReferrables(builder, vectorOfStrongReferrables): builder.PrependUOffsetTRelativeSlot(38, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfStrongReferrables), 0)
+def MonsterStartVectorOfStrongReferrablesVector(builder, numElems): return builder.StartVector(4, numElems, 4)
+def MonsterAddCoOwningReference(builder, coOwningReference): builder.PrependUint64Slot(39, coOwningReference, 0)
+def MonsterAddVectorOfCoOwningReferences(builder, vectorOfCoOwningReferences): builder.PrependUOffsetTRelativeSlot(40, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfCoOwningReferences), 0)
+def MonsterStartVectorOfCoOwningReferencesVector(builder, numElems): return builder.StartVector(8, numElems, 8)
+def MonsterAddNonOwningReference(builder, nonOwningReference): builder.PrependUint64Slot(41, nonOwningReference, 0)
+def MonsterAddVectorOfNonOwningReferences(builder, vectorOfNonOwningReferences): builder.PrependUOffsetTRelativeSlot(42, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfNonOwningReferences), 0)
+def MonsterStartVectorOfNonOwningReferencesVector(builder, numElems): return builder.StartVector(8, numElems, 8)
+def MonsterAddAnyUniqueType(builder, anyUniqueType): builder.PrependUint8Slot(43, anyUniqueType, 0)
+def MonsterAddAnyUnique(builder, anyUnique): builder.PrependUOffsetTRelativeSlot(44, flatbuffers.number_types.UOffsetTFlags.py_type(anyUnique), 0)
+def MonsterAddAnyAmbiguousType(builder, anyAmbiguousType): builder.PrependUint8Slot(45, anyAmbiguousType, 0)
+def MonsterAddAnyAmbiguous(builder, anyAmbiguous): builder.PrependUOffsetTRelativeSlot(46, flatbuffers.number_types.UOffsetTFlags.py_type(anyAmbiguous), 0)
+def MonsterAddVectorOfEnums(builder, vectorOfEnums): builder.PrependUOffsetTRelativeSlot(47, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfEnums), 0)
+def MonsterStartVectorOfEnumsVector(builder, numElems): return builder.StartVector(1, numElems, 1)
+def MonsterEnd(builder): return builder.EndObject()
diff --git a/tests/MyGame/Example/MonsterStorageGrpc.java b/tests/MyGame/Example/MonsterStorageGrpc.java
new file mode 100644
index 0000000..b9f070f
--- /dev/null
+++ b/tests/MyGame/Example/MonsterStorageGrpc.java
@@ -0,0 +1,470 @@
+//Generated by flatc compiler (version 1.11.0)
+//If you make any local changes, they will be lost
+//source: monster_test.fbs
+
+package MyGame.Example;
+
+import com.google.flatbuffers.grpc.FlatbuffersUtils;
+
+import java.nio.ByteBuffer;
+import static io.grpc.MethodDescriptor.generateFullMethodName;
+import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall;
+import static io.grpc.stub.ClientCalls.asyncClientStreamingCall;
+import static io.grpc.stub.ClientCalls.asyncServerStreamingCall;
+import static io.grpc.stub.ClientCalls.asyncUnaryCall;
+import static io.grpc.stub.ClientCalls.blockingServerStreamingCall;
+import static io.grpc.stub.ClientCalls.blockingUnaryCall;
+import static io.grpc.stub.ClientCalls.futureUnaryCall;
+import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncClientStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncServerStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncUnaryCall;
+import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;
+
+/**
+ */
+@javax.annotation.Generated(
+    value = "by gRPC proto compiler",
+    comments = "Source: monster_test.fbs")
+public final class MonsterStorageGrpc {
+
+  private MonsterStorageGrpc() {}
+  
+  public static final String SERVICE_NAME = "MyGame.Example.MonsterStorage";
+  
+  // Static method descriptors that strictly reflect the proto.
+  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+  @java.lang.Deprecated // Use {@link #getStoreMethod()} instead. 
+  public static final io.grpc.MethodDescriptor<MyGame.Example.Monster,
+      MyGame.Example.Stat> METHOD_STORE = getStoreMethod();
+  
+  private static volatile io.grpc.MethodDescriptor<MyGame.Example.Monster,
+      MyGame.Example.Stat> getStoreMethod;
+  
+  private static volatile FlatbuffersUtils.FBExtactor<MyGame.Example.Monster> extractorOfMonster;
+  private static FlatbuffersUtils.FBExtactor<MyGame.Example.Monster> getExtractorOfMonster() {
+      if (extractorOfMonster != null) return extractorOfMonster;
+      synchronized (MonsterStorageGrpc.class) {
+          if (extractorOfMonster != null) return extractorOfMonster;
+          extractorOfMonster = new FlatbuffersUtils.FBExtactor<MyGame.Example.Monster>() {
+              public MyGame.Example.Monster extract (ByteBuffer buffer) {
+                  return MyGame.Example.Monster.getRootAsMonster(buffer);
+              }
+          };
+          return extractorOfMonster;
+      }
+  }
+  
+  private static volatile FlatbuffersUtils.FBExtactor<MyGame.Example.Stat> extractorOfStat;
+  private static FlatbuffersUtils.FBExtactor<MyGame.Example.Stat> getExtractorOfStat() {
+      if (extractorOfStat != null) return extractorOfStat;
+      synchronized (MonsterStorageGrpc.class) {
+          if (extractorOfStat != null) return extractorOfStat;
+          extractorOfStat = new FlatbuffersUtils.FBExtactor<MyGame.Example.Stat>() {
+              public MyGame.Example.Stat extract (ByteBuffer buffer) {
+                  return MyGame.Example.Stat.getRootAsStat(buffer);
+              }
+          };
+          return extractorOfStat;
+      }
+  }
+  
+  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+  public static io.grpc.MethodDescriptor<MyGame.Example.Monster,
+      MyGame.Example.Stat> getStoreMethod() {
+    io.grpc.MethodDescriptor<MyGame.Example.Monster, MyGame.Example.Stat> getStoreMethod;
+    if ((getStoreMethod = MonsterStorageGrpc.getStoreMethod) == null) {
+      synchronized (MonsterStorageGrpc.class) {
+        if ((getStoreMethod = MonsterStorageGrpc.getStoreMethod) == null) {
+          MonsterStorageGrpc.getStoreMethod = getStoreMethod = 
+              io.grpc.MethodDescriptor.<MyGame.Example.Monster, MyGame.Example.Stat>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(
+                  "MyGame.Example.MonsterStorage", "Store"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(FlatbuffersUtils.marshaller(
+                  MyGame.Example.Monster.class, getExtractorOfMonster()))
+              .setResponseMarshaller(FlatbuffersUtils.marshaller(
+                  MyGame.Example.Stat.class, getExtractorOfStat()))
+                  .setSchemaDescriptor(null)
+                  .build();
+          }
+        }
+     }
+     return getStoreMethod;
+  }
+  
+  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+  @java.lang.Deprecated // Use {@link #getRetrieveMethod()} instead. 
+  public static final io.grpc.MethodDescriptor<MyGame.Example.Stat,
+      MyGame.Example.Monster> METHOD_RETRIEVE = getRetrieveMethod();
+  
+  private static volatile io.grpc.MethodDescriptor<MyGame.Example.Stat,
+      MyGame.Example.Monster> getRetrieveMethod;
+  
+  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+  public static io.grpc.MethodDescriptor<MyGame.Example.Stat,
+      MyGame.Example.Monster> getRetrieveMethod() {
+    io.grpc.MethodDescriptor<MyGame.Example.Stat, MyGame.Example.Monster> getRetrieveMethod;
+    if ((getRetrieveMethod = MonsterStorageGrpc.getRetrieveMethod) == null) {
+      synchronized (MonsterStorageGrpc.class) {
+        if ((getRetrieveMethod = MonsterStorageGrpc.getRetrieveMethod) == null) {
+          MonsterStorageGrpc.getRetrieveMethod = getRetrieveMethod = 
+              io.grpc.MethodDescriptor.<MyGame.Example.Stat, MyGame.Example.Monster>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING)
+              .setFullMethodName(generateFullMethodName(
+                  "MyGame.Example.MonsterStorage", "Retrieve"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(FlatbuffersUtils.marshaller(
+                  MyGame.Example.Stat.class, getExtractorOfStat()))
+              .setResponseMarshaller(FlatbuffersUtils.marshaller(
+                  MyGame.Example.Monster.class, getExtractorOfMonster()))
+                  .setSchemaDescriptor(null)
+                  .build();
+          }
+        }
+     }
+     return getRetrieveMethod;
+  }
+  
+  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+  @java.lang.Deprecated // Use {@link #getGetMaxHitPointMethod()} instead. 
+  public static final io.grpc.MethodDescriptor<MyGame.Example.Monster,
+      MyGame.Example.Stat> METHOD_GET_MAX_HIT_POINT = getGetMaxHitPointMethod();
+  
+  private static volatile io.grpc.MethodDescriptor<MyGame.Example.Monster,
+      MyGame.Example.Stat> getGetMaxHitPointMethod;
+  
+  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+  public static io.grpc.MethodDescriptor<MyGame.Example.Monster,
+      MyGame.Example.Stat> getGetMaxHitPointMethod() {
+    io.grpc.MethodDescriptor<MyGame.Example.Monster, MyGame.Example.Stat> getGetMaxHitPointMethod;
+    if ((getGetMaxHitPointMethod = MonsterStorageGrpc.getGetMaxHitPointMethod) == null) {
+      synchronized (MonsterStorageGrpc.class) {
+        if ((getGetMaxHitPointMethod = MonsterStorageGrpc.getGetMaxHitPointMethod) == null) {
+          MonsterStorageGrpc.getGetMaxHitPointMethod = getGetMaxHitPointMethod = 
+              io.grpc.MethodDescriptor.<MyGame.Example.Monster, MyGame.Example.Stat>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.CLIENT_STREAMING)
+              .setFullMethodName(generateFullMethodName(
+                  "MyGame.Example.MonsterStorage", "GetMaxHitPoint"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(FlatbuffersUtils.marshaller(
+                  MyGame.Example.Monster.class, getExtractorOfMonster()))
+              .setResponseMarshaller(FlatbuffersUtils.marshaller(
+                  MyGame.Example.Stat.class, getExtractorOfStat()))
+                  .setSchemaDescriptor(null)
+                  .build();
+          }
+        }
+     }
+     return getGetMaxHitPointMethod;
+  }
+  
+  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+  @java.lang.Deprecated // Use {@link #getGetMinMaxHitPointsMethod()} instead. 
+  public static final io.grpc.MethodDescriptor<MyGame.Example.Monster,
+      MyGame.Example.Stat> METHOD_GET_MIN_MAX_HIT_POINTS = getGetMinMaxHitPointsMethod();
+  
+  private static volatile io.grpc.MethodDescriptor<MyGame.Example.Monster,
+      MyGame.Example.Stat> getGetMinMaxHitPointsMethod;
+  
+  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+  public static io.grpc.MethodDescriptor<MyGame.Example.Monster,
+      MyGame.Example.Stat> getGetMinMaxHitPointsMethod() {
+    io.grpc.MethodDescriptor<MyGame.Example.Monster, MyGame.Example.Stat> getGetMinMaxHitPointsMethod;
+    if ((getGetMinMaxHitPointsMethod = MonsterStorageGrpc.getGetMinMaxHitPointsMethod) == null) {
+      synchronized (MonsterStorageGrpc.class) {
+        if ((getGetMinMaxHitPointsMethod = MonsterStorageGrpc.getGetMinMaxHitPointsMethod) == null) {
+          MonsterStorageGrpc.getGetMinMaxHitPointsMethod = getGetMinMaxHitPointsMethod = 
+              io.grpc.MethodDescriptor.<MyGame.Example.Monster, MyGame.Example.Stat>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.BIDI_STREAMING)
+              .setFullMethodName(generateFullMethodName(
+                  "MyGame.Example.MonsterStorage", "GetMinMaxHitPoints"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(FlatbuffersUtils.marshaller(
+                  MyGame.Example.Monster.class, getExtractorOfMonster()))
+              .setResponseMarshaller(FlatbuffersUtils.marshaller(
+                  MyGame.Example.Stat.class, getExtractorOfStat()))
+                  .setSchemaDescriptor(null)
+                  .build();
+          }
+        }
+     }
+     return getGetMinMaxHitPointsMethod;
+  }
+  
+  /**
+   * Creates a new async stub that supports all call types for the service
+   */
+  public static MonsterStorageStub newStub(io.grpc.Channel channel) {
+    return new MonsterStorageStub(channel);
+  }
+  
+  /**
+   * Creates a new blocking-style stub that supports unary and streaming output calls on the service
+   */
+  public static MonsterStorageBlockingStub newBlockingStub(
+      io.grpc.Channel channel) {
+    return new MonsterStorageBlockingStub(channel);
+  }
+  
+  /**
+   * Creates a new ListenableFuture-style stub that supports unary calls on the service
+   */
+  public static MonsterStorageFutureStub newFutureStub(
+      io.grpc.Channel channel) {
+    return new MonsterStorageFutureStub(channel);
+  }
+  
+  /**
+   */
+  public static abstract class MonsterStorageImplBase implements io.grpc.BindableService {
+    
+    /**
+     */
+    public     void store(MyGame.Example.Monster request,
+        io.grpc.stub.StreamObserver<MyGame.Example.Stat> responseObserver)     {
+      asyncUnimplementedUnaryCall(getStoreMethod(), responseObserver);
+    }
+    
+    /**
+     */
+    public     void retrieve(MyGame.Example.Stat request,
+        io.grpc.stub.StreamObserver<MyGame.Example.Monster> responseObserver)     {
+      asyncUnimplementedUnaryCall(getRetrieveMethod(), responseObserver);
+    }
+    
+    /**
+     */
+    public     io.grpc.stub.StreamObserver<MyGame.Example.Monster> getMaxHitPoint(
+        io.grpc.stub.StreamObserver<MyGame.Example.Stat> responseObserver)     {
+      return asyncUnimplementedStreamingCall(getGetMaxHitPointMethod(), responseObserver);
+    }
+    
+    /**
+     */
+    public     io.grpc.stub.StreamObserver<MyGame.Example.Monster> getMinMaxHitPoints(
+        io.grpc.stub.StreamObserver<MyGame.Example.Stat> responseObserver)     {
+      return asyncUnimplementedStreamingCall(getGetMinMaxHitPointsMethod(), responseObserver);
+    }
+    
+    @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() {
+      return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
+          .addMethod(
+            getStoreMethod(),
+            asyncUnaryCall(
+              new MethodHandlers<
+                MyGame.Example.Monster,
+                MyGame.Example.Stat>(
+                  this, METHODID_STORE)))
+          .addMethod(
+            getRetrieveMethod(),
+            asyncServerStreamingCall(
+              new MethodHandlers<
+                MyGame.Example.Stat,
+                MyGame.Example.Monster>(
+                  this, METHODID_RETRIEVE)))
+          .addMethod(
+            getGetMaxHitPointMethod(),
+            asyncClientStreamingCall(
+              new MethodHandlers<
+                MyGame.Example.Monster,
+                MyGame.Example.Stat>(
+                  this, METHODID_GET_MAX_HIT_POINT)))
+          .addMethod(
+            getGetMinMaxHitPointsMethod(),
+            asyncBidiStreamingCall(
+              new MethodHandlers<
+                MyGame.Example.Monster,
+                MyGame.Example.Stat>(
+                  this, METHODID_GET_MIN_MAX_HIT_POINTS)))
+          .build();
+    }
+  }
+  
+  /**
+   */
+  public static final class MonsterStorageStub extends io.grpc.stub.AbstractStub<MonsterStorageStub> {
+    private MonsterStorageStub(io.grpc.Channel channel) {
+      super(channel);
+    }
+    
+    private MonsterStorageStub(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      super(channel, callOptions);
+    }
+    
+    @java.lang.Override
+    protected MonsterStorageStub build(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      return new MonsterStorageStub(channel, callOptions);
+    }
+    
+    /**
+     */
+    public     void store(MyGame.Example.Monster request,
+        io.grpc.stub.StreamObserver<MyGame.Example.Stat> responseObserver)     {
+      asyncUnaryCall(
+          getChannel().newCall(getStoreMethod(), getCallOptions()), request, responseObserver);
+    }
+    
+    /**
+     */
+    public     void retrieve(MyGame.Example.Stat request,
+        io.grpc.stub.StreamObserver<MyGame.Example.Monster> responseObserver)     {
+      asyncServerStreamingCall(
+          getChannel().newCall(getRetrieveMethod(), getCallOptions()), request, responseObserver);
+    }
+    
+    /**
+     */
+    public     io.grpc.stub.StreamObserver<MyGame.Example.Monster> getMaxHitPoint(
+        io.grpc.stub.StreamObserver<MyGame.Example.Stat> responseObserver)     {
+      return asyncClientStreamingCall(
+          getChannel().newCall(getGetMaxHitPointMethod(), getCallOptions()), responseObserver);
+    }
+    
+    /**
+     */
+    public     io.grpc.stub.StreamObserver<MyGame.Example.Monster> getMinMaxHitPoints(
+        io.grpc.stub.StreamObserver<MyGame.Example.Stat> responseObserver)     {
+      return asyncBidiStreamingCall(
+          getChannel().newCall(getGetMinMaxHitPointsMethod(), getCallOptions()), responseObserver);
+    }
+  }
+  
+  /**
+   */
+  public static final class MonsterStorageBlockingStub extends io.grpc.stub.AbstractStub<MonsterStorageBlockingStub> {
+    private MonsterStorageBlockingStub(io.grpc.Channel channel) {
+      super(channel);
+    }
+    
+    private MonsterStorageBlockingStub(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      super(channel, callOptions);
+    }
+    
+    @java.lang.Override
+    protected MonsterStorageBlockingStub build(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      return new MonsterStorageBlockingStub(channel, callOptions);
+    }
+    
+    /**
+     */
+    public     MyGame.Example.Stat store(MyGame.Example.Monster request)     {
+      return blockingUnaryCall(
+          getChannel(), getStoreMethod(), getCallOptions(), request);
+    }
+    
+    /**
+     */
+    public     java.util.Iterator<MyGame.Example.Monster> retrieve(
+        MyGame.Example.Stat request)     {
+      return blockingServerStreamingCall(
+          getChannel(), getRetrieveMethod(), getCallOptions(), request);
+    }
+  }
+  
+  /**
+   */
+  public static final class MonsterStorageFutureStub extends io.grpc.stub.AbstractStub<MonsterStorageFutureStub> {
+    private MonsterStorageFutureStub(io.grpc.Channel channel) {
+      super(channel);
+    }
+    
+    private MonsterStorageFutureStub(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      super(channel, callOptions);
+    }
+    
+    @java.lang.Override
+    protected MonsterStorageFutureStub build(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      return new MonsterStorageFutureStub(channel, callOptions);
+    }
+    
+    /**
+     */
+    public     com.google.common.util.concurrent.ListenableFuture<MyGame.Example.Stat> store(
+        MyGame.Example.Monster request)     {
+      return futureUnaryCall(
+          getChannel().newCall(getStoreMethod(), getCallOptions()), request);
+    }
+  }
+  
+  private static final int METHODID_STORE = 0;
+  private static final int METHODID_RETRIEVE = 1;
+  private static final int METHODID_GET_MIN_MAX_HIT_POINTS = 2;
+  private static final int METHODID_GET_MAX_HIT_POINT = 3;
+  
+  private static final class MethodHandlers<Req, Resp> implements
+      io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
+      io.grpc.stub.ServerCalls.ServerStreamingMethod<Req, Resp>,
+      io.grpc.stub.ServerCalls.ClientStreamingMethod<Req, Resp>,
+      io.grpc.stub.ServerCalls.BidiStreamingMethod<Req, Resp> {
+    private final MonsterStorageImplBase serviceImpl;
+    private final int methodId;
+  
+    MethodHandlers(MonsterStorageImplBase serviceImpl, int methodId) {
+      this.serviceImpl = serviceImpl;
+      this.methodId = methodId;
+    }
+  
+    @java.lang.Override
+    @java.lang.SuppressWarnings("unchecked")
+    public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) {
+      switch (methodId) {
+        case METHODID_STORE:
+          serviceImpl.store((MyGame.Example.Monster) request,
+              (io.grpc.stub.StreamObserver<MyGame.Example.Stat>) responseObserver);
+          break;
+        case METHODID_RETRIEVE:
+          serviceImpl.retrieve((MyGame.Example.Stat) request,
+              (io.grpc.stub.StreamObserver<MyGame.Example.Monster>) responseObserver);
+          break;
+        default:
+          throw new AssertionError();
+      }
+    }
+    
+    @java.lang.Override
+    @java.lang.SuppressWarnings("unchecked")
+    public io.grpc.stub.StreamObserver<Req> invoke(
+        io.grpc.stub.StreamObserver<Resp> responseObserver) {
+      switch (methodId) {
+        case METHODID_GET_MAX_HIT_POINT:
+          return (io.grpc.stub.StreamObserver<Req>) serviceImpl.getMaxHitPoint(
+              (io.grpc.stub.StreamObserver<MyGame.Example.Stat>) responseObserver);
+        case METHODID_GET_MIN_MAX_HIT_POINTS:
+          return (io.grpc.stub.StreamObserver<Req>) serviceImpl.getMinMaxHitPoints(
+              (io.grpc.stub.StreamObserver<MyGame.Example.Stat>) responseObserver);
+        default:
+          throw new AssertionError();
+      }
+    }
+  }
+  
+  private static volatile io.grpc.ServiceDescriptor serviceDescriptor;
+  
+  public static io.grpc.ServiceDescriptor getServiceDescriptor() {
+    io.grpc.ServiceDescriptor result = serviceDescriptor;
+    if (result == null) {
+      synchronized (MonsterStorageGrpc.class) {
+        result = serviceDescriptor;
+        if (result == null) {
+          serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)              
+              .setSchemaDescriptor(null)              
+              .addMethod(getStoreMethod())              
+              .addMethod(getRetrieveMethod())              
+              .addMethod(getGetMaxHitPointMethod())              
+              .addMethod(getGetMinMaxHitPointsMethod())              
+              .build();
+        }
+      }
+    }
+    return result;
+  }
+}
diff --git a/tests/MyGame/Example/MonsterStorage_grpc.go b/tests/MyGame/Example/MonsterStorage_grpc.go
new file mode 100644
index 0000000..deeec29
--- /dev/null
+++ b/tests/MyGame/Example/MonsterStorage_grpc.go
@@ -0,0 +1,251 @@
+//Generated by gRPC Go plugin
+//If you make any local changes, they will be lost
+//source: monster_test
+
+package Example
+
+import "github.com/google/flatbuffers/go"
+
+import (
+  context "context"
+  grpc "google.golang.org/grpc"
+)
+
+// Client API for MonsterStorage service
+type MonsterStorageClient interface{
+  Store(ctx context.Context, in *flatbuffers.Builder, 
+  	opts... grpc.CallOption) (* Stat, error)  
+  Retrieve(ctx context.Context, in *flatbuffers.Builder, 
+  	opts... grpc.CallOption) (MonsterStorage_RetrieveClient, error)  
+  GetMaxHitPoint(ctx context.Context, 
+  	opts... grpc.CallOption) (MonsterStorage_GetMaxHitPointClient, error)  
+  GetMinMaxHitPoints(ctx context.Context, 
+  	opts... grpc.CallOption) (MonsterStorage_GetMinMaxHitPointsClient, error)  
+}
+
+type monsterStorageClient struct {
+  cc *grpc.ClientConn
+}
+
+func NewMonsterStorageClient(cc *grpc.ClientConn) MonsterStorageClient {
+  return &monsterStorageClient{cc}
+}
+
+func (c *monsterStorageClient) Store(ctx context.Context, in *flatbuffers.Builder, 
+	opts... grpc.CallOption) (* Stat, error) {
+  out := new(Stat)
+  err := grpc.Invoke(ctx, "/MyGame.Example.MonsterStorage/Store", in, out, c.cc, opts...)
+  if err != nil { return nil, err }
+  return out, nil
+}
+
+func (c *monsterStorageClient) Retrieve(ctx context.Context, in *flatbuffers.Builder, 
+	opts... grpc.CallOption) (MonsterStorage_RetrieveClient, error) {
+  stream, err := grpc.NewClientStream(ctx, &_MonsterStorage_serviceDesc.Streams[0], c.cc, "/MyGame.Example.MonsterStorage/Retrieve", opts...)
+  if err != nil { return nil, err }
+  x := &monsterStorageRetrieveClient{stream}
+  if err := x.ClientStream.SendMsg(in); err != nil { return nil, err }
+  if err := x.ClientStream.CloseSend(); err != nil { return nil, err }
+  return x,nil
+}
+
+type MonsterStorage_RetrieveClient interface {
+  Recv() (*Monster, error)
+  grpc.ClientStream
+}
+
+type monsterStorageRetrieveClient struct{
+  grpc.ClientStream
+}
+
+func (x *monsterStorageRetrieveClient) Recv() (*Monster, error) {
+  m := new(Monster)
+  if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }
+  return m, nil
+}
+
+func (c *monsterStorageClient) GetMaxHitPoint(ctx context.Context, 
+	opts... grpc.CallOption) (MonsterStorage_GetMaxHitPointClient, error) {
+  stream, err := grpc.NewClientStream(ctx, &_MonsterStorage_serviceDesc.Streams[1], c.cc, "/MyGame.Example.MonsterStorage/GetMaxHitPoint", opts...)
+  if err != nil { return nil, err }
+  x := &monsterStorageGetMaxHitPointClient{stream}
+  return x,nil
+}
+
+type MonsterStorage_GetMaxHitPointClient interface {
+  Send(*flatbuffers.Builder) error
+  CloseAndRecv() (*Stat, error)
+  grpc.ClientStream
+}
+
+type monsterStorageGetMaxHitPointClient struct{
+  grpc.ClientStream
+}
+
+func (x *monsterStorageGetMaxHitPointClient) Send(m *flatbuffers.Builder) error {
+  return x.ClientStream.SendMsg(m)
+}
+
+func (x *monsterStorageGetMaxHitPointClient) CloseAndRecv() (*Stat, error) {
+  if err := x.ClientStream.CloseSend(); err != nil { return nil, err }
+  m := new (Stat)
+  if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }
+  return m, nil
+}
+
+func (c *monsterStorageClient) GetMinMaxHitPoints(ctx context.Context, 
+	opts... grpc.CallOption) (MonsterStorage_GetMinMaxHitPointsClient, error) {
+  stream, err := grpc.NewClientStream(ctx, &_MonsterStorage_serviceDesc.Streams[2], c.cc, "/MyGame.Example.MonsterStorage/GetMinMaxHitPoints", opts...)
+  if err != nil { return nil, err }
+  x := &monsterStorageGetMinMaxHitPointsClient{stream}
+  return x,nil
+}
+
+type MonsterStorage_GetMinMaxHitPointsClient interface {
+  Send(*flatbuffers.Builder) error
+  Recv() (*Stat, error)
+  grpc.ClientStream
+}
+
+type monsterStorageGetMinMaxHitPointsClient struct{
+  grpc.ClientStream
+}
+
+func (x *monsterStorageGetMinMaxHitPointsClient) Send(m *flatbuffers.Builder) error {
+  return x.ClientStream.SendMsg(m)
+}
+
+func (x *monsterStorageGetMinMaxHitPointsClient) Recv() (*Stat, error) {
+  m := new(Stat)
+  if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }
+  return m, nil
+}
+
+// Server API for MonsterStorage service
+type MonsterStorageServer interface {
+  Store(context.Context, *Monster) (*flatbuffers.Builder, error)  
+  Retrieve(*Stat, MonsterStorage_RetrieveServer) error  
+  GetMaxHitPoint(MonsterStorage_GetMaxHitPointServer) error  
+  GetMinMaxHitPoints(MonsterStorage_GetMinMaxHitPointsServer) error  
+}
+
+func RegisterMonsterStorageServer(s *grpc.Server, srv MonsterStorageServer) {
+  s.RegisterService(&_MonsterStorage_serviceDesc, srv)
+}
+
+func _MonsterStorage_Store_Handler(srv interface{}, ctx context.Context,
+	dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+  in := new(Monster)
+  if err := dec(in); err != nil { return nil, err }
+  if interceptor == nil { return srv.(MonsterStorageServer).Store(ctx, in) }
+  info := &grpc.UnaryServerInfo{
+    Server: srv,
+    FullMethod: "/MyGame.Example.MonsterStorage/Store",
+  }
+  
+  handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+    return srv.(MonsterStorageServer).Store(ctx, req.(* Monster))
+  }
+  return interceptor(ctx, in, info, handler)
+}
+
+
+func _MonsterStorage_Retrieve_Handler(srv interface{}, stream grpc.ServerStream) error {
+  m := new(Stat)
+  if err := stream.RecvMsg(m); err != nil { return err }
+  return srv.(MonsterStorageServer).Retrieve(m, &monsterStorageRetrieveServer{stream})
+}
+
+type MonsterStorage_RetrieveServer interface { 
+  Send(* flatbuffers.Builder) error
+  grpc.ServerStream
+}
+
+type monsterStorageRetrieveServer struct {
+  grpc.ServerStream
+}
+
+func (x *monsterStorageRetrieveServer) Send(m *flatbuffers.Builder) error {
+  return x.ServerStream.SendMsg(m)
+}
+
+
+func _MonsterStorage_GetMaxHitPoint_Handler(srv interface{}, stream grpc.ServerStream) error {
+  return srv.(MonsterStorageServer).GetMaxHitPoint(&monsterStorageGetMaxHitPointServer{stream})
+}
+
+type MonsterStorage_GetMaxHitPointServer interface { 
+  Recv() (* Monster, error)
+  SendAndClose(* flatbuffers.Builder) error
+  grpc.ServerStream
+}
+
+type monsterStorageGetMaxHitPointServer struct {
+  grpc.ServerStream
+}
+
+func (x *monsterStorageGetMaxHitPointServer) Recv() (*Monster, error) {
+  m := new(Monster)
+  if err := x.ServerStream.RecvMsg(m); err != nil { return nil, err }
+  return m, nil
+}
+
+func (x *monsterStorageGetMaxHitPointServer) SendAndClose(m *flatbuffers.Builder) error {
+  return x.ServerStream.SendMsg(m)
+}
+
+
+func _MonsterStorage_GetMinMaxHitPoints_Handler(srv interface{}, stream grpc.ServerStream) error {
+  return srv.(MonsterStorageServer).GetMinMaxHitPoints(&monsterStorageGetMinMaxHitPointsServer{stream})
+}
+
+type MonsterStorage_GetMinMaxHitPointsServer interface { 
+  Send(* flatbuffers.Builder) error
+  Recv() (* Monster, error)
+  grpc.ServerStream
+}
+
+type monsterStorageGetMinMaxHitPointsServer struct {
+  grpc.ServerStream
+}
+
+func (x *monsterStorageGetMinMaxHitPointsServer) Send(m *flatbuffers.Builder) error {
+  return x.ServerStream.SendMsg(m)
+}
+
+func (x *monsterStorageGetMinMaxHitPointsServer) Recv() (*Monster, error) {
+  m := new(Monster)
+  if err := x.ServerStream.RecvMsg(m); err != nil { return nil, err }
+  return m, nil
+}
+
+
+var _MonsterStorage_serviceDesc = grpc.ServiceDesc{
+  ServiceName: "MyGame.Example.MonsterStorage",
+  HandlerType: (*MonsterStorageServer)(nil),
+  Methods: []grpc.MethodDesc{
+    {
+      MethodName: "Store",
+      Handler: _MonsterStorage_Store_Handler, 
+    },
+  },
+  Streams: []grpc.StreamDesc{
+    {
+      StreamName: "Retrieve",
+      Handler: _MonsterStorage_Retrieve_Handler, 
+      ServerStreams: true,
+    },
+    {
+      StreamName: "GetMaxHitPoint",
+      Handler: _MonsterStorage_GetMaxHitPoint_Handler, 
+      ClientStreams: true,
+    },
+    {
+      StreamName: "GetMinMaxHitPoints",
+      Handler: _MonsterStorage_GetMinMaxHitPoints_Handler, 
+      ServerStreams: true,
+      ClientStreams: true,
+    },
+  },
+}
+
diff --git a/tests/MyGame/Example/NestedStruct.cs b/tests/MyGame/Example/NestedStruct.cs
new file mode 100644
index 0000000..3f1f2f0
--- /dev/null
+++ b/tests/MyGame/Example/NestedStruct.cs
@@ -0,0 +1,40 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct NestedStruct : IFlatbufferObject
+{
+  private Struct __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
+  public NestedStruct __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public int A(int j) { return __p.bb.GetInt(__p.bb_pos + 0 + j * 4); }
+  public void MutateA(int j, int a) { __p.bb.PutInt(__p.bb_pos + 0 + j * 4, a); }
+  public MyGame.Example.TestEnum B { get { return (MyGame.Example.TestEnum)__p.bb.GetSbyte(__p.bb_pos + 8); } }
+  public void MutateB(MyGame.Example.TestEnum b) { __p.bb.PutSbyte(__p.bb_pos + 8, (sbyte)b); }
+  public MyGame.Example.TestEnum C(int j) { return (MyGame.Example.TestEnum)__p.bb.GetSbyte(__p.bb_pos + 9 + j * 1); }
+  public void MutateC(int j, MyGame.Example.TestEnum c) { __p.bb.PutSbyte(__p.bb_pos + 9 + j * 1, (sbyte)c); }
+
+  public static Offset<MyGame.Example.NestedStruct> CreateNestedStruct(FlatBufferBuilder builder, int[] A, MyGame.Example.TestEnum B, MyGame.Example.TestEnum[] C) {
+    builder.Prep(4, 12);
+    builder.Pad(1);
+    for (int _idx0 = 2; _idx0 > 0; _idx0--) {
+      builder.PutSbyte((sbyte)C[_idx0-1]);
+    }
+    builder.PutSbyte((sbyte)B);
+    for (int _idx0 = 2; _idx0 > 0; _idx0--) {
+      builder.PutInt(A[_idx0-1]);
+    }
+    return new Offset<MyGame.Example.NestedStruct>(builder.Offset);
+  }
+};
+
+
+}
diff --git a/tests/MyGame/Example/NestedStruct.java b/tests/MyGame/Example/NestedStruct.java
new file mode 100644
index 0000000..3c8a8f6
--- /dev/null
+++ b/tests/MyGame/Example/NestedStruct.java
@@ -0,0 +1,35 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class NestedStruct extends Struct {
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public NestedStruct __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public int a(int j) { return bb.getInt(bb_pos + 0 + j * 4); }
+  public void mutateA(int j, int a) { bb.putInt(bb_pos + 0 + j * 4, a); }
+  public byte b() { return bb.get(bb_pos + 8); }
+  public void mutateB(byte b) { bb.put(bb_pos + 8, b); }
+  public byte c(int j) { return bb.get(bb_pos + 9 + j * 1); }
+  public void mutateC(int j, byte c) { bb.put(bb_pos + 9 + j * 1, c); }
+
+  public static int createNestedStruct(FlatBufferBuilder builder, int[] a, byte b, byte[] c) {
+    builder.prep(4, 12);
+    builder.pad(1);
+    for (int _idx0 = 2; _idx0 > 0; _idx0--) {
+      builder.putByte(c[_idx0-1]);
+    }
+    builder.putByte(b);
+    for (int _idx0 = 2; _idx0 > 0; _idx0--) {
+      builder.putInt(a[_idx0-1]);
+    }
+    return builder.offset();
+  }
+}
+
diff --git a/tests/MyGame/Example/NestedStruct.py b/tests/MyGame/Example/NestedStruct.py
new file mode 100644
index 0000000..aa742f4
--- /dev/null
+++ b/tests/MyGame/Example/NestedStruct.py
@@ -0,0 +1,29 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+import flatbuffers
+
+class NestedStruct(object):
+    __slots__ = ['_tab']
+
+    # NestedStruct
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # NestedStruct
+    def A(self): return [self._tab.Get(flatbuffers.number_types.Int32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(0 + i * 4)) for i in range(2)]
+    # NestedStruct
+    def B(self): return self._tab.Get(flatbuffers.number_types.Int8Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(8))
+    # NestedStruct
+    def C(self): return [self._tab.Get(flatbuffers.number_types.Int8Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(9 + i * 1)) for i in range(2)]
+
+def CreateNestedStruct(builder, a, b, c):
+    builder.Prep(4, 12)
+    builder.Pad(1)
+    for _idx0 in range(2 , 0, -1):
+        builder.PrependInt8(c[_idx0-1])
+    builder.PrependInt8(b)
+    for _idx0 in range(2 , 0, -1):
+        builder.PrependInt32(a[_idx0-1])
+    return builder.Offset()
diff --git a/tests/MyGame/Example/Referrable.cs b/tests/MyGame/Example/Referrable.cs
new file mode 100644
index 0000000..5a79f91
--- /dev/null
+++ b/tests/MyGame/Example/Referrable.cs
@@ -0,0 +1,65 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct Referrable : IFlatbufferObject
+{
+  private Table __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_11_1(); }
+  public static Referrable GetRootAsReferrable(ByteBuffer _bb) { return GetRootAsReferrable(_bb, new Referrable()); }
+  public static Referrable GetRootAsReferrable(ByteBuffer _bb, Referrable obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+  public Referrable __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public ulong Id { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetUlong(o + __p.bb_pos) : (ulong)0; } }
+  public bool MutateId(ulong id) { int o = __p.__offset(4); if (o != 0) { __p.bb.PutUlong(o + __p.bb_pos, id); return true; } else { return false; } }
+
+  public static Offset<MyGame.Example.Referrable> CreateReferrable(FlatBufferBuilder builder,
+      ulong id = 0) {
+    builder.StartTable(1);
+    Referrable.AddId(builder, id);
+    return Referrable.EndReferrable(builder);
+  }
+
+  public static void StartReferrable(FlatBufferBuilder builder) { builder.StartTable(1); }
+  public static void AddId(FlatBufferBuilder builder, ulong id) { builder.AddUlong(0, id, 0); }
+  public static Offset<MyGame.Example.Referrable> EndReferrable(FlatBufferBuilder builder) {
+    int o = builder.EndTable();
+    return new Offset<MyGame.Example.Referrable>(o);
+  }
+
+  public static VectorOffset CreateSortedVectorOfReferrable(FlatBufferBuilder builder, Offset<Referrable>[] offsets) {
+    Array.Sort(offsets, (Offset<Referrable> o1, Offset<Referrable> o2) => builder.DataBuffer.GetUlong(Table.__offset(4, o1.Value, builder.DataBuffer)).CompareTo(builder.DataBuffer.GetUlong(Table.__offset(4, o2.Value, builder.DataBuffer))));
+    return builder.CreateVectorOfTables(offsets);
+  }
+
+  public static Referrable? __lookup_by_key(int vectorLocation, ulong key, ByteBuffer bb) {
+    int span = bb.GetInt(vectorLocation - 4);
+    int start = 0;
+    while (span != 0) {
+      int middle = span / 2;
+      int tableOffset = Table.__indirect(vectorLocation + 4 * (start + middle), bb);
+      int comp = bb.GetUlong(Table.__offset(4, bb.Length - tableOffset, bb)).CompareTo(key);
+      if (comp > 0) {
+        span = middle;
+      } else if (comp < 0) {
+        middle++;
+        start += middle;
+        span -= middle;
+      } else {
+        return new Referrable().__assign(tableOffset, bb);
+      }
+    }
+    return null;
+  }
+};
+
+
+}
diff --git a/tests/MyGame/Example/Referrable.go b/tests/MyGame/Example/Referrable.go
new file mode 100644
index 0000000..0fb06fb
--- /dev/null
+++ b/tests/MyGame/Example/Referrable.go
@@ -0,0 +1,49 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package Example
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+)
+
+type Referrable struct {
+	_tab flatbuffers.Table
+}
+
+func GetRootAsReferrable(buf []byte, offset flatbuffers.UOffsetT) *Referrable {
+	n := flatbuffers.GetUOffsetT(buf[offset:])
+	x := &Referrable{}
+	x.Init(buf, n+offset)
+	return x
+}
+
+func (rcv *Referrable) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *Referrable) Table() flatbuffers.Table {
+	return rcv._tab
+}
+
+func (rcv *Referrable) Id() uint64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
+	if o != 0 {
+		return rcv._tab.GetUint64(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *Referrable) MutateId(n uint64) bool {
+	return rcv._tab.MutateUint64Slot(4, n)
+}
+
+func ReferrableStart(builder *flatbuffers.Builder) {
+	builder.StartObject(1)
+}
+func ReferrableAddId(builder *flatbuffers.Builder, id uint64) {
+	builder.PrependUint64Slot(0, id, 0)
+}
+func ReferrableEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+	return builder.EndObject()
+}
diff --git a/tests/MyGame/Example/Referrable.java b/tests/MyGame/Example/Referrable.java
new file mode 100644
index 0000000..f154857
--- /dev/null
+++ b/tests/MyGame/Example/Referrable.java
@@ -0,0 +1,63 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class Referrable extends Table {
+  public static void ValidateVersion() { Constants.FLATBUFFERS_1_11_1(); }
+  public static Referrable getRootAsReferrable(ByteBuffer _bb) { return getRootAsReferrable(_bb, new Referrable()); }
+  public static Referrable getRootAsReferrable(ByteBuffer _bb, Referrable obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public Referrable __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public long id() { int o = __offset(4); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
+  public boolean mutateId(long id) { int o = __offset(4); if (o != 0) { bb.putLong(o + bb_pos, id); return true; } else { return false; } }
+
+  public static int createReferrable(FlatBufferBuilder builder,
+      long id) {
+    builder.startTable(1);
+    Referrable.addId(builder, id);
+    return Referrable.endReferrable(builder);
+  }
+
+  public static void startReferrable(FlatBufferBuilder builder) { builder.startTable(1); }
+  public static void addId(FlatBufferBuilder builder, long id) { builder.addLong(0, id, 0L); }
+  public static int endReferrable(FlatBufferBuilder builder) {
+    int o = builder.endTable();
+    return o;
+  }
+
+  @Override
+  protected int keysCompare(Integer o1, Integer o2, ByteBuffer _bb) {
+    long val_1 = _bb.getLong(__offset(4, o1, _bb));
+    long val_2 = _bb.getLong(__offset(4, o2, _bb));
+    return val_1 > val_2 ? 1 : val_1 < val_2 ? -1 : 0;
+  }
+
+  public static Referrable __lookup_by_key(Referrable obj, int vectorLocation, long key, ByteBuffer bb) {
+    int span = bb.getInt(vectorLocation - 4);
+    int start = 0;
+    while (span != 0) {
+      int middle = span / 2;
+      int tableOffset = __indirect(vectorLocation + 4 * (start + middle), bb);
+      long val = bb.getLong(__offset(4, bb.capacity() - tableOffset, bb));
+      int comp = val > key ? 1 : val < key ? -1 : 0;
+      if (comp > 0) {
+        span = middle;
+      } else if (comp < 0) {
+        middle++;
+        start += middle;
+        span -= middle;
+      } else {
+        return (obj == null ? new Referrable() : obj).__assign(tableOffset, bb);
+      }
+    }
+    return null;
+  }
+}
+
diff --git a/tests/MyGame/Example/Referrable.kt b/tests/MyGame/Example/Referrable.kt
new file mode 100644
index 0000000..55ff1d8
--- /dev/null
+++ b/tests/MyGame/Example/Referrable.kt
@@ -0,0 +1,80 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Referrable : Table() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : Referrable {
+        __init(_i, _bb)
+        return this
+    }
+    val id : ULong
+        get() {
+            val o = __offset(4)
+            return if(o != 0) bb.getLong(o + bb_pos).toULong() else 0UL
+        }
+    fun mutateId(id: ULong) : Boolean {
+        val o = __offset(4)
+        return if (o != 0) {
+            bb.putLong(o + bb_pos, id.toLong())
+            true
+        } else {
+            false
+        }
+    }
+    override fun keysCompare(o1: Int, o2: Int, _bb: ByteBuffer) : Int {
+        val val_1 = _bb.getLong(__offset(4, o1, _bb))
+        val val_2 = _bb.getLong(__offset(4, o2, _bb))
+        return (val_1 - val_2).sign
+    }
+    companion object {
+        fun validateVersion() = Constants.FLATBUFFERS_1_11_1()
+        fun getRootAsReferrable(_bb: ByteBuffer): Referrable = getRootAsReferrable(_bb, Referrable())
+        fun getRootAsReferrable(_bb: ByteBuffer, obj: Referrable): Referrable {
+            _bb.order(ByteOrder.LITTLE_ENDIAN)
+            return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+        }
+        fun createReferrable(builder: FlatBufferBuilder, id: ULong) : Int {
+            builder.startTable(1)
+            addId(builder, id)
+            return endReferrable(builder)
+        }
+        fun startReferrable(builder: FlatBufferBuilder) = builder.startTable(1)
+        fun addId(builder: FlatBufferBuilder, id: ULong) = builder.addLong(0, id.toLong(), 0)
+        fun endReferrable(builder: FlatBufferBuilder) : Int {
+            val o = builder.endTable()
+            return o
+        }
+        fun __lookup_by_key(obj: Referrable?, vectorLocation: Int, key: ULong, bb: ByteBuffer) : Referrable? {
+            var span = bb.getInt(vectorLocation - 4)
+            var start = 0
+            while (span != 0) {
+                var middle = span / 2
+                val tableOffset = __indirect(vectorLocation + 4 * (start + middle), bb)
+                val value = bb.getLong(__offset(4, bb.capacity() - tableOffset, bb)).toULong()
+                val comp = value.compareTo(key)
+                when {
+                    comp > 0 -> span = middle
+                    comp < 0 -> {
+                        middle++
+                        start += middle
+                        span -= middle
+                    }
+                    else -> {
+                        return (obj ?: Referrable()).__assign(tableOffset, bb)
+                    }
+                }
+            }
+            return null
+        }
+    }
+}
diff --git a/tests/MyGame/Example/Referrable.lua b/tests/MyGame/Example/Referrable.lua
new file mode 100644
index 0000000..9b0f5a1
--- /dev/null
+++ b/tests/MyGame/Example/Referrable.lua
@@ -0,0 +1,35 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Example
+
+local flatbuffers = require('flatbuffers')
+
+local Referrable = {} -- the module
+local Referrable_mt = {} -- the class metatable
+
+function Referrable.New()
+    local o = {}
+    setmetatable(o, {__index = Referrable_mt})
+    return o
+end
+function Referrable.GetRootAsReferrable(buf, offset)
+    local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)
+    local o = Referrable.New()
+    o:Init(buf, n + offset)
+    return o
+end
+function Referrable_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function Referrable_mt:Id()
+    local o = self.view:Offset(4)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint64, o + self.view.pos)
+    end
+    return 0
+end
+function Referrable.Start(builder) builder:StartObject(1) end
+function Referrable.AddId(builder, id) builder:PrependUint64Slot(0, id, 0) end
+function Referrable.End(builder) return builder:EndObject() end
+
+return Referrable -- return the module
\ No newline at end of file
diff --git a/tests/MyGame/Example/Referrable.php b/tests/MyGame/Example/Referrable.php
new file mode 100644
index 0000000..5844011
--- /dev/null
+++ b/tests/MyGame/Example/Referrable.php
@@ -0,0 +1,99 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace MyGame\Example;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class Referrable extends Table
+{
+    /**
+     * @param ByteBuffer $bb
+     * @return Referrable
+     */
+    public static function getRootAsReferrable(ByteBuffer $bb)
+    {
+        $obj = new Referrable();
+        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
+    }
+
+    public static function ReferrableIdentifier()
+    {
+        return "MONS";
+    }
+
+    public static function ReferrableBufferHasIdentifier(ByteBuffer $buf)
+    {
+        return self::__has_identifier($buf, self::ReferrableIdentifier());
+    }
+
+    public static function ReferrableExtension()
+    {
+        return "mon";
+    }
+
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return Referrable
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    /**
+     * @return ulong
+     */
+    public function getId()
+    {
+        $o = $this->__offset(4);
+        return $o != 0 ? $this->bb->getUlong($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return void
+     */
+    public static function startReferrable(FlatBufferBuilder $builder)
+    {
+        $builder->StartObject(1);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return Referrable
+     */
+    public static function createReferrable(FlatBufferBuilder $builder, $id)
+    {
+        $builder->startObject(1);
+        self::addId($builder, $id);
+        $o = $builder->endObject();
+        return $o;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param ulong
+     * @return void
+     */
+    public static function addId(FlatBufferBuilder $builder, $id)
+    {
+        $builder->addUlongX(0, $id, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return int table offset
+     */
+    public static function endReferrable(FlatBufferBuilder $builder)
+    {
+        $o = $builder->endObject();
+        return $o;
+    }
+}
diff --git a/tests/MyGame/Example/Referrable.py b/tests/MyGame/Example/Referrable.py
new file mode 100644
index 0000000..eaec09b
--- /dev/null
+++ b/tests/MyGame/Example/Referrable.py
@@ -0,0 +1,34 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+import flatbuffers
+
+class Referrable(object):
+    __slots__ = ['_tab']
+
+    @classmethod
+    def GetRootAsReferrable(cls, buf, offset):
+        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
+        x = Referrable()
+        x.Init(buf, n + offset)
+        return x
+
+    @classmethod
+    def ReferrableBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
+        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x53", size_prefixed=size_prefixed)
+
+    # Referrable
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # Referrable
+    def Id(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
+        return 0
+
+def ReferrableStart(builder): builder.StartObject(1)
+def ReferrableAddId(builder, id): builder.PrependUint64Slot(0, id, 0)
+def ReferrableEnd(builder): return builder.EndObject()
diff --git a/tests/MyGame/Example/Stat.cs b/tests/MyGame/Example/Stat.cs
new file mode 100644
index 0000000..bcd1004
--- /dev/null
+++ b/tests/MyGame/Example/Stat.cs
@@ -0,0 +1,55 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct Stat : IFlatbufferObject
+{
+  private Table __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_11_1(); }
+  public static Stat GetRootAsStat(ByteBuffer _bb) { return GetRootAsStat(_bb, new Stat()); }
+  public static Stat GetRootAsStat(ByteBuffer _bb, Stat obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+  public Stat __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public string Id { get { int o = __p.__offset(4); return o != 0 ? __p.__string(o + __p.bb_pos) : null; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetIdBytes() { return __p.__vector_as_span(4); }
+#else
+  public ArraySegment<byte>? GetIdBytes() { return __p.__vector_as_arraysegment(4); }
+#endif
+  public byte[] GetIdArray() { return __p.__vector_as_array<byte>(4); }
+  public long Val { get { int o = __p.__offset(6); return o != 0 ? __p.bb.GetLong(o + __p.bb_pos) : (long)0; } }
+  public bool MutateVal(long val) { int o = __p.__offset(6); if (o != 0) { __p.bb.PutLong(o + __p.bb_pos, val); return true; } else { return false; } }
+  public ushort Count { get { int o = __p.__offset(8); return o != 0 ? __p.bb.GetUshort(o + __p.bb_pos) : (ushort)0; } }
+  public bool MutateCount(ushort count) { int o = __p.__offset(8); if (o != 0) { __p.bb.PutUshort(o + __p.bb_pos, count); return true; } else { return false; } }
+
+  public static Offset<MyGame.Example.Stat> CreateStat(FlatBufferBuilder builder,
+      StringOffset idOffset = default(StringOffset),
+      long val = 0,
+      ushort count = 0) {
+    builder.StartTable(3);
+    Stat.AddVal(builder, val);
+    Stat.AddId(builder, idOffset);
+    Stat.AddCount(builder, count);
+    return Stat.EndStat(builder);
+  }
+
+  public static void StartStat(FlatBufferBuilder builder) { builder.StartTable(3); }
+  public static void AddId(FlatBufferBuilder builder, StringOffset idOffset) { builder.AddOffset(0, idOffset.Value, 0); }
+  public static void AddVal(FlatBufferBuilder builder, long val) { builder.AddLong(1, val, 0); }
+  public static void AddCount(FlatBufferBuilder builder, ushort count) { builder.AddUshort(2, count, 0); }
+  public static Offset<MyGame.Example.Stat> EndStat(FlatBufferBuilder builder) {
+    int o = builder.EndTable();
+    return new Offset<MyGame.Example.Stat>(o);
+  }
+};
+
+
+}
diff --git a/tests/MyGame/Example/Stat.go b/tests/MyGame/Example/Stat.go
new file mode 100644
index 0000000..401712f
--- /dev/null
+++ b/tests/MyGame/Example/Stat.go
@@ -0,0 +1,75 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package Example
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+)
+
+type Stat struct {
+	_tab flatbuffers.Table
+}
+
+func GetRootAsStat(buf []byte, offset flatbuffers.UOffsetT) *Stat {
+	n := flatbuffers.GetUOffsetT(buf[offset:])
+	x := &Stat{}
+	x.Init(buf, n+offset)
+	return x
+}
+
+func (rcv *Stat) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *Stat) Table() flatbuffers.Table {
+	return rcv._tab
+}
+
+func (rcv *Stat) Id() []byte {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
+	if o != 0 {
+		return rcv._tab.ByteVector(o + rcv._tab.Pos)
+	}
+	return nil
+}
+
+func (rcv *Stat) Val() int64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
+	if o != 0 {
+		return rcv._tab.GetInt64(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *Stat) MutateVal(n int64) bool {
+	return rcv._tab.MutateInt64Slot(6, n)
+}
+
+func (rcv *Stat) Count() uint16 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(8))
+	if o != 0 {
+		return rcv._tab.GetUint16(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *Stat) MutateCount(n uint16) bool {
+	return rcv._tab.MutateUint16Slot(8, n)
+}
+
+func StatStart(builder *flatbuffers.Builder) {
+	builder.StartObject(3)
+}
+func StatAddId(builder *flatbuffers.Builder, id flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(id), 0)
+}
+func StatAddVal(builder *flatbuffers.Builder, val int64) {
+	builder.PrependInt64Slot(1, val, 0)
+}
+func StatAddCount(builder *flatbuffers.Builder, count uint16) {
+	builder.PrependUint16Slot(2, count, 0)
+}
+func StatEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+	return builder.EndObject()
+}
diff --git a/tests/MyGame/Example/Stat.java b/tests/MyGame/Example/Stat.java
new file mode 100644
index 0000000..58d34f3
--- /dev/null
+++ b/tests/MyGame/Example/Stat.java
@@ -0,0 +1,46 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class Stat extends Table {
+  public static void ValidateVersion() { Constants.FLATBUFFERS_1_11_1(); }
+  public static Stat getRootAsStat(ByteBuffer _bb) { return getRootAsStat(_bb, new Stat()); }
+  public static Stat getRootAsStat(ByteBuffer _bb, Stat obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public Stat __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public String id() { int o = __offset(4); return o != 0 ? __string(o + bb_pos) : null; }
+  public ByteBuffer idAsByteBuffer() { return __vector_as_bytebuffer(4, 1); }
+  public ByteBuffer idInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 4, 1); }
+  public long val() { int o = __offset(6); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
+  public boolean mutateVal(long val) { int o = __offset(6); if (o != 0) { bb.putLong(o + bb_pos, val); return true; } else { return false; } }
+  public int count() { int o = __offset(8); return o != 0 ? bb.getShort(o + bb_pos) & 0xFFFF : 0; }
+  public boolean mutateCount(int count) { int o = __offset(8); if (o != 0) { bb.putShort(o + bb_pos, (short)count); return true; } else { return false; } }
+
+  public static int createStat(FlatBufferBuilder builder,
+      int idOffset,
+      long val,
+      int count) {
+    builder.startTable(3);
+    Stat.addVal(builder, val);
+    Stat.addId(builder, idOffset);
+    Stat.addCount(builder, count);
+    return Stat.endStat(builder);
+  }
+
+  public static void startStat(FlatBufferBuilder builder) { builder.startTable(3); }
+  public static void addId(FlatBufferBuilder builder, int idOffset) { builder.addOffset(0, idOffset, 0); }
+  public static void addVal(FlatBufferBuilder builder, long val) { builder.addLong(1, val, 0L); }
+  public static void addCount(FlatBufferBuilder builder, int count) { builder.addShort(2, (short)count, (short)0); }
+  public static int endStat(FlatBufferBuilder builder) {
+    int o = builder.endTable();
+    return o;
+  }
+}
+
diff --git a/tests/MyGame/Example/Stat.kt b/tests/MyGame/Example/Stat.kt
new file mode 100644
index 0000000..26b293c
--- /dev/null
+++ b/tests/MyGame/Example/Stat.kt
@@ -0,0 +1,78 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Stat : Table() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : Stat {
+        __init(_i, _bb)
+        return this
+    }
+    val id : String?
+        get() {
+            val o = __offset(4)
+            return if (o != 0) __string(o + bb_pos) else null
+        }
+    val idAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(4, 1)
+    fun idInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 4, 1)
+    val val_ : Long
+        get() {
+            val o = __offset(6)
+            return if(o != 0) bb.getLong(o + bb_pos) else 0L
+        }
+    fun mutateVal_(val_: Long) : Boolean {
+        val o = __offset(6)
+        return if (o != 0) {
+            bb.putLong(o + bb_pos, val_)
+            true
+        } else {
+            false
+        }
+    }
+    val count : UShort
+        get() {
+            val o = __offset(8)
+            return if(o != 0) bb.getShort(o + bb_pos).toUShort() else 0u
+        }
+    fun mutateCount(count: UShort) : Boolean {
+        val o = __offset(8)
+        return if (o != 0) {
+            bb.putShort(o + bb_pos, count.toShort())
+            true
+        } else {
+            false
+        }
+    }
+    companion object {
+        fun validateVersion() = Constants.FLATBUFFERS_1_11_1()
+        fun getRootAsStat(_bb: ByteBuffer): Stat = getRootAsStat(_bb, Stat())
+        fun getRootAsStat(_bb: ByteBuffer, obj: Stat): Stat {
+            _bb.order(ByteOrder.LITTLE_ENDIAN)
+            return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+        }
+        fun createStat(builder: FlatBufferBuilder, idOffset: Int, val_: Long, count: UShort) : Int {
+            builder.startTable(3)
+            addVal_(builder, val_)
+            addId(builder, idOffset)
+            addCount(builder, count)
+            return endStat(builder)
+        }
+        fun startStat(builder: FlatBufferBuilder) = builder.startTable(3)
+        fun addId(builder: FlatBufferBuilder, id: Int) = builder.addOffset(0, id, 0)
+        fun addVal_(builder: FlatBufferBuilder, val_: Long) = builder.addLong(1, val_, 0L)
+        fun addCount(builder: FlatBufferBuilder, count: UShort) = builder.addShort(2, count.toShort(), 0)
+        fun endStat(builder: FlatBufferBuilder) : Int {
+            val o = builder.endTable()
+            return o
+        }
+    }
+}
diff --git a/tests/MyGame/Example/Stat.lua b/tests/MyGame/Example/Stat.lua
new file mode 100644
index 0000000..6999184
--- /dev/null
+++ b/tests/MyGame/Example/Stat.lua
@@ -0,0 +1,50 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Example
+
+local flatbuffers = require('flatbuffers')
+
+local Stat = {} -- the module
+local Stat_mt = {} -- the class metatable
+
+function Stat.New()
+    local o = {}
+    setmetatable(o, {__index = Stat_mt})
+    return o
+end
+function Stat.GetRootAsStat(buf, offset)
+    local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)
+    local o = Stat.New()
+    o:Init(buf, n + offset)
+    return o
+end
+function Stat_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function Stat_mt:Id()
+    local o = self.view:Offset(4)
+    if o ~= 0 then
+        return self.view:String(o + self.view.pos)
+    end
+end
+function Stat_mt:Val()
+    local o = self.view:Offset(6)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Int64, o + self.view.pos)
+    end
+    return 0
+end
+function Stat_mt:Count()
+    local o = self.view:Offset(8)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint16, o + self.view.pos)
+    end
+    return 0
+end
+function Stat.Start(builder) builder:StartObject(3) end
+function Stat.AddId(builder, id) builder:PrependUOffsetTRelativeSlot(0, id, 0) end
+function Stat.AddVal(builder, val) builder:PrependInt64Slot(1, val, 0) end
+function Stat.AddCount(builder, count) builder:PrependUint16Slot(2, count, 0) end
+function Stat.End(builder) return builder:EndObject() end
+
+return Stat -- return the module
\ No newline at end of file
diff --git a/tests/MyGame/Example/Stat.php b/tests/MyGame/Example/Stat.php
new file mode 100644
index 0000000..6ef7034
--- /dev/null
+++ b/tests/MyGame/Example/Stat.php
@@ -0,0 +1,136 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace MyGame\Example;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class Stat extends Table
+{
+    /**
+     * @param ByteBuffer $bb
+     * @return Stat
+     */
+    public static function getRootAsStat(ByteBuffer $bb)
+    {
+        $obj = new Stat();
+        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
+    }
+
+    public static function StatIdentifier()
+    {
+        return "MONS";
+    }
+
+    public static function StatBufferHasIdentifier(ByteBuffer $buf)
+    {
+        return self::__has_identifier($buf, self::StatIdentifier());
+    }
+
+    public static function StatExtension()
+    {
+        return "mon";
+    }
+
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return Stat
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    public function getId()
+    {
+        $o = $this->__offset(4);
+        return $o != 0 ? $this->__string($o + $this->bb_pos) : null;
+    }
+
+    /**
+     * @return long
+     */
+    public function getVal()
+    {
+        $o = $this->__offset(6);
+        return $o != 0 ? $this->bb->getLong($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return ushort
+     */
+    public function getCount()
+    {
+        $o = $this->__offset(8);
+        return $o != 0 ? $this->bb->getUshort($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return void
+     */
+    public static function startStat(FlatBufferBuilder $builder)
+    {
+        $builder->StartObject(3);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return Stat
+     */
+    public static function createStat(FlatBufferBuilder $builder, $id, $val, $count)
+    {
+        $builder->startObject(3);
+        self::addId($builder, $id);
+        self::addVal($builder, $val);
+        self::addCount($builder, $count);
+        $o = $builder->endObject();
+        return $o;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param StringOffset
+     * @return void
+     */
+    public static function addId(FlatBufferBuilder $builder, $id)
+    {
+        $builder->addOffsetX(0, $id, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param long
+     * @return void
+     */
+    public static function addVal(FlatBufferBuilder $builder, $val)
+    {
+        $builder->addLongX(1, $val, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param ushort
+     * @return void
+     */
+    public static function addCount(FlatBufferBuilder $builder, $count)
+    {
+        $builder->addUshortX(2, $count, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return int table offset
+     */
+    public static function endStat(FlatBufferBuilder $builder)
+    {
+        $o = $builder->endObject();
+        return $o;
+    }
+}
diff --git a/tests/MyGame/Example/Stat.py b/tests/MyGame/Example/Stat.py
new file mode 100644
index 0000000..0fbd2a7
--- /dev/null
+++ b/tests/MyGame/Example/Stat.py
@@ -0,0 +1,50 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+import flatbuffers
+
+class Stat(object):
+    __slots__ = ['_tab']
+
+    @classmethod
+    def GetRootAsStat(cls, buf, offset):
+        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
+        x = Stat()
+        x.Init(buf, n + offset)
+        return x
+
+    @classmethod
+    def StatBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
+        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x53", size_prefixed=size_prefixed)
+
+    # Stat
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # Stat
+    def Id(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+        if o != 0:
+            return self._tab.String(o + self._tab.Pos)
+        return None
+
+    # Stat
+    def Val(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Int64Flags, o + self._tab.Pos)
+        return 0
+
+    # Stat
+    def Count(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint16Flags, o + self._tab.Pos)
+        return 0
+
+def StatStart(builder): builder.StartObject(3)
+def StatAddId(builder, id): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(id), 0)
+def StatAddVal(builder, val): builder.PrependInt64Slot(1, val, 0)
+def StatAddCount(builder, count): builder.PrependUint16Slot(2, count, 0)
+def StatEnd(builder): return builder.EndObject()
diff --git a/tests/MyGame/Example/Test.cs b/tests/MyGame/Example/Test.cs
new file mode 100644
index 0000000..cd91454
--- /dev/null
+++ b/tests/MyGame/Example/Test.cs
@@ -0,0 +1,33 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct Test : IFlatbufferObject
+{
+  private Struct __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
+  public Test __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public short A { get { return __p.bb.GetShort(__p.bb_pos + 0); } }
+  public void MutateA(short a) { __p.bb.PutShort(__p.bb_pos + 0, a); }
+  public sbyte B { get { return __p.bb.GetSbyte(__p.bb_pos + 2); } }
+  public void MutateB(sbyte b) { __p.bb.PutSbyte(__p.bb_pos + 2, b); }
+
+  public static Offset<MyGame.Example.Test> CreateTest(FlatBufferBuilder builder, short A, sbyte B) {
+    builder.Prep(2, 4);
+    builder.Pad(1);
+    builder.PutSbyte(B);
+    builder.PutShort(A);
+    return new Offset<MyGame.Example.Test>(builder.Offset);
+  }
+};
+
+
+}
diff --git a/tests/MyGame/Example/Test.go b/tests/MyGame/Example/Test.go
new file mode 100644
index 0000000..53f53fd
--- /dev/null
+++ b/tests/MyGame/Example/Test.go
@@ -0,0 +1,42 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package Example
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+)
+
+type Test struct {
+	_tab flatbuffers.Struct
+}
+
+func (rcv *Test) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *Test) Table() flatbuffers.Table {
+	return rcv._tab.Table
+}
+
+func (rcv *Test) A() int16 {
+	return rcv._tab.GetInt16(rcv._tab.Pos + flatbuffers.UOffsetT(0))
+}
+func (rcv *Test) MutateA(n int16) bool {
+	return rcv._tab.MutateInt16(rcv._tab.Pos+flatbuffers.UOffsetT(0), n)
+}
+
+func (rcv *Test) B() int8 {
+	return rcv._tab.GetInt8(rcv._tab.Pos + flatbuffers.UOffsetT(2))
+}
+func (rcv *Test) MutateB(n int8) bool {
+	return rcv._tab.MutateInt8(rcv._tab.Pos+flatbuffers.UOffsetT(2), n)
+}
+
+func CreateTest(builder *flatbuffers.Builder, a int16, b int8) flatbuffers.UOffsetT {
+	builder.Prep(2, 4)
+	builder.Pad(1)
+	builder.PrependInt8(b)
+	builder.PrependInt16(a)
+	return builder.Offset()
+}
diff --git a/tests/MyGame/Example/Test.java b/tests/MyGame/Example/Test.java
new file mode 100644
index 0000000..83fdeb0
--- /dev/null
+++ b/tests/MyGame/Example/Test.java
@@ -0,0 +1,28 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class Test extends Struct {
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public Test __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public short a() { return bb.getShort(bb_pos + 0); }
+  public void mutateA(short a) { bb.putShort(bb_pos + 0, a); }
+  public byte b() { return bb.get(bb_pos + 2); }
+  public void mutateB(byte b) { bb.put(bb_pos + 2, b); }
+
+  public static int createTest(FlatBufferBuilder builder, short a, byte b) {
+    builder.prep(2, 4);
+    builder.pad(1);
+    builder.putByte(b);
+    builder.putShort(a);
+    return builder.offset();
+  }
+}
+
diff --git a/tests/MyGame/Example/Test.kt b/tests/MyGame/Example/Test.kt
new file mode 100644
index 0000000..f2ceed6
--- /dev/null
+++ b/tests/MyGame/Example/Test.kt
@@ -0,0 +1,33 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Test : Struct() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : Test {
+        __init(_i, _bb)
+        return this
+    }
+    val a : Short get() = bb.getShort(bb_pos + 0)
+    fun mutateA(a: Short) : ByteBuffer = bb.putShort(bb_pos + 0, a)
+    val b : Byte get() = bb.get(bb_pos + 2)
+    fun mutateB(b: Byte) : ByteBuffer = bb.put(bb_pos + 2, b)
+    companion object {
+        fun createTest(builder: FlatBufferBuilder, a: Short, b: Byte) : Int {
+            builder.prep(2, 4)
+            builder.pad(1)
+            builder.putByte(b)
+            builder.putShort(a)
+            return builder.offset()
+        }
+    }
+}
diff --git a/tests/MyGame/Example/Test.lua b/tests/MyGame/Example/Test.lua
new file mode 100644
index 0000000..154067b
--- /dev/null
+++ b/tests/MyGame/Example/Test.lua
@@ -0,0 +1,32 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Example
+
+local flatbuffers = require('flatbuffers')
+
+local Test = {} -- the module
+local Test_mt = {} -- the class metatable
+
+function Test.New()
+    local o = {}
+    setmetatable(o, {__index = Test_mt})
+    return o
+end
+function Test_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function Test_mt:A()
+    return self.view:Get(flatbuffers.N.Int16, self.view.pos + 0)
+end
+function Test_mt:B()
+    return self.view:Get(flatbuffers.N.Int8, self.view.pos + 2)
+end
+function Test.CreateTest(builder, a, b)
+    builder:Prep(2, 4)
+    builder:Pad(1)
+    builder:PrependInt8(b)
+    builder:PrependInt16(a)
+    return builder:Offset()
+end
+
+return Test -- return the module
\ No newline at end of file
diff --git a/tests/MyGame/Example/Test.php b/tests/MyGame/Example/Test.php
new file mode 100644
index 0000000..13cced0
--- /dev/null
+++ b/tests/MyGame/Example/Test.php
@@ -0,0 +1,53 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace MyGame\Example;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class Test extends Struct
+{
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return Test
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    /**
+     * @return short
+     */
+    public function GetA()
+    {
+        return $this->bb->getShort($this->bb_pos + 0);
+    }
+
+    /**
+     * @return sbyte
+     */
+    public function GetB()
+    {
+        return $this->bb->getSbyte($this->bb_pos + 2);
+    }
+
+
+    /**
+     * @return int offset
+     */
+    public static function createTest(FlatBufferBuilder $builder, $a, $b)
+    {
+        $builder->prep(2, 4);
+        $builder->pad(1);
+        $builder->putSbyte($b);
+        $builder->putShort($a);
+        return $builder->offset();
+    }
+}
diff --git a/tests/MyGame/Example/Test.py b/tests/MyGame/Example/Test.py
new file mode 100644
index 0000000..3b2fd45
--- /dev/null
+++ b/tests/MyGame/Example/Test.py
@@ -0,0 +1,24 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+import flatbuffers
+
+class Test(object):
+    __slots__ = ['_tab']
+
+    # Test
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # Test
+    def A(self): return self._tab.Get(flatbuffers.number_types.Int16Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(0))
+    # Test
+    def B(self): return self._tab.Get(flatbuffers.number_types.Int8Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(2))
+
+def CreateTest(builder, a, b):
+    builder.Prep(2, 4)
+    builder.Pad(1)
+    builder.PrependInt8(b)
+    builder.PrependInt16(a)
+    return builder.Offset()
diff --git a/tests/MyGame/Example/TestEnum.cs b/tests/MyGame/Example/TestEnum.cs
new file mode 100644
index 0000000..22e83b3
--- /dev/null
+++ b/tests/MyGame/Example/TestEnum.cs
@@ -0,0 +1,16 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+public enum TestEnum : sbyte
+{
+  A = 0,
+  B = 1,
+  C = 2,
+};
+
+
+}
diff --git a/tests/MyGame/Example/TestEnum.java b/tests/MyGame/Example/TestEnum.java
new file mode 100644
index 0000000..411bf8e
--- /dev/null
+++ b/tests/MyGame/Example/TestEnum.java
@@ -0,0 +1,15 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+public final class TestEnum {
+  private TestEnum() { }
+  public static final byte A = 0;
+  public static final byte B = 1;
+  public static final byte C = 2;
+
+  public static final String[] names = { "A", "B", "C", };
+
+  public static String name(int e) { return names[e]; }
+}
+
diff --git a/tests/MyGame/Example/TestEnum.kt b/tests/MyGame/Example/TestEnum.kt
new file mode 100644
index 0000000..ca4d7f8
--- /dev/null
+++ b/tests/MyGame/Example/TestEnum.kt
@@ -0,0 +1,14 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+@Suppress("unused")
+class TestEnum private constructor() {
+    companion object {
+        const val A: Byte = 0
+        const val B: Byte = 1
+        const val C: Byte = 2
+        val names : Array<String> = arrayOf("A", "B", "C")
+        fun name(e: Int) : String = names[e]
+    }
+}
diff --git a/tests/MyGame/Example/TestEnum.py b/tests/MyGame/Example/TestEnum.py
new file mode 100644
index 0000000..d49f10a
--- /dev/null
+++ b/tests/MyGame/Example/TestEnum.py
@@ -0,0 +1,9 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+class TestEnum(object):
+    A = 0
+    B = 1
+    C = 2
+
diff --git a/tests/MyGame/Example/TestSimpleTableWithEnum.cs b/tests/MyGame/Example/TestSimpleTableWithEnum.cs
new file mode 100644
index 0000000..f9ac42e
--- /dev/null
+++ b/tests/MyGame/Example/TestSimpleTableWithEnum.cs
@@ -0,0 +1,40 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+using global::System;
+using global::FlatBuffers;
+
+internal partial struct TestSimpleTableWithEnum : IFlatbufferObject
+{
+  private Table __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_11_1(); }
+  public static TestSimpleTableWithEnum GetRootAsTestSimpleTableWithEnum(ByteBuffer _bb) { return GetRootAsTestSimpleTableWithEnum(_bb, new TestSimpleTableWithEnum()); }
+  public static TestSimpleTableWithEnum GetRootAsTestSimpleTableWithEnum(ByteBuffer _bb, TestSimpleTableWithEnum obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+  public TestSimpleTableWithEnum __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public MyGame.Example.Color Color { get { int o = __p.__offset(4); return o != 0 ? (MyGame.Example.Color)__p.bb.Get(o + __p.bb_pos) : MyGame.Example.Color.Green; } }
+  public bool MutateColor(MyGame.Example.Color color) { int o = __p.__offset(4); if (o != 0) { __p.bb.Put(o + __p.bb_pos, (byte)color); return true; } else { return false; } }
+
+  public static Offset<MyGame.Example.TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(FlatBufferBuilder builder,
+      MyGame.Example.Color color = MyGame.Example.Color.Green) {
+    builder.StartTable(1);
+    TestSimpleTableWithEnum.AddColor(builder, color);
+    return TestSimpleTableWithEnum.EndTestSimpleTableWithEnum(builder);
+  }
+
+  public static void StartTestSimpleTableWithEnum(FlatBufferBuilder builder) { builder.StartTable(1); }
+  public static void AddColor(FlatBufferBuilder builder, MyGame.Example.Color color) { builder.AddByte(0, (byte)color, 2); }
+  public static Offset<MyGame.Example.TestSimpleTableWithEnum> EndTestSimpleTableWithEnum(FlatBufferBuilder builder) {
+    int o = builder.EndTable();
+    return new Offset<MyGame.Example.TestSimpleTableWithEnum>(o);
+  }
+};
+
+
+}
diff --git a/tests/MyGame/Example/TestSimpleTableWithEnum.go b/tests/MyGame/Example/TestSimpleTableWithEnum.go
new file mode 100644
index 0000000..35a6c7c
--- /dev/null
+++ b/tests/MyGame/Example/TestSimpleTableWithEnum.go
@@ -0,0 +1,49 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package Example
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+)
+
+type TestSimpleTableWithEnum struct {
+	_tab flatbuffers.Table
+}
+
+func GetRootAsTestSimpleTableWithEnum(buf []byte, offset flatbuffers.UOffsetT) *TestSimpleTableWithEnum {
+	n := flatbuffers.GetUOffsetT(buf[offset:])
+	x := &TestSimpleTableWithEnum{}
+	x.Init(buf, n+offset)
+	return x
+}
+
+func (rcv *TestSimpleTableWithEnum) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *TestSimpleTableWithEnum) Table() flatbuffers.Table {
+	return rcv._tab
+}
+
+func (rcv *TestSimpleTableWithEnum) Color() Color {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
+	if o != 0 {
+		return Color(rcv._tab.GetByte(o + rcv._tab.Pos))
+	}
+	return 2
+}
+
+func (rcv *TestSimpleTableWithEnum) MutateColor(n Color) bool {
+	return rcv._tab.MutateByteSlot(4, byte(n))
+}
+
+func TestSimpleTableWithEnumStart(builder *flatbuffers.Builder) {
+	builder.StartObject(1)
+}
+func TestSimpleTableWithEnumAddColor(builder *flatbuffers.Builder, color Color) {
+	builder.PrependByteSlot(0, byte(color), 2)
+}
+func TestSimpleTableWithEnumEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+	return builder.EndObject()
+}
diff --git a/tests/MyGame/Example/TestSimpleTableWithEnum.java b/tests/MyGame/Example/TestSimpleTableWithEnum.java
new file mode 100644
index 0000000..c9f1c63
--- /dev/null
+++ b/tests/MyGame/Example/TestSimpleTableWithEnum.java
@@ -0,0 +1,35 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+final class TestSimpleTableWithEnum extends Table {
+  public static void ValidateVersion() { Constants.FLATBUFFERS_1_11_1(); }
+  public static TestSimpleTableWithEnum getRootAsTestSimpleTableWithEnum(ByteBuffer _bb) { return getRootAsTestSimpleTableWithEnum(_bb, new TestSimpleTableWithEnum()); }
+  public static TestSimpleTableWithEnum getRootAsTestSimpleTableWithEnum(ByteBuffer _bb, TestSimpleTableWithEnum obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public TestSimpleTableWithEnum __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public int color() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) & 0xFF : 2; }
+  public boolean mutateColor(int color) { int o = __offset(4); if (o != 0) { bb.put(o + bb_pos, (byte)color); return true; } else { return false; } }
+
+  public static int createTestSimpleTableWithEnum(FlatBufferBuilder builder,
+      int color) {
+    builder.startTable(1);
+    TestSimpleTableWithEnum.addColor(builder, color);
+    return TestSimpleTableWithEnum.endTestSimpleTableWithEnum(builder);
+  }
+
+  public static void startTestSimpleTableWithEnum(FlatBufferBuilder builder) { builder.startTable(1); }
+  public static void addColor(FlatBufferBuilder builder, int color) { builder.addByte(0, (byte)color, (byte)2); }
+  public static int endTestSimpleTableWithEnum(FlatBufferBuilder builder) {
+    int o = builder.endTable();
+    return o;
+  }
+}
+
diff --git a/tests/MyGame/Example/TestSimpleTableWithEnum.kt b/tests/MyGame/Example/TestSimpleTableWithEnum.kt
new file mode 100644
index 0000000..68c6abf
--- /dev/null
+++ b/tests/MyGame/Example/TestSimpleTableWithEnum.kt
@@ -0,0 +1,53 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class TestSimpleTableWithEnum : Table() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : TestSimpleTableWithEnum {
+        __init(_i, _bb)
+        return this
+    }
+    val color : UByte
+        get() {
+            val o = __offset(4)
+            return if(o != 0) bb.get(o + bb_pos).toUByte() else 2u
+        }
+    fun mutateColor(color: UByte) : Boolean {
+        val o = __offset(4)
+        return if (o != 0) {
+            bb.put(o + bb_pos, color.toByte())
+            true
+        } else {
+            false
+        }
+    }
+    companion object {
+        fun validateVersion() = Constants.FLATBUFFERS_1_11_1()
+        fun getRootAsTestSimpleTableWithEnum(_bb: ByteBuffer): TestSimpleTableWithEnum = getRootAsTestSimpleTableWithEnum(_bb, TestSimpleTableWithEnum())
+        fun getRootAsTestSimpleTableWithEnum(_bb: ByteBuffer, obj: TestSimpleTableWithEnum): TestSimpleTableWithEnum {
+            _bb.order(ByteOrder.LITTLE_ENDIAN)
+            return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+        }
+        fun createTestSimpleTableWithEnum(builder: FlatBufferBuilder, color: UByte) : Int {
+            builder.startTable(1)
+            addColor(builder, color)
+            return endTestSimpleTableWithEnum(builder)
+        }
+        fun startTestSimpleTableWithEnum(builder: FlatBufferBuilder) = builder.startTable(1)
+        fun addColor(builder: FlatBufferBuilder, color: UByte) = builder.addByte(0, color.toByte(), 2)
+        fun endTestSimpleTableWithEnum(builder: FlatBufferBuilder) : Int {
+            val o = builder.endTable()
+            return o
+        }
+    }
+}
diff --git a/tests/MyGame/Example/TestSimpleTableWithEnum.lua b/tests/MyGame/Example/TestSimpleTableWithEnum.lua
new file mode 100644
index 0000000..32c8251
--- /dev/null
+++ b/tests/MyGame/Example/TestSimpleTableWithEnum.lua
@@ -0,0 +1,35 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Example
+
+local flatbuffers = require('flatbuffers')
+
+local TestSimpleTableWithEnum = {} -- the module
+local TestSimpleTableWithEnum_mt = {} -- the class metatable
+
+function TestSimpleTableWithEnum.New()
+    local o = {}
+    setmetatable(o, {__index = TestSimpleTableWithEnum_mt})
+    return o
+end
+function TestSimpleTableWithEnum.GetRootAsTestSimpleTableWithEnum(buf, offset)
+    local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)
+    local o = TestSimpleTableWithEnum.New()
+    o:Init(buf, n + offset)
+    return o
+end
+function TestSimpleTableWithEnum_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function TestSimpleTableWithEnum_mt:Color()
+    local o = self.view:Offset(4)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint8, o + self.view.pos)
+    end
+    return 2
+end
+function TestSimpleTableWithEnum.Start(builder) builder:StartObject(1) end
+function TestSimpleTableWithEnum.AddColor(builder, color) builder:PrependUint8Slot(0, color, 2) end
+function TestSimpleTableWithEnum.End(builder) return builder:EndObject() end
+
+return TestSimpleTableWithEnum -- return the module
\ No newline at end of file
diff --git a/tests/MyGame/Example/TestSimpleTableWithEnum.php b/tests/MyGame/Example/TestSimpleTableWithEnum.php
new file mode 100644
index 0000000..6429f8d
--- /dev/null
+++ b/tests/MyGame/Example/TestSimpleTableWithEnum.php
@@ -0,0 +1,99 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace MyGame\Example;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class TestSimpleTableWithEnum extends Table
+{
+    /**
+     * @param ByteBuffer $bb
+     * @return TestSimpleTableWithEnum
+     */
+    public static function getRootAsTestSimpleTableWithEnum(ByteBuffer $bb)
+    {
+        $obj = new TestSimpleTableWithEnum();
+        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
+    }
+
+    public static function TestSimpleTableWithEnumIdentifier()
+    {
+        return "MONS";
+    }
+
+    public static function TestSimpleTableWithEnumBufferHasIdentifier(ByteBuffer $buf)
+    {
+        return self::__has_identifier($buf, self::TestSimpleTableWithEnumIdentifier());
+    }
+
+    public static function TestSimpleTableWithEnumExtension()
+    {
+        return "mon";
+    }
+
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return TestSimpleTableWithEnum
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    /**
+     * @return byte
+     */
+    public function getColor()
+    {
+        $o = $this->__offset(4);
+        return $o != 0 ? $this->bb->getByte($o + $this->bb_pos) : \MyGame\Example\Color::Green;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return void
+     */
+    public static function startTestSimpleTableWithEnum(FlatBufferBuilder $builder)
+    {
+        $builder->StartObject(1);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return TestSimpleTableWithEnum
+     */
+    public static function createTestSimpleTableWithEnum(FlatBufferBuilder $builder, $color)
+    {
+        $builder->startObject(1);
+        self::addColor($builder, $color);
+        $o = $builder->endObject();
+        return $o;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param byte
+     * @return void
+     */
+    public static function addColor(FlatBufferBuilder $builder, $color)
+    {
+        $builder->addByteX(0, $color, 2);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return int table offset
+     */
+    public static function endTestSimpleTableWithEnum(FlatBufferBuilder $builder)
+    {
+        $o = $builder->endObject();
+        return $o;
+    }
+}
diff --git a/tests/MyGame/Example/TestSimpleTableWithEnum.py b/tests/MyGame/Example/TestSimpleTableWithEnum.py
new file mode 100644
index 0000000..cb9c631
--- /dev/null
+++ b/tests/MyGame/Example/TestSimpleTableWithEnum.py
@@ -0,0 +1,34 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+import flatbuffers
+
+class TestSimpleTableWithEnum(object):
+    __slots__ = ['_tab']
+
+    @classmethod
+    def GetRootAsTestSimpleTableWithEnum(cls, buf, offset):
+        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
+        x = TestSimpleTableWithEnum()
+        x.Init(buf, n + offset)
+        return x
+
+    @classmethod
+    def TestSimpleTableWithEnumBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
+        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x53", size_prefixed=size_prefixed)
+
+    # TestSimpleTableWithEnum
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # TestSimpleTableWithEnum
+    def Color(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos)
+        return 2
+
+def TestSimpleTableWithEnumStart(builder): builder.StartObject(1)
+def TestSimpleTableWithEnumAddColor(builder, color): builder.PrependUint8Slot(0, color, 2)
+def TestSimpleTableWithEnumEnd(builder): return builder.EndObject()
diff --git a/tests/MyGame/Example/TypeAliases.cs b/tests/MyGame/Example/TypeAliases.cs
new file mode 100644
index 0000000..a7b54d5
--- /dev/null
+++ b/tests/MyGame/Example/TypeAliases.cs
@@ -0,0 +1,115 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct TypeAliases : IFlatbufferObject
+{
+  private Table __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_11_1(); }
+  public static TypeAliases GetRootAsTypeAliases(ByteBuffer _bb) { return GetRootAsTypeAliases(_bb, new TypeAliases()); }
+  public static TypeAliases GetRootAsTypeAliases(ByteBuffer _bb, TypeAliases obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+  public TypeAliases __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public sbyte I8 { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetSbyte(o + __p.bb_pos) : (sbyte)0; } }
+  public bool MutateI8(sbyte i8) { int o = __p.__offset(4); if (o != 0) { __p.bb.PutSbyte(o + __p.bb_pos, i8); return true; } else { return false; } }
+  public byte U8 { get { int o = __p.__offset(6); return o != 0 ? __p.bb.Get(o + __p.bb_pos) : (byte)0; } }
+  public bool MutateU8(byte u8) { int o = __p.__offset(6); if (o != 0) { __p.bb.Put(o + __p.bb_pos, u8); return true; } else { return false; } }
+  public short I16 { get { int o = __p.__offset(8); return o != 0 ? __p.bb.GetShort(o + __p.bb_pos) : (short)0; } }
+  public bool MutateI16(short i16) { int o = __p.__offset(8); if (o != 0) { __p.bb.PutShort(o + __p.bb_pos, i16); return true; } else { return false; } }
+  public ushort U16 { get { int o = __p.__offset(10); return o != 0 ? __p.bb.GetUshort(o + __p.bb_pos) : (ushort)0; } }
+  public bool MutateU16(ushort u16) { int o = __p.__offset(10); if (o != 0) { __p.bb.PutUshort(o + __p.bb_pos, u16); return true; } else { return false; } }
+  public int I32 { get { int o = __p.__offset(12); return o != 0 ? __p.bb.GetInt(o + __p.bb_pos) : (int)0; } }
+  public bool MutateI32(int i32) { int o = __p.__offset(12); if (o != 0) { __p.bb.PutInt(o + __p.bb_pos, i32); return true; } else { return false; } }
+  public uint U32 { get { int o = __p.__offset(14); return o != 0 ? __p.bb.GetUint(o + __p.bb_pos) : (uint)0; } }
+  public bool MutateU32(uint u32) { int o = __p.__offset(14); if (o != 0) { __p.bb.PutUint(o + __p.bb_pos, u32); return true; } else { return false; } }
+  public long I64 { get { int o = __p.__offset(16); return o != 0 ? __p.bb.GetLong(o + __p.bb_pos) : (long)0; } }
+  public bool MutateI64(long i64) { int o = __p.__offset(16); if (o != 0) { __p.bb.PutLong(o + __p.bb_pos, i64); return true; } else { return false; } }
+  public ulong U64 { get { int o = __p.__offset(18); return o != 0 ? __p.bb.GetUlong(o + __p.bb_pos) : (ulong)0; } }
+  public bool MutateU64(ulong u64) { int o = __p.__offset(18); if (o != 0) { __p.bb.PutUlong(o + __p.bb_pos, u64); return true; } else { return false; } }
+  public float F32 { get { int o = __p.__offset(20); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)0.0f; } }
+  public bool MutateF32(float f32) { int o = __p.__offset(20); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, f32); return true; } else { return false; } }
+  public double F64 { get { int o = __p.__offset(22); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)0.0; } }
+  public bool MutateF64(double f64) { int o = __p.__offset(22); if (o != 0) { __p.bb.PutDouble(o + __p.bb_pos, f64); return true; } else { return false; } }
+  public sbyte V8(int j) { int o = __p.__offset(24); return o != 0 ? __p.bb.GetSbyte(__p.__vector(o) + j * 1) : (sbyte)0; }
+  public int V8Length { get { int o = __p.__offset(24); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetV8Bytes() { return __p.__vector_as_span(24); }
+#else
+  public ArraySegment<byte>? GetV8Bytes() { return __p.__vector_as_arraysegment(24); }
+#endif
+  public sbyte[] GetV8Array() { return __p.__vector_as_array<sbyte>(24); }
+  public bool MutateV8(int j, sbyte v8) { int o = __p.__offset(24); if (o != 0) { __p.bb.PutSbyte(__p.__vector(o) + j * 1, v8); return true; } else { return false; } }
+  public double Vf64(int j) { int o = __p.__offset(26); return o != 0 ? __p.bb.GetDouble(__p.__vector(o) + j * 8) : (double)0; }
+  public int Vf64Length { get { int o = __p.__offset(26); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetVf64Bytes() { return __p.__vector_as_span(26); }
+#else
+  public ArraySegment<byte>? GetVf64Bytes() { return __p.__vector_as_arraysegment(26); }
+#endif
+  public double[] GetVf64Array() { return __p.__vector_as_array<double>(26); }
+  public bool MutateVf64(int j, double vf64) { int o = __p.__offset(26); if (o != 0) { __p.bb.PutDouble(__p.__vector(o) + j * 8, vf64); return true; } else { return false; } }
+
+  public static Offset<MyGame.Example.TypeAliases> CreateTypeAliases(FlatBufferBuilder builder,
+      sbyte i8 = 0,
+      byte u8 = 0,
+      short i16 = 0,
+      ushort u16 = 0,
+      int i32 = 0,
+      uint u32 = 0,
+      long i64 = 0,
+      ulong u64 = 0,
+      float f32 = 0.0f,
+      double f64 = 0.0,
+      VectorOffset v8Offset = default(VectorOffset),
+      VectorOffset vf64Offset = default(VectorOffset)) {
+    builder.StartTable(12);
+    TypeAliases.AddF64(builder, f64);
+    TypeAliases.AddU64(builder, u64);
+    TypeAliases.AddI64(builder, i64);
+    TypeAliases.AddVf64(builder, vf64Offset);
+    TypeAliases.AddV8(builder, v8Offset);
+    TypeAliases.AddF32(builder, f32);
+    TypeAliases.AddU32(builder, u32);
+    TypeAliases.AddI32(builder, i32);
+    TypeAliases.AddU16(builder, u16);
+    TypeAliases.AddI16(builder, i16);
+    TypeAliases.AddU8(builder, u8);
+    TypeAliases.AddI8(builder, i8);
+    return TypeAliases.EndTypeAliases(builder);
+  }
+
+  public static void StartTypeAliases(FlatBufferBuilder builder) { builder.StartTable(12); }
+  public static void AddI8(FlatBufferBuilder builder, sbyte i8) { builder.AddSbyte(0, i8, 0); }
+  public static void AddU8(FlatBufferBuilder builder, byte u8) { builder.AddByte(1, u8, 0); }
+  public static void AddI16(FlatBufferBuilder builder, short i16) { builder.AddShort(2, i16, 0); }
+  public static void AddU16(FlatBufferBuilder builder, ushort u16) { builder.AddUshort(3, u16, 0); }
+  public static void AddI32(FlatBufferBuilder builder, int i32) { builder.AddInt(4, i32, 0); }
+  public static void AddU32(FlatBufferBuilder builder, uint u32) { builder.AddUint(5, u32, 0); }
+  public static void AddI64(FlatBufferBuilder builder, long i64) { builder.AddLong(6, i64, 0); }
+  public static void AddU64(FlatBufferBuilder builder, ulong u64) { builder.AddUlong(7, u64, 0); }
+  public static void AddF32(FlatBufferBuilder builder, float f32) { builder.AddFloat(8, f32, 0.0f); }
+  public static void AddF64(FlatBufferBuilder builder, double f64) { builder.AddDouble(9, f64, 0.0); }
+  public static void AddV8(FlatBufferBuilder builder, VectorOffset v8Offset) { builder.AddOffset(10, v8Offset.Value, 0); }
+  public static VectorOffset CreateV8Vector(FlatBufferBuilder builder, sbyte[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddSbyte(data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateV8VectorBlock(FlatBufferBuilder builder, sbyte[] data) { builder.StartVector(1, data.Length, 1); builder.Add(data); return builder.EndVector(); }
+  public static void StartV8Vector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); }
+  public static void AddVf64(FlatBufferBuilder builder, VectorOffset vf64Offset) { builder.AddOffset(11, vf64Offset.Value, 0); }
+  public static VectorOffset CreateVf64Vector(FlatBufferBuilder builder, double[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddDouble(data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateVf64VectorBlock(FlatBufferBuilder builder, double[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
+  public static void StartVf64Vector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
+  public static Offset<MyGame.Example.TypeAliases> EndTypeAliases(FlatBufferBuilder builder) {
+    int o = builder.EndTable();
+    return new Offset<MyGame.Example.TypeAliases>(o);
+  }
+};
+
+
+}
diff --git a/tests/MyGame/Example/TypeAliases.go b/tests/MyGame/Example/TypeAliases.go
new file mode 100644
index 0000000..d017b5b
--- /dev/null
+++ b/tests/MyGame/Example/TypeAliases.go
@@ -0,0 +1,248 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package Example
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+)
+
+type TypeAliases struct {
+	_tab flatbuffers.Table
+}
+
+func GetRootAsTypeAliases(buf []byte, offset flatbuffers.UOffsetT) *TypeAliases {
+	n := flatbuffers.GetUOffsetT(buf[offset:])
+	x := &TypeAliases{}
+	x.Init(buf, n+offset)
+	return x
+}
+
+func (rcv *TypeAliases) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *TypeAliases) Table() flatbuffers.Table {
+	return rcv._tab
+}
+
+func (rcv *TypeAliases) I8() int8 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
+	if o != 0 {
+		return rcv._tab.GetInt8(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *TypeAliases) MutateI8(n int8) bool {
+	return rcv._tab.MutateInt8Slot(4, n)
+}
+
+func (rcv *TypeAliases) U8() byte {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
+	if o != 0 {
+		return rcv._tab.GetByte(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *TypeAliases) MutateU8(n byte) bool {
+	return rcv._tab.MutateByteSlot(6, n)
+}
+
+func (rcv *TypeAliases) I16() int16 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(8))
+	if o != 0 {
+		return rcv._tab.GetInt16(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *TypeAliases) MutateI16(n int16) bool {
+	return rcv._tab.MutateInt16Slot(8, n)
+}
+
+func (rcv *TypeAliases) U16() uint16 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(10))
+	if o != 0 {
+		return rcv._tab.GetUint16(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *TypeAliases) MutateU16(n uint16) bool {
+	return rcv._tab.MutateUint16Slot(10, n)
+}
+
+func (rcv *TypeAliases) I32() int32 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(12))
+	if o != 0 {
+		return rcv._tab.GetInt32(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *TypeAliases) MutateI32(n int32) bool {
+	return rcv._tab.MutateInt32Slot(12, n)
+}
+
+func (rcv *TypeAliases) U32() uint32 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(14))
+	if o != 0 {
+		return rcv._tab.GetUint32(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *TypeAliases) MutateU32(n uint32) bool {
+	return rcv._tab.MutateUint32Slot(14, n)
+}
+
+func (rcv *TypeAliases) I64() int64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(16))
+	if o != 0 {
+		return rcv._tab.GetInt64(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *TypeAliases) MutateI64(n int64) bool {
+	return rcv._tab.MutateInt64Slot(16, n)
+}
+
+func (rcv *TypeAliases) U64() uint64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(18))
+	if o != 0 {
+		return rcv._tab.GetUint64(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *TypeAliases) MutateU64(n uint64) bool {
+	return rcv._tab.MutateUint64Slot(18, n)
+}
+
+func (rcv *TypeAliases) F32() float32 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(20))
+	if o != 0 {
+		return rcv._tab.GetFloat32(o + rcv._tab.Pos)
+	}
+	return 0.0
+}
+
+func (rcv *TypeAliases) MutateF32(n float32) bool {
+	return rcv._tab.MutateFloat32Slot(20, n)
+}
+
+func (rcv *TypeAliases) F64() float64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(22))
+	if o != 0 {
+		return rcv._tab.GetFloat64(o + rcv._tab.Pos)
+	}
+	return 0.0
+}
+
+func (rcv *TypeAliases) MutateF64(n float64) bool {
+	return rcv._tab.MutateFloat64Slot(22, n)
+}
+
+func (rcv *TypeAliases) V8(j int) int8 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(24))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.GetInt8(a + flatbuffers.UOffsetT(j*1))
+	}
+	return 0
+}
+
+func (rcv *TypeAliases) V8Length() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(24))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *TypeAliases) MutateV8(j int, n int8) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(24))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.MutateInt8(a+flatbuffers.UOffsetT(j*1), n)
+	}
+	return false
+}
+
+func (rcv *TypeAliases) Vf64(j int) float64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(26))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.GetFloat64(a + flatbuffers.UOffsetT(j*8))
+	}
+	return 0
+}
+
+func (rcv *TypeAliases) Vf64Length() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(26))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *TypeAliases) MutateVf64(j int, n float64) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(26))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.MutateFloat64(a+flatbuffers.UOffsetT(j*8), n)
+	}
+	return false
+}
+
+func TypeAliasesStart(builder *flatbuffers.Builder) {
+	builder.StartObject(12)
+}
+func TypeAliasesAddI8(builder *flatbuffers.Builder, i8 int8) {
+	builder.PrependInt8Slot(0, i8, 0)
+}
+func TypeAliasesAddU8(builder *flatbuffers.Builder, u8 byte) {
+	builder.PrependByteSlot(1, u8, 0)
+}
+func TypeAliasesAddI16(builder *flatbuffers.Builder, i16 int16) {
+	builder.PrependInt16Slot(2, i16, 0)
+}
+func TypeAliasesAddU16(builder *flatbuffers.Builder, u16 uint16) {
+	builder.PrependUint16Slot(3, u16, 0)
+}
+func TypeAliasesAddI32(builder *flatbuffers.Builder, i32 int32) {
+	builder.PrependInt32Slot(4, i32, 0)
+}
+func TypeAliasesAddU32(builder *flatbuffers.Builder, u32 uint32) {
+	builder.PrependUint32Slot(5, u32, 0)
+}
+func TypeAliasesAddI64(builder *flatbuffers.Builder, i64 int64) {
+	builder.PrependInt64Slot(6, i64, 0)
+}
+func TypeAliasesAddU64(builder *flatbuffers.Builder, u64 uint64) {
+	builder.PrependUint64Slot(7, u64, 0)
+}
+func TypeAliasesAddF32(builder *flatbuffers.Builder, f32 float32) {
+	builder.PrependFloat32Slot(8, f32, 0.0)
+}
+func TypeAliasesAddF64(builder *flatbuffers.Builder, f64 float64) {
+	builder.PrependFloat64Slot(9, f64, 0.0)
+}
+func TypeAliasesAddV8(builder *flatbuffers.Builder, v8 flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(10, flatbuffers.UOffsetT(v8), 0)
+}
+func TypeAliasesStartV8Vector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(1, numElems, 1)
+}
+func TypeAliasesAddVf64(builder *flatbuffers.Builder, vf64 flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(11, flatbuffers.UOffsetT(vf64), 0)
+}
+func TypeAliasesStartVf64Vector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(8, numElems, 8)
+}
+func TypeAliasesEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+	return builder.EndObject()
+}
diff --git a/tests/MyGame/Example/TypeAliases.java b/tests/MyGame/Example/TypeAliases.java
new file mode 100644
index 0000000..dde6acb
--- /dev/null
+++ b/tests/MyGame/Example/TypeAliases.java
@@ -0,0 +1,100 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class TypeAliases extends Table {
+  public static void ValidateVersion() { Constants.FLATBUFFERS_1_11_1(); }
+  public static TypeAliases getRootAsTypeAliases(ByteBuffer _bb) { return getRootAsTypeAliases(_bb, new TypeAliases()); }
+  public static TypeAliases getRootAsTypeAliases(ByteBuffer _bb, TypeAliases obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public TypeAliases __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public byte i8() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) : 0; }
+  public boolean mutateI8(byte i8) { int o = __offset(4); if (o != 0) { bb.put(o + bb_pos, i8); return true; } else { return false; } }
+  public int u8() { int o = __offset(6); return o != 0 ? bb.get(o + bb_pos) & 0xFF : 0; }
+  public boolean mutateU8(int u8) { int o = __offset(6); if (o != 0) { bb.put(o + bb_pos, (byte)u8); return true; } else { return false; } }
+  public short i16() { int o = __offset(8); return o != 0 ? bb.getShort(o + bb_pos) : 0; }
+  public boolean mutateI16(short i16) { int o = __offset(8); if (o != 0) { bb.putShort(o + bb_pos, i16); return true; } else { return false; } }
+  public int u16() { int o = __offset(10); return o != 0 ? bb.getShort(o + bb_pos) & 0xFFFF : 0; }
+  public boolean mutateU16(int u16) { int o = __offset(10); if (o != 0) { bb.putShort(o + bb_pos, (short)u16); return true; } else { return false; } }
+  public int i32() { int o = __offset(12); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
+  public boolean mutateI32(int i32) { int o = __offset(12); if (o != 0) { bb.putInt(o + bb_pos, i32); return true; } else { return false; } }
+  public long u32() { int o = __offset(14); return o != 0 ? (long)bb.getInt(o + bb_pos) & 0xFFFFFFFFL : 0L; }
+  public boolean mutateU32(long u32) { int o = __offset(14); if (o != 0) { bb.putInt(o + bb_pos, (int)u32); return true; } else { return false; } }
+  public long i64() { int o = __offset(16); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
+  public boolean mutateI64(long i64) { int o = __offset(16); if (o != 0) { bb.putLong(o + bb_pos, i64); return true; } else { return false; } }
+  public long u64() { int o = __offset(18); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
+  public boolean mutateU64(long u64) { int o = __offset(18); if (o != 0) { bb.putLong(o + bb_pos, u64); return true; } else { return false; } }
+  public float f32() { int o = __offset(20); return o != 0 ? bb.getFloat(o + bb_pos) : 0.0f; }
+  public boolean mutateF32(float f32) { int o = __offset(20); if (o != 0) { bb.putFloat(o + bb_pos, f32); return true; } else { return false; } }
+  public double f64() { int o = __offset(22); return o != 0 ? bb.getDouble(o + bb_pos) : 0.0; }
+  public boolean mutateF64(double f64) { int o = __offset(22); if (o != 0) { bb.putDouble(o + bb_pos, f64); return true; } else { return false; } }
+  public byte v8(int j) { int o = __offset(24); return o != 0 ? bb.get(__vector(o) + j * 1) : 0; }
+  public int v8Length() { int o = __offset(24); return o != 0 ? __vector_len(o) : 0; }
+  public ByteBuffer v8AsByteBuffer() { return __vector_as_bytebuffer(24, 1); }
+  public ByteBuffer v8InByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 24, 1); }
+  public boolean mutateV8(int j, byte v8) { int o = __offset(24); if (o != 0) { bb.put(__vector(o) + j * 1, v8); return true; } else { return false; } }
+  public double vf64(int j) { int o = __offset(26); return o != 0 ? bb.getDouble(__vector(o) + j * 8) : 0; }
+  public int vf64Length() { int o = __offset(26); return o != 0 ? __vector_len(o) : 0; }
+  public ByteBuffer vf64AsByteBuffer() { return __vector_as_bytebuffer(26, 8); }
+  public ByteBuffer vf64InByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 26, 8); }
+  public boolean mutateVf64(int j, double vf64) { int o = __offset(26); if (o != 0) { bb.putDouble(__vector(o) + j * 8, vf64); return true; } else { return false; } }
+
+  public static int createTypeAliases(FlatBufferBuilder builder,
+      byte i8,
+      int u8,
+      short i16,
+      int u16,
+      int i32,
+      long u32,
+      long i64,
+      long u64,
+      float f32,
+      double f64,
+      int v8Offset,
+      int vf64Offset) {
+    builder.startTable(12);
+    TypeAliases.addF64(builder, f64);
+    TypeAliases.addU64(builder, u64);
+    TypeAliases.addI64(builder, i64);
+    TypeAliases.addVf64(builder, vf64Offset);
+    TypeAliases.addV8(builder, v8Offset);
+    TypeAliases.addF32(builder, f32);
+    TypeAliases.addU32(builder, u32);
+    TypeAliases.addI32(builder, i32);
+    TypeAliases.addU16(builder, u16);
+    TypeAliases.addI16(builder, i16);
+    TypeAliases.addU8(builder, u8);
+    TypeAliases.addI8(builder, i8);
+    return TypeAliases.endTypeAliases(builder);
+  }
+
+  public static void startTypeAliases(FlatBufferBuilder builder) { builder.startTable(12); }
+  public static void addI8(FlatBufferBuilder builder, byte i8) { builder.addByte(0, i8, 0); }
+  public static void addU8(FlatBufferBuilder builder, int u8) { builder.addByte(1, (byte)u8, (byte)0); }
+  public static void addI16(FlatBufferBuilder builder, short i16) { builder.addShort(2, i16, 0); }
+  public static void addU16(FlatBufferBuilder builder, int u16) { builder.addShort(3, (short)u16, (short)0); }
+  public static void addI32(FlatBufferBuilder builder, int i32) { builder.addInt(4, i32, 0); }
+  public static void addU32(FlatBufferBuilder builder, long u32) { builder.addInt(5, (int)u32, (int)0L); }
+  public static void addI64(FlatBufferBuilder builder, long i64) { builder.addLong(6, i64, 0L); }
+  public static void addU64(FlatBufferBuilder builder, long u64) { builder.addLong(7, u64, 0L); }
+  public static void addF32(FlatBufferBuilder builder, float f32) { builder.addFloat(8, f32, 0.0f); }
+  public static void addF64(FlatBufferBuilder builder, double f64) { builder.addDouble(9, f64, 0.0); }
+  public static void addV8(FlatBufferBuilder builder, int v8Offset) { builder.addOffset(10, v8Offset, 0); }
+  public static int createV8Vector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); }
+  public static void startV8Vector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
+  public static void addVf64(FlatBufferBuilder builder, int vf64Offset) { builder.addOffset(11, vf64Offset, 0); }
+  public static int createVf64Vector(FlatBufferBuilder builder, double[] data) { builder.startVector(8, data.length, 8); for (int i = data.length - 1; i >= 0; i--) builder.addDouble(data[i]); return builder.endVector(); }
+  public static void startVf64Vector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); }
+  public static int endTypeAliases(FlatBufferBuilder builder) {
+    int o = builder.endTable();
+    return o;
+  }
+}
+
diff --git a/tests/MyGame/Example/TypeAliases.kt b/tests/MyGame/Example/TypeAliases.kt
new file mode 100644
index 0000000..d1e8816
--- /dev/null
+++ b/tests/MyGame/Example/TypeAliases.kt
@@ -0,0 +1,263 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class TypeAliases : Table() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : TypeAliases {
+        __init(_i, _bb)
+        return this
+    }
+    val i8 : Byte
+        get() {
+            val o = __offset(4)
+            return if(o != 0) bb.get(o + bb_pos) else 0
+        }
+    fun mutateI8(i8: Byte) : Boolean {
+        val o = __offset(4)
+        return if (o != 0) {
+            bb.put(o + bb_pos, i8)
+            true
+        } else {
+            false
+        }
+    }
+    val u8 : UByte
+        get() {
+            val o = __offset(6)
+            return if(o != 0) bb.get(o + bb_pos).toUByte() else 0u
+        }
+    fun mutateU8(u8: UByte) : Boolean {
+        val o = __offset(6)
+        return if (o != 0) {
+            bb.put(o + bb_pos, u8.toByte())
+            true
+        } else {
+            false
+        }
+    }
+    val i16 : Short
+        get() {
+            val o = __offset(8)
+            return if(o != 0) bb.getShort(o + bb_pos) else 0
+        }
+    fun mutateI16(i16: Short) : Boolean {
+        val o = __offset(8)
+        return if (o != 0) {
+            bb.putShort(o + bb_pos, i16)
+            true
+        } else {
+            false
+        }
+    }
+    val u16 : UShort
+        get() {
+            val o = __offset(10)
+            return if(o != 0) bb.getShort(o + bb_pos).toUShort() else 0u
+        }
+    fun mutateU16(u16: UShort) : Boolean {
+        val o = __offset(10)
+        return if (o != 0) {
+            bb.putShort(o + bb_pos, u16.toShort())
+            true
+        } else {
+            false
+        }
+    }
+    val i32 : Int
+        get() {
+            val o = __offset(12)
+            return if(o != 0) bb.getInt(o + bb_pos) else 0
+        }
+    fun mutateI32(i32: Int) : Boolean {
+        val o = __offset(12)
+        return if (o != 0) {
+            bb.putInt(o + bb_pos, i32)
+            true
+        } else {
+            false
+        }
+    }
+    val u32 : UInt
+        get() {
+            val o = __offset(14)
+            return if(o != 0) bb.getInt(o + bb_pos).toUInt() else 0u
+        }
+    fun mutateU32(u32: UInt) : Boolean {
+        val o = __offset(14)
+        return if (o != 0) {
+            bb.putInt(o + bb_pos, u32.toInt())
+            true
+        } else {
+            false
+        }
+    }
+    val i64 : Long
+        get() {
+            val o = __offset(16)
+            return if(o != 0) bb.getLong(o + bb_pos) else 0L
+        }
+    fun mutateI64(i64: Long) : Boolean {
+        val o = __offset(16)
+        return if (o != 0) {
+            bb.putLong(o + bb_pos, i64)
+            true
+        } else {
+            false
+        }
+    }
+    val u64 : ULong
+        get() {
+            val o = __offset(18)
+            return if(o != 0) bb.getLong(o + bb_pos).toULong() else 0UL
+        }
+    fun mutateU64(u64: ULong) : Boolean {
+        val o = __offset(18)
+        return if (o != 0) {
+            bb.putLong(o + bb_pos, u64.toLong())
+            true
+        } else {
+            false
+        }
+    }
+    val f32 : Float
+        get() {
+            val o = __offset(20)
+            return if(o != 0) bb.getFloat(o + bb_pos) else 0.0f
+        }
+    fun mutateF32(f32: Float) : Boolean {
+        val o = __offset(20)
+        return if (o != 0) {
+            bb.putFloat(o + bb_pos, f32)
+            true
+        } else {
+            false
+        }
+    }
+    val f64 : Double
+        get() {
+            val o = __offset(22)
+            return if(o != 0) bb.getDouble(o + bb_pos) else 0.0
+        }
+    fun mutateF64(f64: Double) : Boolean {
+        val o = __offset(22)
+        return if (o != 0) {
+            bb.putDouble(o + bb_pos, f64)
+            true
+        } else {
+            false
+        }
+    }
+    fun v8(j: Int) : Byte {
+        val o = __offset(24)
+        return if (o != 0) {
+            bb.get(__vector(o) + j * 1)
+        } else {
+            0
+        }
+    }
+    val v8Length : Int
+        get() {
+            val o = __offset(24); return if (o != 0) __vector_len(o) else 0
+        }
+    val v8AsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(24, 1)
+    fun v8InByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 24, 1)
+    fun mutateV8(j: Int, v8: Byte) : Boolean {
+        val o = __offset(24)
+        return if (o != 0) {
+            bb.put(__vector(o) + j * 1, v8)
+            true
+        } else {
+            false
+        }
+    }
+    fun vf64(j: Int) : Double {
+        val o = __offset(26)
+        return if (o != 0) {
+            bb.getDouble(__vector(o) + j * 8)
+        } else {
+            0.0
+        }
+    }
+    val vf64Length : Int
+        get() {
+            val o = __offset(26); return if (o != 0) __vector_len(o) else 0
+        }
+    val vf64AsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(26, 8)
+    fun vf64InByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 26, 8)
+    fun mutateVf64(j: Int, vf64: Double) : Boolean {
+        val o = __offset(26)
+        return if (o != 0) {
+            bb.putDouble(__vector(o) + j * 8, vf64)
+            true
+        } else {
+            false
+        }
+    }
+    companion object {
+        fun validateVersion() = Constants.FLATBUFFERS_1_11_1()
+        fun getRootAsTypeAliases(_bb: ByteBuffer): TypeAliases = getRootAsTypeAliases(_bb, TypeAliases())
+        fun getRootAsTypeAliases(_bb: ByteBuffer, obj: TypeAliases): TypeAliases {
+            _bb.order(ByteOrder.LITTLE_ENDIAN)
+            return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+        }
+        fun createTypeAliases(builder: FlatBufferBuilder, i8: Byte, u8: UByte, i16: Short, u16: UShort, i32: Int, u32: UInt, i64: Long, u64: ULong, f32: Float, f64: Double, v8Offset: Int, vf64Offset: Int) : Int {
+            builder.startTable(12)
+            addF64(builder, f64)
+            addU64(builder, u64)
+            addI64(builder, i64)
+            addVf64(builder, vf64Offset)
+            addV8(builder, v8Offset)
+            addF32(builder, f32)
+            addU32(builder, u32)
+            addI32(builder, i32)
+            addU16(builder, u16)
+            addI16(builder, i16)
+            addU8(builder, u8)
+            addI8(builder, i8)
+            return endTypeAliases(builder)
+        }
+        fun startTypeAliases(builder: FlatBufferBuilder) = builder.startTable(12)
+        fun addI8(builder: FlatBufferBuilder, i8: Byte) = builder.addByte(0, i8, 0)
+        fun addU8(builder: FlatBufferBuilder, u8: UByte) = builder.addByte(1, u8.toByte(), 0)
+        fun addI16(builder: FlatBufferBuilder, i16: Short) = builder.addShort(2, i16, 0)
+        fun addU16(builder: FlatBufferBuilder, u16: UShort) = builder.addShort(3, u16.toShort(), 0)
+        fun addI32(builder: FlatBufferBuilder, i32: Int) = builder.addInt(4, i32, 0)
+        fun addU32(builder: FlatBufferBuilder, u32: UInt) = builder.addInt(5, u32.toInt(), 0)
+        fun addI64(builder: FlatBufferBuilder, i64: Long) = builder.addLong(6, i64, 0L)
+        fun addU64(builder: FlatBufferBuilder, u64: ULong) = builder.addLong(7, u64.toLong(), 0)
+        fun addF32(builder: FlatBufferBuilder, f32: Float) = builder.addFloat(8, f32, 0.0)
+        fun addF64(builder: FlatBufferBuilder, f64: Double) = builder.addDouble(9, f64, 0.0)
+        fun addV8(builder: FlatBufferBuilder, v8: Int) = builder.addOffset(10, v8, 0)
+        fun createV8Vector(builder: FlatBufferBuilder, data: ByteArray) : Int {
+            builder.startVector(1, data.size, 1)
+            for (i in data.size - 1 downTo 0) {
+                builder.addByte(data[i])
+            }
+            return builder.endVector()
+        }
+        fun startV8Vector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(1, numElems, 1)
+        fun addVf64(builder: FlatBufferBuilder, vf64: Int) = builder.addOffset(11, vf64, 0)
+        fun createVf64Vector(builder: FlatBufferBuilder, data: DoubleArray) : Int {
+            builder.startVector(8, data.size, 8)
+            for (i in data.size - 1 downTo 0) {
+                builder.addDouble(data[i])
+            }
+            return builder.endVector()
+        }
+        fun startVf64Vector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(8, numElems, 8)
+        fun endTypeAliases(builder: FlatBufferBuilder) : Int {
+            val o = builder.endTable()
+            return o
+        }
+    }
+}
diff --git a/tests/MyGame/Example/TypeAliases.lua b/tests/MyGame/Example/TypeAliases.lua
new file mode 100644
index 0000000..90f569c
--- /dev/null
+++ b/tests/MyGame/Example/TypeAliases.lua
@@ -0,0 +1,141 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Example
+
+local flatbuffers = require('flatbuffers')
+
+local TypeAliases = {} -- the module
+local TypeAliases_mt = {} -- the class metatable
+
+function TypeAliases.New()
+    local o = {}
+    setmetatable(o, {__index = TypeAliases_mt})
+    return o
+end
+function TypeAliases.GetRootAsTypeAliases(buf, offset)
+    local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)
+    local o = TypeAliases.New()
+    o:Init(buf, n + offset)
+    return o
+end
+function TypeAliases_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function TypeAliases_mt:I8()
+    local o = self.view:Offset(4)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Int8, o + self.view.pos)
+    end
+    return 0
+end
+function TypeAliases_mt:U8()
+    local o = self.view:Offset(6)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint8, o + self.view.pos)
+    end
+    return 0
+end
+function TypeAliases_mt:I16()
+    local o = self.view:Offset(8)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Int16, o + self.view.pos)
+    end
+    return 0
+end
+function TypeAliases_mt:U16()
+    local o = self.view:Offset(10)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint16, o + self.view.pos)
+    end
+    return 0
+end
+function TypeAliases_mt:I32()
+    local o = self.view:Offset(12)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Int32, o + self.view.pos)
+    end
+    return 0
+end
+function TypeAliases_mt:U32()
+    local o = self.view:Offset(14)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint32, o + self.view.pos)
+    end
+    return 0
+end
+function TypeAliases_mt:I64()
+    local o = self.view:Offset(16)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Int64, o + self.view.pos)
+    end
+    return 0
+end
+function TypeAliases_mt:U64()
+    local o = self.view:Offset(18)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint64, o + self.view.pos)
+    end
+    return 0
+end
+function TypeAliases_mt:F32()
+    local o = self.view:Offset(20)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Float32, o + self.view.pos)
+    end
+    return 0.0
+end
+function TypeAliases_mt:F64()
+    local o = self.view:Offset(22)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Float64, o + self.view.pos)
+    end
+    return 0.0
+end
+function TypeAliases_mt:V8(j)
+    local o = self.view:Offset(24)
+    if o ~= 0 then
+        local a = self.view:Vector(o)
+        return self.view:Get(flatbuffers.N.Int8, a + ((j-1) * 1))
+    end
+    return 0
+end
+function TypeAliases_mt:V8Length()
+    local o = self.view:Offset(24)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function TypeAliases_mt:Vf64(j)
+    local o = self.view:Offset(26)
+    if o ~= 0 then
+        local a = self.view:Vector(o)
+        return self.view:Get(flatbuffers.N.Float64, a + ((j-1) * 8))
+    end
+    return 0
+end
+function TypeAliases_mt:Vf64Length()
+    local o = self.view:Offset(26)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function TypeAliases.Start(builder) builder:StartObject(12) end
+function TypeAliases.AddI8(builder, i8) builder:PrependInt8Slot(0, i8, 0) end
+function TypeAliases.AddU8(builder, u8) builder:PrependUint8Slot(1, u8, 0) end
+function TypeAliases.AddI16(builder, i16) builder:PrependInt16Slot(2, i16, 0) end
+function TypeAliases.AddU16(builder, u16) builder:PrependUint16Slot(3, u16, 0) end
+function TypeAliases.AddI32(builder, i32) builder:PrependInt32Slot(4, i32, 0) end
+function TypeAliases.AddU32(builder, u32) builder:PrependUint32Slot(5, u32, 0) end
+function TypeAliases.AddI64(builder, i64) builder:PrependInt64Slot(6, i64, 0) end
+function TypeAliases.AddU64(builder, u64) builder:PrependUint64Slot(7, u64, 0) end
+function TypeAliases.AddF32(builder, f32) builder:PrependFloat32Slot(8, f32, 0.0) end
+function TypeAliases.AddF64(builder, f64) builder:PrependFloat64Slot(9, f64, 0.0) end
+function TypeAliases.AddV8(builder, v8) builder:PrependUOffsetTRelativeSlot(10, v8, 0) end
+function TypeAliases.StartV8Vector(builder, numElems) return builder:StartVector(1, numElems, 1) end
+function TypeAliases.AddVf64(builder, vf64) builder:PrependUOffsetTRelativeSlot(11, vf64, 0) end
+function TypeAliases.StartVf64Vector(builder, numElems) return builder:StartVector(8, numElems, 8) end
+function TypeAliases.End(builder) return builder:EndObject() end
+
+return TypeAliases -- return the module
\ No newline at end of file
diff --git a/tests/MyGame/Example/TypeAliases.php b/tests/MyGame/Example/TypeAliases.php
new file mode 100644
index 0000000..7629897
--- /dev/null
+++ b/tests/MyGame/Example/TypeAliases.php
@@ -0,0 +1,387 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace MyGame\Example;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class TypeAliases extends Table
+{
+    /**
+     * @param ByteBuffer $bb
+     * @return TypeAliases
+     */
+    public static function getRootAsTypeAliases(ByteBuffer $bb)
+    {
+        $obj = new TypeAliases();
+        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
+    }
+
+    public static function TypeAliasesIdentifier()
+    {
+        return "MONS";
+    }
+
+    public static function TypeAliasesBufferHasIdentifier(ByteBuffer $buf)
+    {
+        return self::__has_identifier($buf, self::TypeAliasesIdentifier());
+    }
+
+    public static function TypeAliasesExtension()
+    {
+        return "mon";
+    }
+
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return TypeAliases
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    /**
+     * @return sbyte
+     */
+    public function getI8()
+    {
+        $o = $this->__offset(4);
+        return $o != 0 ? $this->bb->getSbyte($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return byte
+     */
+    public function getU8()
+    {
+        $o = $this->__offset(6);
+        return $o != 0 ? $this->bb->getByte($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return short
+     */
+    public function getI16()
+    {
+        $o = $this->__offset(8);
+        return $o != 0 ? $this->bb->getShort($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return ushort
+     */
+    public function getU16()
+    {
+        $o = $this->__offset(10);
+        return $o != 0 ? $this->bb->getUshort($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getI32()
+    {
+        $o = $this->__offset(12);
+        return $o != 0 ? $this->bb->getInt($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return uint
+     */
+    public function getU32()
+    {
+        $o = $this->__offset(14);
+        return $o != 0 ? $this->bb->getUint($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return long
+     */
+    public function getI64()
+    {
+        $o = $this->__offset(16);
+        return $o != 0 ? $this->bb->getLong($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return ulong
+     */
+    public function getU64()
+    {
+        $o = $this->__offset(18);
+        return $o != 0 ? $this->bb->getUlong($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return float
+     */
+    public function getF32()
+    {
+        $o = $this->__offset(20);
+        return $o != 0 ? $this->bb->getFloat($o + $this->bb_pos) : 0.0;
+    }
+
+    /**
+     * @return double
+     */
+    public function getF64()
+    {
+        $o = $this->__offset(22);
+        return $o != 0 ? $this->bb->getDouble($o + $this->bb_pos) : 0.0;
+    }
+
+    /**
+     * @param int offset
+     * @return sbyte
+     */
+    public function getV8($j)
+    {
+        $o = $this->__offset(24);
+        return $o != 0 ? $this->bb->getSbyte($this->__vector($o) + $j * 1) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getV8Length()
+    {
+        $o = $this->__offset(24);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @param int offset
+     * @return double
+     */
+    public function getVf64($j)
+    {
+        $o = $this->__offset(26);
+        return $o != 0 ? $this->bb->getDouble($this->__vector($o) + $j * 8) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getVf64Length()
+    {
+        $o = $this->__offset(26);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return void
+     */
+    public static function startTypeAliases(FlatBufferBuilder $builder)
+    {
+        $builder->StartObject(12);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return TypeAliases
+     */
+    public static function createTypeAliases(FlatBufferBuilder $builder, $i8, $u8, $i16, $u16, $i32, $u32, $i64, $u64, $f32, $f64, $v8, $vf64)
+    {
+        $builder->startObject(12);
+        self::addI8($builder, $i8);
+        self::addU8($builder, $u8);
+        self::addI16($builder, $i16);
+        self::addU16($builder, $u16);
+        self::addI32($builder, $i32);
+        self::addU32($builder, $u32);
+        self::addI64($builder, $i64);
+        self::addU64($builder, $u64);
+        self::addF32($builder, $f32);
+        self::addF64($builder, $f64);
+        self::addV8($builder, $v8);
+        self::addVf64($builder, $vf64);
+        $o = $builder->endObject();
+        return $o;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param sbyte
+     * @return void
+     */
+    public static function addI8(FlatBufferBuilder $builder, $i8)
+    {
+        $builder->addSbyteX(0, $i8, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param byte
+     * @return void
+     */
+    public static function addU8(FlatBufferBuilder $builder, $u8)
+    {
+        $builder->addByteX(1, $u8, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param short
+     * @return void
+     */
+    public static function addI16(FlatBufferBuilder $builder, $i16)
+    {
+        $builder->addShortX(2, $i16, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param ushort
+     * @return void
+     */
+    public static function addU16(FlatBufferBuilder $builder, $u16)
+    {
+        $builder->addUshortX(3, $u16, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addI32(FlatBufferBuilder $builder, $i32)
+    {
+        $builder->addIntX(4, $i32, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param uint
+     * @return void
+     */
+    public static function addU32(FlatBufferBuilder $builder, $u32)
+    {
+        $builder->addUintX(5, $u32, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param long
+     * @return void
+     */
+    public static function addI64(FlatBufferBuilder $builder, $i64)
+    {
+        $builder->addLongX(6, $i64, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param ulong
+     * @return void
+     */
+    public static function addU64(FlatBufferBuilder $builder, $u64)
+    {
+        $builder->addUlongX(7, $u64, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param float
+     * @return void
+     */
+    public static function addF32(FlatBufferBuilder $builder, $f32)
+    {
+        $builder->addFloatX(8, $f32, 0.0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param double
+     * @return void
+     */
+    public static function addF64(FlatBufferBuilder $builder, $f64)
+    {
+        $builder->addDoubleX(9, $f64, 0.0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addV8(FlatBufferBuilder $builder, $v8)
+    {
+        $builder->addOffsetX(10, $v8, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createV8Vector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(1, count($data), 1);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putSbyte($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startV8Vector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(1, $numElems, 1);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addVf64(FlatBufferBuilder $builder, $vf64)
+    {
+        $builder->addOffsetX(11, $vf64, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createVf64Vector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(8, count($data), 8);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putDouble($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startVf64Vector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(8, $numElems, 8);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return int table offset
+     */
+    public static function endTypeAliases(FlatBufferBuilder $builder)
+    {
+        $o = $builder->endObject();
+        return $o;
+    }
+}
diff --git a/tests/MyGame/Example/TypeAliases.py b/tests/MyGame/Example/TypeAliases.py
new file mode 100644
index 0000000..81e9b06
--- /dev/null
+++ b/tests/MyGame/Example/TypeAliases.py
@@ -0,0 +1,154 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+import flatbuffers
+
+class TypeAliases(object):
+    __slots__ = ['_tab']
+
+    @classmethod
+    def GetRootAsTypeAliases(cls, buf, offset):
+        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
+        x = TypeAliases()
+        x.Init(buf, n + offset)
+        return x
+
+    @classmethod
+    def TypeAliasesBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
+        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x53", size_prefixed=size_prefixed)
+
+    # TypeAliases
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # TypeAliases
+    def I8(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Int8Flags, o + self._tab.Pos)
+        return 0
+
+    # TypeAliases
+    def U8(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos)
+        return 0
+
+    # TypeAliases
+    def I16(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Int16Flags, o + self._tab.Pos)
+        return 0
+
+    # TypeAliases
+    def U16(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint16Flags, o + self._tab.Pos)
+        return 0
+
+    # TypeAliases
+    def I32(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
+        return 0
+
+    # TypeAliases
+    def U32(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint32Flags, o + self._tab.Pos)
+        return 0
+
+    # TypeAliases
+    def I64(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Int64Flags, o + self._tab.Pos)
+        return 0
+
+    # TypeAliases
+    def U64(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(18))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
+        return 0
+
+    # TypeAliases
+    def F32(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(20))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
+        return 0.0
+
+    # TypeAliases
+    def F64(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
+        return 0.0
+
+    # TypeAliases
+    def V8(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.Get(flatbuffers.number_types.Int8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
+        return 0
+
+    # TypeAliases
+    def V8AsNumpy(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
+        if o != 0:
+            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Int8Flags, o)
+        return 0
+
+    # TypeAliases
+    def V8Length(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # TypeAliases
+    def Vf64(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.Get(flatbuffers.number_types.Float64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
+        return 0
+
+    # TypeAliases
+    def Vf64AsNumpy(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
+        if o != 0:
+            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Float64Flags, o)
+        return 0
+
+    # TypeAliases
+    def Vf64Length(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+def TypeAliasesStart(builder): builder.StartObject(12)
+def TypeAliasesAddI8(builder, i8): builder.PrependInt8Slot(0, i8, 0)
+def TypeAliasesAddU8(builder, u8): builder.PrependUint8Slot(1, u8, 0)
+def TypeAliasesAddI16(builder, i16): builder.PrependInt16Slot(2, i16, 0)
+def TypeAliasesAddU16(builder, u16): builder.PrependUint16Slot(3, u16, 0)
+def TypeAliasesAddI32(builder, i32): builder.PrependInt32Slot(4, i32, 0)
+def TypeAliasesAddU32(builder, u32): builder.PrependUint32Slot(5, u32, 0)
+def TypeAliasesAddI64(builder, i64): builder.PrependInt64Slot(6, i64, 0)
+def TypeAliasesAddU64(builder, u64): builder.PrependUint64Slot(7, u64, 0)
+def TypeAliasesAddF32(builder, f32): builder.PrependFloat32Slot(8, f32, 0.0)
+def TypeAliasesAddF64(builder, f64): builder.PrependFloat64Slot(9, f64, 0.0)
+def TypeAliasesAddV8(builder, v8): builder.PrependUOffsetTRelativeSlot(10, flatbuffers.number_types.UOffsetTFlags.py_type(v8), 0)
+def TypeAliasesStartV8Vector(builder, numElems): return builder.StartVector(1, numElems, 1)
+def TypeAliasesAddVf64(builder, vf64): builder.PrependUOffsetTRelativeSlot(11, flatbuffers.number_types.UOffsetTFlags.py_type(vf64), 0)
+def TypeAliasesStartVf64Vector(builder, numElems): return builder.StartVector(8, numElems, 8)
+def TypeAliasesEnd(builder): return builder.EndObject()
diff --git a/tests/MyGame/Example/Vec3.cs b/tests/MyGame/Example/Vec3.cs
new file mode 100644
index 0000000..1dbb315
--- /dev/null
+++ b/tests/MyGame/Example/Vec3.cs
@@ -0,0 +1,49 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct Vec3 : IFlatbufferObject
+{
+  private Struct __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
+  public Vec3 __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public float X { get { return __p.bb.GetFloat(__p.bb_pos + 0); } }
+  public void MutateX(float x) { __p.bb.PutFloat(__p.bb_pos + 0, x); }
+  public float Y { get { return __p.bb.GetFloat(__p.bb_pos + 4); } }
+  public void MutateY(float y) { __p.bb.PutFloat(__p.bb_pos + 4, y); }
+  public float Z { get { return __p.bb.GetFloat(__p.bb_pos + 8); } }
+  public void MutateZ(float z) { __p.bb.PutFloat(__p.bb_pos + 8, z); }
+  public double Test1 { get { return __p.bb.GetDouble(__p.bb_pos + 16); } }
+  public void MutateTest1(double test1) { __p.bb.PutDouble(__p.bb_pos + 16, test1); }
+  public MyGame.Example.Color Test2 { get { return (MyGame.Example.Color)__p.bb.Get(__p.bb_pos + 24); } }
+  public void MutateTest2(MyGame.Example.Color test2) { __p.bb.Put(__p.bb_pos + 24, (byte)test2); }
+  public MyGame.Example.Test Test3 { get { return (new MyGame.Example.Test()).__assign(__p.bb_pos + 26, __p.bb); } }
+
+  public static Offset<MyGame.Example.Vec3> CreateVec3(FlatBufferBuilder builder, float X, float Y, float Z, double Test1, MyGame.Example.Color Test2, short test3_A, sbyte test3_B) {
+    builder.Prep(8, 32);
+    builder.Pad(2);
+    builder.Prep(2, 4);
+    builder.Pad(1);
+    builder.PutSbyte(test3_B);
+    builder.PutShort(test3_A);
+    builder.Pad(1);
+    builder.PutByte((byte)Test2);
+    builder.PutDouble(Test1);
+    builder.Pad(4);
+    builder.PutFloat(Z);
+    builder.PutFloat(Y);
+    builder.PutFloat(X);
+    return new Offset<MyGame.Example.Vec3>(builder.Offset);
+  }
+};
+
+
+}
diff --git a/tests/MyGame/Example/Vec3.go b/tests/MyGame/Example/Vec3.go
new file mode 100644
index 0000000..9131afd
--- /dev/null
+++ b/tests/MyGame/Example/Vec3.go
@@ -0,0 +1,80 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package Example
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+)
+
+type Vec3 struct {
+	_tab flatbuffers.Struct
+}
+
+func (rcv *Vec3) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *Vec3) Table() flatbuffers.Table {
+	return rcv._tab.Table
+}
+
+func (rcv *Vec3) X() float32 {
+	return rcv._tab.GetFloat32(rcv._tab.Pos + flatbuffers.UOffsetT(0))
+}
+func (rcv *Vec3) MutateX(n float32) bool {
+	return rcv._tab.MutateFloat32(rcv._tab.Pos+flatbuffers.UOffsetT(0), n)
+}
+
+func (rcv *Vec3) Y() float32 {
+	return rcv._tab.GetFloat32(rcv._tab.Pos + flatbuffers.UOffsetT(4))
+}
+func (rcv *Vec3) MutateY(n float32) bool {
+	return rcv._tab.MutateFloat32(rcv._tab.Pos+flatbuffers.UOffsetT(4), n)
+}
+
+func (rcv *Vec3) Z() float32 {
+	return rcv._tab.GetFloat32(rcv._tab.Pos + flatbuffers.UOffsetT(8))
+}
+func (rcv *Vec3) MutateZ(n float32) bool {
+	return rcv._tab.MutateFloat32(rcv._tab.Pos+flatbuffers.UOffsetT(8), n)
+}
+
+func (rcv *Vec3) Test1() float64 {
+	return rcv._tab.GetFloat64(rcv._tab.Pos + flatbuffers.UOffsetT(16))
+}
+func (rcv *Vec3) MutateTest1(n float64) bool {
+	return rcv._tab.MutateFloat64(rcv._tab.Pos+flatbuffers.UOffsetT(16), n)
+}
+
+func (rcv *Vec3) Test2() Color {
+	return Color(rcv._tab.GetByte(rcv._tab.Pos + flatbuffers.UOffsetT(24)))
+}
+func (rcv *Vec3) MutateTest2(n Color) bool {
+	return rcv._tab.MutateByte(rcv._tab.Pos+flatbuffers.UOffsetT(24), byte(n))
+}
+
+func (rcv *Vec3) Test3(obj *Test) *Test {
+	if obj == nil {
+		obj = new(Test)
+	}
+	obj.Init(rcv._tab.Bytes, rcv._tab.Pos+26)
+	return obj
+}
+
+func CreateVec3(builder *flatbuffers.Builder, x float32, y float32, z float32, test1 float64, test2 Color, test3_a int16, test3_b int8) flatbuffers.UOffsetT {
+	builder.Prep(8, 32)
+	builder.Pad(2)
+	builder.Prep(2, 4)
+	builder.Pad(1)
+	builder.PrependInt8(test3_b)
+	builder.PrependInt16(test3_a)
+	builder.Pad(1)
+	builder.PrependByte(byte(test2))
+	builder.PrependFloat64(test1)
+	builder.Pad(4)
+	builder.PrependFloat32(z)
+	builder.PrependFloat32(y)
+	builder.PrependFloat32(x)
+	return builder.Offset()
+}
diff --git a/tests/MyGame/Example/Vec3.java b/tests/MyGame/Example/Vec3.java
new file mode 100644
index 0000000..0b67c74
--- /dev/null
+++ b/tests/MyGame/Example/Vec3.java
@@ -0,0 +1,45 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class Vec3 extends Struct {
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public Vec3 __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public float x() { return bb.getFloat(bb_pos + 0); }
+  public void mutateX(float x) { bb.putFloat(bb_pos + 0, x); }
+  public float y() { return bb.getFloat(bb_pos + 4); }
+  public void mutateY(float y) { bb.putFloat(bb_pos + 4, y); }
+  public float z() { return bb.getFloat(bb_pos + 8); }
+  public void mutateZ(float z) { bb.putFloat(bb_pos + 8, z); }
+  public double test1() { return bb.getDouble(bb_pos + 16); }
+  public void mutateTest1(double test1) { bb.putDouble(bb_pos + 16, test1); }
+  public int test2() { return bb.get(bb_pos + 24) & 0xFF; }
+  public void mutateTest2(int test2) { bb.put(bb_pos + 24, (byte)test2); }
+  public MyGame.Example.Test test3() { return test3(new MyGame.Example.Test()); }
+  public MyGame.Example.Test test3(MyGame.Example.Test obj) { return obj.__assign(bb_pos + 26, bb); }
+
+  public static int createVec3(FlatBufferBuilder builder, float x, float y, float z, double test1, int test2, short test3_a, byte test3_b) {
+    builder.prep(8, 32);
+    builder.pad(2);
+    builder.prep(2, 4);
+    builder.pad(1);
+    builder.putByte(test3_b);
+    builder.putShort(test3_a);
+    builder.pad(1);
+    builder.putByte((byte)test2);
+    builder.putDouble(test1);
+    builder.pad(4);
+    builder.putFloat(z);
+    builder.putFloat(y);
+    builder.putFloat(x);
+    return builder.offset();
+  }
+}
+
diff --git a/tests/MyGame/Example/Vec3.kt b/tests/MyGame/Example/Vec3.kt
new file mode 100644
index 0000000..90f1b4a
--- /dev/null
+++ b/tests/MyGame/Example/Vec3.kt
@@ -0,0 +1,50 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Vec3 : Struct() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : Vec3 {
+        __init(_i, _bb)
+        return this
+    }
+    val x : Float get() = bb.getFloat(bb_pos + 0)
+    fun mutateX(x: Float) : ByteBuffer = bb.putFloat(bb_pos + 0, x)
+    val y : Float get() = bb.getFloat(bb_pos + 4)
+    fun mutateY(y: Float) : ByteBuffer = bb.putFloat(bb_pos + 4, y)
+    val z : Float get() = bb.getFloat(bb_pos + 8)
+    fun mutateZ(z: Float) : ByteBuffer = bb.putFloat(bb_pos + 8, z)
+    val test1 : Double get() = bb.getDouble(bb_pos + 16)
+    fun mutateTest1(test1: Double) : ByteBuffer = bb.putDouble(bb_pos + 16, test1)
+    val test2 : UByte get() = bb.get(bb_pos + 24).toUByte()
+    fun mutateTest2(test2: UByte) : ByteBuffer = bb.put(bb_pos + 24, test2.toByte())
+    val test3 : MyGame.Example.Test? get() = test3(MyGame.Example.Test())
+    fun test3(obj: MyGame.Example.Test) : MyGame.Example.Test? = obj.__assign(bb_pos + 26, bb)
+    companion object {
+        fun createVec3(builder: FlatBufferBuilder, x: Float, y: Float, z: Float, test1: Double, test2: UByte, test3_a: Short, test3_b: Byte) : Int {
+            builder.prep(8, 32)
+            builder.pad(2)
+            builder.prep(2, 4)
+            builder.pad(1)
+            builder.putByte(test3_b)
+            builder.putShort(test3_a)
+            builder.pad(1)
+            builder.putByte(test2.toByte())
+            builder.putDouble(test1)
+            builder.pad(4)
+            builder.putFloat(z)
+            builder.putFloat(y)
+            builder.putFloat(x)
+            return builder.offset()
+        }
+    }
+}
diff --git a/tests/MyGame/Example/Vec3.lua b/tests/MyGame/Example/Vec3.lua
new file mode 100644
index 0000000..24d4cc1
--- /dev/null
+++ b/tests/MyGame/Example/Vec3.lua
@@ -0,0 +1,54 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Example
+
+local flatbuffers = require('flatbuffers')
+
+local Vec3 = {} -- the module
+local Vec3_mt = {} -- the class metatable
+
+function Vec3.New()
+    local o = {}
+    setmetatable(o, {__index = Vec3_mt})
+    return o
+end
+function Vec3_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function Vec3_mt:X()
+    return self.view:Get(flatbuffers.N.Float32, self.view.pos + 0)
+end
+function Vec3_mt:Y()
+    return self.view:Get(flatbuffers.N.Float32, self.view.pos + 4)
+end
+function Vec3_mt:Z()
+    return self.view:Get(flatbuffers.N.Float32, self.view.pos + 8)
+end
+function Vec3_mt:Test1()
+    return self.view:Get(flatbuffers.N.Float64, self.view.pos + 16)
+end
+function Vec3_mt:Test2()
+    return self.view:Get(flatbuffers.N.Uint8, self.view.pos + 24)
+end
+function Vec3_mt:Test3(obj)
+    obj:Init(self.view.bytes, self.view.pos + 26)
+    return obj
+end
+function Vec3.CreateVec3(builder, x, y, z, test1, test2, test3_a, test3_b)
+    builder:Prep(8, 32)
+    builder:Pad(2)
+    builder:Prep(2, 4)
+    builder:Pad(1)
+    builder:PrependInt8(test3_b)
+    builder:PrependInt16(test3_a)
+    builder:Pad(1)
+    builder:PrependUint8(test2)
+    builder:PrependFloat64(test1)
+    builder:Pad(4)
+    builder:PrependFloat32(z)
+    builder:PrependFloat32(y)
+    builder:PrependFloat32(x)
+    return builder:Offset()
+end
+
+return Vec3 -- return the module
\ No newline at end of file
diff --git a/tests/MyGame/Example/Vec3.php b/tests/MyGame/Example/Vec3.php
new file mode 100644
index 0000000..4d149e6
--- /dev/null
+++ b/tests/MyGame/Example/Vec3.php
@@ -0,0 +1,96 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace MyGame\Example;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class Vec3 extends Struct
+{
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return Vec3
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    /**
+     * @return float
+     */
+    public function GetX()
+    {
+        return $this->bb->getFloat($this->bb_pos + 0);
+    }
+
+    /**
+     * @return float
+     */
+    public function GetY()
+    {
+        return $this->bb->getFloat($this->bb_pos + 4);
+    }
+
+    /**
+     * @return float
+     */
+    public function GetZ()
+    {
+        return $this->bb->getFloat($this->bb_pos + 8);
+    }
+
+    /**
+     * @return double
+     */
+    public function GetTest1()
+    {
+        return $this->bb->getDouble($this->bb_pos + 16);
+    }
+
+    /**
+     * @return byte
+     */
+    public function GetTest2()
+    {
+        return $this->bb->getByte($this->bb_pos + 24);
+    }
+
+    /**
+     * @return Test
+     */
+    public function getTest3()
+    {
+        $obj = new Test();
+        $obj->init($this->bb_pos + 26, $this->bb);
+        return $obj;
+    }
+
+
+    /**
+     * @return int offset
+     */
+    public static function createVec3(FlatBufferBuilder $builder, $x, $y, $z, $test1, $test2, $test3_a, $test3_b)
+    {
+        $builder->prep(8, 32);
+        $builder->pad(2);
+        $builder->prep(2, 4);
+        $builder->pad(1);
+        $builder->putSbyte($test3_b);
+        $builder->putShort($test3_a);
+        $builder->pad(1);
+        $builder->putByte($test2);
+        $builder->putDouble($test1);
+        $builder->pad(4);
+        $builder->putFloat($z);
+        $builder->putFloat($y);
+        $builder->putFloat($x);
+        return $builder->offset();
+    }
+}
diff --git a/tests/MyGame/Example/Vec3.py b/tests/MyGame/Example/Vec3.py
new file mode 100644
index 0000000..1f32390
--- /dev/null
+++ b/tests/MyGame/Example/Vec3.py
@@ -0,0 +1,44 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+import flatbuffers
+
+class Vec3(object):
+    __slots__ = ['_tab']
+
+    # Vec3
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # Vec3
+    def X(self): return self._tab.Get(flatbuffers.number_types.Float32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(0))
+    # Vec3
+    def Y(self): return self._tab.Get(flatbuffers.number_types.Float32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(4))
+    # Vec3
+    def Z(self): return self._tab.Get(flatbuffers.number_types.Float32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(8))
+    # Vec3
+    def Test1(self): return self._tab.Get(flatbuffers.number_types.Float64Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(16))
+    # Vec3
+    def Test2(self): return self._tab.Get(flatbuffers.number_types.Uint8Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(24))
+    # Vec3
+    def Test3(self, obj):
+        obj.Init(self._tab.Bytes, self._tab.Pos + 26)
+        return obj
+
+
+def CreateVec3(builder, x, y, z, test1, test2, test3_a, test3_b):
+    builder.Prep(8, 32)
+    builder.Pad(2)
+    builder.Prep(2, 4)
+    builder.Pad(1)
+    builder.PrependInt8(test3_b)
+    builder.PrependInt16(test3_a)
+    builder.Pad(1)
+    builder.PrependUint8(test2)
+    builder.PrependFloat64(test1)
+    builder.Pad(4)
+    builder.PrependFloat32(z)
+    builder.PrependFloat32(y)
+    builder.PrependFloat32(x)
+    return builder.Offset()
diff --git a/tests/MyGame/Example/__init__.py b/tests/MyGame/Example/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/MyGame/Example/__init__.py
diff --git a/tests/MyGame/Example2/Monster.cs b/tests/MyGame/Example2/Monster.cs
new file mode 100644
index 0000000..a6e9dce
--- /dev/null
+++ b/tests/MyGame/Example2/Monster.cs
@@ -0,0 +1,30 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example2
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct Monster : IFlatbufferObject
+{
+  private Table __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_11_1(); }
+  public static Monster GetRootAsMonster(ByteBuffer _bb) { return GetRootAsMonster(_bb, new Monster()); }
+  public static Monster GetRootAsMonster(ByteBuffer _bb, Monster obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+  public Monster __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+
+  public static void StartMonster(FlatBufferBuilder builder) { builder.StartTable(0); }
+  public static Offset<MyGame.Example2.Monster> EndMonster(FlatBufferBuilder builder) {
+    int o = builder.EndTable();
+    return new Offset<MyGame.Example2.Monster>(o);
+  }
+};
+
+
+}
diff --git a/tests/MyGame/Example2/Monster.go b/tests/MyGame/Example2/Monster.go
new file mode 100644
index 0000000..d0fae94
--- /dev/null
+++ b/tests/MyGame/Example2/Monster.go
@@ -0,0 +1,34 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package Example2
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+)
+
+type Monster struct {
+	_tab flatbuffers.Table
+}
+
+func GetRootAsMonster(buf []byte, offset flatbuffers.UOffsetT) *Monster {
+	n := flatbuffers.GetUOffsetT(buf[offset:])
+	x := &Monster{}
+	x.Init(buf, n+offset)
+	return x
+}
+
+func (rcv *Monster) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *Monster) Table() flatbuffers.Table {
+	return rcv._tab
+}
+
+func MonsterStart(builder *flatbuffers.Builder) {
+	builder.StartObject(0)
+}
+func MonsterEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+	return builder.EndObject()
+}
diff --git a/tests/MyGame/Example2/Monster.java b/tests/MyGame/Example2/Monster.java
new file mode 100644
index 0000000..7e0cae1
--- /dev/null
+++ b/tests/MyGame/Example2/Monster.java
@@ -0,0 +1,25 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example2;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class Monster extends Table {
+  public static void ValidateVersion() { Constants.FLATBUFFERS_1_11_1(); }
+  public static Monster getRootAsMonster(ByteBuffer _bb) { return getRootAsMonster(_bb, new Monster()); }
+  public static Monster getRootAsMonster(ByteBuffer _bb, Monster obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public Monster __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+
+  public static void startMonster(FlatBufferBuilder builder) { builder.startTable(0); }
+  public static int endMonster(FlatBufferBuilder builder) {
+    int o = builder.endTable();
+    return o;
+  }
+}
+
diff --git a/tests/MyGame/Example2/Monster.kt b/tests/MyGame/Example2/Monster.kt
new file mode 100644
index 0000000..de587ba
--- /dev/null
+++ b/tests/MyGame/Example2/Monster.kt
@@ -0,0 +1,33 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example2
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Monster : Table() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : Monster {
+        __init(_i, _bb)
+        return this
+    }
+    companion object {
+        fun validateVersion() = Constants.FLATBUFFERS_1_11_1()
+        fun getRootAsMonster(_bb: ByteBuffer): Monster = getRootAsMonster(_bb, Monster())
+        fun getRootAsMonster(_bb: ByteBuffer, obj: Monster): Monster {
+            _bb.order(ByteOrder.LITTLE_ENDIAN)
+            return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+        }
+        fun startMonster(builder: FlatBufferBuilder) = builder.startTable(0)
+        fun endMonster(builder: FlatBufferBuilder) : Int {
+            val o = builder.endTable()
+            return o
+        }
+    }
+}
diff --git a/tests/MyGame/Example2/Monster.lua b/tests/MyGame/Example2/Monster.lua
new file mode 100644
index 0000000..347b5db
--- /dev/null
+++ b/tests/MyGame/Example2/Monster.lua
@@ -0,0 +1,27 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Example2
+
+local flatbuffers = require('flatbuffers')
+
+local Monster = {} -- the module
+local Monster_mt = {} -- the class metatable
+
+function Monster.New()
+    local o = {}
+    setmetatable(o, {__index = Monster_mt})
+    return o
+end
+function Monster.GetRootAsMonster(buf, offset)
+    local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)
+    local o = Monster.New()
+    o:Init(buf, n + offset)
+    return o
+end
+function Monster_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function Monster.Start(builder) builder:StartObject(0) end
+function Monster.End(builder) return builder:EndObject() end
+
+return Monster -- return the module
\ No newline at end of file
diff --git a/tests/MyGame/Example2/Monster.php b/tests/MyGame/Example2/Monster.php
new file mode 100644
index 0000000..b00f150
--- /dev/null
+++ b/tests/MyGame/Example2/Monster.php
@@ -0,0 +1,79 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace MyGame\Example2;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class Monster extends Table
+{
+    /**
+     * @param ByteBuffer $bb
+     * @return Monster
+     */
+    public static function getRootAsMonster(ByteBuffer $bb)
+    {
+        $obj = new Monster();
+        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
+    }
+
+    public static function MonsterIdentifier()
+    {
+        return "MONS";
+    }
+
+    public static function MonsterBufferHasIdentifier(ByteBuffer $buf)
+    {
+        return self::__has_identifier($buf, self::MonsterIdentifier());
+    }
+
+    public static function MonsterExtension()
+    {
+        return "mon";
+    }
+
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return Monster
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return void
+     */
+    public static function startMonster(FlatBufferBuilder $builder)
+    {
+        $builder->StartObject(0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return Monster
+     */
+    public static function createMonster(FlatBufferBuilder $builder, )
+    {
+        $builder->startObject(0);
+        $o = $builder->endObject();
+        return $o;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return int table offset
+     */
+    public static function endMonster(FlatBufferBuilder $builder)
+    {
+        $o = $builder->endObject();
+        return $o;
+    }
+}
diff --git a/tests/MyGame/Example2/Monster.py b/tests/MyGame/Example2/Monster.py
new file mode 100644
index 0000000..44cc906
--- /dev/null
+++ b/tests/MyGame/Example2/Monster.py
@@ -0,0 +1,26 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example2
+
+import flatbuffers
+
+class Monster(object):
+    __slots__ = ['_tab']
+
+    @classmethod
+    def GetRootAsMonster(cls, buf, offset):
+        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
+        x = Monster()
+        x.Init(buf, n + offset)
+        return x
+
+    @classmethod
+    def MonsterBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
+        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x53", size_prefixed=size_prefixed)
+
+    # Monster
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+def MonsterStart(builder): builder.StartObject(0)
+def MonsterEnd(builder): return builder.EndObject()
diff --git a/tests/MyGame/Example2/__init__.py b/tests/MyGame/Example2/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/MyGame/Example2/__init__.py
diff --git a/tests/MyGame/InParentNamespace.cs b/tests/MyGame/InParentNamespace.cs
new file mode 100644
index 0000000..869c400
--- /dev/null
+++ b/tests/MyGame/InParentNamespace.cs
@@ -0,0 +1,30 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct InParentNamespace : IFlatbufferObject
+{
+  private Table __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_11_1(); }
+  public static InParentNamespace GetRootAsInParentNamespace(ByteBuffer _bb) { return GetRootAsInParentNamespace(_bb, new InParentNamespace()); }
+  public static InParentNamespace GetRootAsInParentNamespace(ByteBuffer _bb, InParentNamespace obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+  public InParentNamespace __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+
+  public static void StartInParentNamespace(FlatBufferBuilder builder) { builder.StartTable(0); }
+  public static Offset<MyGame.InParentNamespace> EndInParentNamespace(FlatBufferBuilder builder) {
+    int o = builder.EndTable();
+    return new Offset<MyGame.InParentNamespace>(o);
+  }
+};
+
+
+}
diff --git a/tests/MyGame/InParentNamespace.go b/tests/MyGame/InParentNamespace.go
new file mode 100644
index 0000000..fc6ce32
--- /dev/null
+++ b/tests/MyGame/InParentNamespace.go
@@ -0,0 +1,34 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package MyGame
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+)
+
+type InParentNamespace struct {
+	_tab flatbuffers.Table
+}
+
+func GetRootAsInParentNamespace(buf []byte, offset flatbuffers.UOffsetT) *InParentNamespace {
+	n := flatbuffers.GetUOffsetT(buf[offset:])
+	x := &InParentNamespace{}
+	x.Init(buf, n+offset)
+	return x
+}
+
+func (rcv *InParentNamespace) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *InParentNamespace) Table() flatbuffers.Table {
+	return rcv._tab
+}
+
+func InParentNamespaceStart(builder *flatbuffers.Builder) {
+	builder.StartObject(0)
+}
+func InParentNamespaceEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+	return builder.EndObject()
+}
diff --git a/tests/MyGame/InParentNamespace.java b/tests/MyGame/InParentNamespace.java
new file mode 100644
index 0000000..fd10bc3
--- /dev/null
+++ b/tests/MyGame/InParentNamespace.java
@@ -0,0 +1,25 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class InParentNamespace extends Table {
+  public static void ValidateVersion() { Constants.FLATBUFFERS_1_11_1(); }
+  public static InParentNamespace getRootAsInParentNamespace(ByteBuffer _bb) { return getRootAsInParentNamespace(_bb, new InParentNamespace()); }
+  public static InParentNamespace getRootAsInParentNamespace(ByteBuffer _bb, InParentNamespace obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public InParentNamespace __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+
+  public static void startInParentNamespace(FlatBufferBuilder builder) { builder.startTable(0); }
+  public static int endInParentNamespace(FlatBufferBuilder builder) {
+    int o = builder.endTable();
+    return o;
+  }
+}
+
diff --git a/tests/MyGame/InParentNamespace.kt b/tests/MyGame/InParentNamespace.kt
new file mode 100644
index 0000000..76779fc
--- /dev/null
+++ b/tests/MyGame/InParentNamespace.kt
@@ -0,0 +1,33 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class InParentNamespace : Table() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : InParentNamespace {
+        __init(_i, _bb)
+        return this
+    }
+    companion object {
+        fun validateVersion() = Constants.FLATBUFFERS_1_11_1()
+        fun getRootAsInParentNamespace(_bb: ByteBuffer): InParentNamespace = getRootAsInParentNamespace(_bb, InParentNamespace())
+        fun getRootAsInParentNamespace(_bb: ByteBuffer, obj: InParentNamespace): InParentNamespace {
+            _bb.order(ByteOrder.LITTLE_ENDIAN)
+            return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+        }
+        fun startInParentNamespace(builder: FlatBufferBuilder) = builder.startTable(0)
+        fun endInParentNamespace(builder: FlatBufferBuilder) : Int {
+            val o = builder.endTable()
+            return o
+        }
+    }
+}
diff --git a/tests/MyGame/InParentNamespace.lua b/tests/MyGame/InParentNamespace.lua
new file mode 100644
index 0000000..b3fa0c8
--- /dev/null
+++ b/tests/MyGame/InParentNamespace.lua
@@ -0,0 +1,27 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: MyGame
+
+local flatbuffers = require('flatbuffers')
+
+local InParentNamespace = {} -- the module
+local InParentNamespace_mt = {} -- the class metatable
+
+function InParentNamespace.New()
+    local o = {}
+    setmetatable(o, {__index = InParentNamespace_mt})
+    return o
+end
+function InParentNamespace.GetRootAsInParentNamespace(buf, offset)
+    local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)
+    local o = InParentNamespace.New()
+    o:Init(buf, n + offset)
+    return o
+end
+function InParentNamespace_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function InParentNamespace.Start(builder) builder:StartObject(0) end
+function InParentNamespace.End(builder) return builder:EndObject() end
+
+return InParentNamespace -- return the module
\ No newline at end of file
diff --git a/tests/MyGame/InParentNamespace.php b/tests/MyGame/InParentNamespace.php
new file mode 100644
index 0000000..e13a4f3
--- /dev/null
+++ b/tests/MyGame/InParentNamespace.php
@@ -0,0 +1,79 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace MyGame;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class InParentNamespace extends Table
+{
+    /**
+     * @param ByteBuffer $bb
+     * @return InParentNamespace
+     */
+    public static function getRootAsInParentNamespace(ByteBuffer $bb)
+    {
+        $obj = new InParentNamespace();
+        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
+    }
+
+    public static function InParentNamespaceIdentifier()
+    {
+        return "MONS";
+    }
+
+    public static function InParentNamespaceBufferHasIdentifier(ByteBuffer $buf)
+    {
+        return self::__has_identifier($buf, self::InParentNamespaceIdentifier());
+    }
+
+    public static function InParentNamespaceExtension()
+    {
+        return "mon";
+    }
+
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return InParentNamespace
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return void
+     */
+    public static function startInParentNamespace(FlatBufferBuilder $builder)
+    {
+        $builder->StartObject(0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return InParentNamespace
+     */
+    public static function createInParentNamespace(FlatBufferBuilder $builder, )
+    {
+        $builder->startObject(0);
+        $o = $builder->endObject();
+        return $o;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return int table offset
+     */
+    public static function endInParentNamespace(FlatBufferBuilder $builder)
+    {
+        $o = $builder->endObject();
+        return $o;
+    }
+}
diff --git a/tests/MyGame/InParentNamespace.py b/tests/MyGame/InParentNamespace.py
new file mode 100644
index 0000000..3bfcca7
--- /dev/null
+++ b/tests/MyGame/InParentNamespace.py
@@ -0,0 +1,26 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: MyGame
+
+import flatbuffers
+
+class InParentNamespace(object):
+    __slots__ = ['_tab']
+
+    @classmethod
+    def GetRootAsInParentNamespace(cls, buf, offset):
+        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
+        x = InParentNamespace()
+        x.Init(buf, n + offset)
+        return x
+
+    @classmethod
+    def InParentNamespaceBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
+        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x53", size_prefixed=size_prefixed)
+
+    # InParentNamespace
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+def InParentNamespaceStart(builder): builder.StartObject(0)
+def InParentNamespaceEnd(builder): return builder.EndObject()
diff --git a/tests/MyGame/MonsterExtra.cs b/tests/MyGame/MonsterExtra.cs
new file mode 100644
index 0000000..5706390
--- /dev/null
+++ b/tests/MyGame/MonsterExtra.cs
@@ -0,0 +1,108 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct MonsterExtra : IFlatbufferObject
+{
+  private Table __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_11_1(); }
+  public static MonsterExtra GetRootAsMonsterExtra(ByteBuffer _bb) { return GetRootAsMonsterExtra(_bb, new MonsterExtra()); }
+  public static MonsterExtra GetRootAsMonsterExtra(ByteBuffer _bb, MonsterExtra obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public static bool MonsterExtraBufferHasIdentifier(ByteBuffer _bb) { return Table.__has_identifier(_bb, "MONE"); }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+  public MonsterExtra __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public double D0 { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)Double.NaN; } }
+  public bool MutateD0(double d0) { int o = __p.__offset(4); if (o != 0) { __p.bb.PutDouble(o + __p.bb_pos, d0); return true; } else { return false; } }
+  public double D1 { get { int o = __p.__offset(6); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)Double.NaN; } }
+  public bool MutateD1(double d1) { int o = __p.__offset(6); if (o != 0) { __p.bb.PutDouble(o + __p.bb_pos, d1); return true; } else { return false; } }
+  public double D2 { get { int o = __p.__offset(8); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)Double.PositiveInfinity; } }
+  public bool MutateD2(double d2) { int o = __p.__offset(8); if (o != 0) { __p.bb.PutDouble(o + __p.bb_pos, d2); return true; } else { return false; } }
+  public double D3 { get { int o = __p.__offset(10); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)Double.NegativeInfinity; } }
+  public bool MutateD3(double d3) { int o = __p.__offset(10); if (o != 0) { __p.bb.PutDouble(o + __p.bb_pos, d3); return true; } else { return false; } }
+  public float F0 { get { int o = __p.__offset(12); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.NaN; } }
+  public bool MutateF0(float f0) { int o = __p.__offset(12); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, f0); return true; } else { return false; } }
+  public float F1 { get { int o = __p.__offset(14); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.NaN; } }
+  public bool MutateF1(float f1) { int o = __p.__offset(14); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, f1); return true; } else { return false; } }
+  public float F2 { get { int o = __p.__offset(16); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.PositiveInfinity; } }
+  public bool MutateF2(float f2) { int o = __p.__offset(16); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, f2); return true; } else { return false; } }
+  public float F3 { get { int o = __p.__offset(18); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.NegativeInfinity; } }
+  public bool MutateF3(float f3) { int o = __p.__offset(18); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, f3); return true; } else { return false; } }
+  public double Dvec(int j) { int o = __p.__offset(20); return o != 0 ? __p.bb.GetDouble(__p.__vector(o) + j * 8) : (double)0; }
+  public int DvecLength { get { int o = __p.__offset(20); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetDvecBytes() { return __p.__vector_as_span(20); }
+#else
+  public ArraySegment<byte>? GetDvecBytes() { return __p.__vector_as_arraysegment(20); }
+#endif
+  public double[] GetDvecArray() { return __p.__vector_as_array<double>(20); }
+  public bool MutateDvec(int j, double dvec) { int o = __p.__offset(20); if (o != 0) { __p.bb.PutDouble(__p.__vector(o) + j * 8, dvec); return true; } else { return false; } }
+  public float Fvec(int j) { int o = __p.__offset(22); return o != 0 ? __p.bb.GetFloat(__p.__vector(o) + j * 4) : (float)0; }
+  public int FvecLength { get { int o = __p.__offset(22); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetFvecBytes() { return __p.__vector_as_span(22); }
+#else
+  public ArraySegment<byte>? GetFvecBytes() { return __p.__vector_as_arraysegment(22); }
+#endif
+  public float[] GetFvecArray() { return __p.__vector_as_array<float>(22); }
+  public bool MutateFvec(int j, float fvec) { int o = __p.__offset(22); if (o != 0) { __p.bb.PutFloat(__p.__vector(o) + j * 4, fvec); return true; } else { return false; } }
+
+  public static Offset<MyGame.MonsterExtra> CreateMonsterExtra(FlatBufferBuilder builder,
+      double d0 = Double.NaN,
+      double d1 = Double.NaN,
+      double d2 = Double.PositiveInfinity,
+      double d3 = Double.NegativeInfinity,
+      float f0 = Single.NaN,
+      float f1 = Single.NaN,
+      float f2 = Single.PositiveInfinity,
+      float f3 = Single.NegativeInfinity,
+      VectorOffset dvecOffset = default(VectorOffset),
+      VectorOffset fvecOffset = default(VectorOffset)) {
+    builder.StartTable(10);
+    MonsterExtra.AddD3(builder, d3);
+    MonsterExtra.AddD2(builder, d2);
+    MonsterExtra.AddD1(builder, d1);
+    MonsterExtra.AddD0(builder, d0);
+    MonsterExtra.AddFvec(builder, fvecOffset);
+    MonsterExtra.AddDvec(builder, dvecOffset);
+    MonsterExtra.AddF3(builder, f3);
+    MonsterExtra.AddF2(builder, f2);
+    MonsterExtra.AddF1(builder, f1);
+    MonsterExtra.AddF0(builder, f0);
+    return MonsterExtra.EndMonsterExtra(builder);
+  }
+
+  public static void StartMonsterExtra(FlatBufferBuilder builder) { builder.StartTable(10); }
+  public static void AddD0(FlatBufferBuilder builder, double d0) { builder.AddDouble(0, d0, Double.NaN); }
+  public static void AddD1(FlatBufferBuilder builder, double d1) { builder.AddDouble(1, d1, Double.NaN); }
+  public static void AddD2(FlatBufferBuilder builder, double d2) { builder.AddDouble(2, d2, Double.PositiveInfinity); }
+  public static void AddD3(FlatBufferBuilder builder, double d3) { builder.AddDouble(3, d3, Double.NegativeInfinity); }
+  public static void AddF0(FlatBufferBuilder builder, float f0) { builder.AddFloat(4, f0, Single.NaN); }
+  public static void AddF1(FlatBufferBuilder builder, float f1) { builder.AddFloat(5, f1, Single.NaN); }
+  public static void AddF2(FlatBufferBuilder builder, float f2) { builder.AddFloat(6, f2, Single.PositiveInfinity); }
+  public static void AddF3(FlatBufferBuilder builder, float f3) { builder.AddFloat(7, f3, Single.NegativeInfinity); }
+  public static void AddDvec(FlatBufferBuilder builder, VectorOffset dvecOffset) { builder.AddOffset(8, dvecOffset.Value, 0); }
+  public static VectorOffset CreateDvecVector(FlatBufferBuilder builder, double[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddDouble(data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateDvecVectorBlock(FlatBufferBuilder builder, double[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
+  public static void StartDvecVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
+  public static void AddFvec(FlatBufferBuilder builder, VectorOffset fvecOffset) { builder.AddOffset(9, fvecOffset.Value, 0); }
+  public static VectorOffset CreateFvecVector(FlatBufferBuilder builder, float[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddFloat(data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateFvecVectorBlock(FlatBufferBuilder builder, float[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
+  public static void StartFvecVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
+  public static Offset<MyGame.MonsterExtra> EndMonsterExtra(FlatBufferBuilder builder) {
+    int o = builder.EndTable();
+    return new Offset<MyGame.MonsterExtra>(o);
+  }
+  public static void FinishMonsterExtraBuffer(FlatBufferBuilder builder, Offset<MyGame.MonsterExtra> offset) { builder.Finish(offset.Value, "MONE"); }
+  public static void FinishSizePrefixedMonsterExtraBuffer(FlatBufferBuilder builder, Offset<MyGame.MonsterExtra> offset) { builder.FinishSizePrefixed(offset.Value, "MONE"); }
+};
+
+
+}
diff --git a/tests/MyGame/MonsterExtra.java b/tests/MyGame/MonsterExtra.java
new file mode 100644
index 0000000..3022596
--- /dev/null
+++ b/tests/MyGame/MonsterExtra.java
@@ -0,0 +1,93 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class MonsterExtra extends Table {
+  public static void ValidateVersion() { Constants.FLATBUFFERS_1_11_1(); }
+  public static MonsterExtra getRootAsMonsterExtra(ByteBuffer _bb) { return getRootAsMonsterExtra(_bb, new MonsterExtra()); }
+  public static MonsterExtra getRootAsMonsterExtra(ByteBuffer _bb, MonsterExtra obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public static boolean MonsterExtraBufferHasIdentifier(ByteBuffer _bb) { return __has_identifier(_bb, "MONE"); }
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public MonsterExtra __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public double d0() { int o = __offset(4); return o != 0 ? bb.getDouble(o + bb_pos) : Double.NaN; }
+  public boolean mutateD0(double d0) { int o = __offset(4); if (o != 0) { bb.putDouble(o + bb_pos, d0); return true; } else { return false; } }
+  public double d1() { int o = __offset(6); return o != 0 ? bb.getDouble(o + bb_pos) : Double.NaN; }
+  public boolean mutateD1(double d1) { int o = __offset(6); if (o != 0) { bb.putDouble(o + bb_pos, d1); return true; } else { return false; } }
+  public double d2() { int o = __offset(8); return o != 0 ? bb.getDouble(o + bb_pos) : Double.POSITIVE_INFINITY; }
+  public boolean mutateD2(double d2) { int o = __offset(8); if (o != 0) { bb.putDouble(o + bb_pos, d2); return true; } else { return false; } }
+  public double d3() { int o = __offset(10); return o != 0 ? bb.getDouble(o + bb_pos) : Double.NEGATIVE_INFINITY; }
+  public boolean mutateD3(double d3) { int o = __offset(10); if (o != 0) { bb.putDouble(o + bb_pos, d3); return true; } else { return false; } }
+  public float f0() { int o = __offset(12); return o != 0 ? bb.getFloat(o + bb_pos) : Float.NaN; }
+  public boolean mutateF0(float f0) { int o = __offset(12); if (o != 0) { bb.putFloat(o + bb_pos, f0); return true; } else { return false; } }
+  public float f1() { int o = __offset(14); return o != 0 ? bb.getFloat(o + bb_pos) : Float.NaN; }
+  public boolean mutateF1(float f1) { int o = __offset(14); if (o != 0) { bb.putFloat(o + bb_pos, f1); return true; } else { return false; } }
+  public float f2() { int o = __offset(16); return o != 0 ? bb.getFloat(o + bb_pos) : Float.POSITIVE_INFINITY; }
+  public boolean mutateF2(float f2) { int o = __offset(16); if (o != 0) { bb.putFloat(o + bb_pos, f2); return true; } else { return false; } }
+  public float f3() { int o = __offset(18); return o != 0 ? bb.getFloat(o + bb_pos) : Float.NEGATIVE_INFINITY; }
+  public boolean mutateF3(float f3) { int o = __offset(18); if (o != 0) { bb.putFloat(o + bb_pos, f3); return true; } else { return false; } }
+  public double dvec(int j) { int o = __offset(20); return o != 0 ? bb.getDouble(__vector(o) + j * 8) : 0; }
+  public int dvecLength() { int o = __offset(20); return o != 0 ? __vector_len(o) : 0; }
+  public ByteBuffer dvecAsByteBuffer() { return __vector_as_bytebuffer(20, 8); }
+  public ByteBuffer dvecInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 20, 8); }
+  public boolean mutateDvec(int j, double dvec) { int o = __offset(20); if (o != 0) { bb.putDouble(__vector(o) + j * 8, dvec); return true; } else { return false; } }
+  public float fvec(int j) { int o = __offset(22); return o != 0 ? bb.getFloat(__vector(o) + j * 4) : 0; }
+  public int fvecLength() { int o = __offset(22); return o != 0 ? __vector_len(o) : 0; }
+  public ByteBuffer fvecAsByteBuffer() { return __vector_as_bytebuffer(22, 4); }
+  public ByteBuffer fvecInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 22, 4); }
+  public boolean mutateFvec(int j, float fvec) { int o = __offset(22); if (o != 0) { bb.putFloat(__vector(o) + j * 4, fvec); return true; } else { return false; } }
+
+  public static int createMonsterExtra(FlatBufferBuilder builder,
+      double d0,
+      double d1,
+      double d2,
+      double d3,
+      float f0,
+      float f1,
+      float f2,
+      float f3,
+      int dvecOffset,
+      int fvecOffset) {
+    builder.startTable(10);
+    MonsterExtra.addD3(builder, d3);
+    MonsterExtra.addD2(builder, d2);
+    MonsterExtra.addD1(builder, d1);
+    MonsterExtra.addD0(builder, d0);
+    MonsterExtra.addFvec(builder, fvecOffset);
+    MonsterExtra.addDvec(builder, dvecOffset);
+    MonsterExtra.addF3(builder, f3);
+    MonsterExtra.addF2(builder, f2);
+    MonsterExtra.addF1(builder, f1);
+    MonsterExtra.addF0(builder, f0);
+    return MonsterExtra.endMonsterExtra(builder);
+  }
+
+  public static void startMonsterExtra(FlatBufferBuilder builder) { builder.startTable(10); }
+  public static void addD0(FlatBufferBuilder builder, double d0) { builder.addDouble(0, d0, Double.NaN); }
+  public static void addD1(FlatBufferBuilder builder, double d1) { builder.addDouble(1, d1, Double.NaN); }
+  public static void addD2(FlatBufferBuilder builder, double d2) { builder.addDouble(2, d2, Double.POSITIVE_INFINITY); }
+  public static void addD3(FlatBufferBuilder builder, double d3) { builder.addDouble(3, d3, Double.NEGATIVE_INFINITY); }
+  public static void addF0(FlatBufferBuilder builder, float f0) { builder.addFloat(4, f0, Float.NaN); }
+  public static void addF1(FlatBufferBuilder builder, float f1) { builder.addFloat(5, f1, Float.NaN); }
+  public static void addF2(FlatBufferBuilder builder, float f2) { builder.addFloat(6, f2, Float.POSITIVE_INFINITY); }
+  public static void addF3(FlatBufferBuilder builder, float f3) { builder.addFloat(7, f3, Float.NEGATIVE_INFINITY); }
+  public static void addDvec(FlatBufferBuilder builder, int dvecOffset) { builder.addOffset(8, dvecOffset, 0); }
+  public static int createDvecVector(FlatBufferBuilder builder, double[] data) { builder.startVector(8, data.length, 8); for (int i = data.length - 1; i >= 0; i--) builder.addDouble(data[i]); return builder.endVector(); }
+  public static void startDvecVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); }
+  public static void addFvec(FlatBufferBuilder builder, int fvecOffset) { builder.addOffset(9, fvecOffset, 0); }
+  public static int createFvecVector(FlatBufferBuilder builder, float[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addFloat(data[i]); return builder.endVector(); }
+  public static void startFvecVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
+  public static int endMonsterExtra(FlatBufferBuilder builder) {
+    int o = builder.endTable();
+    return o;
+  }
+  public static void finishMonsterExtraBuffer(FlatBufferBuilder builder, int offset) { builder.finish(offset, "MONE"); }
+  public static void finishSizePrefixedMonsterExtraBuffer(FlatBufferBuilder builder, int offset) { builder.finishSizePrefixed(offset, "MONE"); }
+}
+
diff --git a/tests/MyGame/MonsterExtra.kt b/tests/MyGame/MonsterExtra.kt
new file mode 100644
index 0000000..96ea731
--- /dev/null
+++ b/tests/MyGame/MonsterExtra.kt
@@ -0,0 +1,234 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class MonsterExtra : Table() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : MonsterExtra {
+        __init(_i, _bb)
+        return this
+    }
+    val d0 : Double
+        get() {
+            val o = __offset(4)
+            return if(o != 0) bb.getDouble(o + bb_pos) else Double.NaN
+        }
+    fun mutateD0(d0: Double) : Boolean {
+        val o = __offset(4)
+        return if (o != 0) {
+            bb.putDouble(o + bb_pos, d0)
+            true
+        } else {
+            false
+        }
+    }
+    val d1 : Double
+        get() {
+            val o = __offset(6)
+            return if(o != 0) bb.getDouble(o + bb_pos) else Double.NaN
+        }
+    fun mutateD1(d1: Double) : Boolean {
+        val o = __offset(6)
+        return if (o != 0) {
+            bb.putDouble(o + bb_pos, d1)
+            true
+        } else {
+            false
+        }
+    }
+    val d2 : Double
+        get() {
+            val o = __offset(8)
+            return if(o != 0) bb.getDouble(o + bb_pos) else Double.POSITIVE_INFINITY
+        }
+    fun mutateD2(d2: Double) : Boolean {
+        val o = __offset(8)
+        return if (o != 0) {
+            bb.putDouble(o + bb_pos, d2)
+            true
+        } else {
+            false
+        }
+    }
+    val d3 : Double
+        get() {
+            val o = __offset(10)
+            return if(o != 0) bb.getDouble(o + bb_pos) else Double.NEGATIVE_INFINITY
+        }
+    fun mutateD3(d3: Double) : Boolean {
+        val o = __offset(10)
+        return if (o != 0) {
+            bb.putDouble(o + bb_pos, d3)
+            true
+        } else {
+            false
+        }
+    }
+    val f0 : Float
+        get() {
+            val o = __offset(12)
+            return if(o != 0) bb.getFloat(o + bb_pos) else Float.NaN
+        }
+    fun mutateF0(f0: Float) : Boolean {
+        val o = __offset(12)
+        return if (o != 0) {
+            bb.putFloat(o + bb_pos, f0)
+            true
+        } else {
+            false
+        }
+    }
+    val f1 : Float
+        get() {
+            val o = __offset(14)
+            return if(o != 0) bb.getFloat(o + bb_pos) else Float.NaN
+        }
+    fun mutateF1(f1: Float) : Boolean {
+        val o = __offset(14)
+        return if (o != 0) {
+            bb.putFloat(o + bb_pos, f1)
+            true
+        } else {
+            false
+        }
+    }
+    val f2 : Float
+        get() {
+            val o = __offset(16)
+            return if(o != 0) bb.getFloat(o + bb_pos) else Float.POSITIVE_INFINITY
+        }
+    fun mutateF2(f2: Float) : Boolean {
+        val o = __offset(16)
+        return if (o != 0) {
+            bb.putFloat(o + bb_pos, f2)
+            true
+        } else {
+            false
+        }
+    }
+    val f3 : Float
+        get() {
+            val o = __offset(18)
+            return if(o != 0) bb.getFloat(o + bb_pos) else Float.NEGATIVE_INFINITY
+        }
+    fun mutateF3(f3: Float) : Boolean {
+        val o = __offset(18)
+        return if (o != 0) {
+            bb.putFloat(o + bb_pos, f3)
+            true
+        } else {
+            false
+        }
+    }
+    fun dvec(j: Int) : Double {
+        val o = __offset(20)
+        return if (o != 0) {
+            bb.getDouble(__vector(o) + j * 8)
+        } else {
+            0.0
+        }
+    }
+    val dvecLength : Int
+        get() {
+            val o = __offset(20); return if (o != 0) __vector_len(o) else 0
+        }
+    val dvecAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(20, 8)
+    fun dvecInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 20, 8)
+    fun mutateDvec(j: Int, dvec: Double) : Boolean {
+        val o = __offset(20)
+        return if (o != 0) {
+            bb.putDouble(__vector(o) + j * 8, dvec)
+            true
+        } else {
+            false
+        }
+    }
+    fun fvec(j: Int) : Float {
+        val o = __offset(22)
+        return if (o != 0) {
+            bb.getFloat(__vector(o) + j * 4)
+        } else {
+            0.0f
+        }
+    }
+    val fvecLength : Int
+        get() {
+            val o = __offset(22); return if (o != 0) __vector_len(o) else 0
+        }
+    val fvecAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(22, 4)
+    fun fvecInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 22, 4)
+    fun mutateFvec(j: Int, fvec: Float) : Boolean {
+        val o = __offset(22)
+        return if (o != 0) {
+            bb.putFloat(__vector(o) + j * 4, fvec)
+            true
+        } else {
+            false
+        }
+    }
+    companion object {
+        fun validateVersion() = Constants.FLATBUFFERS_1_11_1()
+        fun getRootAsMonsterExtra(_bb: ByteBuffer): MonsterExtra = getRootAsMonsterExtra(_bb, MonsterExtra())
+        fun getRootAsMonsterExtra(_bb: ByteBuffer, obj: MonsterExtra): MonsterExtra {
+            _bb.order(ByteOrder.LITTLE_ENDIAN)
+            return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+        }
+        fun MonsterExtraBufferHasIdentifier(_bb: ByteBuffer) : Boolean = __has_identifier(_bb, "MONE")
+        fun createMonsterExtra(builder: FlatBufferBuilder, d0: Double, d1: Double, d2: Double, d3: Double, f0: Float, f1: Float, f2: Float, f3: Float, dvecOffset: Int, fvecOffset: Int) : Int {
+            builder.startTable(10)
+            addD3(builder, d3)
+            addD2(builder, d2)
+            addD1(builder, d1)
+            addD0(builder, d0)
+            addFvec(builder, fvecOffset)
+            addDvec(builder, dvecOffset)
+            addF3(builder, f3)
+            addF2(builder, f2)
+            addF1(builder, f1)
+            addF0(builder, f0)
+            return endMonsterExtra(builder)
+        }
+        fun startMonsterExtra(builder: FlatBufferBuilder) = builder.startTable(10)
+        fun addD0(builder: FlatBufferBuilder, d0: Double) = builder.addDouble(0, d0, Double.NaN)
+        fun addD1(builder: FlatBufferBuilder, d1: Double) = builder.addDouble(1, d1, Double.NaN)
+        fun addD2(builder: FlatBufferBuilder, d2: Double) = builder.addDouble(2, d2, Double.POSITIVE_INFINITY)
+        fun addD3(builder: FlatBufferBuilder, d3: Double) = builder.addDouble(3, d3, Double.NEGATIVE_INFINITY)
+        fun addF0(builder: FlatBufferBuilder, f0: Float) = builder.addFloat(4, f0, Double.NaN)
+        fun addF1(builder: FlatBufferBuilder, f1: Float) = builder.addFloat(5, f1, Double.NaN)
+        fun addF2(builder: FlatBufferBuilder, f2: Float) = builder.addFloat(6, f2, Double.POSITIVE_INFINITY)
+        fun addF3(builder: FlatBufferBuilder, f3: Float) = builder.addFloat(7, f3, Double.NEGATIVE_INFINITY)
+        fun addDvec(builder: FlatBufferBuilder, dvec: Int) = builder.addOffset(8, dvec, 0)
+        fun createDvecVector(builder: FlatBufferBuilder, data: DoubleArray) : Int {
+            builder.startVector(8, data.size, 8)
+            for (i in data.size - 1 downTo 0) {
+                builder.addDouble(data[i])
+            }
+            return builder.endVector()
+        }
+        fun startDvecVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(8, numElems, 8)
+        fun addFvec(builder: FlatBufferBuilder, fvec: Int) = builder.addOffset(9, fvec, 0)
+        fun createFvecVector(builder: FlatBufferBuilder, data: FloatArray) : Int {
+            builder.startVector(4, data.size, 4)
+            for (i in data.size - 1 downTo 0) {
+                builder.addFloat(data[i])
+            }
+            return builder.endVector()
+        }
+        fun startFvecVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(4, numElems, 4)
+        fun endMonsterExtra(builder: FlatBufferBuilder) : Int {
+            val o = builder.endTable()
+            return o
+        }
+        fun finishMonsterExtraBuffer(builder: FlatBufferBuilder, offset: Int) = builder.finish(offset, "MONE")
+        fun finishSizePrefixedMonsterExtraBuffer(builder: FlatBufferBuilder, offset: Int) = builder.finishSizePrefixed(offset, "MONE")
+    }
+}
diff --git a/tests/MyGame/MonsterExtra.py b/tests/MyGame/MonsterExtra.py
new file mode 100644
index 0000000..1f7dcb2
--- /dev/null
+++ b/tests/MyGame/MonsterExtra.py
@@ -0,0 +1,138 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: MyGame
+
+import flatbuffers
+
+class MonsterExtra(object):
+    __slots__ = ['_tab']
+
+    @classmethod
+    def GetRootAsMonsterExtra(cls, buf, offset):
+        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
+        x = MonsterExtra()
+        x.Init(buf, n + offset)
+        return x
+
+    @classmethod
+    def MonsterExtraBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
+        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x45", size_prefixed=size_prefixed)
+
+    # MonsterExtra
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # MonsterExtra
+    def D0(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
+        return float('nan')
+
+    # MonsterExtra
+    def D1(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
+        return float('nan')
+
+    # MonsterExtra
+    def D2(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
+        return float('inf')
+
+    # MonsterExtra
+    def D3(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
+        return float('-inf')
+
+    # MonsterExtra
+    def F0(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
+        return float('nan')
+
+    # MonsterExtra
+    def F1(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
+        return float('nan')
+
+    # MonsterExtra
+    def F2(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
+        return float('inf')
+
+    # MonsterExtra
+    def F3(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(18))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
+        return float('-inf')
+
+    # MonsterExtra
+    def Dvec(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(20))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.Get(flatbuffers.number_types.Float64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
+        return 0
+
+    # MonsterExtra
+    def DvecAsNumpy(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(20))
+        if o != 0:
+            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Float64Flags, o)
+        return 0
+
+    # MonsterExtra
+    def DvecLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(20))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # MonsterExtra
+    def Fvec(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.Get(flatbuffers.number_types.Float32Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
+        return 0
+
+    # MonsterExtra
+    def FvecAsNumpy(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
+        if o != 0:
+            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Float32Flags, o)
+        return 0
+
+    # MonsterExtra
+    def FvecLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+def MonsterExtraStart(builder): builder.StartObject(10)
+def MonsterExtraAddD0(builder, d0): builder.PrependFloat64Slot(0, d0, float('nan'))
+def MonsterExtraAddD1(builder, d1): builder.PrependFloat64Slot(1, d1, float('nan'))
+def MonsterExtraAddD2(builder, d2): builder.PrependFloat64Slot(2, d2, float('inf'))
+def MonsterExtraAddD3(builder, d3): builder.PrependFloat64Slot(3, d3, float('-inf'))
+def MonsterExtraAddF0(builder, f0): builder.PrependFloat32Slot(4, f0, float('nan'))
+def MonsterExtraAddF1(builder, f1): builder.PrependFloat32Slot(5, f1, float('nan'))
+def MonsterExtraAddF2(builder, f2): builder.PrependFloat32Slot(6, f2, float('inf'))
+def MonsterExtraAddF3(builder, f3): builder.PrependFloat32Slot(7, f3, float('-inf'))
+def MonsterExtraAddDvec(builder, dvec): builder.PrependUOffsetTRelativeSlot(8, flatbuffers.number_types.UOffsetTFlags.py_type(dvec), 0)
+def MonsterExtraStartDvecVector(builder, numElems): return builder.StartVector(8, numElems, 8)
+def MonsterExtraAddFvec(builder, fvec): builder.PrependUOffsetTRelativeSlot(9, flatbuffers.number_types.UOffsetTFlags.py_type(fvec), 0)
+def MonsterExtraStartFvecVector(builder, numElems): return builder.StartVector(4, numElems, 4)
+def MonsterExtraEnd(builder): return builder.EndObject()
diff --git a/tests/MyGame/__init__.py b/tests/MyGame/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/MyGame/__init__.py
diff --git a/tests/PythonTest.sh b/tests/PythonTest.sh
new file mode 100755
index 0000000..e4dbe8d
--- /dev/null
+++ b/tests/PythonTest.sh
@@ -0,0 +1,79 @@
+#!/bin/bash -eu
+#
+# 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.
+
+pushd "$(dirname $0)" >/dev/null
+test_dir="$(pwd)"
+gen_code_path=${test_dir}
+runtime_library_dir=${test_dir}/../python
+
+# Emit Python code for the example schema in the test dir:
+${test_dir}/../flatc -p -o ${gen_code_path} -I include_test monster_test.fbs
+
+# Syntax: run_tests <interpreter> <benchmark vtable dedupes>
+#                   <benchmark read count> <benchmark build count>
+interpreters_tested=()
+function run_tests() {
+  if $(which ${1} >/dev/null); then
+    echo "Testing with interpreter: ${1}"
+    PYTHONDONTWRITEBYTECODE=1 \
+    JYTHONDONTWRITEBYTECODE=1 \
+    PYTHONPATH=${runtime_library_dir}:${gen_code_path} \
+    JYTHONPATH=${runtime_library_dir}:${gen_code_path} \
+    COMPARE_GENERATED_TO_GO=0 \
+    COMPARE_GENERATED_TO_JAVA=0 \
+    $1 py_test.py $2 $3 $4
+    interpreters_tested+=(${1})
+    echo
+  fi
+}
+
+# Run test suite with these interpreters. The arguments are benchmark counts.
+run_tests python2.6 100 100 100
+run_tests python2.7 100 100 100
+run_tests python3 100 100 100
+run_tests pypy 100 100 100
+
+# NOTE: We'd like to support python2.5 in the future.
+
+# NOTE: Jython 2.7.0 fails due to a bug in the stdlib `struct` library:
+#       http://bugs.jython.org/issue2188
+
+if [ ${#interpreters_tested[@]} -eq 0 ]; then
+  echo "No Python interpeters found on this system, could not run tests."
+  exit 1
+fi
+
+# Run test suite with default python intereter.
+# (If the Python program `coverage` is available, it will be run, too.
+#  Install `coverage` with `pip install coverage`.)
+if $(which coverage >/dev/null); then
+  echo 'Found coverage utility, running coverage with default Python:'
+
+  PYTHONDONTWRITEBYTECODE=1 \
+  PYTHONPATH=${runtime_library_dir}:${gen_code_path} \
+  coverage run --source=flatbuffers,MyGame py_test.py 0 0 0 > /dev/null
+
+  echo
+  cov_result=`coverage report --omit="*flatbuffers/vendor*,*py_test*" \
+              | tail -n 1 | awk ' { print $4 } '`
+  echo "Code coverage: ${cov_result}"
+else
+  echo -n "Did not find coverage utility for default Python, skipping. "
+  echo "Install with 'pip install coverage'."
+fi
+
+echo
+echo "OK: all tests passed for ${#interpreters_tested[@]} interpreters: ${interpreters_tested[@]}."
diff --git a/tests/RustTest.bat b/tests/RustTest.bat
new file mode 100644
index 0000000..ba9cfd2
--- /dev/null
+++ b/tests/RustTest.bat
@@ -0,0 +1,23 @@
+@echo off
+rem Copyright 2018 Google Inc. All rights reserved.
+rem
+rem Licensed under the Apache License, Version 2.0 (the "License");
+rem you may not use this file except in compliance with the License.
+rem You may obtain a copy of the License at
+rem
+rem     http://www.apache.org/licenses/LICENSE-2.0
+rem
+rem Unless required by applicable law or agreed to in writing, software
+rem distributed under the License is distributed on an "AS IS" BASIS,
+rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+rem See the License for the specific language governing permissions and
+rem limitations under the License.
+
+rem Compile then run the Rust test.
+
+rem TODO(rw): how do we make this script abort the calling script in appveyor?
+
+cd rust_usage_test
+cargo test -- --quiet || exit /b 1
+cargo run --bin=alloc_check || exit /b 1
+cd ..
diff --git a/tests/RustTest.sh b/tests/RustTest.sh
new file mode 100755
index 0000000..0a3974b
--- /dev/null
+++ b/tests/RustTest.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+set -e
+#
+# Copyright 2018 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.
+
+if [[ "$1" == "mips-unknown-linux-gnu" ]]; then
+    TARGET_FLAG="--target mips-unknown-linux-gnu"
+    export CARGO_TARGET_MIPS_UNKNOWN_LINUX_GNU_LINKER=mips-linux-gnu-gcc
+    export CARGO_TARGET_MIPS_UNKNOWN_LINUX_GNU_RUNNER="qemu-mips -L /usr/mips-linux-gnu"
+fi
+
+cd ./rust_usage_test
+cargo test $TARGET_FLAG -- --quiet
+TEST_RESULT=$?
+if [[ $TEST_RESULT  == 0 ]]; then
+    echo "OK: Rust tests passed."
+else
+    echo "KO: Rust tests failed."
+    exit 1
+fi
+
+cargo run $TARGET_FLAG --bin=alloc_check
+TEST_RESULT=$?
+if [[ $TEST_RESULT  == 0 ]]; then
+    echo "OK: Rust heap alloc test passed."
+else
+    echo "KO: Rust heap alloc test failed."
+    exit 1
+fi
+
+cargo bench $TARGET_FLAG
diff --git a/tests/TestAll.sh b/tests/TestAll.sh
new file mode 100644
index 0000000..0fc0acd
--- /dev/null
+++ b/tests/TestAll.sh
@@ -0,0 +1,63 @@
+echo "************************ Java:"
+
+sh JavaTest.sh
+
+echo "************************ Kotlin:"
+
+sh KotlinTest.sh
+
+echo "************************ Go:"
+
+sh GoTest.sh
+
+echo "************************ Python:"
+
+sh PythonTest.sh
+
+echo "************************ JavaScript:"
+
+sh JavaScriptTest.sh
+# FIXME does not exist:
+# sh JavaScriptUnionVectorTest.sh
+
+echo "************************ TypeScript:"
+
+sh TypeScriptTest.sh
+
+echo "************************ C++:"
+
+cd ..
+./flattests
+cd tests
+
+echo "************************ C#:"
+
+cd FlatBuffers.Test
+sh NetTest.sh
+cd ..
+
+echo "************************ PHP:"
+
+php phpTest.php
+sh phpUnionVectorTest.sh
+
+echo "************************ Dart:"
+
+sh DartTest.sh
+
+echo "************************ Rust:"
+
+sh RustTest.sh
+
+echo "************************ Lobster:"
+
+# TODO: test if available.
+# lobster lobstertest.lobster
+
+echo "************************ C:"
+
+echo "(in a different repo)"
+
+echo "************************ Swift:"
+
+echo "(in a different repo)"
diff --git a/tests/TypeScriptTest.sh b/tests/TypeScriptTest.sh
new file mode 100755
index 0000000..fa650a4
--- /dev/null
+++ b/tests/TypeScriptTest.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+#
+# Copyright 2016 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.
+
+pushd "$(dirname $0)" >/dev/null
+
+npm install @types/flatbuffers
+
+../flatc --ts --no-fb-import --gen-mutable -o ts -I include_test monster_test.fbs
+../flatc -b -I include_test monster_test.fbs unicode_test.json
+tsc --strict --noUnusedParameters --noUnusedLocals --noImplicitReturns --strictNullChecks ts/monster_test_generated.ts
+node JavaScriptTest ./ts/monster_test_generated
+
+../flatc --ts --js --no-fb-import -o ts union_vector/union_vector.fbs
+
+# test JS version first, then transpile and rerun for TS
+node JavaScriptUnionVectorTest ./ts/union_vector_generated
+tsc --strict --noUnusedParameters --noUnusedLocals --noImplicitReturns --strictNullChecks ts/union_vector_generated.ts
+node JavaScriptUnionVectorTest ./ts/union_vector_generated
+
+npm uninstall @types/flatbuffers
diff --git a/tests/arrays_test.bfbs b/tests/arrays_test.bfbs
new file mode 100644
index 0000000..2a89968
--- /dev/null
+++ b/tests/arrays_test.bfbs
Binary files differ
diff --git a/tests/arrays_test.fbs b/tests/arrays_test.fbs
new file mode 100644
index 0000000..40bce66
--- /dev/null
+++ b/tests/arrays_test.fbs
@@ -0,0 +1,24 @@
+namespace MyGame.Example;
+
+enum TestEnum : byte { A, B, C }
+
+struct NestedStruct{
+  a:[int:2];
+  b:TestEnum;
+  c:[TestEnum:2];
+}
+
+struct ArrayStruct{
+  a:float;
+  b:[int:0xF];
+  c:byte;
+  d:[NestedStruct:2];
+}
+
+table ArrayTable{
+  a:ArrayStruct;
+}
+
+root_type ArrayTable;
+file_identifier "ARRT";
+file_extension "mon";
diff --git a/tests/arrays_test.golden b/tests/arrays_test.golden
new file mode 100644
index 0000000..c032688
--- /dev/null
+++ b/tests/arrays_test.golden
@@ -0,0 +1,19 @@
+{
+  a : {
+    a: 12.34,
+    b: [1,2,3,4,5,6,7,8,9,0xA,0xB,0xC,0xD,0xE,0xF],
+    c: -127,
+    d: [
+      {
+        a : [-1,2],
+        b : A,
+        c : [C, B]
+      },
+      {
+        a : [3,-4],
+        b : B,
+        c : [B, A]
+      }
+    ]
+  }
+}
\ No newline at end of file
diff --git a/tests/arrays_test.schema.json b/tests/arrays_test.schema.json
new file mode 100644
index 0000000..6803a1a
--- /dev/null
+++ b/tests/arrays_test.schema.json
@@ -0,0 +1,60 @@
+{
+  "$schema": "http://json-schema.org/draft-04/schema#",
+  "definitions": {
+    "MyGame_Example_TestEnum" : {
+      "type" : "string",
+      "enum": ["A", "B", "C"]
+    },
+    "MyGame_Example_NestedStruct" : {
+      "type" : "object",
+      "properties" : {
+        "a" : {
+                "type" : "array", "items" : { "type" : "number" },
+                "minItems": 2,
+                "maxItems": 2
+              },
+        "b" : {
+                "$ref" : "#/definitions/MyGame_Example_TestEnum"
+              },
+        "c" : {
+                "$ref" : "#/definitions/MyGame_Example_TestEnum",
+                "minItems": 2,
+                "maxItems": 2
+              }
+      },
+      "additionalProperties" : false
+    },
+    "MyGame_Example_ArrayStruct" : {
+      "type" : "object",
+      "properties" : {
+        "a" : {
+                "type" : "number"
+              },
+        "b" : {
+                "type" : "array", "items" : { "type" : "number" },
+                "minItems": 15,
+                "maxItems": 15
+              },
+        "c" : {
+                "type" : "number"
+              },
+        "d" : {
+                "type" : "array", "items" : { "$ref" : "#/definitions/MyGame_Example_NestedStruct" },
+                "minItems": 2,
+                "maxItems": 2
+              }
+      },
+      "additionalProperties" : false
+    },
+    "MyGame_Example_ArrayTable" : {
+      "type" : "object",
+      "properties" : {
+        "a" : {
+                "$ref" : "#/definitions/MyGame_Example_ArrayStruct"
+              }
+      },
+      "additionalProperties" : false
+    }
+  },
+  "$ref" : "#/definitions/MyGame_Example_ArrayTable"
+}
diff --git a/tests/arrays_test_generated.h b/tests/arrays_test_generated.h
new file mode 100644
index 0000000..9875785
--- /dev/null
+++ b/tests/arrays_test_generated.h
@@ -0,0 +1,419 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+#ifndef FLATBUFFERS_GENERATED_ARRAYSTEST_MYGAME_EXAMPLE_H_
+#define FLATBUFFERS_GENERATED_ARRAYSTEST_MYGAME_EXAMPLE_H_
+
+#include "flatbuffers/flatbuffers.h"
+
+namespace MyGame {
+namespace Example {
+
+struct NestedStruct;
+
+struct ArrayStruct;
+
+struct ArrayTable;
+struct ArrayTableT;
+
+bool operator==(const NestedStruct &lhs, const NestedStruct &rhs);
+bool operator!=(const NestedStruct &lhs, const NestedStruct &rhs);
+bool operator==(const ArrayStruct &lhs, const ArrayStruct &rhs);
+bool operator!=(const ArrayStruct &lhs, const ArrayStruct &rhs);
+bool operator==(const ArrayTableT &lhs, const ArrayTableT &rhs);
+bool operator!=(const ArrayTableT &lhs, const ArrayTableT &rhs);
+
+inline const flatbuffers::TypeTable *NestedStructTypeTable();
+
+inline const flatbuffers::TypeTable *ArrayStructTypeTable();
+
+inline const flatbuffers::TypeTable *ArrayTableTypeTable();
+
+enum class TestEnum : int8_t {
+  A = 0,
+  B = 1,
+  C = 2,
+  MIN = A,
+  MAX = C
+};
+
+inline const TestEnum (&EnumValuesTestEnum())[3] {
+  static const TestEnum values[] = {
+    TestEnum::A,
+    TestEnum::B,
+    TestEnum::C
+  };
+  return values;
+}
+
+inline const char * const *EnumNamesTestEnum() {
+  static const char * const names[4] = {
+    "A",
+    "B",
+    "C",
+    nullptr
+  };
+  return names;
+}
+
+inline const char *EnumNameTestEnum(TestEnum e) {
+  if (e < TestEnum::A || e > TestEnum::C) return "";
+  const size_t index = static_cast<size_t>(e);
+  return EnumNamesTestEnum()[index];
+}
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) NestedStruct FLATBUFFERS_FINAL_CLASS {
+ private:
+  int32_t a_[2];
+  int8_t b_;
+  int8_t c_[2];
+  int8_t padding0__;
+
+ public:
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return NestedStructTypeTable();
+  }
+  NestedStruct() {
+    memset(static_cast<void *>(this), 0, sizeof(NestedStruct));
+  }
+  NestedStruct(MyGame::Example::TestEnum _b)
+      : b_(flatbuffers::EndianScalar(static_cast<int8_t>(_b))) {
+    std::memset(a_, 0, sizeof(a_));
+    std::memset(c_, 0, sizeof(c_));
+    (void)padding0__;
+  }
+  const flatbuffers::Array<int32_t, 2> *a() const {
+    return reinterpret_cast<const flatbuffers::Array<int32_t, 2> *>(a_);
+  }
+  flatbuffers::Array<int32_t, 2> *mutable_a() {
+    return reinterpret_cast<flatbuffers::Array<int32_t, 2> *>(a_);
+  }
+  MyGame::Example::TestEnum b() const {
+    return static_cast<MyGame::Example::TestEnum>(flatbuffers::EndianScalar(b_));
+  }
+  void mutate_b(MyGame::Example::TestEnum _b) {
+    flatbuffers::WriteScalar(&b_, static_cast<int8_t>(_b));
+  }
+  const flatbuffers::Array<MyGame::Example::TestEnum, 2> *c() const {
+    return reinterpret_cast<const flatbuffers::Array<MyGame::Example::TestEnum, 2> *>(c_);
+  }
+  flatbuffers::Array<MyGame::Example::TestEnum, 2> *mutable_c() {
+    return reinterpret_cast<flatbuffers::Array<MyGame::Example::TestEnum, 2> *>(c_);
+  }
+};
+FLATBUFFERS_STRUCT_END(NestedStruct, 12);
+
+inline bool operator==(const NestedStruct &lhs, const NestedStruct &rhs) {
+  return
+      (lhs.a() == rhs.a()) &&
+      (lhs.b() == rhs.b()) &&
+      (lhs.c() == rhs.c());
+}
+
+inline bool operator!=(const NestedStruct &lhs, const NestedStruct &rhs) {
+    return !(lhs == rhs);
+}
+
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) ArrayStruct FLATBUFFERS_FINAL_CLASS {
+ private:
+  float a_;
+  int32_t b_[15];
+  int8_t c_;
+  int8_t padding0__;  int16_t padding1__;
+  MyGame::Example::NestedStruct d_[2];
+
+ public:
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return ArrayStructTypeTable();
+  }
+  ArrayStruct() {
+    memset(static_cast<void *>(this), 0, sizeof(ArrayStruct));
+  }
+  ArrayStruct(float _a, int8_t _c)
+      : a_(flatbuffers::EndianScalar(_a)),
+        c_(flatbuffers::EndianScalar(_c)),
+        padding0__(0),
+        padding1__(0) {
+    std::memset(b_, 0, sizeof(b_));
+    (void)padding0__;    (void)padding1__;
+    std::memset(d_, 0, sizeof(d_));
+  }
+  float a() const {
+    return flatbuffers::EndianScalar(a_);
+  }
+  void mutate_a(float _a) {
+    flatbuffers::WriteScalar(&a_, _a);
+  }
+  const flatbuffers::Array<int32_t, 15> *b() const {
+    return reinterpret_cast<const flatbuffers::Array<int32_t, 15> *>(b_);
+  }
+  flatbuffers::Array<int32_t, 15> *mutable_b() {
+    return reinterpret_cast<flatbuffers::Array<int32_t, 15> *>(b_);
+  }
+  int8_t c() const {
+    return flatbuffers::EndianScalar(c_);
+  }
+  void mutate_c(int8_t _c) {
+    flatbuffers::WriteScalar(&c_, _c);
+  }
+  const flatbuffers::Array<MyGame::Example::NestedStruct, 2> *d() const {
+    return reinterpret_cast<const flatbuffers::Array<MyGame::Example::NestedStruct, 2> *>(d_);
+  }
+  flatbuffers::Array<MyGame::Example::NestedStruct, 2> *mutable_d() {
+    return reinterpret_cast<flatbuffers::Array<MyGame::Example::NestedStruct, 2> *>(d_);
+  }
+};
+FLATBUFFERS_STRUCT_END(ArrayStruct, 92);
+
+inline bool operator==(const ArrayStruct &lhs, const ArrayStruct &rhs) {
+  return
+      (lhs.a() == rhs.a()) &&
+      (lhs.b() == rhs.b()) &&
+      (lhs.c() == rhs.c()) &&
+      (lhs.d() == rhs.d());
+}
+
+inline bool operator!=(const ArrayStruct &lhs, const ArrayStruct &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct ArrayTableT : public flatbuffers::NativeTable {
+  typedef ArrayTable TableType;
+  flatbuffers::unique_ptr<MyGame::Example::ArrayStruct> a;
+  ArrayTableT() {
+  }
+};
+
+inline bool operator==(const ArrayTableT &lhs, const ArrayTableT &rhs) {
+  return
+      (lhs.a == rhs.a);
+}
+
+inline bool operator!=(const ArrayTableT &lhs, const ArrayTableT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct ArrayTable FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef ArrayTableT NativeTableType;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return ArrayTableTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_A = 4
+  };
+  const MyGame::Example::ArrayStruct *a() const {
+    return GetStruct<const MyGame::Example::ArrayStruct *>(VT_A);
+  }
+  MyGame::Example::ArrayStruct *mutable_a() {
+    return GetStruct<MyGame::Example::ArrayStruct *>(VT_A);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<MyGame::Example::ArrayStruct>(verifier, VT_A) &&
+           verifier.EndTable();
+  }
+  ArrayTableT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(ArrayTableT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<ArrayTable> Pack(flatbuffers::FlatBufferBuilder &_fbb, const ArrayTableT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct ArrayTableBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_a(const MyGame::Example::ArrayStruct *a) {
+    fbb_.AddStruct(ArrayTable::VT_A, a);
+  }
+  explicit ArrayTableBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  ArrayTableBuilder &operator=(const ArrayTableBuilder &);
+  flatbuffers::Offset<ArrayTable> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<ArrayTable>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<ArrayTable> CreateArrayTable(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const MyGame::Example::ArrayStruct *a = 0) {
+  ArrayTableBuilder builder_(_fbb);
+  builder_.add_a(a);
+  return builder_.Finish();
+}
+
+flatbuffers::Offset<ArrayTable> CreateArrayTable(flatbuffers::FlatBufferBuilder &_fbb, const ArrayTableT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+inline ArrayTableT *ArrayTable::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = new ArrayTableT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+inline void ArrayTable::UnPackTo(ArrayTableT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+  { auto _e = a(); if (_e) _o->a = flatbuffers::unique_ptr<MyGame::Example::ArrayStruct>(new MyGame::Example::ArrayStruct(*_e)); };
+}
+
+inline flatbuffers::Offset<ArrayTable> ArrayTable::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ArrayTableT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateArrayTable(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<ArrayTable> CreateArrayTable(flatbuffers::FlatBufferBuilder &_fbb, const ArrayTableT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ArrayTableT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  auto _a = _o->a ? _o->a.get() : 0;
+  return MyGame::Example::CreateArrayTable(
+      _fbb,
+      _a);
+}
+
+inline const flatbuffers::TypeTable *TestEnumTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_CHAR, 0, 0 },
+    { flatbuffers::ET_CHAR, 0, 0 },
+    { flatbuffers::ET_CHAR, 0, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Example::TestEnumTypeTable
+  };
+  static const char * const names[] = {
+    "A",
+    "B",
+    "C"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_ENUM, 3, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *NestedStructTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SEQUENCE, 0, -1 },
+    { flatbuffers::ET_CHAR, 0, 0 },
+    { flatbuffers::ET_SEQUENCE, 0, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Example::TestEnumTypeTable
+  };
+  static const int64_t values[] = { 0, 8, 9, 12 };
+  static const char * const names[] = {
+    "a",
+    "b",
+    "c"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_STRUCT, 3, type_codes, type_refs, values, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *ArrayStructTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_SEQUENCE, 0, -1 },
+    { flatbuffers::ET_CHAR, 0, -1 },
+    { flatbuffers::ET_SEQUENCE, 0, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Example::NestedStructTypeTable
+  };
+  static const int64_t values[] = { 0, 4, 64, 68, 92 };
+  static const char * const names[] = {
+    "a",
+    "b",
+    "c",
+    "d"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_STRUCT, 4, type_codes, type_refs, values, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *ArrayTableTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SEQUENCE, 0, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Example::ArrayStructTypeTable
+  };
+  static const char * const names[] = {
+    "a"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 1, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+inline const MyGame::Example::ArrayTable *GetArrayTable(const void *buf) {
+  return flatbuffers::GetRoot<MyGame::Example::ArrayTable>(buf);
+}
+
+inline const MyGame::Example::ArrayTable *GetSizePrefixedArrayTable(const void *buf) {
+  return flatbuffers::GetSizePrefixedRoot<MyGame::Example::ArrayTable>(buf);
+}
+
+inline ArrayTable *GetMutableArrayTable(void *buf) {
+  return flatbuffers::GetMutableRoot<ArrayTable>(buf);
+}
+
+inline const char *ArrayTableIdentifier() {
+  return "ARRT";
+}
+
+inline bool ArrayTableBufferHasIdentifier(const void *buf) {
+  return flatbuffers::BufferHasIdentifier(
+      buf, ArrayTableIdentifier());
+}
+
+inline bool VerifyArrayTableBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifyBuffer<MyGame::Example::ArrayTable>(ArrayTableIdentifier());
+}
+
+inline bool VerifySizePrefixedArrayTableBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifySizePrefixedBuffer<MyGame::Example::ArrayTable>(ArrayTableIdentifier());
+}
+
+inline const char *ArrayTableExtension() {
+  return "mon";
+}
+
+inline void FinishArrayTableBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<MyGame::Example::ArrayTable> root) {
+  fbb.Finish(root, ArrayTableIdentifier());
+}
+
+inline void FinishSizePrefixedArrayTableBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<MyGame::Example::ArrayTable> root) {
+  fbb.FinishSizePrefixed(root, ArrayTableIdentifier());
+}
+
+inline flatbuffers::unique_ptr<MyGame::Example::ArrayTableT> UnPackArrayTable(
+    const void *buf,
+    const flatbuffers::resolver_function_t *res = nullptr) {
+  return flatbuffers::unique_ptr<MyGame::Example::ArrayTableT>(GetArrayTable(buf)->UnPack(res));
+}
+
+inline flatbuffers::unique_ptr<MyGame::Example::ArrayTableT> UnPackSizePrefixedArrayTable(
+    const void *buf,
+    const flatbuffers::resolver_function_t *res = nullptr) {
+  return flatbuffers::unique_ptr<MyGame::Example::ArrayTableT>(GetSizePrefixedArrayTable(buf)->UnPack(res));
+}
+
+}  // namespace Example
+}  // namespace MyGame
+
+#endif  // FLATBUFFERS_GENERATED_ARRAYSTEST_MYGAME_EXAMPLE_H_
diff --git a/tests/docker/Dockerfile.testing.build_flatc_debian_stretch b/tests/docker/Dockerfile.testing.build_flatc_debian_stretch
new file mode 100644
index 0000000..197a555
--- /dev/null
+++ b/tests/docker/Dockerfile.testing.build_flatc_debian_stretch
@@ -0,0 +1,9 @@
+FROM debian:9.6-slim as base
+RUN apt -qq update >/dev/null
+RUN apt -qq install -y cmake make build-essential >/dev/null
+FROM base
+WORKDIR /code
+ADD . .
+RUN cmake -G "Unix Makefiles"
+RUN make flatc
+RUN ls flatc
diff --git a/tests/docker/TODO.Dockerfile.testing.php.hhvm_2019_01_16 b/tests/docker/TODO.Dockerfile.testing.php.hhvm_2019_01_16
new file mode 100644
index 0000000..e5023fa
--- /dev/null
+++ b/tests/docker/TODO.Dockerfile.testing.php.hhvm_2019_01_16
@@ -0,0 +1,18 @@
+# This does not pass tests due to the following error:
+#
+# Fatal error: Uncaught exception 'InvalidArgumentException' with message 'Google\FlatBuffers\ByteBuffer::getX() expects parameter 1 by reference, but the call was not annotated with '&'. in /code/php/FlatbufferBuilder.php:971
+# Stack trace:
+# #0 /code/tests/phpTest.php(277): Google\FlatBuffers\FlatbufferBuilder->sizedByteArray()
+# #1 /code/tests/phpTest.php(79): fuzzTest1()
+# #2 /code/tests/phpTest.php(86): main()
+# #3 {main}
+#   thrown in in /code/php/FlatbufferBuilder.php:971
+FROM hhvm/hhvm:2019.01.16 as base
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN hhvm --version
+RUN hhvm phpTest.php
+RUN ../flatc --php -o php union_vector/union_vector.fbs
+RUN hhvm phpUnionVectorTest.php
diff --git a/tests/docker/TODO.Dockerfile.testing.python.cpython_with_conda b/tests/docker/TODO.Dockerfile.testing.python.cpython_with_conda
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/docker/TODO.Dockerfile.testing.python.cpython_with_conda
diff --git a/tests/docker/TODO.Dockerfile.testing.python.cpython_with_numpy b/tests/docker/TODO.Dockerfile.testing.python.cpython_with_numpy
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/docker/TODO.Dockerfile.testing.python.cpython_with_numpy
diff --git a/tests/docker/TODO.Dockerfile.testing.python.pypy_6_0_0_py2 b/tests/docker/TODO.Dockerfile.testing.python.pypy_6_0_0_py2
new file mode 100644
index 0000000..849b92e
--- /dev/null
+++ b/tests/docker/TODO.Dockerfile.testing.python.pypy_6_0_0_py2
@@ -0,0 +1,7 @@
+FROM pypy:2-6.0.0-slim as base
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN pypy --version
+RUN ./PythonTest.sh
diff --git a/tests/docker/TODO.Dockerfile.testing.python.pypy_6_0_0_py3 b/tests/docker/TODO.Dockerfile.testing.python.pypy_6_0_0_py3
new file mode 100644
index 0000000..2df6b2a
--- /dev/null
+++ b/tests/docker/TODO.Dockerfile.testing.python.pypy_6_0_0_py3
@@ -0,0 +1,7 @@
+FROM pypy:3-6.0.0-slim as base
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN pypy --version
+RUN ./PythonTest.sh
diff --git a/tests/docker/languages/Dockerfile.testing.csharp.mono_5_18 b/tests/docker/languages/Dockerfile.testing.csharp.mono_5_18
new file mode 100644
index 0000000..e6ba550
--- /dev/null
+++ b/tests/docker/languages/Dockerfile.testing.csharp.mono_5_18
@@ -0,0 +1,8 @@
+FROM mono:5.18 as base
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN mono --version
+WORKDIR /code/tests/FlatBuffers.Test
+RUN sh NetTest.sh
diff --git a/tests/docker/languages/Dockerfile.testing.golang.1_11 b/tests/docker/languages/Dockerfile.testing.golang.1_11
new file mode 100644
index 0000000..81707ea
--- /dev/null
+++ b/tests/docker/languages/Dockerfile.testing.golang.1_11
@@ -0,0 +1,7 @@
+FROM golang:1.11-stretch as base
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN go version
+RUN ./GoTest.sh
diff --git a/tests/docker/languages/Dockerfile.testing.java.openjdk_10_0_2 b/tests/docker/languages/Dockerfile.testing.java.openjdk_10_0_2
new file mode 100644
index 0000000..82c3add
--- /dev/null
+++ b/tests/docker/languages/Dockerfile.testing.java.openjdk_10_0_2
@@ -0,0 +1,7 @@
+FROM openjdk:10.0.2-jdk-slim-sid as base
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN java -version
+RUN ./JavaTest.sh
diff --git a/tests/docker/languages/Dockerfile.testing.java.openjdk_11_0_1 b/tests/docker/languages/Dockerfile.testing.java.openjdk_11_0_1
new file mode 100644
index 0000000..ac1c3cc
--- /dev/null
+++ b/tests/docker/languages/Dockerfile.testing.java.openjdk_11_0_1
@@ -0,0 +1,7 @@
+FROM openjdk:11.0.1-jdk-slim-sid as base
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN java -version
+RUN ./JavaTest.sh
diff --git a/tests/docker/languages/Dockerfile.testing.node.10_13_0 b/tests/docker/languages/Dockerfile.testing.node.10_13_0
new file mode 100644
index 0000000..b821105
--- /dev/null
+++ b/tests/docker/languages/Dockerfile.testing.node.10_13_0
@@ -0,0 +1,8 @@
+FROM node:10.13.0-stretch as base
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN node --version
+RUN ../flatc -b -I include_test monster_test.fbs unicode_test.json
+RUN node JavaScriptTest ./monster_test_generated
diff --git a/tests/docker/languages/Dockerfile.testing.node.11_2_0 b/tests/docker/languages/Dockerfile.testing.node.11_2_0
new file mode 100644
index 0000000..f6b48e6
--- /dev/null
+++ b/tests/docker/languages/Dockerfile.testing.node.11_2_0
@@ -0,0 +1,8 @@
+FROM node:11.2.0-stretch as base
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN node --version
+RUN ../flatc -b -I include_test monster_test.fbs unicode_test.json
+RUN node JavaScriptTest ./monster_test_generated
diff --git a/tests/docker/languages/Dockerfile.testing.php.zend_7_3 b/tests/docker/languages/Dockerfile.testing.php.zend_7_3
new file mode 100644
index 0000000..6cdf43c
--- /dev/null
+++ b/tests/docker/languages/Dockerfile.testing.php.zend_7_3
@@ -0,0 +1,8 @@
+FROM php:7.3-cli-stretch as base
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN php --version
+RUN php phpTest.php
+RUN sh phpUnionVectorTest.sh
diff --git a/tests/docker/languages/Dockerfile.testing.python.cpython_2_7_15 b/tests/docker/languages/Dockerfile.testing.python.cpython_2_7_15
new file mode 100644
index 0000000..e68303e
--- /dev/null
+++ b/tests/docker/languages/Dockerfile.testing.python.cpython_2_7_15
@@ -0,0 +1,8 @@
+FROM python:2.7.15-slim-stretch as base
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN python --version
+RUN pip install coverage
+RUN ./PythonTest.sh
diff --git a/tests/docker/languages/Dockerfile.testing.python.cpython_3_7_1 b/tests/docker/languages/Dockerfile.testing.python.cpython_3_7_1
new file mode 100644
index 0000000..7c2f15c
--- /dev/null
+++ b/tests/docker/languages/Dockerfile.testing.python.cpython_3_7_1
@@ -0,0 +1,8 @@
+FROM python:3.7.1-slim-stretch as base
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN python --version
+RUN pip install coverage
+RUN ./PythonTest.sh
diff --git a/tests/docker/languages/Dockerfile.testing.rust.1_30_1 b/tests/docker/languages/Dockerfile.testing.rust.1_30_1
new file mode 100644
index 0000000..4d1755c
--- /dev/null
+++ b/tests/docker/languages/Dockerfile.testing.rust.1_30_1
@@ -0,0 +1,7 @@
+FROM rust:1.30.1-slim-stretch as base
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN rustc --version
+RUN ./RustTest.sh
diff --git a/tests/docker/languages/Dockerfile.testing.rust.big_endian.1_30_1 b/tests/docker/languages/Dockerfile.testing.rust.big_endian.1_30_1
new file mode 100644
index 0000000..f2e93f4
--- /dev/null
+++ b/tests/docker/languages/Dockerfile.testing.rust.big_endian.1_30_1
@@ -0,0 +1,15 @@
+FROM rust:1.30.1-slim-stretch as base
+RUN apt -qq update -y && apt -qq install -y \
+    gcc-mips-linux-gnu \
+    libexpat1 \
+    libmagic1 \
+    libmpdec2 \
+    libreadline7 \
+    qemu-user
+RUN rustup target add mips-unknown-linux-gnu
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN rustc --version
+RUN ./RustTest.sh mips-unknown-linux-gnu
diff --git a/tests/fuzzer/CMakeLists.txt b/tests/fuzzer/CMakeLists.txt
new file mode 100644
index 0000000..7df5df2
--- /dev/null
+++ b/tests/fuzzer/CMakeLists.txt
@@ -0,0 +1,91 @@
+cmake_minimum_required(VERSION 3.9)
+
+set(CMAKE_VERBOSE_MAKEFILE ON)
+
+set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+set(CMAKE_POSITION_INDEPENDENT_CODE ON)
+
+project(FlatBuffersFuzzerTests)
+
+set(CMAKE_CXX_FLAGS
+  "${CMAKE_CXX_FLAGS} -std=c++14 -Wall -pedantic -Werror -Wextra -Wno-unused-parameter -fsigned-char")
+
+set(CMAKE_CXX_FLAGS
+  "${CMAKE_CXX_FLAGS} -g -fsigned-char -fno-omit-frame-pointer")
+
+# Typical slowdown introduced by MemorySanitizer (memory) is 3x.
+# '-fsanitize=address' not allowed with '-fsanitize=memory'
+if(YES)
+  set(CMAKE_CXX_FLAGS
+    "${CMAKE_CXX_FLAGS} -fsanitize=fuzzer,address,undefined")
+else()
+  set(CMAKE_CXX_FLAGS
+    "${CMAKE_CXX_FLAGS} -fsanitize=fuzzer,memory,undefined -fsanitize-memory-track-origins=2")
+endif()
+
+set(CMAKE_CXX_FLAGS
+  "${CMAKE_CXX_FLAGS} -fsanitize-coverage=edge,trace-cmp")
+
+# enable link-time optimisation
+# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto")
+
+# https://llvm.org/docs/Passes.html
+# save IR to see call graph
+# make one bitcode file:> llvm-link *.bc -o out.bc
+# print call-graph:> opt out.bc -analyze -print-callgraph &> callgraph.txt
+# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -save-temps -flto")
+
+set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=lld")
+
+set(FLATBUFFERS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../")
+
+set(FlatBuffers_Library_SRCS
+  ${FLATBUFFERS_DIR}/include/flatbuffers/code_generators.h
+  ${FLATBUFFERS_DIR}/include/flatbuffers/base.h
+  ${FLATBUFFERS_DIR}/include/flatbuffers/flatbuffers.h
+  ${FLATBUFFERS_DIR}/include/flatbuffers/hash.h
+  ${FLATBUFFERS_DIR}/include/flatbuffers/idl.h
+  ${FLATBUFFERS_DIR}/include/flatbuffers/util.h
+  ${FLATBUFFERS_DIR}/include/flatbuffers/reflection.h
+  ${FLATBUFFERS_DIR}/include/flatbuffers/reflection_generated.h
+  ${FLATBUFFERS_DIR}/include/flatbuffers/stl_emulation.h
+  ${FLATBUFFERS_DIR}/include/flatbuffers/flexbuffers.h
+  ${FLATBUFFERS_DIR}/include/flatbuffers/registry.h
+  ${FLATBUFFERS_DIR}/include/flatbuffers/minireflect.h
+  ${FLATBUFFERS_DIR}/src/code_generators.cpp
+  ${FLATBUFFERS_DIR}/src/idl_parser.cpp
+  ${FLATBUFFERS_DIR}/src/idl_gen_text.cpp
+  ${FLATBUFFERS_DIR}/src/reflection.cpp
+  ${FLATBUFFERS_DIR}/src/util.cpp
+  ${FLATBUFFERS_DIR}/tests/test_assert.cpp
+)
+
+include_directories(${FLATBUFFERS_DIR}/include)
+include_directories(${FLATBUFFERS_DIR}/tests)
+add_library(flatbuffers STATIC ${FlatBuffers_Library_SRCS})
+
+# FLATBUFFERS_ASSERT should assert in Release as well.
+# Redefine FLATBUFFERS_ASSERT macro definition.
+# Declare as PUBLIC to cover asserts in all included header files.
+target_compile_definitions(flatbuffers PUBLIC
+   FLATBUFFERS_ASSERT=fuzzer_assert_impl)
+target_compile_definitions(flatbuffers PUBLIC
+   FLATBUFFERS_ASSERT_INCLUDE="${CMAKE_CURRENT_SOURCE_DIR}/fuzzer_assert.h")
+
+if(NOT DEFINED FLATBUFFERS_MAX_PARSING_DEPTH)
+  # Force checking of RecursionError in the test
+  set(FLATBUFFERS_MAX_PARSING_DEPTH 8)
+endif()
+message(STATUS "FLATBUFFERS_MAX_PARSING_DEPTH: ${FLATBUFFERS_MAX_PARSING_DEPTH}")
+target_compile_definitions(flatbuffers PRIVATE FLATBUFFERS_MAX_PARSING_DEPTH=8)
+
+# Setup fuzzer tests.
+
+add_executable(scalar_fuzzer flatbuffers_scalar_fuzzer.cc)
+target_link_libraries(scalar_fuzzer PRIVATE flatbuffers)
+
+add_executable(parser_fuzzer flatbuffers_parser_fuzzer.cc)
+target_link_libraries(parser_fuzzer PRIVATE flatbuffers)
+
+add_executable(verifier_fuzzer flatbuffers_verifier_fuzzer.cc)
+target_link_libraries(verifier_fuzzer PRIVATE flatbuffers)
diff --git a/tests/fuzzer/flatbuffers_parser_fuzzer.cc b/tests/fuzzer/flatbuffers_parser_fuzzer.cc
new file mode 100644
index 0000000..87dd2d2
--- /dev/null
+++ b/tests/fuzzer/flatbuffers_parser_fuzzer.cc
@@ -0,0 +1,67 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#include <stddef.h>
+#include <stdint.h>
+#include <clocale>
+#include <string>
+
+#include "flatbuffers/idl.h"
+#include "test_init.h"
+
+static constexpr uint8_t flags_strict_json = 0x01;
+static constexpr uint8_t flags_skip_unexpected_fields_in_json = 0x02;
+static constexpr uint8_t flags_allow_non_utf8 = 0x04;
+// static constexpr uint8_t flags_flag_3 = 0x08;
+// static constexpr uint8_t flags_flag_4 = 0x10;
+// static constexpr uint8_t flags_flag_5 = 0x20;
+// static constexpr uint8_t flags_flag_6 = 0x40;
+// static constexpr uint8_t flags_flag_7 = 0x80;
+
+// Utility for test run.
+OneTimeTestInit OneTimeTestInit::one_time_init_;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  // Reserve one byte for Parser flags and one byte for repetition counter.
+  if (size < 3) return 0;
+  const uint8_t flags = data[0];
+  // normalize to ascii alphabet
+  const int extra_rep_number = data[1] >= '0' ? (data[1] - '0') : 0;
+  data += 2;
+  size -= 2;  // bypass
+
+  const std::string original(reinterpret_cast<const char *>(data), size);
+  auto input = std::string(original.c_str());  // until '\0'
+  if (input.empty()) return 0;
+
+  flatbuffers::IDLOptions opts;
+  opts.strict_json = (flags & flags_strict_json);
+  opts.skip_unexpected_fields_in_json =
+      (flags & flags_skip_unexpected_fields_in_json);
+  opts.allow_non_utf8 = (flags & flags_allow_non_utf8);
+
+  flatbuffers::Parser parser(opts);
+
+  // Guarantee 0-termination in the input.
+  auto parse_input = input.c_str();
+
+  // The fuzzer can adjust the number repetition if a side-effects have found.
+  // Each test should pass at least two times to ensure that the parser doesn't
+  // have any hidden-states or locale-depended effects.
+  for (auto cnt = 0; cnt < (extra_rep_number + 2); cnt++) {
+    // Each even run (0,2,4..) will test locale independed code.
+    auto use_locale = !!OneTimeTestInit::test_locale() && (0 == (cnt % 2));
+    // Set new locale.
+    if (use_locale) {
+      FLATBUFFERS_ASSERT(setlocale(LC_ALL, OneTimeTestInit::test_locale()));
+    }
+
+    // Check Parser.
+    parser.Parse(parse_input);
+
+    // Restore locale.
+    if (use_locale) { FLATBUFFERS_ASSERT(setlocale(LC_ALL, "C")); }
+  }
+
+  return 0;
+}
diff --git a/tests/fuzzer/flatbuffers_scalar_fuzzer.cc b/tests/fuzzer/flatbuffers_scalar_fuzzer.cc
new file mode 100644
index 0000000..074a488
--- /dev/null
+++ b/tests/fuzzer/flatbuffers_scalar_fuzzer.cc
@@ -0,0 +1,351 @@
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <algorithm>
+#include <clocale>
+#include <memory>
+#include <regex>
+#include <string>
+
+#include "flatbuffers/idl.h"
+#include "test_init.h"
+
+static constexpr uint8_t flags_scalar_type = 0x0F;  // type of scalar value
+static constexpr uint8_t flags_quotes_kind = 0x10;  // quote " or '
+// reserved for future: json {named} or [unnamed]
+// static constexpr uint8_t flags_json_bracer = 0x20;
+
+// Find all 'subj' sub-strings and replace first character of sub-string.
+// BreakSequence("testest","tes", 'X') -> "XesXest".
+// BreakSequence("xxx","xx", 'Y') -> "YYx".
+static void BreakSequence(std::string &s, const char *subj, char repl) {
+  size_t pos = 0;
+  while (pos = s.find(subj, pos), pos != std::string::npos) {
+    s.at(pos) = repl;
+    pos++;
+  }
+}
+
+// Remove all leading and trailing symbols matched with pattern set.
+// StripString("xy{xy}y", "xy") -> "{xy}"
+static std::string StripString(const std::string &s, const char *pattern,
+                               size_t *pos = nullptr) {
+  if (pos) *pos = 0;
+  // leading
+  auto first = s.find_first_not_of(pattern);
+  if (std::string::npos == first) return "";
+  if (pos) *pos = first;
+  // trailing
+  auto last = s.find_last_not_of(pattern);
+  assert(last < s.length());
+  assert(first <= last);
+  return s.substr(first, last - first + 1);
+}
+
+class RegexMatcher {
+ protected:
+  virtual bool MatchNumber(const std::string &input) const = 0;
+
+ public:
+  virtual ~RegexMatcher() = default;
+
+  struct MatchResult {
+    size_t pos{ 0 };
+    size_t len{ 0 };
+    bool res{ false };
+    bool quoted{ false };
+  };
+
+  MatchResult Match(const std::string &input) const {
+    MatchResult r;
+    // strip leading and trailing "spaces" accepted by flatbuffer
+    auto test = StripString(input, "\t\r\n ", &r.pos);
+    r.len = test.size();
+    // check quotes
+    if (test.size() >= 2) {
+      auto fch = test.front();
+      auto lch = test.back();
+      r.quoted = (fch == lch) && (fch == '\'' || fch == '\"');
+      if (r.quoted) {
+        // remove quotes for regex test
+        test = test.substr(1, test.size() - 2);
+      }
+    }
+    // Fast check:
+    if (test.empty()) return r;
+    // A string with a valid scalar shouldn't have non-ascii or non-printable
+    // symbols.
+    for (auto c : test) {
+      if ((c < ' ') || (c > '~')) return r;
+    }
+    // Check with regex
+    r.res = MatchNumber(test);
+    return r;
+  }
+
+  bool MatchRegexList(const std::string &input,
+                      const std::vector<std::regex> &re_list) const {
+    auto str = StripString(input, " ");
+    if (str.empty()) return false;
+    for (auto &re : re_list) {
+      std::smatch match;
+      if (std::regex_match(str, match, re)) return true;
+    }
+    return false;
+  }
+};
+
+class IntegerRegex : public RegexMatcher {
+ protected:
+  bool MatchNumber(const std::string &input) const override {
+    static const std::vector<std::regex> re_list = {
+      std::regex{ R"(^[-+]?[0-9]+$)", std::regex_constants::optimize },
+
+      std::regex{
+          R"(^[-+]?0[xX][0-9a-fA-F]+$)", std::regex_constants::optimize }
+    };
+    return MatchRegexList(input, re_list);
+  }
+
+ public:
+  IntegerRegex() = default;
+  virtual ~IntegerRegex() = default;
+};
+
+class UIntegerRegex : public RegexMatcher {
+ protected:
+  bool MatchNumber(const std::string &input) const override {
+    static const std::vector<std::regex> re_list = {
+      std::regex{ R"(^[+]?[0-9]+$)", std::regex_constants::optimize },
+      std::regex{
+          R"(^[+]?0[xX][0-9a-fA-F]+$)", std::regex_constants::optimize },
+      // accept -0 number
+      std::regex{ R"(^[-](?:0[xX])?0+$)", std::regex_constants::optimize }
+    };
+    return MatchRegexList(input, re_list);
+  }
+
+ public:
+  UIntegerRegex() = default;
+  virtual ~UIntegerRegex() = default;
+};
+
+class BooleanRegex : public IntegerRegex {
+ protected:
+  bool MatchNumber(const std::string &input) const override {
+    if (input == "true" || input == "false") return true;
+    return IntegerRegex::MatchNumber(input);
+  }
+
+ public:
+  BooleanRegex() = default;
+  virtual ~BooleanRegex() = default;
+};
+
+class FloatRegex : public RegexMatcher {
+ protected:
+  bool MatchNumber(const std::string &input) const override {
+    static const std::vector<std::regex> re_list = {
+      // hex-float
+      std::regex{
+          R"(^[-+]?0[xX](?:(?:[.][0-9a-fA-F]+)|(?:[0-9a-fA-F]+[.][0-9a-fA-F]*)|(?:[0-9a-fA-F]+))[pP][-+]?[0-9]+$)",
+          std::regex_constants::optimize },
+      // dec-float
+      std::regex{
+          R"(^[-+]?(?:(?:[.][0-9]+)|(?:[0-9]+[.][0-9]*)|(?:[0-9]+))(?:[eE][-+]?[0-9]+)?$)",
+          std::regex_constants::optimize },
+
+      std::regex{ R"(^[-+]?(?:nan|inf|infinity)$)",
+                  std::regex_constants::optimize | std::regex_constants::icase }
+    };
+    return MatchRegexList(input, re_list);
+  }
+
+ public:
+  FloatRegex() = default;
+  virtual ~FloatRegex() = default;
+};
+
+class ScalarReferenceResult {
+ private:
+  ScalarReferenceResult(const char *_type, RegexMatcher::MatchResult _matched)
+      : type(_type), matched(_matched) {}
+
+ public:
+  // Decode scalar type and check if the input string satisfies the scalar type.
+  static ScalarReferenceResult Check(uint8_t code, const std::string &input) {
+    switch (code) {
+      case 0x0: return { "double", FloatRegex().Match(input) };
+      case 0x1: return { "float", FloatRegex().Match(input) };
+      case 0x2: return { "int8", IntegerRegex().Match(input) };
+      case 0x3: return { "int16", IntegerRegex().Match(input) };
+      case 0x4: return { "int32", IntegerRegex().Match(input) };
+      case 0x5: return { "int64", IntegerRegex().Match(input) };
+      case 0x6: return { "uint8", UIntegerRegex().Match(input) };
+      case 0x7: return { "uint16", UIntegerRegex().Match(input) };
+      case 0x8: return { "uint32", UIntegerRegex().Match(input) };
+      case 0x9: return { "uint64", UIntegerRegex().Match(input) };
+      case 0xA: return { "bool", BooleanRegex().Match(input) };
+      default: return { "float", FloatRegex().Match(input) };
+    };
+  }
+
+  const char *type;
+  const RegexMatcher::MatchResult matched;
+};
+
+bool Parse(flatbuffers::Parser &parser, const std::string &json,
+           std::string *_text) {
+  auto done = parser.Parse(json.c_str());
+  if (done) {
+    TEST_EQ(GenerateText(parser, parser.builder_.GetBufferPointer(), _text),
+            true);
+  } else {
+    *_text = parser.error_;
+  }
+  return done;
+}
+
+// Utility for test run.
+OneTimeTestInit OneTimeTestInit::one_time_init_;
+
+// llvm std::regex have problem with stack overflow, limit maximum length.
+// ./scalar_fuzzer -max_len=3000
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  // Reserve one byte for Parser flags and one byte for repetition counter.
+  if (size < 3) return 0;
+  const uint8_t flags = data[0];
+  // normalize to ascii alphabet
+  const int extra_rep_number = data[1] >= '0' ? (data[1] - '0') : 0;
+  data += 2;
+  size -= 2;  // bypass
+
+  // Guarantee 0-termination.
+  const std::string original(reinterpret_cast<const char *>(data), size);
+  auto input = std::string(original.c_str());  // until '\0'
+  if (input.empty()) return 0;
+
+  // Break comments in json to avoid complexity with regex matcher.
+  // The string " 12345 /* text */" will be accepted if insert it to string
+  // expression: "table X { Y: " + " 12345 /* text */" + "; }.
+  // But strings like this will complicate regex matcher.
+  // We reject this by transform "/* text */ 12345" to "@* text */ 12345".
+  BreakSequence(input, "//", '@');  // "//" -> "@/"
+  BreakSequence(input, "/*", '@');  // "/*" -> "@*"
+  // Break all known scalar functions (todo: add them to regex?):
+  for (auto f : { "deg", "rad", "sin", "cos", "tan", "asin", "acos", "atan" }) {
+    BreakSequence(input, f, '_');  // ident -> ident
+  }
+
+  // Extract type of scalar from 'flags' and check if the input string satisfies
+  // the scalar type.
+  const auto ref_res =
+      ScalarReferenceResult::Check(flags & flags_scalar_type, input);
+  auto &recheck = ref_res.matched;
+
+  // Create parser
+  flatbuffers::IDLOptions opts;
+  opts.force_defaults = true;
+  opts.output_default_scalars_in_json = true;
+  opts.indent_step = -1;
+  opts.strict_json = true;
+
+  flatbuffers::Parser parser(opts);
+  auto schema =
+      "table X { Y: " + std::string(ref_res.type) + "; } root_type X;";
+  TEST_EQ_FUNC(parser.Parse(schema.c_str()), true);
+
+  // The fuzzer can adjust the number repetition if a side-effects have found.
+  // Each test should pass at least two times to ensure that the parser doesn't
+  // have any hidden-states or locale-depended effects.
+  for (auto cnt = 0; cnt < (extra_rep_number + 2); cnt++) {
+    // Each even run (0,2,4..) will test locale independed code.
+    auto use_locale = !!OneTimeTestInit::test_locale() && (0 == (cnt % 2));
+    // Set new locale.
+    if (use_locale) {
+      FLATBUFFERS_ASSERT(setlocale(LC_ALL, OneTimeTestInit::test_locale()));
+    }
+
+    // Parse original input as-is.
+    auto orig_scalar = "{ \"Y\" : " + input + " }";
+    std::string orig_back;
+    auto orig_done = Parse(parser, orig_scalar, &orig_back);
+
+    if (recheck.res != orig_done) {
+      // look for "does not fit" or "doesn't fit" or "out of range"
+      auto not_fit =
+          (true == recheck.res)
+              ? ((orig_back.find("does not fit") != std::string::npos) ||
+                 (orig_back.find("out of range") != std::string::npos))
+              : false;
+
+      if (false == not_fit) {
+        TEST_OUTPUT_LINE("Stage 1 failed: Parser(%d) != Regex(%d)", orig_done,
+                         recheck.res);
+        TEST_EQ_STR(orig_back.c_str(),
+                    input.substr(recheck.pos, recheck.len).c_str());
+        TEST_EQ_FUNC(orig_done, recheck.res);
+      }
+    }
+
+    // Try to make quoted string and test it.
+    std::string qouted_input;
+    if (true == recheck.quoted) {
+      // we can't simply remove quotes, they may be nested "'12'".
+      // Original string "\'12\'" converted to "'12'".
+      // The string can be an invalid string by JSON rules, but after quotes
+      // removed can transform to valid.
+      assert(recheck.len >= 2);
+    } else {
+      const auto quote = (flags & flags_quotes_kind) ? '\"' : '\'';
+      qouted_input = input;  // copy
+      qouted_input.insert(recheck.pos + recheck.len, 1, quote);
+      qouted_input.insert(recheck.pos, 1, quote);
+    }
+
+    // Test quoted version of the string
+    if (!qouted_input.empty()) {
+      auto fix_scalar = "{ \"Y\" : " + qouted_input + " }";
+      std::string fix_back;
+      auto fix_done = Parse(parser, fix_scalar, &fix_back);
+
+      if (orig_done != fix_done) {
+        TEST_OUTPUT_LINE("Stage 2 failed: Parser(%d) != Regex(%d)", fix_done,
+                         orig_done);
+        TEST_EQ_STR(fix_back.c_str(), orig_back.c_str());
+      }
+      if (orig_done) { TEST_EQ_STR(fix_back.c_str(), orig_back.c_str()); }
+      TEST_EQ_FUNC(fix_done, orig_done);
+    }
+
+    // Create new parser and test default value
+    if (true == orig_done) {
+      flatbuffers::Parser def_parser(opts);  // re-use options
+      auto def_schema = "table X { Y: " + std::string(ref_res.type) + " = " +
+                        input + "; } root_type X;" +
+                        "{}";  // <- with empty json {}!
+
+      auto def_done = def_parser.Parse(def_schema.c_str());
+      if (false == def_done) {
+        TEST_OUTPUT_LINE("Stage 3.1 failed with _error = %s",
+                         def_parser.error_.c_str());
+        FLATBUFFERS_ASSERT(false);
+      }
+      // Compare with print.
+      std::string ref_string, def_string;
+      FLATBUFFERS_ASSERT(GenerateText(
+          parser, parser.builder_.GetBufferPointer(), &ref_string));
+      FLATBUFFERS_ASSERT(GenerateText(
+          def_parser, def_parser.builder_.GetBufferPointer(), &def_string));
+      if (ref_string != def_string) {
+        TEST_OUTPUT_LINE("Stage 3.2 failed: '%s' != '%s'", def_string.c_str(),
+                         ref_string.c_str());
+        FLATBUFFERS_ASSERT(false);
+      }
+    }
+
+    // Restore locale.
+    if (use_locale) { FLATBUFFERS_ASSERT(setlocale(LC_ALL, "C")); }
+  }
+  return 0;
+}
diff --git a/tests/fuzzer/flatbuffers_verifier_fuzzer.cc b/tests/fuzzer/flatbuffers_verifier_fuzzer.cc
new file mode 100644
index 0000000..d7d453c
--- /dev/null
+++ b/tests/fuzzer/flatbuffers_verifier_fuzzer.cc
@@ -0,0 +1,14 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#include <stddef.h>
+#include <stdint.h>
+#include <string>
+
+#include "monster_test_generated.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  flatbuffers::Verifier verifier(data, size);
+  MyGame::Example::VerifyMonsterBuffer(verifier);
+  return 0;
+}
diff --git a/tests/fuzzer/fuzzer_assert.h b/tests/fuzzer/fuzzer_assert.h
new file mode 100644
index 0000000..afdcf78
--- /dev/null
+++ b/tests/fuzzer/fuzzer_assert.h
@@ -0,0 +1,9 @@
+#ifndef FUZZER_ASSERT_IMPL_H_
+#define FUZZER_ASSERT_IMPL_H_
+
+// Declare Debug/Release independed assert macro.
+#define fuzzer_assert_impl(x) (!!(x) ? static_cast<void>(0) : __builtin_trap())
+
+extern "C" void __builtin_trap(void);
+
+#endif // !FUZZER_ASSERT_IMPL_H_
diff --git a/tests/fuzzer/readme.md b/tests/fuzzer/readme.md
new file mode 100644
index 0000000..c5e147b
--- /dev/null
+++ b/tests/fuzzer/readme.md
@@ -0,0 +1,55 @@
+# Test Flatbuffers library with help of libFuzzer
+Test suite of Flatbuffers library has fuzzer section with tests are based on libFuzzer library.
+
+> LibFuzzer is in-process, coverage-guided, evolutionary fuzzing engine.
+LibFuzzer is linked with the library under test, and feeds fuzzed inputs to the library via a specific fuzzing entrypoint (aka “target function”);
+the fuzzer then tracks which areas of the code are reached, and generates mutations on the corpus of input data in order to maximize the code coverage.
+The code coverage information for libFuzzer is provided by LLVM’s SanitizerCoverage instrumentation.
+
+For details about **libFuzzer** see: https://llvm.org/docs/LibFuzzer.html
+
+To build and run these tests LLVM compiler (with clang frontend) and CMake should be installed before.
+
+The fuzzer section include three tests:
+- `verifier_fuzzer` checks stability of deserialization engine for `Monster` schema;
+- `parser_fuzzer` checks stability of schema and json parser under various inputs;
+- `scalar_parser` focused on validation of the parser while parse numeric scalars in schema and/or json files;
+
+## Run tests with a specific locale
+The grammar of the Flatbuffers library is based on printable-ASCII characters.
+By design, the Flatbuffers library should be independent of the global or thread locales used by an end-user application.
+Set environment variable `FLATBUFFERS_TEST_LOCALE` to run a fuzzer with a specific C-locale:
+```sh
+>FLATBUFFERS_TEST_LOCALE="" ./scalar_parser
+>FLATBUFFERS_TEST_LOCALE="ru_RU.CP1251" ./parser_fuzzer
+```
+
+## Run fuzzer
+These are examples of running a fuzzer.
+Flags may vary and depend on a version of the libFuzzer library.
+For details, run a fuzzer with `-help` flag: `./parser_fuzzer -help=1`
+
+`./verifier_fuzzer -reduce_depth=1 -use_value_profile=1 -shrink=1 ../.corpus_verifier/`
+
+`./parser_fuzzer -reduce_depth=1 -use_value_profile=1 -shrink=1 ../.corpus_parser/`
+
+`./scalar_fuzzer -reduce_depth=1 -use_value_profile=1 -shrink=1 -max_len=3000 ../.corpus_parser/ ../.seed_parser/`
+
+Flag `-only_ascii=1` is useful for fast number-compatibility checking while run `scalar_fuzzer`:  
+`./scalar_fuzzer -only_ascii=1 -reduce_depth=1 -use_value_profile=1 -shrink=1 -max_len=3000 -timeout=10 -rss_limit_mb=2048 -jobs=2 ../.corpus_parser/ ../.seed_parser/`
+
+Run with a specific C-locale:  
+`FLATBUFFERS_TEST_LOCALE="ru_RU.CP1251" ./scalar_fuzzer -reduce_depth=1 -use_value_profile=1 -shrink=1 -max_len=3000 -timeout=10 -rss_limit_mb=2048 ../.corpus_parser/ ../.seed_parser/`
+
+## Merge (minimize) corpus
+The **libFuzzer** allow to filter (minimize) corpus with help of `-merge` flag:
+> -merge
+    If set to 1, any corpus inputs from the 2nd, 3rd etc. corpus directories that trigger new code coverage will be merged into the first corpus directory.
+    Defaults to 0. This flag can be used to minimize a corpus.
+
+Merge several seeds to one (a new collected corpus to the seed collection, for example):
+`./scalar_fuzzer -merge=1 ../.seed_parser/ ../.corpus_parser/`
+
+## Know limitations
+- LLVM 7.0 std::regex library has problem with stack overflow, maximum length of input for `scalar_fuzzer` run should be limited to 3000.
+  Example: `./scalar_fuzzer -max_len=3000`
diff --git a/tests/fuzzer/test_init.h b/tests/fuzzer/test_init.h
new file mode 100644
index 0000000..3d8d07c
--- /dev/null
+++ b/tests/fuzzer/test_init.h
@@ -0,0 +1,56 @@
+
+#ifndef FUZZER_TEST_INIT_H_
+#define FUZZER_TEST_INIT_H_
+
+#include "fuzzer_assert.h"
+#include "test_assert.h"
+
+static_assert(__has_feature(memory_sanitizer) ||
+                  __has_feature(address_sanitizer),
+              "sanitizer disabled");
+
+// Utility for test run.
+struct OneTimeTestInit {
+  // Declare trap for the Flatbuffers test engine.
+  // This hook terminate program both in Debug and Release.
+  static bool TestFailListener(const char *expval, const char *val,
+                               const char *exp, const char *file, int line,
+                               const char *func = 0) {
+    (void)expval;
+    (void)val;
+    (void)exp;
+    (void)file;
+    (void)line;
+    (void)func;
+    // FLATBUFFERS_ASSERT redefined to be fully independent of the Flatbuffers
+    // library implementation (see test_assert.h for details).
+    fuzzer_assert_impl(false);  // terminate
+    return false;
+  }
+
+  OneTimeTestInit() : has_locale_(false) {
+    // Fuzzer test should be independent of the test engine implementation.
+    // This hook will terminate test if TEST_EQ/TEST_ASSERT asserted.
+    InitTestEngine(OneTimeTestInit::TestFailListener);
+
+    // Read a locale for the test.
+    if (flatbuffers::ReadEnvironmentVariable("FLATBUFFERS_TEST_LOCALE",
+                                             &test_locale_)) {
+      TEST_OUTPUT_LINE("The environment variable FLATBUFFERS_TEST_LOCALE=%s",
+                       test_locale_.c_str());
+      test_locale_ = flatbuffers::RemoveStringQuotes(test_locale_);
+      has_locale_ = true;
+    }
+  }
+
+  static const char *test_locale() {
+    return one_time_init_.has_locale_ ? nullptr
+                                      : one_time_init_.test_locale_.c_str();
+  }
+
+  bool has_locale_;
+  std::string test_locale_;
+  static OneTimeTestInit one_time_init_;
+};
+
+#endif  // !FUZZER_TEST_INIT_H_
\ No newline at end of file
diff --git a/tests/generate_code.bat b/tests/generate_code.bat
new file mode 100644
index 0000000..59033b8
--- /dev/null
+++ b/tests/generate_code.bat
@@ -0,0 +1,46 @@
+:: Copyright 2015 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.
+
+set buildtype=Release
+if "%1"=="-b" set buildtype=%2
+
+..\%buildtype%\flatc.exe --cpp --java --csharp --dart --go --binary --lobster --lua --python --js --ts --php --rust --grpc --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes --cpp-ptr-type flatbuffers::unique_ptr  --no-fb-import -I include_test monster_test.fbs monsterdata_test.json || goto FAIL
+..\%buildtype%\flatc.exe --cpp --java --csharp --dart --go --binary --lobster --lua --python --js --ts --php --rust --gen-mutable --reflect-names --no-fb-import --cpp-ptr-type flatbuffers::unique_ptr  -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs || goto FAIL
+..\%buildtype%\flatc.exe --cpp --java --csharp --js --ts --php --gen-mutable --reflect-names --gen-object-api --gen-compare --cpp-ptr-type flatbuffers::unique_ptr -o union_vector ./union_vector/union_vector.fbs || goto FAIL
+..\%buildtype%\flatc.exe -b --schema --bfbs-comments --bfbs-builtins -I include_test monster_test.fbs || goto FAIL
+..\%buildtype%\flatc.exe -b --schema --bfbs-comments --bfbs-builtins -I include_test arrays_test.fbs || goto FAIL
+..\%buildtype%\flatc.exe --jsonschema --schema -I include_test monster_test.fbs || goto FAIL
+..\%buildtype%\flatc.exe --cpp --java --csharp --python --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes --scoped-enums --jsonschema --cpp-ptr-type flatbuffers::unique_ptr arrays_test.fbs || goto FAIL
+..\%buildtype%\flatc.exe --cpp --gen-mutable --gen-object-api --reflect-names --cpp-ptr-type flatbuffers::unique_ptr native_type_test.fbs || goto FAIL
+
+IF NOT "%MONSTER_EXTRA%"=="skip" (
+  @echo Generate MosterExtra
+  ..\%buildtype%\flatc.exe --cpp --java --csharp --python --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes monster_extra.fbs monsterdata_extra.json || goto FAIL
+) else (
+  @echo monster_extra.fbs skipped (the strtod function from MSVC2013 or older doesn't support NaN/Inf arguments)
+)
+
+cd ../samples
+..\%buildtype%\flatc.exe --cpp --lobster --gen-mutable --reflect-names --gen-object-api --gen-compare --cpp-ptr-type flatbuffers::unique_ptr monster.fbs || goto FAIL
+..\%buildtype%\flatc.exe -b --schema --bfbs-comments --bfbs-builtins monster.fbs || goto FAIL
+cd ../reflection
+call generate_code.bat %1 %2 || goto FAIL
+
+set EXITCODE=0
+goto SUCCESS
+:FAIL
+set EXITCODE=1
+:SUCCESS
+cd ../tests
+EXIT /B %EXITCODE%
diff --git a/tests/generate_code.sh b/tests/generate_code.sh
new file mode 100755
index 0000000..d086c2f
--- /dev/null
+++ b/tests/generate_code.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+#
+# Copyright 2015 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.
+set -e
+
+../flatc --cpp --java --kotlin  --csharp --dart --go --binary --lobster --lua --python --js --ts --php --rust --grpc --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes --cpp-ptr-type flatbuffers::unique_ptr  --no-fb-import -I include_test monster_test.fbs monsterdata_test.json
+../flatc --cpp --java --kotlin --csharp --dart --go --binary --lobster --lua --python --js --ts --php --rust --gen-mutable --reflect-names --no-fb-import --cpp-ptr-type flatbuffers::unique_ptr  -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs
+../flatc --cpp --java --kotlin --csharp --js --ts --php --gen-mutable --reflect-names --gen-object-api --gen-compare --cpp-ptr-type flatbuffers::unique_ptr -o union_vector ./union_vector/union_vector.fbs
+../flatc -b --schema --bfbs-comments --bfbs-builtins -I include_test monster_test.fbs
+../flatc -b --schema --bfbs-comments --bfbs-builtins -I include_test arrays_test.fbs
+../flatc --jsonschema --schema -I include_test monster_test.fbs
+../flatc --cpp --java --kotlin --csharp --python --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes monster_extra.fbs monsterdata_extra.json
+../flatc --cpp --java --csharp --python --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes --scoped-enums --jsonschema --cpp-ptr-type flatbuffers::unique_ptr arrays_test.fbs
+cd ../samples
+../flatc --cpp --kotlin --lobster --gen-mutable --reflect-names --gen-object-api --gen-compare --cpp-ptr-type flatbuffers::unique_ptr monster.fbs
+../flatc -b --schema --bfbs-comments --bfbs-builtins monster.fbs
+cd ../reflection
+./generate_code.sh
diff --git a/tests/go_test.go b/tests/go_test.go
new file mode 100644
index 0000000..4784705
--- /dev/null
+++ b/tests/go_test.go
@@ -0,0 +1,1889 @@
+/*
+ * 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.
+ */
+
+package main
+
+import (
+	mygame "MyGame"          // refers to generated code
+	example "MyGame/Example" // refers to generated code
+
+	"bytes"
+	"flag"
+	"fmt"
+	"io/ioutil"
+	"os"
+	"reflect"
+	"sort"
+	"testing"
+
+	flatbuffers "github.com/google/flatbuffers/go"
+)
+
+var (
+	cppData, javaData, outData string
+	fuzz                       bool
+	fuzzFields, fuzzObjects    int
+)
+
+func init() {
+	flag.StringVar(&cppData, "cpp_data", "",
+		"location of monsterdata_test.mon to verify against (required)")
+	flag.StringVar(&javaData, "java_data", "",
+		"location of monsterdata_java_wire.mon to verify against (optional)")
+	flag.StringVar(&outData, "out_data", "",
+		"location to write generated Go data")
+	flag.BoolVar(&fuzz, "fuzz", false, "perform fuzzing")
+	flag.IntVar(&fuzzFields, "fuzz_fields", 4, "fields per fuzzer object")
+	flag.IntVar(&fuzzObjects, "fuzz_objects", 10000,
+		"number of fuzzer objects (higher is slower and more thorough")
+	flag.Parse()
+
+	if cppData == "" {
+		fmt.Fprintf(os.Stderr, "cpp_data argument is required\n")
+		os.Exit(1)
+	}
+}
+
+// Store specific byte patterns in these variables for the fuzzer. These
+// values are taken verbatim from the C++ function FuzzTest1.
+var (
+	overflowingInt32Val = flatbuffers.GetInt32([]byte{0x83, 0x33, 0x33, 0x33})
+	overflowingInt64Val = flatbuffers.GetInt64([]byte{0x84, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44})
+)
+
+// TestAll runs all checks, failing if any errors occur.
+func TestAll(t *testing.T) {
+	// Verify that the Go FlatBuffers runtime library generates the
+	// expected bytes (does not use any schema):
+	CheckByteLayout(t.Fatalf)
+	CheckMutateMethods(t.Fatalf)
+
+	// Verify that panics are raised during exceptional conditions:
+	CheckNotInObjectError(t.Fatalf)
+	CheckStringIsNestedError(t.Fatalf)
+	CheckByteStringIsNestedError(t.Fatalf)
+	CheckStructIsNotInlineError(t.Fatalf)
+	CheckFinishedBytesError(t.Fatalf)
+
+	// Verify that GetRootAs works for non-root tables
+	CheckGetRootAsForNonRootTable(t.Fatalf)
+	CheckTableAccessors(t.Fatalf)
+
+	// Verify that using the generated Go code builds a buffer without
+	// returning errors:
+	generated, off := CheckGeneratedBuild(t.Fatalf)
+
+	// Verify that the buffer generated by Go code is readable by the
+	// generated Go code:
+	CheckReadBuffer(generated, off, t.Fatalf)
+	CheckMutateBuffer(generated, off, t.Fatalf)
+
+	// Verify that the buffer generated by C++ code is readable by the
+	// generated Go code:
+	monsterDataCpp, err := ioutil.ReadFile(cppData)
+	if err != nil {
+		t.Fatal(err)
+	}
+	CheckReadBuffer(monsterDataCpp, 0, t.Fatalf)
+	CheckMutateBuffer(monsterDataCpp, 0, t.Fatalf)
+
+	// Verify that vtables are deduplicated when written:
+	CheckVtableDeduplication(t.Fatalf)
+
+	// Verify the enum names
+	CheckEnumNames(t.Fatalf)
+
+	// Verify enum String methods
+	CheckEnumString(t.Fatalf)
+
+	// Verify the enum values maps
+	CheckEnumValues(t.Fatalf)
+
+	// Verify that the Go code used in FlatBuffers documentation passes
+	// some sanity checks:
+	CheckDocExample(generated, off, t.Fatalf)
+
+	// Check Builder.CreateByteVector
+	CheckCreateByteVector(t.Fatalf)
+
+	// Check a parent namespace import
+	CheckParentNamespace(t.Fatalf)
+
+	// If the filename of the FlatBuffers file generated by the Java test
+	// is given, check that Go code can read it, and that Go code
+	// generates an identical buffer when used to create the example data:
+	if javaData != "" {
+		monsterDataJava, err := ioutil.ReadFile(javaData)
+		if err != nil {
+			t.Fatal(err)
+		}
+		CheckReadBuffer(monsterDataJava, 0, t.Fatalf)
+		CheckByteEquality(generated[off:], monsterDataJava, t.Fatalf)
+	}
+
+	// Verify that various fuzzing scenarios produce a valid FlatBuffer.
+	if fuzz {
+		checkFuzz(fuzzFields, fuzzObjects, t.Fatalf)
+	}
+
+	// Write the generated buffer out to a file:
+	err = ioutil.WriteFile(outData, generated[off:], os.FileMode(0644))
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+// CheckReadBuffer checks that the given buffer is evaluated correctly
+// as the example Monster.
+func CheckReadBuffer(buf []byte, offset flatbuffers.UOffsetT, fail func(string, ...interface{})) {
+	// try the two ways of generating a monster
+	monster1 := example.GetRootAsMonster(buf, offset)
+	monster2 := &example.Monster{}
+	flatbuffers.GetRootAs(buf, offset, monster2)
+	for _, monster := range []*example.Monster{monster1, monster2} {
+		if got := monster.Hp(); 80 != got {
+			fail(FailString("hp", 80, got))
+		}
+
+		// default
+		if got := monster.Mana(); 150 != got {
+			fail(FailString("mana", 150, got))
+		}
+
+		if got := monster.Name(); !bytes.Equal([]byte("MyMonster"), got) {
+			fail(FailString("name", "MyMonster", got))
+		}
+
+		if got := monster.Color(); example.ColorBlue != got {
+			fail(FailString("color", example.ColorBlue, got))
+		}
+
+		if got := monster.Testbool(); true != got {
+			fail(FailString("testbool", true, got))
+		}
+
+		// initialize a Vec3 from Pos()
+		vec := new(example.Vec3)
+		vec = monster.Pos(vec)
+		if vec == nil {
+			fail("vec3 initialization failed")
+		}
+
+		// check that new allocs equal given ones:
+		vec2 := monster.Pos(nil)
+		if !reflect.DeepEqual(vec, vec2) {
+			fail("fresh allocation failed")
+		}
+
+		// verify the properties of the Vec3
+		if got := vec.X(); float32(1.0) != got {
+			fail(FailString("Pos.X", float32(1.0), got))
+		}
+
+		if got := vec.Y(); float32(2.0) != got {
+			fail(FailString("Pos.Y", float32(2.0), got))
+		}
+
+		if got := vec.Z(); float32(3.0) != got {
+			fail(FailString("Pos.Z", float32(3.0), got))
+		}
+
+		if got := vec.Test1(); float64(3.0) != got {
+			fail(FailString("Pos.Test1", float64(3.0), got))
+		}
+
+		if got := vec.Test2(); example.ColorGreen != got {
+			fail(FailString("Pos.Test2", example.ColorGreen, got))
+		}
+
+		// initialize a Test from Test3(...)
+		t := new(example.Test)
+		t = vec.Test3(t)
+		if t == nil {
+			fail("vec.Test3(&t) failed")
+		}
+
+		// check that new allocs equal given ones:
+		t2 := vec.Test3(nil)
+		if !reflect.DeepEqual(t, t2) {
+			fail("fresh allocation failed")
+		}
+
+		// verify the properties of the Test
+		if got := t.A(); int16(5) != got {
+			fail(FailString("t.A()", int16(5), got))
+		}
+
+		if got := t.B(); int8(6) != got {
+			fail(FailString("t.B()", int8(6), got))
+		}
+
+		if got := monster.TestType(); example.AnyMonster != got {
+			fail(FailString("monster.TestType()", example.AnyMonster, got))
+		}
+
+		// initialize a Table from a union field Test(...)
+		var table2 flatbuffers.Table
+		if ok := monster.Test(&table2); !ok {
+			fail("monster.Test(&monster2) failed")
+		}
+
+		// initialize a Monster from the Table from the union
+		var monster2 example.Monster
+		monster2.Init(table2.Bytes, table2.Pos)
+
+		if got := monster2.Name(); !bytes.Equal([]byte("Fred"), got) {
+			fail(FailString("monster2.Name()", "Fred", got))
+		}
+
+		inventorySlice := monster.InventoryBytes()
+		if len(inventorySlice) != monster.InventoryLength() {
+			fail(FailString("len(monster.InventoryBytes) != monster.InventoryLength", len(inventorySlice), monster.InventoryLength()))
+		}
+
+		if got := monster.InventoryLength(); 5 != got {
+			fail(FailString("monster.InventoryLength", 5, got))
+		}
+
+		invsum := 0
+		l := monster.InventoryLength()
+		for i := 0; i < l; i++ {
+			v := monster.Inventory(i)
+			if v != inventorySlice[i] {
+				fail(FailString("monster inventory slice[i] != Inventory(i)", v, inventorySlice[i]))
+			}
+			invsum += int(v)
+		}
+		if invsum != 10 {
+			fail(FailString("monster inventory sum", 10, invsum))
+		}
+
+		if got := monster.Test4Length(); 2 != got {
+			fail(FailString("monster.Test4Length()", 2, got))
+		}
+
+		var test0 example.Test
+		ok := monster.Test4(&test0, 0)
+		if !ok {
+			fail(FailString("monster.Test4(&test0, 0)", true, ok))
+		}
+
+		var test1 example.Test
+		ok = monster.Test4(&test1, 1)
+		if !ok {
+			fail(FailString("monster.Test4(&test1, 1)", true, ok))
+		}
+
+		// the position of test0 and test1 are swapped in monsterdata_java_wire
+		// and monsterdata_test_wire, so ignore ordering
+		v0 := test0.A()
+		v1 := test0.B()
+		v2 := test1.A()
+		v3 := test1.B()
+		sum := int(v0) + int(v1) + int(v2) + int(v3)
+
+		if 100 != sum {
+			fail(FailString("test0 and test1 sum", 100, sum))
+		}
+
+		if got := monster.TestarrayofstringLength(); 2 != got {
+			fail(FailString("Testarrayofstring length", 2, got))
+		}
+
+		if got := monster.Testarrayofstring(0); !bytes.Equal([]byte("test1"), got) {
+			fail(FailString("Testarrayofstring(0)", "test1", got))
+		}
+
+		if got := monster.Testarrayofstring(1); !bytes.Equal([]byte("test2"), got) {
+			fail(FailString("Testarrayofstring(1)", "test2", got))
+		}
+	}
+}
+
+// CheckMutateBuffer checks that the given buffer can be mutated correctly
+// as the example Monster. Only available scalar values are mutated.
+func CheckMutateBuffer(org []byte, offset flatbuffers.UOffsetT, fail func(string, ...interface{})) {
+	// make a copy to mutate
+	buf := make([]byte, len(org))
+	copy(buf, org)
+
+	// load monster data from the buffer
+	monster := example.GetRootAsMonster(buf, offset)
+
+	// test case struct
+	type testcase struct {
+		field  string
+		testfn func() bool
+	}
+
+	testForOriginalValues := []testcase{
+		testcase{"Hp", func() bool { return monster.Hp() == 80 }},
+		testcase{"Mana", func() bool { return monster.Mana() == 150 }},
+		testcase{"Testbool", func() bool { return monster.Testbool() == true }},
+		testcase{"Pos.X'", func() bool { return monster.Pos(nil).X() == float32(1.0) }},
+		testcase{"Pos.Y'", func() bool { return monster.Pos(nil).Y() == float32(2.0) }},
+		testcase{"Pos.Z'", func() bool { return monster.Pos(nil).Z() == float32(3.0) }},
+		testcase{"Pos.Test1'", func() bool { return monster.Pos(nil).Test1() == float64(3.0) }},
+		testcase{"Pos.Test2'", func() bool { return monster.Pos(nil).Test2() == example.ColorGreen }},
+		testcase{"Pos.Test3.A", func() bool { return monster.Pos(nil).Test3(nil).A() == int16(5) }},
+		testcase{"Pos.Test3.B", func() bool { return monster.Pos(nil).Test3(nil).B() == int8(6) }},
+		testcase{"Inventory[2]", func() bool { return monster.Inventory(2) == byte(2) }},
+	}
+
+	testMutability := []testcase{
+		testcase{"Hp", func() bool { return monster.MutateHp(70) }},
+		testcase{"Mana", func() bool { return !monster.MutateMana(140) }},
+		testcase{"Testbool", func() bool { return monster.MutateTestbool(false) }},
+		testcase{"Pos.X", func() bool { return monster.Pos(nil).MutateX(10.0) }},
+		testcase{"Pos.Y", func() bool { return monster.Pos(nil).MutateY(20.0) }},
+		testcase{"Pos.Z", func() bool { return monster.Pos(nil).MutateZ(30.0) }},
+		testcase{"Pos.Test1", func() bool { return monster.Pos(nil).MutateTest1(30.0) }},
+		testcase{"Pos.Test2", func() bool { return monster.Pos(nil).MutateTest2(example.ColorBlue) }},
+		testcase{"Pos.Test3.A", func() bool { return monster.Pos(nil).Test3(nil).MutateA(50) }},
+		testcase{"Pos.Test3.B", func() bool { return monster.Pos(nil).Test3(nil).MutateB(60) }},
+		testcase{"Inventory[2]", func() bool { return monster.MutateInventory(2, 200) }},
+	}
+
+	testForMutatedValues := []testcase{
+		testcase{"Hp", func() bool { return monster.Hp() == 70 }},
+		testcase{"Mana", func() bool { return monster.Mana() == 150 }},
+		testcase{"Testbool", func() bool { return monster.Testbool() == false }},
+		testcase{"Pos.X'", func() bool { return monster.Pos(nil).X() == float32(10.0) }},
+		testcase{"Pos.Y'", func() bool { return monster.Pos(nil).Y() == float32(20.0) }},
+		testcase{"Pos.Z'", func() bool { return monster.Pos(nil).Z() == float32(30.0) }},
+		testcase{"Pos.Test1'", func() bool { return monster.Pos(nil).Test1() == float64(30.0) }},
+		testcase{"Pos.Test2'", func() bool { return monster.Pos(nil).Test2() == example.ColorBlue }},
+		testcase{"Pos.Test3.A", func() bool { return monster.Pos(nil).Test3(nil).A() == int16(50) }},
+		testcase{"Pos.Test3.B", func() bool { return monster.Pos(nil).Test3(nil).B() == int8(60) }},
+		testcase{"Inventory[2]", func() bool { return monster.Inventory(2) == byte(200) }},
+	}
+
+	testInvalidEnumValues := []testcase{
+		testcase{"Pos.Test2", func() bool { return monster.Pos(nil).MutateTest2(example.Color(20)) }},
+		testcase{"Pos.Test2", func() bool { return monster.Pos(nil).Test2() == example.Color(20) }},
+	}
+
+	// make sure original values are okay
+	for _, t := range testForOriginalValues {
+		if !t.testfn() {
+			fail("field '" + t.field + "' doesn't have the expected original value")
+		}
+	}
+
+	// try to mutate fields and check mutability
+	for _, t := range testMutability {
+		if !t.testfn() {
+			fail(FailString("field '"+t.field+"' failed mutability test", true, false))
+		}
+	}
+
+	// test whether values have changed
+	for _, t := range testForMutatedValues {
+		if !t.testfn() {
+			fail("field '" + t.field + "' doesn't have the expected mutated value")
+		}
+	}
+
+	// make sure the buffer has changed
+	if reflect.DeepEqual(buf, org) {
+		fail("mutate buffer failed")
+	}
+
+	// To make sure the buffer has changed accordingly
+	// Read data from the buffer and verify all fields
+	monster = example.GetRootAsMonster(buf, offset)
+	for _, t := range testForMutatedValues {
+		if !t.testfn() {
+			fail("field '" + t.field + "' doesn't have the expected mutated value")
+		}
+	}
+
+	// a couple extra tests for "invalid" enum values, which don't correspond to
+	// anything in the schema, but are allowed
+	for _, t := range testInvalidEnumValues {
+		if !t.testfn() {
+			fail("field '" + t.field + "' doesn't work with an invalid enum value")
+		}
+	}
+
+	// reverting all fields to original values should
+	// re-create the original buffer. Mutate all fields
+	// back to their original values and compare buffers.
+	// This test is done to make sure mutations do not do
+	// any unnecessary changes to the buffer.
+	monster = example.GetRootAsMonster(buf, offset)
+	monster.MutateHp(80)
+	monster.MutateTestbool(true)
+	monster.Pos(nil).MutateX(1.0)
+	monster.Pos(nil).MutateY(2.0)
+	monster.Pos(nil).MutateZ(3.0)
+	monster.Pos(nil).MutateTest1(3.0)
+	monster.Pos(nil).MutateTest2(example.ColorGreen)
+	monster.Pos(nil).Test3(nil).MutateA(5)
+	monster.Pos(nil).Test3(nil).MutateB(6)
+	monster.MutateInventory(2, 2)
+
+	for _, t := range testForOriginalValues {
+		if !t.testfn() {
+			fail("field '" + t.field + "' doesn't have the expected original value")
+		}
+	}
+
+	// buffer should have original values
+	if !reflect.DeepEqual(buf, org) {
+		fail("revert changes failed")
+	}
+}
+
+// Low level stress/fuzz test: serialize/deserialize a variety of
+// different kinds of data in different combinations
+func checkFuzz(fuzzFields, fuzzObjects int, fail func(string, ...interface{})) {
+
+	// Values we're testing against: chosen to ensure no bits get chopped
+	// off anywhere, and also be different from eachother.
+	boolVal := true
+	int8Val := int8(-127) // 0x81
+	uint8Val := uint8(0xFF)
+	int16Val := int16(-32222) // 0x8222
+	uint16Val := uint16(0xFEEE)
+	int32Val := int32(overflowingInt32Val)
+	uint32Val := uint32(0xFDDDDDDD)
+	int64Val := int64(overflowingInt64Val)
+	uint64Val := uint64(0xFCCCCCCCCCCCCCCC)
+	float32Val := float32(3.14159)
+	float64Val := float64(3.14159265359)
+
+	testValuesMax := 11 // hardcoded to the number of scalar types
+
+	builder := flatbuffers.NewBuilder(0)
+	l := NewLCG()
+
+	objects := make([]flatbuffers.UOffsetT, fuzzObjects)
+
+	// Generate fuzzObjects random objects each consisting of
+	// fuzzFields fields, each of a random type.
+	for i := 0; i < fuzzObjects; i++ {
+		builder.StartObject(fuzzFields)
+
+		for f := 0; f < fuzzFields; f++ {
+			choice := l.Next() % uint32(testValuesMax)
+			switch choice {
+			case 0:
+				builder.PrependBoolSlot(int(f), boolVal, false)
+			case 1:
+				builder.PrependInt8Slot(int(f), int8Val, 0)
+			case 2:
+				builder.PrependUint8Slot(int(f), uint8Val, 0)
+			case 3:
+				builder.PrependInt16Slot(int(f), int16Val, 0)
+			case 4:
+				builder.PrependUint16Slot(int(f), uint16Val, 0)
+			case 5:
+				builder.PrependInt32Slot(int(f), int32Val, 0)
+			case 6:
+				builder.PrependUint32Slot(int(f), uint32Val, 0)
+			case 7:
+				builder.PrependInt64Slot(int(f), int64Val, 0)
+			case 8:
+				builder.PrependUint64Slot(int(f), uint64Val, 0)
+			case 9:
+				builder.PrependFloat32Slot(int(f), float32Val, 0)
+			case 10:
+				builder.PrependFloat64Slot(int(f), float64Val, 0)
+			}
+		}
+
+		off := builder.EndObject()
+
+		// store the offset from the end of the builder buffer,
+		// since it will keep growing:
+		objects[i] = off
+	}
+
+	// Do some bookkeeping to generate stats on fuzzes:
+	stats := map[string]int{}
+	check := func(desc string, want, got interface{}) {
+		stats[desc]++
+		if want != got {
+			fail("%s want %v got %v", desc, want, got)
+		}
+	}
+
+	l = NewLCG() // Reset.
+
+	// Test that all objects we generated are readable and return the
+	// expected values. We generate random objects in the same order
+	// so this is deterministic.
+	for i := 0; i < fuzzObjects; i++ {
+
+		table := &flatbuffers.Table{
+			Bytes: builder.Bytes,
+			Pos:   flatbuffers.UOffsetT(len(builder.Bytes)) - objects[i],
+		}
+
+		for j := 0; j < fuzzFields; j++ {
+			f := flatbuffers.VOffsetT((flatbuffers.VtableMetadataFields + j) * flatbuffers.SizeVOffsetT)
+			choice := l.Next() % uint32(testValuesMax)
+
+			switch choice {
+			case 0:
+				check("bool", boolVal, table.GetBoolSlot(f, false))
+			case 1:
+				check("int8", int8Val, table.GetInt8Slot(f, 0))
+			case 2:
+				check("uint8", uint8Val, table.GetUint8Slot(f, 0))
+			case 3:
+				check("int16", int16Val, table.GetInt16Slot(f, 0))
+			case 4:
+				check("uint16", uint16Val, table.GetUint16Slot(f, 0))
+			case 5:
+				check("int32", int32Val, table.GetInt32Slot(f, 0))
+			case 6:
+				check("uint32", uint32Val, table.GetUint32Slot(f, 0))
+			case 7:
+				check("int64", int64Val, table.GetInt64Slot(f, 0))
+			case 8:
+				check("uint64", uint64Val, table.GetUint64Slot(f, 0))
+			case 9:
+				check("float32", float32Val, table.GetFloat32Slot(f, 0))
+			case 10:
+				check("float64", float64Val, table.GetFloat64Slot(f, 0))
+			}
+		}
+	}
+
+	// If enough checks were made, verify that all scalar types were used:
+	if fuzzFields*fuzzObjects >= testValuesMax {
+		if len(stats) != testValuesMax {
+			fail("fuzzing failed to test all scalar types")
+		}
+	}
+
+	// Print some counts, if needed:
+	if testing.Verbose() {
+		if fuzzFields == 0 || fuzzObjects == 0 {
+			fmt.Printf("fuzz\tfields: %d\tobjects: %d\t[none]\t%d\n",
+				fuzzFields, fuzzObjects, 0)
+		} else {
+			keys := make([]string, 0, len(stats))
+			for k := range stats {
+				keys = append(keys, k)
+			}
+			sort.Strings(keys)
+			for _, k := range keys {
+				fmt.Printf("fuzz\tfields: %d\tobjects: %d\t%s\t%d\n",
+					fuzzFields, fuzzObjects, k, stats[k])
+			}
+		}
+	}
+
+	return
+}
+
+// FailString makes a message for when expectations differ from reality.
+func FailString(name string, want, got interface{}) string {
+	return fmt.Sprintf("bad %s: want %#v got %#v", name, want, got)
+}
+
+// CheckByteLayout verifies the bytes of a Builder in various scenarios.
+func CheckByteLayout(fail func(string, ...interface{})) {
+	var b *flatbuffers.Builder
+
+	var i int
+	check := func(want []byte) {
+		i++
+		got := b.Bytes[b.Head():]
+		if !bytes.Equal(want, got) {
+			fail("case %d: want\n%v\nbut got\n%v\n", i, want, got)
+		}
+	}
+
+	// test 1: numbers
+
+	b = flatbuffers.NewBuilder(0)
+	check([]byte{})
+	b.PrependBool(true)
+	check([]byte{1})
+	b.PrependInt8(-127)
+	check([]byte{129, 1})
+	b.PrependUint8(255)
+	check([]byte{255, 129, 1})
+	b.PrependInt16(-32222)
+	check([]byte{0x22, 0x82, 0, 255, 129, 1}) // first pad
+	b.PrependUint16(0xFEEE)
+	check([]byte{0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1}) // no pad this time
+	b.PrependInt32(-53687092)
+	check([]byte{204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1})
+	b.PrependUint32(0x98765432)
+	check([]byte{0x32, 0x54, 0x76, 0x98, 204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1})
+
+	// test 1b: numbers 2
+
+	b = flatbuffers.NewBuilder(0)
+	b.PrependUint64(0x1122334455667788)
+	check([]byte{0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11})
+
+	// test 2: 1xbyte vector
+
+	b = flatbuffers.NewBuilder(0)
+	check([]byte{})
+	b.StartVector(flatbuffers.SizeByte, 1, 1)
+	check([]byte{0, 0, 0}) // align to 4bytes
+	b.PrependByte(1)
+	check([]byte{1, 0, 0, 0})
+	b.EndVector(1)
+	check([]byte{1, 0, 0, 0, 1, 0, 0, 0}) // padding
+
+	// test 3: 2xbyte vector
+
+	b = flatbuffers.NewBuilder(0)
+	b.StartVector(flatbuffers.SizeByte, 2, 1)
+	check([]byte{0, 0}) // align to 4bytes
+	b.PrependByte(1)
+	check([]byte{1, 0, 0})
+	b.PrependByte(2)
+	check([]byte{2, 1, 0, 0})
+	b.EndVector(2)
+	check([]byte{2, 0, 0, 0, 2, 1, 0, 0}) // padding
+
+	// test 3b: 11xbyte vector matches builder size
+
+	b = flatbuffers.NewBuilder(12)
+	b.StartVector(flatbuffers.SizeByte, 8, 1)
+	start := []byte{}
+	check(start)
+	for i := 1; i < 12; i++ {
+		b.PrependByte(byte(i))
+		start = append([]byte{byte(i)}, start...)
+		check(start)
+	}
+	b.EndVector(8)
+	check(append([]byte{8, 0, 0, 0}, start...))
+
+	// test 4: 1xuint16 vector
+
+	b = flatbuffers.NewBuilder(0)
+	b.StartVector(flatbuffers.SizeUint16, 1, 1)
+	check([]byte{0, 0}) // align to 4bytes
+	b.PrependUint16(1)
+	check([]byte{1, 0, 0, 0})
+	b.EndVector(1)
+	check([]byte{1, 0, 0, 0, 1, 0, 0, 0}) // padding
+
+	// test 5: 2xuint16 vector
+
+	b = flatbuffers.NewBuilder(0)
+	b.StartVector(flatbuffers.SizeUint16, 2, 1)
+	check([]byte{}) // align to 4bytes
+	b.PrependUint16(0xABCD)
+	check([]byte{0xCD, 0xAB})
+	b.PrependUint16(0xDCBA)
+	check([]byte{0xBA, 0xDC, 0xCD, 0xAB})
+	b.EndVector(2)
+	check([]byte{2, 0, 0, 0, 0xBA, 0xDC, 0xCD, 0xAB})
+
+	// test 6: CreateString
+
+	b = flatbuffers.NewBuilder(0)
+	b.CreateString("foo")
+	check([]byte{3, 0, 0, 0, 'f', 'o', 'o', 0}) // 0-terminated, no pad
+	b.CreateString("moop")
+	check([]byte{4, 0, 0, 0, 'm', 'o', 'o', 'p', 0, 0, 0, 0, // 0-terminated, 3-byte pad
+		3, 0, 0, 0, 'f', 'o', 'o', 0})
+
+	// test 6b: CreateString unicode
+
+	b = flatbuffers.NewBuilder(0)
+	// These characters are chinese from blog.golang.org/strings
+	// We use escape codes here so that editors without unicode support
+	// aren't bothered:
+	uni_str := "\u65e5\u672c\u8a9e"
+	b.CreateString(uni_str)
+	check([]byte{9, 0, 0, 0, 230, 151, 165, 230, 156, 172, 232, 170, 158, 0, //  null-terminated, 2-byte pad
+		0, 0})
+
+	// test 6c: CreateByteString
+
+	b = flatbuffers.NewBuilder(0)
+	b.CreateByteString([]byte("foo"))
+	check([]byte{3, 0, 0, 0, 'f', 'o', 'o', 0}) // 0-terminated, no pad
+	b.CreateByteString([]byte("moop"))
+	check([]byte{4, 0, 0, 0, 'm', 'o', 'o', 'p', 0, 0, 0, 0, // 0-terminated, 3-byte pad
+		3, 0, 0, 0, 'f', 'o', 'o', 0})
+
+	// test 7: empty vtable
+	b = flatbuffers.NewBuilder(0)
+	b.StartObject(0)
+	check([]byte{})
+	b.EndObject()
+	check([]byte{4, 0, 4, 0, 4, 0, 0, 0})
+
+	// test 8: vtable with one true bool
+	b = flatbuffers.NewBuilder(0)
+	check([]byte{})
+	b.StartObject(1)
+	check([]byte{})
+	b.PrependBoolSlot(0, true, false)
+	b.EndObject()
+	check([]byte{
+		6, 0, // vtable bytes
+		8, 0, // length of object including vtable offset
+		7, 0, // start of bool value
+		6, 0, 0, 0, // offset for start of vtable (int32)
+		0, 0, 0, // padded to 4 bytes
+		1, // bool value
+	})
+
+	// test 9: vtable with one default bool
+	b = flatbuffers.NewBuilder(0)
+	check([]byte{})
+	b.StartObject(1)
+	check([]byte{})
+	b.PrependBoolSlot(0, false, false)
+	b.EndObject()
+	check([]byte{
+		4, 0, // vtable bytes
+		4, 0, // end of object from here
+		// entry 1 is zero and not stored.
+		4, 0, 0, 0, // offset for start of vtable (int32)
+	})
+
+	// test 10: vtable with one int16
+	b = flatbuffers.NewBuilder(0)
+	b.StartObject(1)
+	b.PrependInt16Slot(0, 0x789A, 0)
+	b.EndObject()
+	check([]byte{
+		6, 0, // vtable bytes
+		8, 0, // end of object from here
+		6, 0, // offset to value
+		6, 0, 0, 0, // offset for start of vtable (int32)
+		0, 0, // padding to 4 bytes
+		0x9A, 0x78,
+	})
+
+	// test 11: vtable with two int16
+	b = flatbuffers.NewBuilder(0)
+	b.StartObject(2)
+	b.PrependInt16Slot(0, 0x3456, 0)
+	b.PrependInt16Slot(1, 0x789A, 0)
+	b.EndObject()
+	check([]byte{
+		8, 0, // vtable bytes
+		8, 0, // end of object from here
+		6, 0, // offset to value 0
+		4, 0, // offset to value 1
+		8, 0, 0, 0, // offset for start of vtable (int32)
+		0x9A, 0x78, // value 1
+		0x56, 0x34, // value 0
+	})
+
+	// test 12: vtable with int16 and bool
+	b = flatbuffers.NewBuilder(0)
+	b.StartObject(2)
+	b.PrependInt16Slot(0, 0x3456, 0)
+	b.PrependBoolSlot(1, true, false)
+	b.EndObject()
+	check([]byte{
+		8, 0, // vtable bytes
+		8, 0, // end of object from here
+		6, 0, // offset to value 0
+		5, 0, // offset to value 1
+		8, 0, 0, 0, // offset for start of vtable (int32)
+		0,          // padding
+		1,          // value 1
+		0x56, 0x34, // value 0
+	})
+
+	// test 12: vtable with empty vector
+	b = flatbuffers.NewBuilder(0)
+	b.StartVector(flatbuffers.SizeByte, 0, 1)
+	vecend := b.EndVector(0)
+	b.StartObject(1)
+	b.PrependUOffsetTSlot(0, vecend, 0)
+	b.EndObject()
+	check([]byte{
+		6, 0, // vtable bytes
+		8, 0,
+		4, 0, // offset to vector offset
+		6, 0, 0, 0, // offset for start of vtable (int32)
+		4, 0, 0, 0,
+		0, 0, 0, 0, // length of vector (not in struct)
+	})
+
+	// test 12b: vtable with empty vector of byte and some scalars
+	b = flatbuffers.NewBuilder(0)
+	b.StartVector(flatbuffers.SizeByte, 0, 1)
+	vecend = b.EndVector(0)
+	b.StartObject(2)
+	b.PrependInt16Slot(0, 55, 0)
+	b.PrependUOffsetTSlot(1, vecend, 0)
+	b.EndObject()
+	check([]byte{
+		8, 0, // vtable bytes
+		12, 0,
+		10, 0, // offset to value 0
+		4, 0, // offset to vector offset
+		8, 0, 0, 0, // vtable loc
+		8, 0, 0, 0, // value 1
+		0, 0, 55, 0, // value 0
+
+		0, 0, 0, 0, // length of vector (not in struct)
+	})
+
+	// test 13: vtable with 1 int16 and 2-vector of int16
+	b = flatbuffers.NewBuilder(0)
+	b.StartVector(flatbuffers.SizeInt16, 2, 1)
+	b.PrependInt16(0x1234)
+	b.PrependInt16(0x5678)
+	vecend = b.EndVector(2)
+	b.StartObject(2)
+	b.PrependUOffsetTSlot(1, vecend, 0)
+	b.PrependInt16Slot(0, 55, 0)
+	b.EndObject()
+	check([]byte{
+		8, 0, // vtable bytes
+		12, 0, // length of object
+		6, 0, // start of value 0 from end of vtable
+		8, 0, // start of value 1 from end of buffer
+		8, 0, 0, 0, // offset for start of vtable (int32)
+		0, 0, // padding
+		55, 0, // value 0
+		4, 0, 0, 0, // vector position from here
+		2, 0, 0, 0, // length of vector (uint32)
+		0x78, 0x56, // vector value 1
+		0x34, 0x12, // vector value 0
+	})
+
+	// test 14: vtable with 1 struct of 1 int8, 1 int16, 1 int32
+	b = flatbuffers.NewBuilder(0)
+	b.StartObject(1)
+	b.Prep(4+4+4, 0)
+	b.PrependInt8(55)
+	b.Pad(3)
+	b.PrependInt16(0x1234)
+	b.Pad(2)
+	b.PrependInt32(0x12345678)
+	structStart := b.Offset()
+	b.PrependStructSlot(0, structStart, 0)
+	b.EndObject()
+	check([]byte{
+		6, 0, // vtable bytes
+		16, 0, // end of object from here
+		4, 0, // start of struct from here
+		6, 0, 0, 0, // offset for start of vtable (int32)
+		0x78, 0x56, 0x34, 0x12, // value 2
+		0, 0, // padding
+		0x34, 0x12, // value 1
+		0, 0, 0, // padding
+		55, // value 0
+	})
+
+	// test 15: vtable with 1 vector of 2 struct of 2 int8
+	b = flatbuffers.NewBuilder(0)
+	b.StartVector(flatbuffers.SizeInt8*2, 2, 1)
+	b.PrependInt8(33)
+	b.PrependInt8(44)
+	b.PrependInt8(55)
+	b.PrependInt8(66)
+	vecend = b.EndVector(2)
+	b.StartObject(1)
+	b.PrependUOffsetTSlot(0, vecend, 0)
+	b.EndObject()
+	check([]byte{
+		6, 0, // vtable bytes
+		8, 0,
+		4, 0, // offset of vector offset
+		6, 0, 0, 0, // offset for start of vtable (int32)
+		4, 0, 0, 0, // vector start offset
+
+		2, 0, 0, 0, // vector length
+		66, // vector value 1,1
+		55, // vector value 1,0
+		44, // vector value 0,1
+		33, // vector value 0,0
+	})
+
+	// test 16: table with some elements
+	b = flatbuffers.NewBuilder(0)
+	b.StartObject(2)
+	b.PrependInt8Slot(0, 33, 0)
+	b.PrependInt16Slot(1, 66, 0)
+	off := b.EndObject()
+	b.Finish(off)
+
+	check([]byte{
+		12, 0, 0, 0, // root of table: points to vtable offset
+
+		8, 0, // vtable bytes
+		8, 0, // end of object from here
+		7, 0, // start of value 0
+		4, 0, // start of value 1
+
+		8, 0, 0, 0, // offset for start of vtable (int32)
+
+		66, 0, // value 1
+		0,  // padding
+		33, // value 0
+	})
+
+	// test 17: one unfinished table and one finished table
+	b = flatbuffers.NewBuilder(0)
+	b.StartObject(2)
+	b.PrependInt8Slot(0, 33, 0)
+	b.PrependInt8Slot(1, 44, 0)
+	off = b.EndObject()
+	b.Finish(off)
+
+	b.StartObject(3)
+	b.PrependInt8Slot(0, 55, 0)
+	b.PrependInt8Slot(1, 66, 0)
+	b.PrependInt8Slot(2, 77, 0)
+	off = b.EndObject()
+	b.Finish(off)
+
+	check([]byte{
+		16, 0, 0, 0, // root of table: points to object
+		0, 0, // padding
+
+		10, 0, // vtable bytes
+		8, 0, // size of object
+		7, 0, // start of value 0
+		6, 0, // start of value 1
+		5, 0, // start of value 2
+		10, 0, 0, 0, // offset for start of vtable (int32)
+		0,  // padding
+		77, // value 2
+		66, // value 1
+		55, // value 0
+
+		12, 0, 0, 0, // root of table: points to object
+
+		8, 0, // vtable bytes
+		8, 0, // size of object
+		7, 0, // start of value 0
+		6, 0, // start of value 1
+		8, 0, 0, 0, // offset for start of vtable (int32)
+		0, 0, // padding
+		44, // value 1
+		33, // value 0
+	})
+
+	// test 18: a bunch of bools
+	b = flatbuffers.NewBuilder(0)
+	b.StartObject(8)
+	b.PrependBoolSlot(0, true, false)
+	b.PrependBoolSlot(1, true, false)
+	b.PrependBoolSlot(2, true, false)
+	b.PrependBoolSlot(3, true, false)
+	b.PrependBoolSlot(4, true, false)
+	b.PrependBoolSlot(5, true, false)
+	b.PrependBoolSlot(6, true, false)
+	b.PrependBoolSlot(7, true, false)
+	off = b.EndObject()
+	b.Finish(off)
+
+	check([]byte{
+		24, 0, 0, 0, // root of table: points to vtable offset
+
+		20, 0, // vtable bytes
+		12, 0, // size of object
+		11, 0, // start of value 0
+		10, 0, // start of value 1
+		9, 0, // start of value 2
+		8, 0, // start of value 3
+		7, 0, // start of value 4
+		6, 0, // start of value 5
+		5, 0, // start of value 6
+		4, 0, // start of value 7
+		20, 0, 0, 0, // vtable offset
+
+		1, // value 7
+		1, // value 6
+		1, // value 5
+		1, // value 4
+		1, // value 3
+		1, // value 2
+		1, // value 1
+		1, // value 0
+	})
+
+	// test 19: three bools
+	b = flatbuffers.NewBuilder(0)
+	b.StartObject(3)
+	b.PrependBoolSlot(0, true, false)
+	b.PrependBoolSlot(1, true, false)
+	b.PrependBoolSlot(2, true, false)
+	off = b.EndObject()
+	b.Finish(off)
+
+	check([]byte{
+		16, 0, 0, 0, // root of table: points to vtable offset
+
+		0, 0, // padding
+
+		10, 0, // vtable bytes
+		8, 0, // size of object
+		7, 0, // start of value 0
+		6, 0, // start of value 1
+		5, 0, // start of value 2
+		10, 0, 0, 0, // vtable offset from here
+
+		0, // padding
+		1, // value 2
+		1, // value 1
+		1, // value 0
+	})
+
+	// test 20: some floats
+	b = flatbuffers.NewBuilder(0)
+	b.StartObject(1)
+	b.PrependFloat32Slot(0, 1.0, 0.0)
+	off = b.EndObject()
+
+	check([]byte{
+		6, 0, // vtable bytes
+		8, 0, // size of object
+		4, 0, // start of value 0
+		6, 0, 0, 0, // vtable offset
+
+		0, 0, 128, 63, // value 0
+	})
+}
+
+// CheckManualBuild builds a Monster manually.
+func CheckManualBuild(fail func(string, ...interface{})) ([]byte, flatbuffers.UOffsetT) {
+	b := flatbuffers.NewBuilder(0)
+	str := b.CreateString("MyMonster")
+
+	b.StartVector(1, 5, 1)
+	b.PrependByte(4)
+	b.PrependByte(3)
+	b.PrependByte(2)
+	b.PrependByte(1)
+	b.PrependByte(0)
+	inv := b.EndVector(5)
+
+	b.StartObject(13)
+	b.PrependInt16Slot(2, 20, 100)
+	mon2 := b.EndObject()
+
+	// Test4Vector
+	b.StartVector(4, 2, 1)
+
+	// Test 0
+	b.Prep(2, 4)
+	b.Pad(1)
+	b.PlaceInt8(20)
+	b.PlaceInt16(10)
+
+	// Test 1
+	b.Prep(2, 4)
+	b.Pad(1)
+	b.PlaceInt8(40)
+	b.PlaceInt16(30)
+
+	// end testvector
+	test4 := b.EndVector(2)
+
+	b.StartObject(13)
+
+	// a vec3
+	b.Prep(16, 32)
+	b.Pad(2)
+	b.Prep(2, 4)
+	b.Pad(1)
+	b.PlaceByte(6)
+	b.PlaceInt16(5)
+	b.Pad(1)
+	b.PlaceByte(4)
+	b.PlaceFloat64(3.0)
+	b.Pad(4)
+	b.PlaceFloat32(3.0)
+	b.PlaceFloat32(2.0)
+	b.PlaceFloat32(1.0)
+	vec3Loc := b.Offset()
+	// end vec3
+
+	b.PrependStructSlot(0, vec3Loc, 0) // vec3. noop
+	b.PrependInt16Slot(2, 80, 100)     // hp
+	b.PrependUOffsetTSlot(3, str, 0)
+	b.PrependUOffsetTSlot(5, inv, 0) // inventory
+	b.PrependByteSlot(7, 1, 0)
+	b.PrependUOffsetTSlot(8, mon2, 0)
+	b.PrependUOffsetTSlot(9, test4, 0)
+	mon := b.EndObject()
+
+	b.Finish(mon)
+
+	return b.Bytes, b.Head()
+}
+
+func CheckGetRootAsForNonRootTable(fail func(string, ...interface{})) {
+	b := flatbuffers.NewBuilder(0)
+	str := b.CreateString("MyStat")
+	example.StatStart(b)
+	example.StatAddId(b, str)
+	example.StatAddVal(b, 12345678)
+	example.StatAddCount(b, 12345)
+	stat_end := example.StatEnd(b)
+	b.Finish(stat_end)
+
+	stat := example.GetRootAsStat(b.Bytes, b.Head())
+
+	if got := stat.Id(); !bytes.Equal([]byte("MyStat"), got) {
+		fail(FailString("stat.Id()", "MyStat", got))
+	}
+
+	if got := stat.Val(); 12345678 != got {
+		fail(FailString("stat.Val()", 12345678, got))
+	}
+
+	if got := stat.Count(); 12345 != got {
+		fail(FailString("stat.Count()", 12345, got))
+	}
+}
+
+// CheckGeneratedBuild uses generated code to build the example Monster.
+func CheckGeneratedBuild(fail func(string, ...interface{})) ([]byte, flatbuffers.UOffsetT) {
+	b := flatbuffers.NewBuilder(0)
+	str := b.CreateString("MyMonster")
+	test1 := b.CreateString("test1")
+	test2 := b.CreateString("test2")
+	fred := b.CreateString("Fred")
+
+	example.MonsterStartInventoryVector(b, 5)
+	b.PrependByte(4)
+	b.PrependByte(3)
+	b.PrependByte(2)
+	b.PrependByte(1)
+	b.PrependByte(0)
+	inv := b.EndVector(5)
+
+	example.MonsterStart(b)
+	example.MonsterAddName(b, fred)
+	mon2 := example.MonsterEnd(b)
+
+	example.MonsterStartTest4Vector(b, 2)
+	example.CreateTest(b, 10, 20)
+	example.CreateTest(b, 30, 40)
+	test4 := b.EndVector(2)
+
+	example.MonsterStartTestarrayofstringVector(b, 2)
+	b.PrependUOffsetT(test2)
+	b.PrependUOffsetT(test1)
+	testArrayOfString := b.EndVector(2)
+
+	example.MonsterStart(b)
+
+	pos := example.CreateVec3(b, 1.0, 2.0, 3.0, 3.0, example.ColorGreen, 5, 6)
+	example.MonsterAddPos(b, pos)
+
+	example.MonsterAddHp(b, 80)
+	example.MonsterAddName(b, str)
+	example.MonsterAddTestbool(b, true)
+	example.MonsterAddInventory(b, inv)
+	example.MonsterAddTestType(b, 1)
+	example.MonsterAddTest(b, mon2)
+	example.MonsterAddTest4(b, test4)
+	example.MonsterAddTestarrayofstring(b, testArrayOfString)
+	mon := example.MonsterEnd(b)
+
+	b.Finish(mon)
+
+	return b.Bytes, b.Head()
+}
+
+// CheckTableAccessors checks that the table accessors work as expected.
+func CheckTableAccessors(fail func(string, ...interface{})) {
+	// test struct accessor
+	b := flatbuffers.NewBuilder(0)
+	pos := example.CreateVec3(b, 1.0, 2.0, 3.0, 3.0, 4, 5, 6)
+	b.Finish(pos)
+	vec3Bytes := b.FinishedBytes()
+	vec3 := &example.Vec3{}
+	flatbuffers.GetRootAs(vec3Bytes, 0, vec3)
+
+	if bytes.Compare(vec3Bytes, vec3.Table().Bytes) != 0 {
+		fail("invalid vec3 table")
+	}
+
+	// test table accessor
+	b = flatbuffers.NewBuilder(0)
+	str := b.CreateString("MyStat")
+	example.StatStart(b)
+	example.StatAddId(b, str)
+	example.StatAddVal(b, 12345678)
+	example.StatAddCount(b, 12345)
+	pos = example.StatEnd(b)
+	b.Finish(pos)
+	statBytes := b.FinishedBytes()
+	stat := &example.Stat{}
+	flatbuffers.GetRootAs(statBytes, 0, stat)
+
+	if bytes.Compare(statBytes, stat.Table().Bytes) != 0 {
+		fail("invalid stat table")
+	}
+}
+
+// CheckVtableDeduplication verifies that vtables are deduplicated.
+func CheckVtableDeduplication(fail func(string, ...interface{})) {
+	b := flatbuffers.NewBuilder(0)
+
+	b.StartObject(4)
+	b.PrependByteSlot(0, 0, 0)
+	b.PrependByteSlot(1, 11, 0)
+	b.PrependByteSlot(2, 22, 0)
+	b.PrependInt16Slot(3, 33, 0)
+	obj0 := b.EndObject()
+
+	b.StartObject(4)
+	b.PrependByteSlot(0, 0, 0)
+	b.PrependByteSlot(1, 44, 0)
+	b.PrependByteSlot(2, 55, 0)
+	b.PrependInt16Slot(3, 66, 0)
+	obj1 := b.EndObject()
+
+	b.StartObject(4)
+	b.PrependByteSlot(0, 0, 0)
+	b.PrependByteSlot(1, 77, 0)
+	b.PrependByteSlot(2, 88, 0)
+	b.PrependInt16Slot(3, 99, 0)
+	obj2 := b.EndObject()
+
+	got := b.Bytes[b.Head():]
+
+	want := []byte{
+		240, 255, 255, 255, // == -12. offset to dedupped vtable.
+		99, 0,
+		88,
+		77,
+		248, 255, 255, 255, // == -8. offset to dedupped vtable.
+		66, 0,
+		55,
+		44,
+		12, 0,
+		8, 0,
+		0, 0,
+		7, 0,
+		6, 0,
+		4, 0,
+		12, 0, 0, 0,
+		33, 0,
+		22,
+		11,
+	}
+
+	if !bytes.Equal(want, got) {
+		fail("testVtableDeduplication want:\n%d %v\nbut got:\n%d %v\n",
+			len(want), want, len(got), got)
+	}
+
+	table0 := &flatbuffers.Table{Bytes: b.Bytes, Pos: flatbuffers.UOffsetT(len(b.Bytes)) - obj0}
+	table1 := &flatbuffers.Table{Bytes: b.Bytes, Pos: flatbuffers.UOffsetT(len(b.Bytes)) - obj1}
+	table2 := &flatbuffers.Table{Bytes: b.Bytes, Pos: flatbuffers.UOffsetT(len(b.Bytes)) - obj2}
+
+	testTable := func(tab *flatbuffers.Table, a flatbuffers.VOffsetT, b, c, d byte) {
+		// vtable size
+		if got := tab.GetVOffsetTSlot(0, 0); 12 != got {
+			fail("failed 0, 0: %d", got)
+		}
+		// object size
+		if got := tab.GetVOffsetTSlot(2, 0); 8 != got {
+			fail("failed 2, 0: %d", got)
+		}
+		// default value
+		if got := tab.GetVOffsetTSlot(4, 0); a != got {
+			fail("failed 4, 0: %d", got)
+		}
+		if got := tab.GetByteSlot(6, 0); b != got {
+			fail("failed 6, 0: %d", got)
+		}
+		if val := tab.GetByteSlot(8, 0); c != val {
+			fail("failed 8, 0: %d", got)
+		}
+		if got := tab.GetByteSlot(10, 0); d != got {
+			fail("failed 10, 0: %d", got)
+		}
+	}
+
+	testTable(table0, 0, 11, 22, 33)
+	testTable(table1, 0, 44, 55, 66)
+	testTable(table2, 0, 77, 88, 99)
+}
+
+// CheckNotInObjectError verifies that `EndObject` fails if not inside an
+// object.
+func CheckNotInObjectError(fail func(string, ...interface{})) {
+	b := flatbuffers.NewBuilder(0)
+
+	defer func() {
+		r := recover()
+		if r == nil {
+			fail("expected panic in CheckNotInObjectError")
+		}
+	}()
+	b.EndObject()
+}
+
+// CheckStringIsNestedError verifies that a string can not be created inside
+// another object.
+func CheckStringIsNestedError(fail func(string, ...interface{})) {
+	b := flatbuffers.NewBuilder(0)
+	b.StartObject(0)
+	defer func() {
+		r := recover()
+		if r == nil {
+			fail("expected panic in CheckStringIsNestedError")
+		}
+	}()
+	b.CreateString("foo")
+}
+
+// CheckByteStringIsNestedError verifies that a bytestring can not be created
+// inside another object.
+func CheckByteStringIsNestedError(fail func(string, ...interface{})) {
+	b := flatbuffers.NewBuilder(0)
+	b.StartObject(0)
+	defer func() {
+		r := recover()
+		if r == nil {
+			fail("expected panic in CheckByteStringIsNestedError")
+		}
+	}()
+	b.CreateByteString([]byte("foo"))
+}
+
+// CheckStructIsNotInlineError verifies that writing a struct in a location
+// away from where it is used will cause a panic.
+func CheckStructIsNotInlineError(fail func(string, ...interface{})) {
+	b := flatbuffers.NewBuilder(0)
+	b.StartObject(0)
+	defer func() {
+		r := recover()
+		if r == nil {
+			fail("expected panic in CheckStructIsNotInlineError")
+		}
+	}()
+	b.PrependStructSlot(0, 1, 0)
+}
+
+// CheckFinishedBytesError verifies that `FinishedBytes` panics if the table
+// is not finished.
+func CheckFinishedBytesError(fail func(string, ...interface{})) {
+	b := flatbuffers.NewBuilder(0)
+
+	defer func() {
+		r := recover()
+		if r == nil {
+			fail("expected panic in CheckFinishedBytesError")
+		}
+	}()
+	b.FinishedBytes()
+}
+
+// CheckEnumNames checks that the generated enum names are correct.
+func CheckEnumNames(fail func(string, ...interface{})) {
+	{
+		want := map[example.Any]string{
+			example.AnyNONE:                    "NONE",
+			example.AnyMonster:                 "Monster",
+			example.AnyTestSimpleTableWithEnum: "TestSimpleTableWithEnum",
+			example.AnyMyGame_Example2_Monster: "MyGame_Example2_Monster",
+		}
+		got := example.EnumNamesAny
+		if !reflect.DeepEqual(got, want) {
+			fail("enum name is not equal")
+		}
+	}
+	{
+		want := map[example.Color]string{
+			example.ColorRed:   "Red",
+			example.ColorGreen: "Green",
+			example.ColorBlue:  "Blue",
+		}
+		got := example.EnumNamesColor
+		if !reflect.DeepEqual(got, want) {
+			fail("enum name is not equal")
+		}
+	}
+}
+
+// CheckEnumString checks the String method on generated enum types.
+func CheckEnumString(fail func(string, ...interface{})) {
+	if got := example.AnyMonster.String(); got != "Monster" {
+		fail("Monster.String: %q != %q", got, "Monster")
+	}
+	if got := fmt.Sprintf("color: %s", example.ColorGreen); got != "color: Green" {
+		fail("color.String: %q != %q", got, "color: Green")
+	}
+}
+
+// CheckEnumValues checks that the generated enum values maps are correct.
+func CheckEnumValues(fail func(string, ...interface{})) {
+	{
+		want := map[string]example.Any{
+			"NONE":                    example.AnyNONE,
+			"Monster":                 example.AnyMonster,
+			"TestSimpleTableWithEnum": example.AnyTestSimpleTableWithEnum,
+			"MyGame_Example2_Monster": example.AnyMyGame_Example2_Monster,
+		}
+		got := example.EnumValuesAny
+		if !reflect.DeepEqual(got, want) {
+			fail("enum name is not equal")
+		}
+	}
+	{
+		want := map[string]example.Color{
+			"Red":   example.ColorRed,
+			"Green": example.ColorGreen,
+			"Blue":  example.ColorBlue,
+		}
+		got := example.EnumValuesColor
+		if !reflect.DeepEqual(got, want) {
+			fail("enum name is not equal")
+		}
+	}
+}
+
+// CheckDocExample checks that the code given in FlatBuffers documentation
+// is syntactically correct.
+func CheckDocExample(buf []byte, off flatbuffers.UOffsetT, fail func(string, ...interface{})) {
+	monster := example.GetRootAsMonster(buf, off)
+	_ = monster.Hp()
+	_ = monster.Pos(nil)
+	for i := 0; i < monster.InventoryLength(); i++ {
+		_ = monster.Inventory(i) // do something here
+	}
+
+	builder := flatbuffers.NewBuilder(0)
+
+	example.MonsterStartInventoryVector(builder, 5)
+	for i := 4; i >= 0; i-- {
+		builder.PrependByte(byte(i))
+	}
+	inv := builder.EndVector(5)
+
+	str := builder.CreateString("MyMonster")
+	example.MonsterStart(builder)
+	example.MonsterAddPos(builder, example.CreateVec3(builder, 1.0, 2.0, 3.0, 3.0, example.Color(4), 5, 6))
+	example.MonsterAddHp(builder, 80)
+	example.MonsterAddName(builder, str)
+	example.MonsterAddInventory(builder, inv)
+	example.MonsterAddTestType(builder, 1)
+	example.MonsterAddColor(builder, example.ColorRed)
+	// example.MonsterAddTest(builder, mon2)
+	// example.MonsterAddTest4(builder, test4s)
+	_ = example.MonsterEnd(builder)
+}
+
+func CheckCreateByteVector(fail func(string, ...interface{})) {
+	raw := [30]byte{}
+	for i := 0; i < len(raw); i++ {
+		raw[i] = byte(i)
+	}
+
+	for size := 0; size < len(raw); size++ {
+		b1 := flatbuffers.NewBuilder(0)
+		b2 := flatbuffers.NewBuilder(0)
+		b1.StartVector(1, size, 1)
+		for i := size - 1; i >= 0; i-- {
+			b1.PrependByte(raw[i])
+		}
+		b1.EndVector(size)
+		b2.CreateByteVector(raw[:size])
+		CheckByteEquality(b1.Bytes, b2.Bytes, fail)
+	}
+}
+
+func CheckParentNamespace(fail func(string, ...interface{})) {
+	var empty, nonempty []byte
+
+	// create monster with an empty parent namespace field
+	{
+		builder := flatbuffers.NewBuilder(0)
+
+		example.MonsterStart(builder)
+		m := example.MonsterEnd(builder)
+		builder.Finish(m)
+
+		empty = make([]byte, len(builder.FinishedBytes()))
+		copy(empty, builder.FinishedBytes())
+	}
+
+	// create monster with a non-empty parent namespace field
+	{
+		builder := flatbuffers.NewBuilder(0)
+		mygame.InParentNamespaceStart(builder)
+		pn := mygame.InParentNamespaceEnd(builder)
+
+		example.MonsterStart(builder)
+		example.MonsterAddParentNamespaceTest(builder, pn)
+		m := example.MonsterEnd(builder)
+
+		builder.Finish(m)
+
+		nonempty = make([]byte, len(builder.FinishedBytes()))
+		copy(nonempty, builder.FinishedBytes())
+	}
+
+	// read monster with empty parent namespace field
+	{
+		m := example.GetRootAsMonster(empty, 0)
+		if m.ParentNamespaceTest(nil) != nil {
+			fail("expected nil ParentNamespaceTest for empty field")
+		}
+	}
+
+	// read monster with non-empty parent namespace field
+	{
+		m := example.GetRootAsMonster(nonempty, 0)
+		if m.ParentNamespaceTest(nil) == nil {
+			fail("expected non-nil ParentNamespaceTest for non-empty field")
+		}
+	}
+}
+
+// Include simple random number generator to ensure results will be the
+// same cross platform.
+// http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator
+type LCG uint32
+
+const InitialLCGSeed = 48271
+
+func NewLCG() *LCG {
+	n := uint32(InitialLCGSeed)
+	l := LCG(n)
+	return &l
+}
+
+func (lcg *LCG) Reset() {
+	*lcg = InitialLCGSeed
+}
+
+func (lcg *LCG) Next() uint32 {
+	n := uint32((uint64(*lcg) * uint64(279470273)) % uint64(4294967291))
+	*lcg = LCG(n)
+	return n
+}
+
+// CheckByteEquality verifies that two byte buffers are the same.
+func CheckByteEquality(a, b []byte, fail func(string, ...interface{})) {
+	if !bytes.Equal(a, b) {
+		fail("objects are not byte-wise equal")
+	}
+}
+
+// CheckMutateMethods checks all mutate methods one by one
+func CheckMutateMethods(fail func(string, ...interface{})) {
+	b := flatbuffers.NewBuilder(0)
+	b.StartObject(15)
+	b.PrependBoolSlot(0, true, false)
+	b.PrependByteSlot(1, 1, 0)
+	b.PrependUint8Slot(2, 2, 0)
+	b.PrependUint16Slot(3, 3, 0)
+	b.PrependUint32Slot(4, 4, 0)
+	b.PrependUint64Slot(5, 5, 0)
+	b.PrependInt8Slot(6, 6, 0)
+	b.PrependInt16Slot(7, 7, 0)
+	b.PrependInt32Slot(8, 8, 0)
+	b.PrependInt64Slot(9, 9, 0)
+	b.PrependFloat32Slot(10, 10, 0)
+	b.PrependFloat64Slot(11, 11, 0)
+
+	b.PrependUOffsetTSlot(12, 12, 0)
+	uoVal := b.Offset() - 12
+
+	b.PrependVOffsetT(13)
+	b.Slot(13)
+
+	b.PrependSOffsetT(14)
+	b.Slot(14)
+	soVal := flatbuffers.SOffsetT(b.Offset() - 14)
+
+	offset := b.EndObject()
+
+	t := &flatbuffers.Table{
+		Bytes: b.Bytes,
+		Pos:   flatbuffers.UOffsetT(len(b.Bytes)) - offset,
+	}
+
+	calcVOffsetT := func(slot int) (vtableOffset flatbuffers.VOffsetT) {
+		return flatbuffers.VOffsetT((flatbuffers.VtableMetadataFields + slot) * flatbuffers.SizeVOffsetT)
+	}
+	calcUOffsetT := func(vtableOffset flatbuffers.VOffsetT) (valueOffset flatbuffers.UOffsetT) {
+		return t.Pos + flatbuffers.UOffsetT(t.Offset(vtableOffset))
+	}
+
+	type testcase struct {
+		field  string
+		testfn func() bool
+	}
+
+	testForOriginalValues := []testcase{
+		testcase{"BoolSlot", func() bool { return t.GetBoolSlot(calcVOffsetT(0), true) == true }},
+		testcase{"ByteSlot", func() bool { return t.GetByteSlot(calcVOffsetT(1), 1) == 1 }},
+		testcase{"Uint8Slot", func() bool { return t.GetUint8Slot(calcVOffsetT(2), 2) == 2 }},
+		testcase{"Uint16Slot", func() bool { return t.GetUint16Slot(calcVOffsetT(3), 3) == 3 }},
+		testcase{"Uint32Slot", func() bool { return t.GetUint32Slot(calcVOffsetT(4), 4) == 4 }},
+		testcase{"Uint64Slot", func() bool { return t.GetUint64Slot(calcVOffsetT(5), 5) == 5 }},
+		testcase{"Int8Slot", func() bool { return t.GetInt8Slot(calcVOffsetT(6), 6) == 6 }},
+		testcase{"Int16Slot", func() bool { return t.GetInt16Slot(calcVOffsetT(7), 7) == 7 }},
+		testcase{"Int32Slot", func() bool { return t.GetInt32Slot(calcVOffsetT(8), 8) == 8 }},
+		testcase{"Int64Slot", func() bool { return t.GetInt64Slot(calcVOffsetT(9), 9) == 9 }},
+		testcase{"Float32Slot", func() bool { return t.GetFloat32Slot(calcVOffsetT(10), 10) == 10 }},
+		testcase{"Float64Slot", func() bool { return t.GetFloat64Slot(calcVOffsetT(11), 11) == 11 }},
+		testcase{"UOffsetTSlot", func() bool { return t.GetUOffsetT(calcUOffsetT(calcVOffsetT(12))) == uoVal }},
+		testcase{"VOffsetTSlot", func() bool { return t.GetVOffsetT(calcUOffsetT(calcVOffsetT(13))) == 13 }},
+		testcase{"SOffsetTSlot", func() bool { return t.GetSOffsetT(calcUOffsetT(calcVOffsetT(14))) == soVal }},
+	}
+
+	testMutability := []testcase{
+		testcase{"BoolSlot", func() bool { return t.MutateBoolSlot(calcVOffsetT(0), false) }},
+		testcase{"ByteSlot", func() bool { return t.MutateByteSlot(calcVOffsetT(1), 2) }},
+		testcase{"Uint8Slot", func() bool { return t.MutateUint8Slot(calcVOffsetT(2), 4) }},
+		testcase{"Uint16Slot", func() bool { return t.MutateUint16Slot(calcVOffsetT(3), 6) }},
+		testcase{"Uint32Slot", func() bool { return t.MutateUint32Slot(calcVOffsetT(4), 8) }},
+		testcase{"Uint64Slot", func() bool { return t.MutateUint64Slot(calcVOffsetT(5), 10) }},
+		testcase{"Int8Slot", func() bool { return t.MutateInt8Slot(calcVOffsetT(6), 12) }},
+		testcase{"Int16Slot", func() bool { return t.MutateInt16Slot(calcVOffsetT(7), 14) }},
+		testcase{"Int32Slot", func() bool { return t.MutateInt32Slot(calcVOffsetT(8), 16) }},
+		testcase{"Int64Slot", func() bool { return t.MutateInt64Slot(calcVOffsetT(9), 18) }},
+		testcase{"Float32Slot", func() bool { return t.MutateFloat32Slot(calcVOffsetT(10), 20) }},
+		testcase{"Float64Slot", func() bool { return t.MutateFloat64Slot(calcVOffsetT(11), 22) }},
+		testcase{"UOffsetTSlot", func() bool { return t.MutateUOffsetT(calcUOffsetT(calcVOffsetT(12)), 24) }},
+		testcase{"VOffsetTSlot", func() bool { return t.MutateVOffsetT(calcUOffsetT(calcVOffsetT(13)), 26) }},
+		testcase{"SOffsetTSlot", func() bool { return t.MutateSOffsetT(calcUOffsetT(calcVOffsetT(14)), 28) }},
+	}
+
+	testMutabilityWithoutSlot := []testcase{
+		testcase{"BoolSlot", func() bool { return t.MutateBoolSlot(calcVOffsetT(16), false) }},
+		testcase{"ByteSlot", func() bool { return t.MutateByteSlot(calcVOffsetT(16), 2) }},
+		testcase{"Uint8Slot", func() bool { return t.MutateUint8Slot(calcVOffsetT(16), 2) }},
+		testcase{"Uint16Slot", func() bool { return t.MutateUint16Slot(calcVOffsetT(16), 2) }},
+		testcase{"Uint32Slot", func() bool { return t.MutateUint32Slot(calcVOffsetT(16), 2) }},
+		testcase{"Uint64Slot", func() bool { return t.MutateUint64Slot(calcVOffsetT(16), 2) }},
+		testcase{"Int8Slot", func() bool { return t.MutateInt8Slot(calcVOffsetT(16), 2) }},
+		testcase{"Int16Slot", func() bool { return t.MutateInt16Slot(calcVOffsetT(16), 2) }},
+		testcase{"Int32Slot", func() bool { return t.MutateInt32Slot(calcVOffsetT(16), 2) }},
+		testcase{"Int64Slot", func() bool { return t.MutateInt64Slot(calcVOffsetT(16), 2) }},
+		testcase{"Float32Slot", func() bool { return t.MutateFloat32Slot(calcVOffsetT(16), 2) }},
+		testcase{"Float64Slot", func() bool { return t.MutateFloat64Slot(calcVOffsetT(16), 2) }},
+	}
+
+	testForMutatedValues := []testcase{
+		testcase{"BoolSlot", func() bool { return t.GetBoolSlot(calcVOffsetT(0), true) == false }},
+		testcase{"ByteSlot", func() bool { return t.GetByteSlot(calcVOffsetT(1), 1) == 2 }},
+		testcase{"Uint8Slot", func() bool { return t.GetUint8Slot(calcVOffsetT(2), 1) == 4 }},
+		testcase{"Uint16Slot", func() bool { return t.GetUint16Slot(calcVOffsetT(3), 1) == 6 }},
+		testcase{"Uint32Slot", func() bool { return t.GetUint32Slot(calcVOffsetT(4), 1) == 8 }},
+		testcase{"Uint64Slot", func() bool { return t.GetUint64Slot(calcVOffsetT(5), 1) == 10 }},
+		testcase{"Int8Slot", func() bool { return t.GetInt8Slot(calcVOffsetT(6), 1) == 12 }},
+		testcase{"Int16Slot", func() bool { return t.GetInt16Slot(calcVOffsetT(7), 1) == 14 }},
+		testcase{"Int32Slot", func() bool { return t.GetInt32Slot(calcVOffsetT(8), 1) == 16 }},
+		testcase{"Int64Slot", func() bool { return t.GetInt64Slot(calcVOffsetT(9), 1) == 18 }},
+		testcase{"Float32Slot", func() bool { return t.GetFloat32Slot(calcVOffsetT(10), 1) == 20 }},
+		testcase{"Float64Slot", func() bool { return t.GetFloat64Slot(calcVOffsetT(11), 1) == 22 }},
+		testcase{"UOffsetTSlot", func() bool { return t.GetUOffsetT(calcUOffsetT(calcVOffsetT(12))) == 24 }},
+		testcase{"VOffsetTSlot", func() bool { return t.GetVOffsetT(calcUOffsetT(calcVOffsetT(13))) == 26 }},
+		testcase{"SOffsetTSlot", func() bool { return t.GetSOffsetT(calcUOffsetT(calcVOffsetT(14))) == 28 }},
+	}
+
+	// make sure original values are okay
+	for _, t := range testForOriginalValues {
+		if !t.testfn() {
+			fail(t.field + "' field doesn't have the expected original value")
+		}
+	}
+
+	// try to mutate fields and check mutability
+	for _, t := range testMutability {
+		if !t.testfn() {
+			fail(FailString(t.field+"' field failed mutability test", "passed", "failed"))
+		}
+	}
+
+	// try to mutate fields and check mutability
+	// these have wrong slots so should fail
+	for _, t := range testMutabilityWithoutSlot {
+		if t.testfn() {
+			fail(FailString(t.field+"' field failed no slot mutability test", "failed", "passed"))
+		}
+	}
+
+	// test whether values have changed
+	for _, t := range testForMutatedValues {
+		if !t.testfn() {
+			fail(t.field + "' field doesn't have the expected mutated value")
+		}
+	}
+}
+
+// BenchmarkVtableDeduplication measures the speed of vtable deduplication
+// by creating prePop vtables, then populating b.N objects with a
+// different single vtable.
+//
+// When b.N is large (as in long benchmarks), memory usage may be high.
+func BenchmarkVtableDeduplication(b *testing.B) {
+	prePop := 10
+	builder := flatbuffers.NewBuilder(0)
+
+	// pre-populate some vtables:
+	for i := 0; i < prePop; i++ {
+		builder.StartObject(i)
+		for j := 0; j < i; j++ {
+			builder.PrependInt16Slot(j, int16(j), 0)
+		}
+		builder.EndObject()
+	}
+
+	// benchmark deduplication of a new vtable:
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		lim := prePop
+
+		builder.StartObject(lim)
+		for j := 0; j < lim; j++ {
+			builder.PrependInt16Slot(j, int16(j), 0)
+		}
+		builder.EndObject()
+	}
+}
+
+// BenchmarkParseGold measures the speed of parsing the 'gold' data
+// used throughout this test suite.
+func BenchmarkParseGold(b *testing.B) {
+	buf, offset := CheckGeneratedBuild(b.Fatalf)
+	monster := example.GetRootAsMonster(buf, offset)
+
+	// use these to prevent allocations:
+	reuse_pos := example.Vec3{}
+	reuse_test3 := example.Test{}
+	reuse_table2 := flatbuffers.Table{}
+	reuse_monster2 := example.Monster{}
+	reuse_test4_0 := example.Test{}
+	reuse_test4_1 := example.Test{}
+
+	b.SetBytes(int64(len(buf[offset:])))
+	b.ReportAllocs()
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		monster.Hp()
+		monster.Mana()
+		name := monster.Name()
+		_ = name[0]
+		_ = name[len(name)-1]
+
+		monster.Pos(&reuse_pos)
+		reuse_pos.X()
+		reuse_pos.Y()
+		reuse_pos.Z()
+		reuse_pos.Test1()
+		reuse_pos.Test2()
+		reuse_pos.Test3(&reuse_test3)
+		reuse_test3.A()
+		reuse_test3.B()
+		monster.TestType()
+		monster.Test(&reuse_table2)
+		reuse_monster2.Init(reuse_table2.Bytes, reuse_table2.Pos)
+		name2 := reuse_monster2.Name()
+		_ = name2[0]
+		_ = name2[len(name2)-1]
+		monster.InventoryLength()
+		l := monster.InventoryLength()
+		for i := 0; i < l; i++ {
+			monster.Inventory(i)
+		}
+		monster.Test4Length()
+		monster.Test4(&reuse_test4_0, 0)
+		monster.Test4(&reuse_test4_1, 1)
+
+		reuse_test4_0.A()
+		reuse_test4_0.B()
+		reuse_test4_1.A()
+		reuse_test4_1.B()
+
+		monster.TestarrayofstringLength()
+		str0 := monster.Testarrayofstring(0)
+		_ = str0[0]
+		_ = str0[len(str0)-1]
+		str1 := monster.Testarrayofstring(1)
+		_ = str1[0]
+		_ = str1[len(str1)-1]
+	}
+}
+
+// BenchmarkBuildGold uses generated code to build the example Monster.
+func BenchmarkBuildGold(b *testing.B) {
+	buf, offset := CheckGeneratedBuild(b.Fatalf)
+	bytes_length := int64(len(buf[offset:]))
+
+	reuse_str := "MyMonster"
+	reuse_test1 := "test1"
+	reuse_test2 := "test2"
+	reuse_fred := "Fred"
+
+	b.SetBytes(bytes_length)
+	bldr := flatbuffers.NewBuilder(0)
+	b.ResetTimer()
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		bldr.Reset()
+
+		str := bldr.CreateString(reuse_str)
+		test1 := bldr.CreateString(reuse_test1)
+		test2 := bldr.CreateString(reuse_test2)
+		fred := bldr.CreateString(reuse_fred)
+
+		example.MonsterStartInventoryVector(bldr, 5)
+		bldr.PrependByte(4)
+		bldr.PrependByte(3)
+		bldr.PrependByte(2)
+		bldr.PrependByte(1)
+		bldr.PrependByte(0)
+		inv := bldr.EndVector(5)
+
+		example.MonsterStart(bldr)
+		example.MonsterAddName(bldr, fred)
+		mon2 := example.MonsterEnd(bldr)
+
+		example.MonsterStartTest4Vector(bldr, 2)
+		example.CreateTest(bldr, 10, 20)
+		example.CreateTest(bldr, 30, 40)
+		test4 := bldr.EndVector(2)
+
+		example.MonsterStartTestarrayofstringVector(bldr, 2)
+		bldr.PrependUOffsetT(test2)
+		bldr.PrependUOffsetT(test1)
+		testArrayOfString := bldr.EndVector(2)
+
+		example.MonsterStart(bldr)
+
+		pos := example.CreateVec3(bldr, 1.0, 2.0, 3.0, 3.0, example.ColorGreen, 5, 6)
+		example.MonsterAddPos(bldr, pos)
+
+		example.MonsterAddHp(bldr, 80)
+		example.MonsterAddName(bldr, str)
+		example.MonsterAddInventory(bldr, inv)
+		example.MonsterAddTestType(bldr, 1)
+		example.MonsterAddTest(bldr, mon2)
+		example.MonsterAddTest4(bldr, test4)
+		example.MonsterAddTestarrayofstring(bldr, testArrayOfString)
+		mon := example.MonsterEnd(bldr)
+
+		bldr.Finish(mon)
+	}
+}
diff --git a/tests/include_test/include_test1.fbs b/tests/include_test/include_test1.fbs
new file mode 100644
index 0000000..804856a
--- /dev/null
+++ b/tests/include_test/include_test1.fbs
@@ -0,0 +1,7 @@
+include "sub/include_test2.fbs";
+include "sub/include_test2.fbs";  // should be skipped
+include "include_test1.fbs";  // should be skipped
+
+table TableA {
+  b:MyGame.OtherNameSpace.TableB;
+}
diff --git a/tests/include_test/sub/include_test2.fbs b/tests/include_test/sub/include_test2.fbs
new file mode 100644
index 0000000..7225735
--- /dev/null
+++ b/tests/include_test/sub/include_test2.fbs
@@ -0,0 +1,12 @@
+include "include_test1.fbs";
+include "sub/include_test2.fbs";    // should be skipped
+
+namespace MyGame.OtherNameSpace;
+
+enum FromInclude:long { IncludeVal }
+
+struct Unused { a:int; }
+
+table TableB {
+  a:TableA;
+}
diff --git a/tests/javatest.bin b/tests/javatest.bin
new file mode 100644
index 0000000..804dbba
--- /dev/null
+++ b/tests/javatest.bin
Binary files differ
diff --git a/tests/lobstertest.lobster b/tests/lobstertest.lobster
new file mode 100644
index 0000000..7ea9b38
--- /dev/null
+++ b/tests/lobstertest.lobster
@@ -0,0 +1,137 @@
+// Copyright 2018 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.
+
+import from "../lobster/"
+import monster_test_generated
+
+def check_read_buffer(buf):
+    // CheckReadBuffer checks that the given buffer is evaluated correctly as the example Monster.
+    let monster = MyGame_Example_GetRootAsMonster(buf)
+
+    assert monster.hp == 80
+    assert monster.mana == 150
+    assert monster.name == "MyMonster"
+
+    let vec = monster.pos
+    assert vec
+    assert vec.x == 1.0
+    assert vec.y == 2.0
+    assert vec.z == 3.0
+    assert vec.test1 == 3.0
+    assert vec.test2 == 2
+
+    let t = vec.test3
+    assert t
+    assert t.a == 5
+    assert t.b == 6
+
+    assert monster.test_type == MyGame_Example_Any_Monster
+    assert monster.test_as_Monster.name == "Fred"
+
+    assert monster.inventory_length == 5
+    assert sum(map(monster.inventory_length) i: monster.inventory(i)) == 10
+
+    for(5) i:
+        assert monster.vector_of_longs(i) == pow(10, i * 2)
+
+    assert equal([-1.7976931348623157e+308, 0, 1.7976931348623157e+308],
+                 (map(monster.vector_of_doubles_length) i: monster.vector_of_doubles(i)))
+
+    assert monster.test4_length == 2
+    let test0 = monster.test4(0)
+    let test1 = monster.test4(1)
+    assert test0.a + test0.b + test1.a + test1.b == 100
+
+    assert monster.testarrayofstring_length == 2
+    assert monster.testarrayofstring(0) == "test1"
+    assert monster.testarrayofstring(1) == "test2"
+
+    assert monster.testarrayoftables_length == 0
+    assert monster.testnestedflatbuffer_length == 0
+    assert not monster.testempty()
+
+def make_monster_from_generated_code():
+    // Use generated code to build the example Monster.
+    let b = flatbuffers_builder {}
+
+    let name = b.CreateString("MyMonster")
+    let fred = b.CreateString("Fred")
+
+    let inv = b.MyGame_Example_MonsterCreateInventoryVector([ 0, 1, 2, 3, 4 ])
+
+    let mon2 = MyGame_Example_MonsterBuilder { b }
+        .start()
+        .add_name(fred)
+        .end()
+
+    b.MyGame_Example_MonsterStartTest4Vector(2)
+    b.MyGame_Example_CreateTest(10, 20)
+    b.MyGame_Example_CreateTest(30, 40)
+    let test4 = b.EndVector(2)
+
+    let test_array_of_string = b.MyGame_Example_MonsterCreateTestarrayofstringVector(
+                                   [ b.CreateString("test1"), b.CreateString("test2") ])
+
+    let vector_of_longs = b.MyGame_Example_MonsterCreateVectorOfLongsVector(
+                              [ 1, 100, 10000, 1000000, 100000000 ])
+
+    let vector_of_doubles = b.MyGame_Example_MonsterCreateVectorOfDoublesVector(
+                                [ -1.7976931348623157e+308, 0, 1.7976931348623157e+308 ])
+
+    let mon = MyGame_Example_MonsterBuilder { b }
+        .start()
+        .add_pos(b.MyGame_Example_CreateVec3(1.0, 2.0, 3.0, 3.0,
+                 MyGame_Example_Color_Green, 5, 6))
+        .add_hp(80)
+        .add_name(name)
+        .add_inventory(inv)
+        .add_test_type(MyGame_Example_Any_Monster)
+        .add_test(mon2)
+        .add_test4(test4)
+        .add_testarrayofstring(test_array_of_string)
+        .add_vector_of_longs(vector_of_longs)
+        .add_vector_of_doubles(vector_of_doubles)
+        .end()
+
+    b.Finish(mon)
+
+    return b.SizedCopy()
+
+// Verify that the canonical flatbuffer file (produced by the C++ implementation)
+// is readable by the generated Lobster code.
+let fb2 = read_file("monsterdata_test.mon")
+assert fb2
+check_read_buffer(fb2)
+
+// Verify that using the generated Lobster code builds a buffer without
+// returning errors, and is interpreted correctly.
+let fb1 = make_monster_from_generated_code()
+check_read_buffer(fb1)
+// Write the result to file for no good reason.
+write_file("monsterdata_lobster_wire.mon", fb1)
+
+// Test converting the buffer to JSON and parsing the JSON back again.
+let schema = read_file("monster_test.fbs")
+assert schema
+let includedirs = [ "include_test" ]
+// Convert binary to JSON:
+let json, err1 = flatbuffers_binary_to_json(schema, fb1, includedirs)
+assert not err1
+// Parse JSON back to binary:
+let fb3, err2 = flatbuffers_json_to_binary(schema, json, includedirs)
+assert not err2
+// Check the resulting binary again (full roundtrip test):
+check_read_buffer(fb3)
+
+print "Lobster test succesful!"
\ No newline at end of file
diff --git a/tests/luatest.lua b/tests/luatest.lua
new file mode 100644
index 0000000..c85a4ec
--- /dev/null
+++ b/tests/luatest.lua
@@ -0,0 +1,296 @@
+package.path = string.format("../lua/?.lua;./?.lua;%s",package.path)
+
+local function checkReadBuffer(buf, offset, sizePrefix)
+    offset = offset or 0
+    
+    if type(buf) == "string" then
+        buf = flatbuffers.binaryArray.New(buf)
+    end
+    
+    if sizePrefix then               
+        local size = flatbuffers.N.Int32:Unpack(buf, offset)
+        assert(size == #buf - offset - 4)
+        offset = offset + flatbuffers.N.Int32.bytewidth
+    end    
+    
+    local mon = monster.GetRootAsMonster(buf, offset)
+    assert(mon:Hp() == 80, "Monster Hp is not 80")
+    assert(mon:Mana() == 150, "Monster Mana is not 150")
+    assert(mon:Name() == "MyMonster", "Monster Name is not MyMonster")
+    
+    local vec = assert(mon:Pos(), "Monster Position is nil")
+    assert(vec:X() == 1.0)
+    assert(vec:Y() == 2.0)
+    assert(vec:Z() == 3.0)
+    assert(vec:Test1() == 3.0)
+    assert(vec:Test2() == 2)
+    
+    local t = require("MyGame.Example.Test").New()
+    t = assert(vec:Test3(t))
+    
+    assert(t:A() == 5)
+    assert(t:B() == 6)
+    
+    local ut = require("MyGame.Example.Any")
+    assert(mon:TestType() == ut.Monster)
+    
+    local table2 = mon:Test()
+    assert(getmetatable(table2) == "flatbuffers.view.mt")
+    
+    local mon2 = monster.New()
+    mon2:Init(table2.bytes, table2.pos)
+    
+    assert(mon2:Name() == "Fred")
+    
+    assert(mon:InventoryLength() == 5)
+    local invsum = 0
+    for i=1,mon:InventoryLength() do
+        local v = mon:Inventory(i)
+        invsum = invsum + v
+    end
+    assert(invsum == 10)
+    
+    for i=1,5 do
+        assert(mon:VectorOfLongs(i) == 10^((i-1)*2))
+    end
+    
+    local dbls = { -1.7976931348623157e+308, 0, 1.7976931348623157e+308}
+    for i=1,mon:VectorOfDoublesLength() do
+        assert(mon:VectorOfDoubles(i) == dbls[i])
+    end
+    
+    assert(mon:Test4Length() == 2)
+    
+    local test0 = mon:Test4(1)
+    local test1 = mon:Test4(2)
+    
+    local v0 = test0:A()
+    local v1 = test0:B()
+    local v2 = test1:A()
+    local v3 = test1:B()
+    
+    local sumtest12 = v0 + v1 + v2 + v3
+    assert(sumtest12 == 100)
+    
+    assert(mon:TestarrayofstringLength() == 2)
+    assert(mon:Testarrayofstring(1) == "test1")
+    assert(mon:Testarrayofstring(2) == "test2")
+    
+    assert(mon:TestarrayoftablesLength() == 0)
+    assert(mon:TestnestedflatbufferLength() == 0)
+    assert(mon:Testempty() == nil)
+end
+
+local function generateMonster(sizePrefix)
+    local b = flatbuffers.Builder(0)
+    local str = b:CreateString("MyMonster")
+    local test1 = b:CreateString("test1")
+    local test2 = b:CreateString("test2")
+    local fred = b:CreateString("Fred")
+    
+    monster.StartInventoryVector(b, 5)
+    b:PrependByte(4)
+    b:PrependByte(3)
+    b:PrependByte(2)
+    b:PrependByte(1)
+    b:PrependByte(0)
+    local inv = b:EndVector(5)
+    
+    monster.Start(b)
+    monster.AddName(b, fred)
+    local mon2 = monster.End(b)
+    
+    monster.StartTest4Vector(b, 2)
+    test.CreateTest(b, 10, 20)
+    test.CreateTest(b, 30, 40)
+    local test4 = b:EndVector(2)
+    
+    monster.StartTestarrayofstringVector(b, 2)
+    b:PrependUOffsetTRelative(test2)
+    b:PrependUOffsetTRelative(test1)
+    local testArrayOfString = b:EndVector(2)
+    
+    monster.StartVectorOfLongsVector(b, 5)
+    b:PrependInt64(100000000)
+    b:PrependInt64(1000000)
+    b:PrependInt64(10000)
+    b:PrependInt64(100)
+    b:PrependInt64(1)
+    local vectorOfLongs = b:EndVector(5)
+    
+    monster.StartVectorOfDoublesVector(b, 3)
+    b:PrependFloat64(1.7976931348623157e+308)
+    b:PrependFloat64(0)
+    b:PrependFloat64(-1.7976931348623157e+308)
+    local vectorOfDoubles = b:EndVector(3)
+    
+    monster.Start(b)
+    local pos = vec3.CreateVec3(b, 1.0, 2.0, 3.0, 3.0, 2, 5, 6)
+    monster.AddPos(b, pos)
+    
+    monster.AddHp(b, 80)
+    monster.AddName(b, str)
+    monster.AddInventory(b, inv)
+    monster.AddTestType(b, 1)
+    monster.AddTest(b, mon2)
+    monster.AddTest4(b, test4)
+    monster.AddTestbool(b, true)
+    monster.AddTestbool(b, false)
+    monster.AddTestbool(b, null)
+    monster.AddTestbool(b,"true")
+    monster.AddTestarrayofstring(b, testArrayOfString)
+    monster.AddVectorOfLongs(b, vectorOfLongs)
+    monster.AddVectorOfDoubles(b, vectorOfDoubles)
+    local mon = monster.End(b)
+    
+    if sizePrefix then
+        b:FinishSizePrefixed(mon)
+    else
+        b:Finish(mon)
+    end
+    return b:Output(true), b:Head()
+end
+
+local function sizePrefix(sizePrefix)
+    local buf,offset = generateMonster(sizePrefix)
+    checkReadBuffer(buf, offset, sizePrefix)
+end
+
+local function testCanonicalData()
+    local f = assert(io.open('monsterdata_test.mon', 'rb'))
+    local wireData = f:read("*a")
+    f:close()    
+    checkReadBuffer(wireData)  
+end    
+    
+local function benchmarkMakeMonster(count)
+    local length = #(generateMonster())
+    
+    --require("flatbuffers.profiler")
+    --profiler = newProfiler("call")
+    --profiler:start()
+    
+    local s = os.clock()
+    for i=1,count do
+        generateMonster()
+    end
+    local e = os.clock()    
+    
+    --profiler:stop()
+
+    --local outfile = io.open( "profile.txt", "w+" )
+    --profiler:report( outfile, true)
+    --outfile:close()
+    
+    
+    local dur = (e - s)
+    local rate = count / (dur * 1000)
+    local data = (length * count) / (1024 * 1024)
+    local dataRate = data / dur
+    
+    print(string.format('built %d %d-byte flatbuffers in %.2fsec: %.2f/msec, %.2fMB/sec',
+        count, length, dur, rate, dataRate))
+end
+
+local function benchmarkReadBuffer(count)
+    local f = assert(io.open('monsterdata_test.mon', 'rb'))
+    local buf = f:read("*a")
+    f:close()    
+        
+    local s = os.clock()
+    for i=1,count do
+        checkReadBuffer(buf)
+    end
+    local e = os.clock()
+        
+    local dur = (e - s)
+    local rate = count / (dur * 1000)
+    local data = (#buf * count) / (1024 * 1024)
+    local dataRate = data / dur
+    
+    print(string.format('traversed %d %d-byte flatbuffers in %.2fsec: %.2f/msec, %.2fMB/sec',
+        count, #buf, dur, rate, dataRate))
+end
+    
+local tests = 
+{ 
+    {   
+        f = sizePrefix, 
+        d = "Test size prefix",
+        args = {{true}, {false}}
+    },
+    {   
+        f = testCanonicalData, 
+        d = "Tests Canonical flatbuffer file included in repo"       
+    },
+    {
+        f = benchmarkMakeMonster,
+        d = "Benchmark making monsters",
+        args = {
+            {100}, 
+            {1000},
+            {10000},
+        }
+    },   
+    {
+        f = benchmarkReadBuffer,
+        d = "Benchmark reading monsters",
+        args = {
+            {100}, 
+            {1000},
+            {10000},
+            -- uncomment following to run 1 million to compare. 
+            -- Took ~141 seconds on my machine
+            --{1000000}, 
+        }
+    }, 
+}
+
+local result, err = xpcall(function()
+    flatbuffers = assert(require("flatbuffers"))
+    monster = assert(require("MyGame.Example.Monster"))  
+    test = assert(require("MyGame.Example.Test"))
+    vec3 = assert(require("MyGame.Example.Vec3"))
+    
+    local function buildArgList(tbl)
+        local s = ""
+        for _,item in ipairs(tbl) do
+            s = s .. tostring(item) .. ","          
+        end
+        return s:sub(1,-2)
+    end
+    
+    local testsPassed, testsFailed = 0,0
+    for _,test in ipairs(tests) do
+        local allargs = test.args or {{}}
+        for _,args in ipairs(allargs) do
+            local results, err = xpcall(test.f,debug.traceback, table.unpack(args))        
+            if results then
+                testsPassed = testsPassed + 1
+            else
+                testsFailed = testsFailed + 1
+                print(string.format(" Test [%s](%s) failed: \n\t%s", 
+                        test.d or "", 
+                        buildArgList(args),
+                        err)) 
+            end
+        end
+    end
+    
+    local totalTests = testsPassed + testsFailed
+    print(string.format("# of test passed: %d / %d (%.2f%%)",
+        testsPassed, 
+        totalTests, 
+        totalTests ~= 0 
+            and 100 * (testsPassed / totalTests) 
+            or 0)
+        )
+    
+    return 0
+end, debug.traceback)
+
+if not result then
+    print("Unable to run tests due to test framework error: ",err)
+end
+
+os.exit(result or -1)
diff --git a/tests/monster_extra.fbs b/tests/monster_extra.fbs
new file mode 100644
index 0000000..d0fc7fe
--- /dev/null
+++ b/tests/monster_extra.fbs
@@ -0,0 +1,21 @@
+namespace MyGame;
+
+// Not all programming languages support this extra table.
+table MonsterExtra {
+  // Float-point values with NaN and Inf defaults.
+  d0:double = nan;
+  d1:double = -nan; // parser must ignore sign of NaN
+  d2:double = +inf;
+  d3:double = -inf;
+  f0:float = -nan; // parser must ignore sign of NaN
+  f1:float = +nan;
+  f2:float = +inf;
+  f3:float = -inf;
+  dvec : [double];
+  fvec : [float];
+}
+
+root_type MonsterExtra;
+
+file_identifier "MONE";
+file_extension "mon";
diff --git a/tests/monster_extra_generated.h b/tests/monster_extra_generated.h
new file mode 100644
index 0000000..d7ff900
--- /dev/null
+++ b/tests/monster_extra_generated.h
@@ -0,0 +1,406 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+#ifndef FLATBUFFERS_GENERATED_MONSTEREXTRA_MYGAME_H_
+#define FLATBUFFERS_GENERATED_MONSTEREXTRA_MYGAME_H_
+
+#include "flatbuffers/flatbuffers.h"
+
+namespace MyGame {
+
+struct MonsterExtra;
+struct MonsterExtraT;
+
+bool operator==(const MonsterExtraT &lhs, const MonsterExtraT &rhs);
+bool operator!=(const MonsterExtraT &lhs, const MonsterExtraT &rhs);
+
+inline const flatbuffers::TypeTable *MonsterExtraTypeTable();
+
+struct MonsterExtraT : public flatbuffers::NativeTable {
+  typedef MonsterExtra TableType;
+  double d0;
+  double d1;
+  double d2;
+  double d3;
+  float f0;
+  float f1;
+  float f2;
+  float f3;
+  std::vector<double> dvec;
+  std::vector<float> fvec;
+  MonsterExtraT()
+      : d0(std::numeric_limits<double>::quiet_NaN()),
+        d1(std::numeric_limits<double>::quiet_NaN()),
+        d2(std::numeric_limits<double>::infinity()),
+        d3(-std::numeric_limits<double>::infinity()),
+        f0(std::numeric_limits<float>::quiet_NaN()),
+        f1(std::numeric_limits<float>::quiet_NaN()),
+        f2(std::numeric_limits<float>::infinity()),
+        f3(-std::numeric_limits<float>::infinity()) {
+  }
+};
+
+inline bool operator==(const MonsterExtraT &lhs, const MonsterExtraT &rhs) {
+  return
+      (lhs.d0 == rhs.d0) &&
+      (lhs.d1 == rhs.d1) &&
+      (lhs.d2 == rhs.d2) &&
+      (lhs.d3 == rhs.d3) &&
+      (lhs.f0 == rhs.f0) &&
+      (lhs.f1 == rhs.f1) &&
+      (lhs.f2 == rhs.f2) &&
+      (lhs.f3 == rhs.f3) &&
+      (lhs.dvec == rhs.dvec) &&
+      (lhs.fvec == rhs.fvec);
+}
+
+inline bool operator!=(const MonsterExtraT &lhs, const MonsterExtraT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct MonsterExtra FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef MonsterExtraT NativeTableType;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return MonsterExtraTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_D0 = 4,
+    VT_D1 = 6,
+    VT_D2 = 8,
+    VT_D3 = 10,
+    VT_F0 = 12,
+    VT_F1 = 14,
+    VT_F2 = 16,
+    VT_F3 = 18,
+    VT_DVEC = 20,
+    VT_FVEC = 22
+  };
+  double d0() const {
+    return GetField<double>(VT_D0, std::numeric_limits<double>::quiet_NaN());
+  }
+  bool mutate_d0(double _d0) {
+    return SetField<double>(VT_D0, _d0, std::numeric_limits<double>::quiet_NaN());
+  }
+  double d1() const {
+    return GetField<double>(VT_D1, std::numeric_limits<double>::quiet_NaN());
+  }
+  bool mutate_d1(double _d1) {
+    return SetField<double>(VT_D1, _d1, std::numeric_limits<double>::quiet_NaN());
+  }
+  double d2() const {
+    return GetField<double>(VT_D2, std::numeric_limits<double>::infinity());
+  }
+  bool mutate_d2(double _d2) {
+    return SetField<double>(VT_D2, _d2, std::numeric_limits<double>::infinity());
+  }
+  double d3() const {
+    return GetField<double>(VT_D3, -std::numeric_limits<double>::infinity());
+  }
+  bool mutate_d3(double _d3) {
+    return SetField<double>(VT_D3, _d3, -std::numeric_limits<double>::infinity());
+  }
+  float f0() const {
+    return GetField<float>(VT_F0, std::numeric_limits<float>::quiet_NaN());
+  }
+  bool mutate_f0(float _f0) {
+    return SetField<float>(VT_F0, _f0, std::numeric_limits<float>::quiet_NaN());
+  }
+  float f1() const {
+    return GetField<float>(VT_F1, std::numeric_limits<float>::quiet_NaN());
+  }
+  bool mutate_f1(float _f1) {
+    return SetField<float>(VT_F1, _f1, std::numeric_limits<float>::quiet_NaN());
+  }
+  float f2() const {
+    return GetField<float>(VT_F2, std::numeric_limits<float>::infinity());
+  }
+  bool mutate_f2(float _f2) {
+    return SetField<float>(VT_F2, _f2, std::numeric_limits<float>::infinity());
+  }
+  float f3() const {
+    return GetField<float>(VT_F3, -std::numeric_limits<float>::infinity());
+  }
+  bool mutate_f3(float _f3) {
+    return SetField<float>(VT_F3, _f3, -std::numeric_limits<float>::infinity());
+  }
+  const flatbuffers::Vector<double> *dvec() const {
+    return GetPointer<const flatbuffers::Vector<double> *>(VT_DVEC);
+  }
+  flatbuffers::Vector<double> *mutable_dvec() {
+    return GetPointer<flatbuffers::Vector<double> *>(VT_DVEC);
+  }
+  const flatbuffers::Vector<float> *fvec() const {
+    return GetPointer<const flatbuffers::Vector<float> *>(VT_FVEC);
+  }
+  flatbuffers::Vector<float> *mutable_fvec() {
+    return GetPointer<flatbuffers::Vector<float> *>(VT_FVEC);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<double>(verifier, VT_D0) &&
+           VerifyField<double>(verifier, VT_D1) &&
+           VerifyField<double>(verifier, VT_D2) &&
+           VerifyField<double>(verifier, VT_D3) &&
+           VerifyField<float>(verifier, VT_F0) &&
+           VerifyField<float>(verifier, VT_F1) &&
+           VerifyField<float>(verifier, VT_F2) &&
+           VerifyField<float>(verifier, VT_F3) &&
+           VerifyOffset(verifier, VT_DVEC) &&
+           verifier.VerifyVector(dvec()) &&
+           VerifyOffset(verifier, VT_FVEC) &&
+           verifier.VerifyVector(fvec()) &&
+           verifier.EndTable();
+  }
+  MonsterExtraT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(MonsterExtraT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<MonsterExtra> Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterExtraT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct MonsterExtraBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_d0(double d0) {
+    fbb_.AddElement<double>(MonsterExtra::VT_D0, d0, std::numeric_limits<double>::quiet_NaN());
+  }
+  void add_d1(double d1) {
+    fbb_.AddElement<double>(MonsterExtra::VT_D1, d1, std::numeric_limits<double>::quiet_NaN());
+  }
+  void add_d2(double d2) {
+    fbb_.AddElement<double>(MonsterExtra::VT_D2, d2, std::numeric_limits<double>::infinity());
+  }
+  void add_d3(double d3) {
+    fbb_.AddElement<double>(MonsterExtra::VT_D3, d3, -std::numeric_limits<double>::infinity());
+  }
+  void add_f0(float f0) {
+    fbb_.AddElement<float>(MonsterExtra::VT_F0, f0, std::numeric_limits<float>::quiet_NaN());
+  }
+  void add_f1(float f1) {
+    fbb_.AddElement<float>(MonsterExtra::VT_F1, f1, std::numeric_limits<float>::quiet_NaN());
+  }
+  void add_f2(float f2) {
+    fbb_.AddElement<float>(MonsterExtra::VT_F2, f2, std::numeric_limits<float>::infinity());
+  }
+  void add_f3(float f3) {
+    fbb_.AddElement<float>(MonsterExtra::VT_F3, f3, -std::numeric_limits<float>::infinity());
+  }
+  void add_dvec(flatbuffers::Offset<flatbuffers::Vector<double>> dvec) {
+    fbb_.AddOffset(MonsterExtra::VT_DVEC, dvec);
+  }
+  void add_fvec(flatbuffers::Offset<flatbuffers::Vector<float>> fvec) {
+    fbb_.AddOffset(MonsterExtra::VT_FVEC, fvec);
+  }
+  explicit MonsterExtraBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  MonsterExtraBuilder &operator=(const MonsterExtraBuilder &);
+  flatbuffers::Offset<MonsterExtra> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<MonsterExtra>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<MonsterExtra> CreateMonsterExtra(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    double d0 = std::numeric_limits<double>::quiet_NaN(),
+    double d1 = std::numeric_limits<double>::quiet_NaN(),
+    double d2 = std::numeric_limits<double>::infinity(),
+    double d3 = -std::numeric_limits<double>::infinity(),
+    float f0 = std::numeric_limits<float>::quiet_NaN(),
+    float f1 = std::numeric_limits<float>::quiet_NaN(),
+    float f2 = std::numeric_limits<float>::infinity(),
+    float f3 = -std::numeric_limits<float>::infinity(),
+    flatbuffers::Offset<flatbuffers::Vector<double>> dvec = 0,
+    flatbuffers::Offset<flatbuffers::Vector<float>> fvec = 0) {
+  MonsterExtraBuilder builder_(_fbb);
+  builder_.add_d3(d3);
+  builder_.add_d2(d2);
+  builder_.add_d1(d1);
+  builder_.add_d0(d0);
+  builder_.add_fvec(fvec);
+  builder_.add_dvec(dvec);
+  builder_.add_f3(f3);
+  builder_.add_f2(f2);
+  builder_.add_f1(f1);
+  builder_.add_f0(f0);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<MonsterExtra> CreateMonsterExtraDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    double d0 = std::numeric_limits<double>::quiet_NaN(),
+    double d1 = std::numeric_limits<double>::quiet_NaN(),
+    double d2 = std::numeric_limits<double>::infinity(),
+    double d3 = -std::numeric_limits<double>::infinity(),
+    float f0 = std::numeric_limits<float>::quiet_NaN(),
+    float f1 = std::numeric_limits<float>::quiet_NaN(),
+    float f2 = std::numeric_limits<float>::infinity(),
+    float f3 = -std::numeric_limits<float>::infinity(),
+    const std::vector<double> *dvec = nullptr,
+    const std::vector<float> *fvec = nullptr) {
+  auto dvec__ = dvec ? _fbb.CreateVector<double>(*dvec) : 0;
+  auto fvec__ = fvec ? _fbb.CreateVector<float>(*fvec) : 0;
+  return MyGame::CreateMonsterExtra(
+      _fbb,
+      d0,
+      d1,
+      d2,
+      d3,
+      f0,
+      f1,
+      f2,
+      f3,
+      dvec__,
+      fvec__);
+}
+
+flatbuffers::Offset<MonsterExtra> CreateMonsterExtra(flatbuffers::FlatBufferBuilder &_fbb, const MonsterExtraT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+inline MonsterExtraT *MonsterExtra::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = new MonsterExtraT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+inline void MonsterExtra::UnPackTo(MonsterExtraT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+  { auto _e = d0(); _o->d0 = _e; };
+  { auto _e = d1(); _o->d1 = _e; };
+  { auto _e = d2(); _o->d2 = _e; };
+  { auto _e = d3(); _o->d3 = _e; };
+  { auto _e = f0(); _o->f0 = _e; };
+  { auto _e = f1(); _o->f1 = _e; };
+  { auto _e = f2(); _o->f2 = _e; };
+  { auto _e = f3(); _o->f3 = _e; };
+  { auto _e = dvec(); if (_e) { _o->dvec.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->dvec[_i] = _e->Get(_i); } } };
+  { auto _e = fvec(); if (_e) { _o->fvec.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->fvec[_i] = _e->Get(_i); } } };
+}
+
+inline flatbuffers::Offset<MonsterExtra> MonsterExtra::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterExtraT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateMonsterExtra(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<MonsterExtra> CreateMonsterExtra(flatbuffers::FlatBufferBuilder &_fbb, const MonsterExtraT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const MonsterExtraT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  auto _d0 = _o->d0;
+  auto _d1 = _o->d1;
+  auto _d2 = _o->d2;
+  auto _d3 = _o->d3;
+  auto _f0 = _o->f0;
+  auto _f1 = _o->f1;
+  auto _f2 = _o->f2;
+  auto _f3 = _o->f3;
+  auto _dvec = _o->dvec.size() ? _fbb.CreateVector(_o->dvec) : 0;
+  auto _fvec = _o->fvec.size() ? _fbb.CreateVector(_o->fvec) : 0;
+  return MyGame::CreateMonsterExtra(
+      _fbb,
+      _d0,
+      _d1,
+      _d2,
+      _d3,
+      _f0,
+      _f1,
+      _f2,
+      _f3,
+      _dvec,
+      _fvec);
+}
+
+inline const flatbuffers::TypeTable *MonsterExtraTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_DOUBLE, 0, -1 },
+    { flatbuffers::ET_DOUBLE, 0, -1 },
+    { flatbuffers::ET_DOUBLE, 0, -1 },
+    { flatbuffers::ET_DOUBLE, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_DOUBLE, 1, -1 },
+    { flatbuffers::ET_FLOAT, 1, -1 }
+  };
+  static const char * const names[] = {
+    "d0",
+    "d1",
+    "d2",
+    "d3",
+    "f0",
+    "f1",
+    "f2",
+    "f3",
+    "dvec",
+    "fvec"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 10, type_codes, nullptr, nullptr, names
+  };
+  return &tt;
+}
+
+inline const MyGame::MonsterExtra *GetMonsterExtra(const void *buf) {
+  return flatbuffers::GetRoot<MyGame::MonsterExtra>(buf);
+}
+
+inline const MyGame::MonsterExtra *GetSizePrefixedMonsterExtra(const void *buf) {
+  return flatbuffers::GetSizePrefixedRoot<MyGame::MonsterExtra>(buf);
+}
+
+inline MonsterExtra *GetMutableMonsterExtra(void *buf) {
+  return flatbuffers::GetMutableRoot<MonsterExtra>(buf);
+}
+
+inline const char *MonsterExtraIdentifier() {
+  return "MONE";
+}
+
+inline bool MonsterExtraBufferHasIdentifier(const void *buf) {
+  return flatbuffers::BufferHasIdentifier(
+      buf, MonsterExtraIdentifier());
+}
+
+inline bool VerifyMonsterExtraBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifyBuffer<MyGame::MonsterExtra>(MonsterExtraIdentifier());
+}
+
+inline bool VerifySizePrefixedMonsterExtraBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifySizePrefixedBuffer<MyGame::MonsterExtra>(MonsterExtraIdentifier());
+}
+
+inline const char *MonsterExtraExtension() {
+  return "mon";
+}
+
+inline void FinishMonsterExtraBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<MyGame::MonsterExtra> root) {
+  fbb.Finish(root, MonsterExtraIdentifier());
+}
+
+inline void FinishSizePrefixedMonsterExtraBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<MyGame::MonsterExtra> root) {
+  fbb.FinishSizePrefixed(root, MonsterExtraIdentifier());
+}
+
+inline std::unique_ptr<MyGame::MonsterExtraT> UnPackMonsterExtra(
+    const void *buf,
+    const flatbuffers::resolver_function_t *res = nullptr) {
+  return std::unique_ptr<MyGame::MonsterExtraT>(GetMonsterExtra(buf)->UnPack(res));
+}
+
+inline std::unique_ptr<MyGame::MonsterExtraT> UnPackSizePrefixedMonsterExtra(
+    const void *buf,
+    const flatbuffers::resolver_function_t *res = nullptr) {
+  return std::unique_ptr<MyGame::MonsterExtraT>(GetSizePrefixedMonsterExtra(buf)->UnPack(res));
+}
+
+}  // namespace MyGame
+
+#endif  // FLATBUFFERS_GENERATED_MONSTEREXTRA_MYGAME_H_
diff --git a/tests/monster_test.bfbs b/tests/monster_test.bfbs
new file mode 100644
index 0000000..02d618d
--- /dev/null
+++ b/tests/monster_test.bfbs
Binary files differ
diff --git a/tests/monster_test.fbs b/tests/monster_test.fbs
new file mode 100644
index 0000000..d791094
--- /dev/null
+++ b/tests/monster_test.fbs
@@ -0,0 +1,138 @@
+// test schema file
+
+include "include_test1.fbs";
+
+namespace MyGame;
+
+table InParentNamespace {}
+
+namespace MyGame.Example2;
+
+table Monster {}  // Test having same name as below, but in different namespace.
+
+namespace MyGame.Example;
+
+attribute "priority";
+
+/// Composite components of Monster color.
+enum Color:ubyte (bit_flags) { 
+  Red = 0, // color Red = (1u << 0)
+  /// \brief color Green
+  /// Green is bit_flag with value (1u << 1)
+  Green, 
+  /// \brief color Blue (1u << 3)
+  Blue = 3, 
+}
+
+union Any { Monster, TestSimpleTableWithEnum, MyGame.Example2.Monster }
+
+union AnyUniqueAliases { M: Monster, TS: TestSimpleTableWithEnum, M2: MyGame.Example2.Monster }
+union AnyAmbiguousAliases { M1: Monster, M2: Monster, M3: Monster }
+
+struct Test { a:short; b:byte; }
+
+table TestSimpleTableWithEnum (csharp_partial, private) {
+  color: Color = Green;
+}
+
+struct Vec3 (force_align: 8) {
+  x:float;
+  y:float;
+  z:float;
+  test1:double;
+  test2:Color;
+  test3:Test;
+}
+
+struct Ability {
+  id:uint(key);
+  distance:uint;
+}
+
+table Stat {
+  id:string;
+  val:long;
+  count:ushort;
+}
+
+table Referrable {
+  id:ulong(key, hash:"fnv1a_64");
+}
+
+/// an example documentation comment: monster object
+table Monster {
+  pos:Vec3 (id: 0);
+  hp:short = 100 (id: 2);
+  mana:short = 150 (id: 1);
+  name:string (id: 3, required, key);
+  color:Color = Blue (id: 6);
+  inventory:[ubyte] (id: 5);
+  friendly:bool = false (deprecated, priority: 1, id: 4);
+  /// an example documentation comment: this will end up in the generated code
+  /// multiline too
+  testarrayoftables:[Monster] (id: 11);
+  testarrayofstring:[string] (id: 10);
+  testarrayofstring2:[string] (id: 28);
+  testarrayofbools:[bool] (id: 24);
+  testarrayofsortedstruct:[Ability] (id: 29);
+  enemy:MyGame.Example.Monster (id:12);  // Test referring by full namespace.
+  test:Any (id: 8);
+  test4:[Test] (id: 9);
+  test5:[Test] (id: 31);
+  testnestedflatbuffer:[ubyte] (id:13, nested_flatbuffer: "Monster");
+  testempty:Stat (id:14);
+  testbool:bool (id:15);
+  testhashs32_fnv1:int (id:16, hash:"fnv1_32");
+  testhashu32_fnv1:uint (id:17, hash:"fnv1_32");
+  testhashs64_fnv1:long (id:18, hash:"fnv1_64");
+  testhashu64_fnv1:ulong (id:19, hash:"fnv1_64");
+  testhashs32_fnv1a:int (id:20, hash:"fnv1a_32");
+  testhashu32_fnv1a:uint (id:21, hash:"fnv1a_32", cpp_type:"Stat");
+  testhashs64_fnv1a:long (id:22, hash:"fnv1a_64");
+  testhashu64_fnv1a:ulong (id:23, hash:"fnv1a_64");
+  testf:float = 3.14159 (id:25);
+  testf2:float = 3 (id:26);
+  testf3:float (id:27);
+  flex:[ubyte] (id:30, flexbuffer);
+  vector_of_longs:[long] (id:32);
+  vector_of_doubles:[double] (id:33);
+  parent_namespace_test:InParentNamespace (id:34);
+  vector_of_referrables:[Referrable](id:35);
+  single_weak_reference:ulong(id:36, hash:"fnv1a_64", cpp_type:"ReferrableT");
+  vector_of_weak_references:[ulong](id:37, hash:"fnv1a_64", cpp_type:"ReferrableT");
+  vector_of_strong_referrables:[Referrable](id:38, cpp_ptr_type:"default_ptr_type");                 //was shared_ptr
+  co_owning_reference:ulong(id:39, hash:"fnv1a_64", cpp_type:"ReferrableT", cpp_ptr_type:"naked");  //was shared_ptr as well
+  vector_of_co_owning_references:[ulong](id:40, hash:"fnv1a_64", cpp_type:"ReferrableT", cpp_ptr_type:"default_ptr_type", cpp_ptr_type_get:".get()");  //was shared_ptr
+  non_owning_reference:ulong(id:41, hash:"fnv1a_64", cpp_type:"ReferrableT", cpp_ptr_type:"naked", cpp_ptr_type_get:"");                              //was weak_ptr
+  vector_of_non_owning_references:[ulong](id:42, hash:"fnv1a_64", cpp_type:"ReferrableT", cpp_ptr_type:"naked", cpp_ptr_type_get:"");                 //was weak_ptr
+  any_unique:AnyUniqueAliases(id:44);
+  any_ambiguous:AnyAmbiguousAliases (id:46);
+  vector_of_enums:[Color] (id:47);
+}
+
+table TypeAliases {
+    i8:int8;
+    u8:uint8;
+    i16:int16;
+    u16:uint16;
+    i32:int32;
+    u32:uint32;
+    i64:int64;
+    u64:uint64;
+    f32:float32;
+    f64:float64;
+    v8:[int8];
+    vf64:[float64];
+}
+
+rpc_service MonsterStorage {
+  Store(Monster):Stat (streaming: "none");
+  Retrieve(Stat):Monster (streaming: "server", idempotent);
+  GetMaxHitPoint(Monster):Stat (streaming: "client");
+  GetMinMaxHitPoints(Monster):Stat (streaming: "bidi");
+}
+
+root_type Monster;
+
+file_identifier "MONS";
+file_extension "mon";
diff --git a/tests/monster_test.grpc.fb.cc b/tests/monster_test.grpc.fb.cc
new file mode 100644
index 0000000..f83e604
--- /dev/null
+++ b/tests/monster_test.grpc.fb.cc
@@ -0,0 +1,142 @@
+// Generated by the gRPC C++ plugin.
+// If you make any local change, they will be lost.
+// source: monster_test
+
+#include "monster_test_generated.h"
+#include "monster_test.grpc.fb.h"
+
+#include <grpc++/impl/codegen/async_stream.h>
+#include <grpc++/impl/codegen/async_unary_call.h>
+#include <grpc++/impl/codegen/channel_interface.h>
+#include <grpc++/impl/codegen/client_unary_call.h>
+#include <grpc++/impl/codegen/method_handler_impl.h>
+#include <grpc++/impl/codegen/rpc_service_method.h>
+#include <grpc++/impl/codegen/service_type.h>
+#include <grpc++/impl/codegen/sync_stream.h>
+namespace MyGame {
+namespace Example {
+
+static const char* MonsterStorage_method_names[] = {
+  "/MyGame.Example.MonsterStorage/Store",
+  "/MyGame.Example.MonsterStorage/Retrieve",
+  "/MyGame.Example.MonsterStorage/GetMaxHitPoint",
+  "/MyGame.Example.MonsterStorage/GetMinMaxHitPoints",
+};
+
+std::unique_ptr< MonsterStorage::Stub> MonsterStorage::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) {
+  std::unique_ptr< MonsterStorage::Stub> stub(new MonsterStorage::Stub(channel));
+  return stub;
+}
+
+MonsterStorage::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel)
+  : channel_(channel)  , rpcmethod_Store_(MonsterStorage_method_names[0], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+  , rpcmethod_Retrieve_(MonsterStorage_method_names[1], ::grpc::internal::RpcMethod::SERVER_STREAMING, channel)
+  , rpcmethod_GetMaxHitPoint_(MonsterStorage_method_names[2], ::grpc::internal::RpcMethod::CLIENT_STREAMING, channel)
+  , rpcmethod_GetMinMaxHitPoints_(MonsterStorage_method_names[3], ::grpc::internal::RpcMethod::BIDI_STREAMING, channel)
+  {}
+  
+::grpc::Status MonsterStorage::Stub::Store(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Monster>& request, flatbuffers::grpc::Message<Stat>* response) {
+  return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_Store_, context, request, response);
+}
+
+::grpc::ClientAsyncResponseReader< flatbuffers::grpc::Message<Stat>>* MonsterStorage::Stub::AsyncStoreRaw(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Monster>& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc::internal::ClientAsyncResponseReaderFactory< flatbuffers::grpc::Message<Stat>>::Create(channel_.get(), cq, rpcmethod_Store_, context, request, true);
+}
+
+::grpc::ClientAsyncResponseReader< flatbuffers::grpc::Message<Stat>>* MonsterStorage::Stub::PrepareAsyncStoreRaw(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Monster>& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc::internal::ClientAsyncResponseReaderFactory< flatbuffers::grpc::Message<Stat>>::Create(channel_.get(), cq, rpcmethod_Store_, context, request, false);
+}
+
+::grpc::ClientReader< flatbuffers::grpc::Message<Monster>>* MonsterStorage::Stub::RetrieveRaw(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Stat>& request) {
+  return ::grpc::internal::ClientReaderFactory< flatbuffers::grpc::Message<Monster>>::Create(channel_.get(), rpcmethod_Retrieve_, context, request);
+}
+
+::grpc::ClientAsyncReader< flatbuffers::grpc::Message<Monster>>* MonsterStorage::Stub::AsyncRetrieveRaw(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Stat>& request, ::grpc::CompletionQueue* cq, void* tag) {
+  return ::grpc::internal::ClientAsyncReaderFactory< flatbuffers::grpc::Message<Monster>>::Create(channel_.get(), cq, rpcmethod_Retrieve_, context, request, true, tag);
+}
+
+::grpc::ClientAsyncReader< flatbuffers::grpc::Message<Monster>>* MonsterStorage::Stub::PrepareAsyncRetrieveRaw(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Stat>& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc::internal::ClientAsyncReaderFactory< flatbuffers::grpc::Message<Monster>>::Create(channel_.get(), cq, rpcmethod_Retrieve_, context, request, false, nullptr);
+}
+
+::grpc::ClientWriter< flatbuffers::grpc::Message<Monster>>* MonsterStorage::Stub::GetMaxHitPointRaw(::grpc::ClientContext* context, flatbuffers::grpc::Message<Stat>* response) {
+  return ::grpc::internal::ClientWriterFactory< flatbuffers::grpc::Message<Monster>>::Create(channel_.get(), rpcmethod_GetMaxHitPoint_, context, response);
+}
+
+::grpc::ClientAsyncWriter< flatbuffers::grpc::Message<Monster>>* MonsterStorage::Stub::AsyncGetMaxHitPointRaw(::grpc::ClientContext* context, flatbuffers::grpc::Message<Stat>* response, ::grpc::CompletionQueue* cq, void* tag) {
+  return ::grpc::internal::ClientAsyncWriterFactory< flatbuffers::grpc::Message<Monster>>::Create(channel_.get(), cq, rpcmethod_GetMaxHitPoint_, context, response, true, tag);
+}
+
+::grpc::ClientAsyncWriter< flatbuffers::grpc::Message<Monster>>* MonsterStorage::Stub::PrepareAsyncGetMaxHitPointRaw(::grpc::ClientContext* context, flatbuffers::grpc::Message<Stat>* response, ::grpc::CompletionQueue* cq) {
+  return ::grpc::internal::ClientAsyncWriterFactory< flatbuffers::grpc::Message<Monster>>::Create(channel_.get(), cq, rpcmethod_GetMaxHitPoint_, context, response, false, nullptr);
+}
+
+::grpc::ClientReaderWriter< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>* MonsterStorage::Stub::GetMinMaxHitPointsRaw(::grpc::ClientContext* context) {
+  return ::grpc::internal::ClientReaderWriterFactory< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>::Create(channel_.get(), rpcmethod_GetMinMaxHitPoints_, context);
+}
+
+::grpc::ClientAsyncReaderWriter< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>* MonsterStorage::Stub::AsyncGetMinMaxHitPointsRaw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) {
+  return ::grpc::internal::ClientAsyncReaderWriterFactory< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>::Create(channel_.get(), cq, rpcmethod_GetMinMaxHitPoints_, context, true, tag);
+}
+
+::grpc::ClientAsyncReaderWriter< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>* MonsterStorage::Stub::PrepareAsyncGetMinMaxHitPointsRaw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) {
+  return ::grpc::internal::ClientAsyncReaderWriterFactory< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>::Create(channel_.get(), cq, rpcmethod_GetMinMaxHitPoints_, context, false, nullptr);
+}
+
+MonsterStorage::Service::Service() {
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      MonsterStorage_method_names[0],
+      ::grpc::internal::RpcMethod::NORMAL_RPC,
+      new ::grpc::internal::RpcMethodHandler< MonsterStorage::Service, flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>(
+          std::mem_fn(&MonsterStorage::Service::Store), this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      MonsterStorage_method_names[1],
+      ::grpc::internal::RpcMethod::SERVER_STREAMING,
+      new ::grpc::internal::ServerStreamingHandler< MonsterStorage::Service, flatbuffers::grpc::Message<Stat>, flatbuffers::grpc::Message<Monster>>(
+          std::mem_fn(&MonsterStorage::Service::Retrieve), this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      MonsterStorage_method_names[2],
+      ::grpc::internal::RpcMethod::CLIENT_STREAMING,
+      new ::grpc::internal::ClientStreamingHandler< MonsterStorage::Service, flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>(
+          std::mem_fn(&MonsterStorage::Service::GetMaxHitPoint), this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      MonsterStorage_method_names[3],
+      ::grpc::internal::RpcMethod::BIDI_STREAMING,
+      new ::grpc::internal::BidiStreamingHandler< MonsterStorage::Service, flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>(
+          std::mem_fn(&MonsterStorage::Service::GetMinMaxHitPoints), this)));
+}
+
+MonsterStorage::Service::~Service() {
+}
+
+::grpc::Status MonsterStorage::Service::Store(::grpc::ServerContext* context, const flatbuffers::grpc::Message<Monster>* request, flatbuffers::grpc::Message<Stat>* response) {
+  (void) context;
+  (void) request;
+  (void) response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status MonsterStorage::Service::Retrieve(::grpc::ServerContext* context, const flatbuffers::grpc::Message<Stat>* request, ::grpc::ServerWriter< flatbuffers::grpc::Message<Monster>>* writer) {
+  (void) context;
+  (void) request;
+  (void) writer;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status MonsterStorage::Service::GetMaxHitPoint(::grpc::ServerContext* context, ::grpc::ServerReader< flatbuffers::grpc::Message<Monster>>* reader, flatbuffers::grpc::Message<Stat>* response) {
+  (void) context;
+  (void) reader;
+  (void) response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status MonsterStorage::Service::GetMinMaxHitPoints(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< flatbuffers::grpc::Message<Stat>, flatbuffers::grpc::Message<Monster>>* stream) {
+  (void) context;
+  (void) stream;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+
+}  // namespace MyGame
+}  // namespace Example
+
diff --git a/tests/monster_test.grpc.fb.h b/tests/monster_test.grpc.fb.h
new file mode 100644
index 0000000..72402ec
--- /dev/null
+++ b/tests/monster_test.grpc.fb.h
@@ -0,0 +1,350 @@
+// Generated by the gRPC C++ plugin.
+// If you make any local change, they will be lost.
+// source: monster_test
+#ifndef GRPC_monster_5ftest__INCLUDED
+#define GRPC_monster_5ftest__INCLUDED
+
+#include "monster_test_generated.h"
+#include "flatbuffers/grpc.h"
+
+#include <grpc++/impl/codegen/async_stream.h>
+#include <grpc++/impl/codegen/async_unary_call.h>
+#include <grpc++/impl/codegen/method_handler_impl.h>
+#include <grpc++/impl/codegen/proto_utils.h>
+#include <grpc++/impl/codegen/rpc_method.h>
+#include <grpc++/impl/codegen/service_type.h>
+#include <grpc++/impl/codegen/status.h>
+#include <grpc++/impl/codegen/stub_options.h>
+#include <grpc++/impl/codegen/sync_stream.h>
+
+namespace grpc {
+class CompletionQueue;
+class Channel;
+class ServerCompletionQueue;
+class ServerContext;
+}  // namespace grpc
+
+namespace MyGame {
+namespace Example {
+
+class MonsterStorage final {
+ public:
+  static constexpr char const* service_full_name() {
+    return "MyGame.Example.MonsterStorage";
+  }
+  class StubInterface {
+   public:
+    virtual ~StubInterface() {}
+    virtual ::grpc::Status Store(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Monster>& request, flatbuffers::grpc::Message<Stat>* response) = 0;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< flatbuffers::grpc::Message<Stat>>> AsyncStore(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Monster>& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< flatbuffers::grpc::Message<Stat>>>(AsyncStoreRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< flatbuffers::grpc::Message<Stat>>> PrepareAsyncStore(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Monster>& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< flatbuffers::grpc::Message<Stat>>>(PrepareAsyncStoreRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientReaderInterface< flatbuffers::grpc::Message<Monster>>> Retrieve(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Stat>& request) {
+      return std::unique_ptr< ::grpc::ClientReaderInterface< flatbuffers::grpc::Message<Monster>>>(RetrieveRaw(context, request));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReaderInterface< flatbuffers::grpc::Message<Monster>>> AsyncRetrieve(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Stat>& request, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< flatbuffers::grpc::Message<Monster>>>(AsyncRetrieveRaw(context, request, cq, tag));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReaderInterface< flatbuffers::grpc::Message<Monster>>> PrepareAsyncRetrieve(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Stat>& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< flatbuffers::grpc::Message<Monster>>>(PrepareAsyncRetrieveRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientWriterInterface< flatbuffers::grpc::Message<Monster>>> GetMaxHitPoint(::grpc::ClientContext* context, flatbuffers::grpc::Message<Stat>* response) {
+      return std::unique_ptr< ::grpc::ClientWriterInterface< flatbuffers::grpc::Message<Monster>>>(GetMaxHitPointRaw(context, response));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncWriterInterface< flatbuffers::grpc::Message<Monster>>> AsyncGetMaxHitPoint(::grpc::ClientContext* context, flatbuffers::grpc::Message<Stat>* response, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncWriterInterface< flatbuffers::grpc::Message<Monster>>>(AsyncGetMaxHitPointRaw(context, response, cq, tag));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncWriterInterface< flatbuffers::grpc::Message<Monster>>> PrepareAsyncGetMaxHitPoint(::grpc::ClientContext* context, flatbuffers::grpc::Message<Stat>* response, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncWriterInterface< flatbuffers::grpc::Message<Monster>>>(PrepareAsyncGetMaxHitPointRaw(context, response, cq));
+    }
+    std::unique_ptr< ::grpc::ClientReaderWriterInterface< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>> GetMinMaxHitPoints(::grpc::ClientContext* context) {
+      return std::unique_ptr< ::grpc::ClientReaderWriterInterface< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>>(GetMinMaxHitPointsRaw(context));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>> AsyncGetMinMaxHitPoints(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>>(AsyncGetMinMaxHitPointsRaw(context, cq, tag));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>> PrepareAsyncGetMinMaxHitPoints(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>>(PrepareAsyncGetMinMaxHitPointsRaw(context, cq));
+    }
+  private:
+    virtual ::grpc::ClientAsyncResponseReaderInterface< flatbuffers::grpc::Message<Stat>>* AsyncStoreRaw(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Monster>& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< flatbuffers::grpc::Message<Stat>>* PrepareAsyncStoreRaw(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Monster>& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientReaderInterface< flatbuffers::grpc::Message<Monster>>* RetrieveRaw(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Stat>& request) = 0;
+    virtual ::grpc::ClientAsyncReaderInterface< flatbuffers::grpc::Message<Monster>>* AsyncRetrieveRaw(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Stat>& request, ::grpc::CompletionQueue* cq, void* tag) = 0;
+    virtual ::grpc::ClientAsyncReaderInterface< flatbuffers::grpc::Message<Monster>>* PrepareAsyncRetrieveRaw(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Stat>& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientWriterInterface< flatbuffers::grpc::Message<Monster>>* GetMaxHitPointRaw(::grpc::ClientContext* context, flatbuffers::grpc::Message<Stat>* response) = 0;
+    virtual ::grpc::ClientAsyncWriterInterface< flatbuffers::grpc::Message<Monster>>* AsyncGetMaxHitPointRaw(::grpc::ClientContext* context, flatbuffers::grpc::Message<Stat>* response, ::grpc::CompletionQueue* cq, void* tag) = 0;
+    virtual ::grpc::ClientAsyncWriterInterface< flatbuffers::grpc::Message<Monster>>* PrepareAsyncGetMaxHitPointRaw(::grpc::ClientContext* context, flatbuffers::grpc::Message<Stat>* response, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientReaderWriterInterface< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>* GetMinMaxHitPointsRaw(::grpc::ClientContext* context) = 0;
+    virtual ::grpc::ClientAsyncReaderWriterInterface< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>* AsyncGetMinMaxHitPointsRaw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) = 0;
+    virtual ::grpc::ClientAsyncReaderWriterInterface< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>* PrepareAsyncGetMinMaxHitPointsRaw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) = 0;
+  };
+  class Stub final : public StubInterface {
+   public:
+    Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel);
+    ::grpc::Status Store(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Monster>& request, flatbuffers::grpc::Message<Stat>* response) override;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< flatbuffers::grpc::Message<Stat>>> AsyncStore(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Monster>& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< flatbuffers::grpc::Message<Stat>>>(AsyncStoreRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< flatbuffers::grpc::Message<Stat>>> PrepareAsyncStore(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Monster>& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< flatbuffers::grpc::Message<Stat>>>(PrepareAsyncStoreRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientReader< flatbuffers::grpc::Message<Monster>>> Retrieve(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Stat>& request) {
+      return std::unique_ptr< ::grpc::ClientReader< flatbuffers::grpc::Message<Monster>>>(RetrieveRaw(context, request));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReader< flatbuffers::grpc::Message<Monster>>> AsyncRetrieve(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Stat>& request, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncReader< flatbuffers::grpc::Message<Monster>>>(AsyncRetrieveRaw(context, request, cq, tag));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReader< flatbuffers::grpc::Message<Monster>>> PrepareAsyncRetrieve(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Stat>& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncReader< flatbuffers::grpc::Message<Monster>>>(PrepareAsyncRetrieveRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientWriter< flatbuffers::grpc::Message<Monster>>> GetMaxHitPoint(::grpc::ClientContext* context, flatbuffers::grpc::Message<Stat>* response) {
+      return std::unique_ptr< ::grpc::ClientWriter< flatbuffers::grpc::Message<Monster>>>(GetMaxHitPointRaw(context, response));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncWriter< flatbuffers::grpc::Message<Monster>>> AsyncGetMaxHitPoint(::grpc::ClientContext* context, flatbuffers::grpc::Message<Stat>* response, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncWriter< flatbuffers::grpc::Message<Monster>>>(AsyncGetMaxHitPointRaw(context, response, cq, tag));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncWriter< flatbuffers::grpc::Message<Monster>>> PrepareAsyncGetMaxHitPoint(::grpc::ClientContext* context, flatbuffers::grpc::Message<Stat>* response, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncWriter< flatbuffers::grpc::Message<Monster>>>(PrepareAsyncGetMaxHitPointRaw(context, response, cq));
+    }
+    std::unique_ptr< ::grpc::ClientReaderWriter< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>> GetMinMaxHitPoints(::grpc::ClientContext* context) {
+      return std::unique_ptr< ::grpc::ClientReaderWriter< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>>(GetMinMaxHitPointsRaw(context));
+    }
+    std::unique_ptr<  ::grpc::ClientAsyncReaderWriter< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>> AsyncGetMinMaxHitPoints(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderWriter< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>>(AsyncGetMinMaxHitPointsRaw(context, cq, tag));
+    }
+    std::unique_ptr<  ::grpc::ClientAsyncReaderWriter< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>> PrepareAsyncGetMinMaxHitPoints(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderWriter< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>>(PrepareAsyncGetMinMaxHitPointsRaw(context, cq));
+    }
+  
+   private:
+    std::shared_ptr< ::grpc::ChannelInterface> channel_;
+    ::grpc::ClientAsyncResponseReader< flatbuffers::grpc::Message<Stat>>* AsyncStoreRaw(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Monster>& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< flatbuffers::grpc::Message<Stat>>* PrepareAsyncStoreRaw(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Monster>& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientReader< flatbuffers::grpc::Message<Monster>>* RetrieveRaw(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Stat>& request) override;
+    ::grpc::ClientAsyncReader< flatbuffers::grpc::Message<Monster>>* AsyncRetrieveRaw(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Stat>& request, ::grpc::CompletionQueue* cq, void* tag) override;
+    ::grpc::ClientAsyncReader< flatbuffers::grpc::Message<Monster>>* PrepareAsyncRetrieveRaw(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Stat>& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientWriter< flatbuffers::grpc::Message<Monster>>* GetMaxHitPointRaw(::grpc::ClientContext* context, flatbuffers::grpc::Message<Stat>* response) override;
+    ::grpc::ClientAsyncWriter< flatbuffers::grpc::Message<Monster>>* AsyncGetMaxHitPointRaw(::grpc::ClientContext* context, flatbuffers::grpc::Message<Stat>* response, ::grpc::CompletionQueue* cq, void* tag) override;
+    ::grpc::ClientAsyncWriter< flatbuffers::grpc::Message<Monster>>* PrepareAsyncGetMaxHitPointRaw(::grpc::ClientContext* context, flatbuffers::grpc::Message<Stat>* response, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientReaderWriter< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>* GetMinMaxHitPointsRaw(::grpc::ClientContext* context) override;
+    ::grpc::ClientAsyncReaderWriter< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>* AsyncGetMinMaxHitPointsRaw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) override;
+    ::grpc::ClientAsyncReaderWriter< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>* PrepareAsyncGetMinMaxHitPointsRaw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) override;
+    const ::grpc::internal::RpcMethod rpcmethod_Store_;
+    const ::grpc::internal::RpcMethod rpcmethod_Retrieve_;
+    const ::grpc::internal::RpcMethod rpcmethod_GetMaxHitPoint_;
+    const ::grpc::internal::RpcMethod rpcmethod_GetMinMaxHitPoints_;
+  };
+  static std::unique_ptr<Stub> NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions());
+  
+  class Service : public ::grpc::Service {
+   public:
+    Service();
+    virtual ~Service();
+    virtual ::grpc::Status Store(::grpc::ServerContext* context, const flatbuffers::grpc::Message<Monster>* request, flatbuffers::grpc::Message<Stat>* response);
+    virtual ::grpc::Status Retrieve(::grpc::ServerContext* context, const flatbuffers::grpc::Message<Stat>* request, ::grpc::ServerWriter< flatbuffers::grpc::Message<Monster>>* writer);
+    virtual ::grpc::Status GetMaxHitPoint(::grpc::ServerContext* context, ::grpc::ServerReader< flatbuffers::grpc::Message<Monster>>* reader, flatbuffers::grpc::Message<Stat>* response);
+    virtual ::grpc::Status GetMinMaxHitPoints(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< flatbuffers::grpc::Message<Stat>, flatbuffers::grpc::Message<Monster>>* stream);
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_Store : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithAsyncMethod_Store() {
+      ::grpc::Service::MarkMethodAsync(0);
+    }
+    ~WithAsyncMethod_Store() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status Store(::grpc::ServerContext* context, const flatbuffers::grpc::Message<Monster>* request, flatbuffers::grpc::Message<Stat>* response) final override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestStore(::grpc::ServerContext* context, flatbuffers::grpc::Message<Monster>* request, ::grpc::ServerAsyncResponseWriter< flatbuffers::grpc::Message<Stat>>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_Retrieve : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithAsyncMethod_Retrieve() {
+      ::grpc::Service::MarkMethodAsync(1);
+    }
+    ~WithAsyncMethod_Retrieve() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status Retrieve(::grpc::ServerContext* context, const flatbuffers::grpc::Message<Stat>* request, ::grpc::ServerWriter< flatbuffers::grpc::Message<Monster>>* writer) final override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestRetrieve(::grpc::ServerContext* context, flatbuffers::grpc::Message<Stat>* request, ::grpc::ServerAsyncWriter< flatbuffers::grpc::Message<Monster>>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncServerStreaming(1, context, request, writer, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_GetMaxHitPoint : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithAsyncMethod_GetMaxHitPoint() {
+      ::grpc::Service::MarkMethodAsync(2);
+    }
+    ~WithAsyncMethod_GetMaxHitPoint() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetMaxHitPoint(::grpc::ServerContext* context, ::grpc::ServerReader< flatbuffers::grpc::Message<Monster>>* reader, flatbuffers::grpc::Message<Stat>* response) final override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestGetMaxHitPoint(::grpc::ServerContext* context, ::grpc::ServerAsyncReader< flatbuffers::grpc::Message<Stat>, flatbuffers::grpc::Message<Monster>>* reader, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncClientStreaming(2, context, reader, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_GetMinMaxHitPoints : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithAsyncMethod_GetMinMaxHitPoints() {
+      ::grpc::Service::MarkMethodAsync(3);
+    }
+    ~WithAsyncMethod_GetMinMaxHitPoints() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetMinMaxHitPoints(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< flatbuffers::grpc::Message<Stat>, flatbuffers::grpc::Message<Monster>>* stream) final override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestGetMinMaxHitPoints(::grpc::ServerContext* context, ::grpc::ServerAsyncReaderWriter< flatbuffers::grpc::Message<Stat>, flatbuffers::grpc::Message<Monster>>* stream, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncBidiStreaming(3, context, stream, new_call_cq, notification_cq, tag);
+    }
+  };
+  typedef   WithAsyncMethod_Store<  WithAsyncMethod_Retrieve<  WithAsyncMethod_GetMaxHitPoint<  WithAsyncMethod_GetMinMaxHitPoints<  Service   >   >   >   >   AsyncService;
+  template <class BaseClass>
+  class WithGenericMethod_Store : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithGenericMethod_Store() {
+      ::grpc::Service::MarkMethodGeneric(0);
+    }
+    ~WithGenericMethod_Store() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status Store(::grpc::ServerContext* context, const flatbuffers::grpc::Message<Monster>* request, flatbuffers::grpc::Message<Stat>* response) final override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_Retrieve : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithGenericMethod_Retrieve() {
+      ::grpc::Service::MarkMethodGeneric(1);
+    }
+    ~WithGenericMethod_Retrieve() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status Retrieve(::grpc::ServerContext* context, const flatbuffers::grpc::Message<Stat>* request, ::grpc::ServerWriter< flatbuffers::grpc::Message<Monster>>* writer) final override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_GetMaxHitPoint : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithGenericMethod_GetMaxHitPoint() {
+      ::grpc::Service::MarkMethodGeneric(2);
+    }
+    ~WithGenericMethod_GetMaxHitPoint() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetMaxHitPoint(::grpc::ServerContext* context, ::grpc::ServerReader< flatbuffers::grpc::Message<Monster>>* reader, flatbuffers::grpc::Message<Stat>* response) final override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_GetMinMaxHitPoints : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithGenericMethod_GetMinMaxHitPoints() {
+      ::grpc::Service::MarkMethodGeneric(3);
+    }
+    ~WithGenericMethod_GetMinMaxHitPoints() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetMinMaxHitPoints(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< flatbuffers::grpc::Message<Stat>, flatbuffers::grpc::Message<Monster>>* stream) final override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithStreamedUnaryMethod_Store : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithStreamedUnaryMethod_Store() {
+      ::grpc::Service::MarkMethodStreamed(0,
+        new ::grpc::internal::StreamedUnaryHandler< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>(std::bind(&WithStreamedUnaryMethod_Store<BaseClass>::StreamedStore, this, std::placeholders::_1, std::placeholders::_2)));
+    }
+    ~WithStreamedUnaryMethod_Store() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status Store(::grpc::ServerContext* context, const flatbuffers::grpc::Message<Monster>* request, flatbuffers::grpc::Message<Stat>* response) final override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with streamed unary
+    virtual ::grpc::Status StreamedStore(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< flatbuffers::grpc::Message<Monster>,flatbuffers::grpc::Message<Stat>>* server_unary_streamer) = 0;
+  };
+  typedef   WithStreamedUnaryMethod_Store<  Service   >   StreamedUnaryService;
+  template <class BaseClass>
+  class WithSplitStreamingMethod_Retrieve : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithSplitStreamingMethod_Retrieve() {
+      ::grpc::Service::MarkMethodStreamed(1,
+        new ::grpc::internal::SplitServerStreamingHandler< flatbuffers::grpc::Message<Stat>, flatbuffers::grpc::Message<Monster>>(std::bind(&WithSplitStreamingMethod_Retrieve<BaseClass>::StreamedRetrieve, this, std::placeholders::_1, std::placeholders::_2)));
+    }
+    ~WithSplitStreamingMethod_Retrieve() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status Retrieve(::grpc::ServerContext* context, const flatbuffers::grpc::Message<Stat>* request, ::grpc::ServerWriter< flatbuffers::grpc::Message<Monster>>* writer) final override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with split streamed
+    virtual ::grpc::Status StreamedRetrieve(::grpc::ServerContext* context, ::grpc::ServerSplitStreamer< flatbuffers::grpc::Message<Stat>,flatbuffers::grpc::Message<Monster>>* server_split_streamer) = 0;
+  };
+  typedef   WithSplitStreamingMethod_Retrieve<  Service   >   SplitStreamedService;
+  typedef   WithStreamedUnaryMethod_Store<  WithSplitStreamingMethod_Retrieve<  Service   >   >   StreamedService;
+};
+
+}  // namespace Example
+}  // namespace MyGame
+
+
+#endif  // GRPC_monster_5ftest__INCLUDED
diff --git a/tests/monster_test.schema.json b/tests/monster_test.schema.json
new file mode 100644
index 0000000..7fb7500
--- /dev/null
+++ b/tests/monster_test.schema.json
@@ -0,0 +1,340 @@
+{
+  "$schema": "http://json-schema.org/draft-04/schema#",
+  "definitions": {
+    "MyGame_OtherNameSpace_FromInclude" : {
+      "type" : "string",
+      "enum": ["IncludeVal"]
+    },
+    "MyGame_Example_Color" : {
+      "type" : "string",
+      "enum": ["Red", "Green", "Blue"]
+    },
+    "MyGame_Example_Any" : {
+      "type" : "string",
+      "enum": ["NONE", "Monster", "TestSimpleTableWithEnum", "MyGame_Example2_Monster"]
+    },
+    "MyGame_Example_AnyUniqueAliases" : {
+      "type" : "string",
+      "enum": ["NONE", "M", "TS", "M2"]
+    },
+    "MyGame_Example_AnyAmbiguousAliases" : {
+      "type" : "string",
+      "enum": ["NONE", "M1", "M2", "M3"]
+    },
+    "MyGame_OtherNameSpace_Unused" : {
+      "type" : "object",
+      "properties" : {
+        "a" : {
+                "type" : "number"
+              }
+      },
+      "additionalProperties" : false
+    },
+    "MyGame_OtherNameSpace_TableB" : {
+      "type" : "object",
+      "properties" : {
+        "a" : {
+                "$ref" : "#/definitions/TableA"
+              }
+      },
+      "additionalProperties" : false
+    },
+    "TableA" : {
+      "type" : "object",
+      "properties" : {
+        "b" : {
+                "$ref" : "#/definitions/MyGame_OtherNameSpace_TableB"
+              }
+      },
+      "additionalProperties" : false
+    },
+    "MyGame_InParentNamespace" : {
+      "type" : "object",
+      "properties" : {
+      },
+      "additionalProperties" : false
+    },
+    "MyGame_Example2_Monster" : {
+      "type" : "object",
+      "properties" : {
+      },
+      "additionalProperties" : false
+    },
+    "MyGame_Example_Test" : {
+      "type" : "object",
+      "properties" : {
+        "a" : {
+                "type" : "number"
+              },
+        "b" : {
+                "type" : "number"
+              }
+      },
+      "additionalProperties" : false
+    },
+    "MyGame_Example_TestSimpleTableWithEnum" : {
+      "type" : "object",
+      "properties" : {
+        "color" : {
+                "$ref" : "#/definitions/MyGame_Example_Color"
+              }
+      },
+      "additionalProperties" : false
+    },
+    "MyGame_Example_Vec3" : {
+      "type" : "object",
+      "properties" : {
+        "x" : {
+                "type" : "number"
+              },
+        "y" : {
+                "type" : "number"
+              },
+        "z" : {
+                "type" : "number"
+              },
+        "test1" : {
+                "type" : "number"
+              },
+        "test2" : {
+                "$ref" : "#/definitions/MyGame_Example_Color"
+              },
+        "test3" : {
+                "$ref" : "#/definitions/MyGame_Example_Test"
+              }
+      },
+      "additionalProperties" : false
+    },
+    "MyGame_Example_Ability" : {
+      "type" : "object",
+      "properties" : {
+        "id" : {
+                "type" : "number"
+              },
+        "distance" : {
+                "type" : "number"
+              }
+      },
+      "additionalProperties" : false
+    },
+    "MyGame_Example_Stat" : {
+      "type" : "object",
+      "properties" : {
+        "id" : {
+                "type" : "string"
+              },
+        "val" : {
+                "type" : "number"
+              },
+        "count" : {
+                "type" : "number"
+              }
+      },
+      "additionalProperties" : false
+    },
+    "MyGame_Example_Referrable" : {
+      "type" : "object",
+      "properties" : {
+        "id" : {
+                "type" : "number"
+              }
+      },
+      "additionalProperties" : false
+    },
+    "MyGame_Example_Monster" : {
+      "type" : "object",
+      "description" : " an example documentation comment: monster object",
+      "properties" : {
+        "pos" : {
+                "$ref" : "#/definitions/MyGame_Example_Vec3"
+              },
+        "mana" : {
+                "type" : "number"
+              },
+        "hp" : {
+                "type" : "number"
+              },
+        "name" : {
+                "type" : "string"
+              },
+        "friendly" : {
+                "type" : "boolean"
+              },
+        "inventory" : {
+                "type" : "array", "items" : { "type" : "number" }
+              },
+        "color" : {
+                "$ref" : "#/definitions/MyGame_Example_Color"
+              },
+        "test_type" : {
+                "$ref" : "#/definitions/MyGame_Example_Any"
+              },
+        "test" : {
+                "anyOf": [{ "$ref" : "#/definitions/MyGame_Example_Monster" },{ "$ref" : "#/definitions/MyGame_Example_TestSimpleTableWithEnum" },{ "$ref" : "#/definitions/MyGame_Example2_Monster" }]
+              },
+        "test4" : {
+                "type" : "array", "items" : { "$ref" : "#/definitions/MyGame_Example_Test" }
+              },
+        "testarrayofstring" : {
+                "type" : "array", "items" : { "type" : "string" }
+              },
+        "testarrayoftables" : {
+                "type" : "array", "items" : { "$ref" : "#/definitions/MyGame_Example_Monster" }
+              },
+        "enemy" : {
+                "$ref" : "#/definitions/MyGame_Example_Monster"
+              },
+        "testnestedflatbuffer" : {
+                "type" : "array", "items" : { "type" : "number" }
+              },
+        "testempty" : {
+                "$ref" : "#/definitions/MyGame_Example_Stat"
+              },
+        "testbool" : {
+                "type" : "boolean"
+              },
+        "testhashs32_fnv1" : {
+                "type" : "number"
+              },
+        "testhashu32_fnv1" : {
+                "type" : "number"
+              },
+        "testhashs64_fnv1" : {
+                "type" : "number"
+              },
+        "testhashu64_fnv1" : {
+                "type" : "number"
+              },
+        "testhashs32_fnv1a" : {
+                "type" : "number"
+              },
+        "testhashu32_fnv1a" : {
+                "type" : "number"
+              },
+        "testhashs64_fnv1a" : {
+                "type" : "number"
+              },
+        "testhashu64_fnv1a" : {
+                "type" : "number"
+              },
+        "testarrayofbools" : {
+                "type" : "array", "items" : { "type" : "boolean" }
+              },
+        "testf" : {
+                "type" : "number"
+              },
+        "testf2" : {
+                "type" : "number"
+              },
+        "testf3" : {
+                "type" : "number"
+              },
+        "testarrayofstring2" : {
+                "type" : "array", "items" : { "type" : "string" }
+              },
+        "testarrayofsortedstruct" : {
+                "type" : "array", "items" : { "$ref" : "#/definitions/MyGame_Example_Ability" }
+              },
+        "flex" : {
+                "type" : "array", "items" : { "type" : "number" }
+              },
+        "test5" : {
+                "type" : "array", "items" : { "$ref" : "#/definitions/MyGame_Example_Test" }
+              },
+        "vector_of_longs" : {
+                "type" : "array", "items" : { "type" : "number" }
+              },
+        "vector_of_doubles" : {
+                "type" : "array", "items" : { "type" : "number" }
+              },
+        "parent_namespace_test" : {
+                "$ref" : "#/definitions/MyGame_InParentNamespace"
+              },
+        "vector_of_referrables" : {
+                "type" : "array", "items" : { "$ref" : "#/definitions/MyGame_Example_Referrable" }
+              },
+        "single_weak_reference" : {
+                "type" : "number"
+              },
+        "vector_of_weak_references" : {
+                "type" : "array", "items" : { "type" : "number" }
+              },
+        "vector_of_strong_referrables" : {
+                "type" : "array", "items" : { "$ref" : "#/definitions/MyGame_Example_Referrable" }
+              },
+        "co_owning_reference" : {
+                "type" : "number"
+              },
+        "vector_of_co_owning_references" : {
+                "type" : "array", "items" : { "type" : "number" }
+              },
+        "non_owning_reference" : {
+                "type" : "number"
+              },
+        "vector_of_non_owning_references" : {
+                "type" : "array", "items" : { "type" : "number" }
+              },
+        "any_unique_type" : {
+                "$ref" : "#/definitions/MyGame_Example_AnyUniqueAliases"
+              },
+        "any_unique" : {
+                "anyOf": [{ "$ref" : "#/definitions/MyGame_Example_Monster" },{ "$ref" : "#/definitions/MyGame_Example_TestSimpleTableWithEnum" },{ "$ref" : "#/definitions/MyGame_Example2_Monster" }]
+              },
+        "any_ambiguous_type" : {
+                "$ref" : "#/definitions/MyGame_Example_AnyAmbiguousAliases"
+              },
+        "any_ambiguous" : {
+                "anyOf": [{ "$ref" : "#/definitions/MyGame_Example_Monster" },{ "$ref" : "#/definitions/MyGame_Example_Monster" },{ "$ref" : "#/definitions/MyGame_Example_Monster" }]
+              },
+        "vector_of_enums" : {
+                "$ref" : "#/definitions/MyGame_Example_Color"
+              }
+      },
+      "required" : ["name"],
+      "additionalProperties" : false
+    },
+    "MyGame_Example_TypeAliases" : {
+      "type" : "object",
+      "properties" : {
+        "i8" : {
+                "type" : "number"
+              },
+        "u8" : {
+                "type" : "number"
+              },
+        "i16" : {
+                "type" : "number"
+              },
+        "u16" : {
+                "type" : "number"
+              },
+        "i32" : {
+                "type" : "number"
+              },
+        "u32" : {
+                "type" : "number"
+              },
+        "i64" : {
+                "type" : "number"
+              },
+        "u64" : {
+                "type" : "number"
+              },
+        "f32" : {
+                "type" : "number"
+              },
+        "f64" : {
+                "type" : "number"
+              },
+        "v8" : {
+                "type" : "array", "items" : { "type" : "number" }
+              },
+        "vf64" : {
+                "type" : "array", "items" : { "type" : "number" }
+              }
+      },
+      "additionalProperties" : false
+    }
+  },
+  "$ref" : "#/definitions/MyGame_Example_Monster"
+}
diff --git a/tests/monster_test_generated.h b/tests/monster_test_generated.h
new file mode 100644
index 0000000..4016ce9
--- /dev/null
+++ b/tests/monster_test_generated.h
@@ -0,0 +1,3499 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+#ifndef FLATBUFFERS_GENERATED_MONSTERTEST_MYGAME_EXAMPLE_H_
+#define FLATBUFFERS_GENERATED_MONSTERTEST_MYGAME_EXAMPLE_H_
+
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/flexbuffers.h"
+
+namespace MyGame {
+
+struct InParentNamespace;
+struct InParentNamespaceT;
+
+namespace Example2 {
+
+struct Monster;
+struct MonsterT;
+
+}  // namespace Example2
+
+namespace Example {
+
+struct Test;
+
+struct TestSimpleTableWithEnum;
+struct TestSimpleTableWithEnumT;
+
+struct Vec3;
+
+struct Ability;
+
+struct Stat;
+struct StatT;
+
+struct Referrable;
+struct ReferrableT;
+
+struct Monster;
+struct MonsterT;
+
+struct TypeAliases;
+struct TypeAliasesT;
+
+}  // namespace Example
+
+bool operator==(const InParentNamespaceT &lhs, const InParentNamespaceT &rhs);
+bool operator!=(const InParentNamespaceT &lhs, const InParentNamespaceT &rhs);
+namespace Example2 {
+
+bool operator==(const MonsterT &lhs, const MonsterT &rhs);
+bool operator!=(const MonsterT &lhs, const MonsterT &rhs);
+}  // namespace Example2
+
+namespace Example {
+
+bool operator==(const Test &lhs, const Test &rhs);
+bool operator!=(const Test &lhs, const Test &rhs);
+bool operator==(const TestSimpleTableWithEnumT &lhs, const TestSimpleTableWithEnumT &rhs);
+bool operator!=(const TestSimpleTableWithEnumT &lhs, const TestSimpleTableWithEnumT &rhs);
+bool operator==(const Vec3 &lhs, const Vec3 &rhs);
+bool operator!=(const Vec3 &lhs, const Vec3 &rhs);
+bool operator==(const Ability &lhs, const Ability &rhs);
+bool operator!=(const Ability &lhs, const Ability &rhs);
+bool operator==(const StatT &lhs, const StatT &rhs);
+bool operator!=(const StatT &lhs, const StatT &rhs);
+bool operator==(const ReferrableT &lhs, const ReferrableT &rhs);
+bool operator!=(const ReferrableT &lhs, const ReferrableT &rhs);
+bool operator==(const MonsterT &lhs, const MonsterT &rhs);
+bool operator!=(const MonsterT &lhs, const MonsterT &rhs);
+bool operator==(const TypeAliasesT &lhs, const TypeAliasesT &rhs);
+bool operator!=(const TypeAliasesT &lhs, const TypeAliasesT &rhs);
+
+}  // namespace Example
+
+inline const flatbuffers::TypeTable *InParentNamespaceTypeTable();
+
+namespace Example2 {
+
+inline const flatbuffers::TypeTable *MonsterTypeTable();
+
+}  // namespace Example2
+
+namespace Example {
+
+inline const flatbuffers::TypeTable *TestTypeTable();
+
+inline const flatbuffers::TypeTable *TestSimpleTableWithEnumTypeTable();
+
+inline const flatbuffers::TypeTable *Vec3TypeTable();
+
+inline const flatbuffers::TypeTable *AbilityTypeTable();
+
+inline const flatbuffers::TypeTable *StatTypeTable();
+
+inline const flatbuffers::TypeTable *ReferrableTypeTable();
+
+inline const flatbuffers::TypeTable *MonsterTypeTable();
+
+inline const flatbuffers::TypeTable *TypeAliasesTypeTable();
+
+/// Composite components of Monster color.
+enum Color {
+  Color_Red = 1,
+  /// \brief color Green
+  /// Green is bit_flag with value (1u << 1)
+  Color_Green = 2,
+  /// \brief color Blue (1u << 3)
+  Color_Blue = 8,
+  Color_NONE = 0,
+  Color_ANY = 11
+};
+
+inline const Color (&EnumValuesColor())[3] {
+  static const Color values[] = {
+    Color_Red,
+    Color_Green,
+    Color_Blue
+  };
+  return values;
+}
+
+inline const char * const *EnumNamesColor() {
+  static const char * const names[9] = {
+    "Red",
+    "Green",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "Blue",
+    nullptr
+  };
+  return names;
+}
+
+inline const char *EnumNameColor(Color e) {
+  if (e < Color_Red || e > Color_Blue) return "";
+  const size_t index = static_cast<size_t>(e) - static_cast<size_t>(Color_Red);
+  return EnumNamesColor()[index];
+}
+
+enum Any {
+  Any_NONE = 0,
+  Any_Monster = 1,
+  Any_TestSimpleTableWithEnum = 2,
+  Any_MyGame_Example2_Monster = 3,
+  Any_MIN = Any_NONE,
+  Any_MAX = Any_MyGame_Example2_Monster
+};
+
+inline const Any (&EnumValuesAny())[4] {
+  static const Any values[] = {
+    Any_NONE,
+    Any_Monster,
+    Any_TestSimpleTableWithEnum,
+    Any_MyGame_Example2_Monster
+  };
+  return values;
+}
+
+inline const char * const *EnumNamesAny() {
+  static const char * const names[5] = {
+    "NONE",
+    "Monster",
+    "TestSimpleTableWithEnum",
+    "MyGame_Example2_Monster",
+    nullptr
+  };
+  return names;
+}
+
+inline const char *EnumNameAny(Any e) {
+  if (e < Any_NONE || e > Any_MyGame_Example2_Monster) return "";
+  const size_t index = static_cast<size_t>(e);
+  return EnumNamesAny()[index];
+}
+
+template<typename T> struct AnyTraits {
+  static const Any enum_value = Any_NONE;
+};
+
+template<> struct AnyTraits<MyGame::Example::Monster> {
+  static const Any enum_value = Any_Monster;
+};
+
+template<> struct AnyTraits<MyGame::Example::TestSimpleTableWithEnum> {
+  static const Any enum_value = Any_TestSimpleTableWithEnum;
+};
+
+template<> struct AnyTraits<MyGame::Example2::Monster> {
+  static const Any enum_value = Any_MyGame_Example2_Monster;
+};
+
+struct AnyUnion {
+  Any type;
+  void *value;
+
+  AnyUnion() : type(Any_NONE), value(nullptr) {}
+  AnyUnion(AnyUnion&& u) FLATBUFFERS_NOEXCEPT :
+    type(Any_NONE), value(nullptr)
+    { std::swap(type, u.type); std::swap(value, u.value); }
+  AnyUnion(const AnyUnion &) FLATBUFFERS_NOEXCEPT;
+  AnyUnion &operator=(const AnyUnion &u) FLATBUFFERS_NOEXCEPT
+    { AnyUnion t(u); std::swap(type, t.type); std::swap(value, t.value); return *this; }
+  AnyUnion &operator=(AnyUnion &&u) FLATBUFFERS_NOEXCEPT
+    { std::swap(type, u.type); std::swap(value, u.value); return *this; }
+  ~AnyUnion() { Reset(); }
+
+  void Reset();
+
+#ifndef FLATBUFFERS_CPP98_STL
+  template <typename T>
+  void Set(T&& val) {
+    using RT = typename std::remove_reference<T>::type;
+    Reset();
+    type = AnyTraits<typename RT::TableType>::enum_value;
+    if (type != Any_NONE) {
+      value = new RT(std::forward<T>(val));
+    }
+  }
+#endif  // FLATBUFFERS_CPP98_STL
+
+  static void *UnPack(const void *obj, Any type, const flatbuffers::resolver_function_t *resolver);
+  flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher = nullptr) const;
+
+  MyGame::Example::MonsterT *AsMonster() {
+    return type == Any_Monster ?
+      reinterpret_cast<MyGame::Example::MonsterT *>(value) : nullptr;
+  }
+  const MyGame::Example::MonsterT *AsMonster() const {
+    return type == Any_Monster ?
+      reinterpret_cast<const MyGame::Example::MonsterT *>(value) : nullptr;
+  }
+  MyGame::Example::TestSimpleTableWithEnumT *AsTestSimpleTableWithEnum() {
+    return type == Any_TestSimpleTableWithEnum ?
+      reinterpret_cast<MyGame::Example::TestSimpleTableWithEnumT *>(value) : nullptr;
+  }
+  const MyGame::Example::TestSimpleTableWithEnumT *AsTestSimpleTableWithEnum() const {
+    return type == Any_TestSimpleTableWithEnum ?
+      reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(value) : nullptr;
+  }
+  MyGame::Example2::MonsterT *AsMyGame_Example2_Monster() {
+    return type == Any_MyGame_Example2_Monster ?
+      reinterpret_cast<MyGame::Example2::MonsterT *>(value) : nullptr;
+  }
+  const MyGame::Example2::MonsterT *AsMyGame_Example2_Monster() const {
+    return type == Any_MyGame_Example2_Monster ?
+      reinterpret_cast<const MyGame::Example2::MonsterT *>(value) : nullptr;
+  }
+};
+
+
+inline bool operator==(const AnyUnion &lhs, const AnyUnion &rhs) {
+  if (lhs.type != rhs.type) return false;
+  switch (lhs.type) {
+    case Any_NONE: {
+      return true;
+    }
+    case Any_Monster: {
+      return *(reinterpret_cast<const MyGame::Example::MonsterT *>(lhs.value)) ==
+             *(reinterpret_cast<const MyGame::Example::MonsterT *>(rhs.value));
+    }
+    case Any_TestSimpleTableWithEnum: {
+      return *(reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(lhs.value)) ==
+             *(reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(rhs.value));
+    }
+    case Any_MyGame_Example2_Monster: {
+      return *(reinterpret_cast<const MyGame::Example2::MonsterT *>(lhs.value)) ==
+             *(reinterpret_cast<const MyGame::Example2::MonsterT *>(rhs.value));
+    }
+    default: {
+      return false;
+    }
+  }
+}
+
+inline bool operator!=(const AnyUnion &lhs, const AnyUnion &rhs) {
+    return !(lhs == rhs);
+}
+
+bool VerifyAny(flatbuffers::Verifier &verifier, const void *obj, Any type);
+bool VerifyAnyVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types);
+
+enum AnyUniqueAliases {
+  AnyUniqueAliases_NONE = 0,
+  AnyUniqueAliases_M = 1,
+  AnyUniqueAliases_TS = 2,
+  AnyUniqueAliases_M2 = 3,
+  AnyUniqueAliases_MIN = AnyUniqueAliases_NONE,
+  AnyUniqueAliases_MAX = AnyUniqueAliases_M2
+};
+
+inline const AnyUniqueAliases (&EnumValuesAnyUniqueAliases())[4] {
+  static const AnyUniqueAliases values[] = {
+    AnyUniqueAliases_NONE,
+    AnyUniqueAliases_M,
+    AnyUniqueAliases_TS,
+    AnyUniqueAliases_M2
+  };
+  return values;
+}
+
+inline const char * const *EnumNamesAnyUniqueAliases() {
+  static const char * const names[5] = {
+    "NONE",
+    "M",
+    "TS",
+    "M2",
+    nullptr
+  };
+  return names;
+}
+
+inline const char *EnumNameAnyUniqueAliases(AnyUniqueAliases e) {
+  if (e < AnyUniqueAliases_NONE || e > AnyUniqueAliases_M2) return "";
+  const size_t index = static_cast<size_t>(e);
+  return EnumNamesAnyUniqueAliases()[index];
+}
+
+template<typename T> struct AnyUniqueAliasesTraits {
+  static const AnyUniqueAliases enum_value = AnyUniqueAliases_NONE;
+};
+
+template<> struct AnyUniqueAliasesTraits<MyGame::Example::Monster> {
+  static const AnyUniqueAliases enum_value = AnyUniqueAliases_M;
+};
+
+template<> struct AnyUniqueAliasesTraits<MyGame::Example::TestSimpleTableWithEnum> {
+  static const AnyUniqueAliases enum_value = AnyUniqueAliases_TS;
+};
+
+template<> struct AnyUniqueAliasesTraits<MyGame::Example2::Monster> {
+  static const AnyUniqueAliases enum_value = AnyUniqueAliases_M2;
+};
+
+struct AnyUniqueAliasesUnion {
+  AnyUniqueAliases type;
+  void *value;
+
+  AnyUniqueAliasesUnion() : type(AnyUniqueAliases_NONE), value(nullptr) {}
+  AnyUniqueAliasesUnion(AnyUniqueAliasesUnion&& u) FLATBUFFERS_NOEXCEPT :
+    type(AnyUniqueAliases_NONE), value(nullptr)
+    { std::swap(type, u.type); std::swap(value, u.value); }
+  AnyUniqueAliasesUnion(const AnyUniqueAliasesUnion &) FLATBUFFERS_NOEXCEPT;
+  AnyUniqueAliasesUnion &operator=(const AnyUniqueAliasesUnion &u) FLATBUFFERS_NOEXCEPT
+    { AnyUniqueAliasesUnion t(u); std::swap(type, t.type); std::swap(value, t.value); return *this; }
+  AnyUniqueAliasesUnion &operator=(AnyUniqueAliasesUnion &&u) FLATBUFFERS_NOEXCEPT
+    { std::swap(type, u.type); std::swap(value, u.value); return *this; }
+  ~AnyUniqueAliasesUnion() { Reset(); }
+
+  void Reset();
+
+#ifndef FLATBUFFERS_CPP98_STL
+  template <typename T>
+  void Set(T&& val) {
+    using RT = typename std::remove_reference<T>::type;
+    Reset();
+    type = AnyUniqueAliasesTraits<typename RT::TableType>::enum_value;
+    if (type != AnyUniqueAliases_NONE) {
+      value = new RT(std::forward<T>(val));
+    }
+  }
+#endif  // FLATBUFFERS_CPP98_STL
+
+  static void *UnPack(const void *obj, AnyUniqueAliases type, const flatbuffers::resolver_function_t *resolver);
+  flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher = nullptr) const;
+
+  MyGame::Example::MonsterT *AsM() {
+    return type == AnyUniqueAliases_M ?
+      reinterpret_cast<MyGame::Example::MonsterT *>(value) : nullptr;
+  }
+  const MyGame::Example::MonsterT *AsM() const {
+    return type == AnyUniqueAliases_M ?
+      reinterpret_cast<const MyGame::Example::MonsterT *>(value) : nullptr;
+  }
+  MyGame::Example::TestSimpleTableWithEnumT *AsTS() {
+    return type == AnyUniqueAliases_TS ?
+      reinterpret_cast<MyGame::Example::TestSimpleTableWithEnumT *>(value) : nullptr;
+  }
+  const MyGame::Example::TestSimpleTableWithEnumT *AsTS() const {
+    return type == AnyUniqueAliases_TS ?
+      reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(value) : nullptr;
+  }
+  MyGame::Example2::MonsterT *AsM2() {
+    return type == AnyUniqueAliases_M2 ?
+      reinterpret_cast<MyGame::Example2::MonsterT *>(value) : nullptr;
+  }
+  const MyGame::Example2::MonsterT *AsM2() const {
+    return type == AnyUniqueAliases_M2 ?
+      reinterpret_cast<const MyGame::Example2::MonsterT *>(value) : nullptr;
+  }
+};
+
+
+inline bool operator==(const AnyUniqueAliasesUnion &lhs, const AnyUniqueAliasesUnion &rhs) {
+  if (lhs.type != rhs.type) return false;
+  switch (lhs.type) {
+    case AnyUniqueAliases_NONE: {
+      return true;
+    }
+    case AnyUniqueAliases_M: {
+      return *(reinterpret_cast<const MyGame::Example::MonsterT *>(lhs.value)) ==
+             *(reinterpret_cast<const MyGame::Example::MonsterT *>(rhs.value));
+    }
+    case AnyUniqueAliases_TS: {
+      return *(reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(lhs.value)) ==
+             *(reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(rhs.value));
+    }
+    case AnyUniqueAliases_M2: {
+      return *(reinterpret_cast<const MyGame::Example2::MonsterT *>(lhs.value)) ==
+             *(reinterpret_cast<const MyGame::Example2::MonsterT *>(rhs.value));
+    }
+    default: {
+      return false;
+    }
+  }
+}
+
+inline bool operator!=(const AnyUniqueAliasesUnion &lhs, const AnyUniqueAliasesUnion &rhs) {
+    return !(lhs == rhs);
+}
+
+bool VerifyAnyUniqueAliases(flatbuffers::Verifier &verifier, const void *obj, AnyUniqueAliases type);
+bool VerifyAnyUniqueAliasesVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types);
+
+enum AnyAmbiguousAliases {
+  AnyAmbiguousAliases_NONE = 0,
+  AnyAmbiguousAliases_M1 = 1,
+  AnyAmbiguousAliases_M2 = 2,
+  AnyAmbiguousAliases_M3 = 3,
+  AnyAmbiguousAliases_MIN = AnyAmbiguousAliases_NONE,
+  AnyAmbiguousAliases_MAX = AnyAmbiguousAliases_M3
+};
+
+inline const AnyAmbiguousAliases (&EnumValuesAnyAmbiguousAliases())[4] {
+  static const AnyAmbiguousAliases values[] = {
+    AnyAmbiguousAliases_NONE,
+    AnyAmbiguousAliases_M1,
+    AnyAmbiguousAliases_M2,
+    AnyAmbiguousAliases_M3
+  };
+  return values;
+}
+
+inline const char * const *EnumNamesAnyAmbiguousAliases() {
+  static const char * const names[5] = {
+    "NONE",
+    "M1",
+    "M2",
+    "M3",
+    nullptr
+  };
+  return names;
+}
+
+inline const char *EnumNameAnyAmbiguousAliases(AnyAmbiguousAliases e) {
+  if (e < AnyAmbiguousAliases_NONE || e > AnyAmbiguousAliases_M3) return "";
+  const size_t index = static_cast<size_t>(e);
+  return EnumNamesAnyAmbiguousAliases()[index];
+}
+
+struct AnyAmbiguousAliasesUnion {
+  AnyAmbiguousAliases type;
+  void *value;
+
+  AnyAmbiguousAliasesUnion() : type(AnyAmbiguousAliases_NONE), value(nullptr) {}
+  AnyAmbiguousAliasesUnion(AnyAmbiguousAliasesUnion&& u) FLATBUFFERS_NOEXCEPT :
+    type(AnyAmbiguousAliases_NONE), value(nullptr)
+    { std::swap(type, u.type); std::swap(value, u.value); }
+  AnyAmbiguousAliasesUnion(const AnyAmbiguousAliasesUnion &) FLATBUFFERS_NOEXCEPT;
+  AnyAmbiguousAliasesUnion &operator=(const AnyAmbiguousAliasesUnion &u) FLATBUFFERS_NOEXCEPT
+    { AnyAmbiguousAliasesUnion t(u); std::swap(type, t.type); std::swap(value, t.value); return *this; }
+  AnyAmbiguousAliasesUnion &operator=(AnyAmbiguousAliasesUnion &&u) FLATBUFFERS_NOEXCEPT
+    { std::swap(type, u.type); std::swap(value, u.value); return *this; }
+  ~AnyAmbiguousAliasesUnion() { Reset(); }
+
+  void Reset();
+
+  static void *UnPack(const void *obj, AnyAmbiguousAliases type, const flatbuffers::resolver_function_t *resolver);
+  flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher = nullptr) const;
+
+  MyGame::Example::MonsterT *AsM1() {
+    return type == AnyAmbiguousAliases_M1 ?
+      reinterpret_cast<MyGame::Example::MonsterT *>(value) : nullptr;
+  }
+  const MyGame::Example::MonsterT *AsM1() const {
+    return type == AnyAmbiguousAliases_M1 ?
+      reinterpret_cast<const MyGame::Example::MonsterT *>(value) : nullptr;
+  }
+  MyGame::Example::MonsterT *AsM2() {
+    return type == AnyAmbiguousAliases_M2 ?
+      reinterpret_cast<MyGame::Example::MonsterT *>(value) : nullptr;
+  }
+  const MyGame::Example::MonsterT *AsM2() const {
+    return type == AnyAmbiguousAliases_M2 ?
+      reinterpret_cast<const MyGame::Example::MonsterT *>(value) : nullptr;
+  }
+  MyGame::Example::MonsterT *AsM3() {
+    return type == AnyAmbiguousAliases_M3 ?
+      reinterpret_cast<MyGame::Example::MonsterT *>(value) : nullptr;
+  }
+  const MyGame::Example::MonsterT *AsM3() const {
+    return type == AnyAmbiguousAliases_M3 ?
+      reinterpret_cast<const MyGame::Example::MonsterT *>(value) : nullptr;
+  }
+};
+
+
+inline bool operator==(const AnyAmbiguousAliasesUnion &lhs, const AnyAmbiguousAliasesUnion &rhs) {
+  if (lhs.type != rhs.type) return false;
+  switch (lhs.type) {
+    case AnyAmbiguousAliases_NONE: {
+      return true;
+    }
+    case AnyAmbiguousAliases_M1: {
+      return *(reinterpret_cast<const MyGame::Example::MonsterT *>(lhs.value)) ==
+             *(reinterpret_cast<const MyGame::Example::MonsterT *>(rhs.value));
+    }
+    case AnyAmbiguousAliases_M2: {
+      return *(reinterpret_cast<const MyGame::Example::MonsterT *>(lhs.value)) ==
+             *(reinterpret_cast<const MyGame::Example::MonsterT *>(rhs.value));
+    }
+    case AnyAmbiguousAliases_M3: {
+      return *(reinterpret_cast<const MyGame::Example::MonsterT *>(lhs.value)) ==
+             *(reinterpret_cast<const MyGame::Example::MonsterT *>(rhs.value));
+    }
+    default: {
+      return false;
+    }
+  }
+}
+
+inline bool operator!=(const AnyAmbiguousAliasesUnion &lhs, const AnyAmbiguousAliasesUnion &rhs) {
+    return !(lhs == rhs);
+}
+
+bool VerifyAnyAmbiguousAliases(flatbuffers::Verifier &verifier, const void *obj, AnyAmbiguousAliases type);
+bool VerifyAnyAmbiguousAliasesVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types);
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(2) Test FLATBUFFERS_FINAL_CLASS {
+ private:
+  int16_t a_;
+  int8_t b_;
+  int8_t padding0__;
+
+ public:
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return TestTypeTable();
+  }
+  Test() {
+    memset(static_cast<void *>(this), 0, sizeof(Test));
+  }
+  Test(int16_t _a, int8_t _b)
+      : a_(flatbuffers::EndianScalar(_a)),
+        b_(flatbuffers::EndianScalar(_b)),
+        padding0__(0) {
+    (void)padding0__;
+  }
+  int16_t a() const {
+    return flatbuffers::EndianScalar(a_);
+  }
+  void mutate_a(int16_t _a) {
+    flatbuffers::WriteScalar(&a_, _a);
+  }
+  int8_t b() const {
+    return flatbuffers::EndianScalar(b_);
+  }
+  void mutate_b(int8_t _b) {
+    flatbuffers::WriteScalar(&b_, _b);
+  }
+};
+FLATBUFFERS_STRUCT_END(Test, 4);
+
+inline bool operator==(const Test &lhs, const Test &rhs) {
+  return
+      (lhs.a() == rhs.a()) &&
+      (lhs.b() == rhs.b());
+}
+
+inline bool operator!=(const Test &lhs, const Test &rhs) {
+    return !(lhs == rhs);
+}
+
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Vec3 FLATBUFFERS_FINAL_CLASS {
+ private:
+  float x_;
+  float y_;
+  float z_;
+  int32_t padding0__;
+  double test1_;
+  uint8_t test2_;
+  int8_t padding1__;
+  MyGame::Example::Test test3_;
+  int16_t padding2__;
+
+ public:
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return Vec3TypeTable();
+  }
+  Vec3() {
+    memset(static_cast<void *>(this), 0, sizeof(Vec3));
+  }
+  Vec3(float _x, float _y, float _z, double _test1, MyGame::Example::Color _test2, const MyGame::Example::Test &_test3)
+      : x_(flatbuffers::EndianScalar(_x)),
+        y_(flatbuffers::EndianScalar(_y)),
+        z_(flatbuffers::EndianScalar(_z)),
+        padding0__(0),
+        test1_(flatbuffers::EndianScalar(_test1)),
+        test2_(flatbuffers::EndianScalar(static_cast<uint8_t>(_test2))),
+        padding1__(0),
+        test3_(_test3),
+        padding2__(0) {
+    (void)padding0__;
+    (void)padding1__;
+    (void)padding2__;
+  }
+  float x() const {
+    return flatbuffers::EndianScalar(x_);
+  }
+  void mutate_x(float _x) {
+    flatbuffers::WriteScalar(&x_, _x);
+  }
+  float y() const {
+    return flatbuffers::EndianScalar(y_);
+  }
+  void mutate_y(float _y) {
+    flatbuffers::WriteScalar(&y_, _y);
+  }
+  float z() const {
+    return flatbuffers::EndianScalar(z_);
+  }
+  void mutate_z(float _z) {
+    flatbuffers::WriteScalar(&z_, _z);
+  }
+  double test1() const {
+    return flatbuffers::EndianScalar(test1_);
+  }
+  void mutate_test1(double _test1) {
+    flatbuffers::WriteScalar(&test1_, _test1);
+  }
+  MyGame::Example::Color test2() const {
+    return static_cast<MyGame::Example::Color>(flatbuffers::EndianScalar(test2_));
+  }
+  void mutate_test2(MyGame::Example::Color _test2) {
+    flatbuffers::WriteScalar(&test2_, static_cast<uint8_t>(_test2));
+  }
+  const MyGame::Example::Test &test3() const {
+    return test3_;
+  }
+  MyGame::Example::Test &mutable_test3() {
+    return test3_;
+  }
+};
+FLATBUFFERS_STRUCT_END(Vec3, 32);
+
+inline bool operator==(const Vec3 &lhs, const Vec3 &rhs) {
+  return
+      (lhs.x() == rhs.x()) &&
+      (lhs.y() == rhs.y()) &&
+      (lhs.z() == rhs.z()) &&
+      (lhs.test1() == rhs.test1()) &&
+      (lhs.test2() == rhs.test2()) &&
+      (lhs.test3() == rhs.test3());
+}
+
+inline bool operator!=(const Vec3 &lhs, const Vec3 &rhs) {
+    return !(lhs == rhs);
+}
+
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Ability FLATBUFFERS_FINAL_CLASS {
+ private:
+  uint32_t id_;
+  uint32_t distance_;
+
+ public:
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return AbilityTypeTable();
+  }
+  Ability() {
+    memset(static_cast<void *>(this), 0, sizeof(Ability));
+  }
+  Ability(uint32_t _id, uint32_t _distance)
+      : id_(flatbuffers::EndianScalar(_id)),
+        distance_(flatbuffers::EndianScalar(_distance)) {
+  }
+  uint32_t id() const {
+    return flatbuffers::EndianScalar(id_);
+  }
+  void mutate_id(uint32_t _id) {
+    flatbuffers::WriteScalar(&id_, _id);
+  }
+  bool KeyCompareLessThan(const Ability *o) const {
+    return id() < o->id();
+  }
+  int KeyCompareWithValue(uint32_t val) const {
+    return static_cast<int>(id() > val) - static_cast<int>(id() < val);
+  }
+  uint32_t distance() const {
+    return flatbuffers::EndianScalar(distance_);
+  }
+  void mutate_distance(uint32_t _distance) {
+    flatbuffers::WriteScalar(&distance_, _distance);
+  }
+};
+FLATBUFFERS_STRUCT_END(Ability, 8);
+
+inline bool operator==(const Ability &lhs, const Ability &rhs) {
+  return
+      (lhs.id() == rhs.id()) &&
+      (lhs.distance() == rhs.distance());
+}
+
+inline bool operator!=(const Ability &lhs, const Ability &rhs) {
+    return !(lhs == rhs);
+}
+
+
+}  // namespace Example
+
+struct InParentNamespaceT : public flatbuffers::NativeTable {
+  typedef InParentNamespace TableType;
+  InParentNamespaceT() {
+  }
+};
+
+inline bool operator==(const InParentNamespaceT &, const InParentNamespaceT &) {
+  return true;
+}
+
+inline bool operator!=(const InParentNamespaceT &lhs, const InParentNamespaceT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct InParentNamespace FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef InParentNamespaceT NativeTableType;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return InParentNamespaceTypeTable();
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           verifier.EndTable();
+  }
+  InParentNamespaceT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(InParentNamespaceT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<InParentNamespace> Pack(flatbuffers::FlatBufferBuilder &_fbb, const InParentNamespaceT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct InParentNamespaceBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  explicit InParentNamespaceBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  InParentNamespaceBuilder &operator=(const InParentNamespaceBuilder &);
+  flatbuffers::Offset<InParentNamespace> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<InParentNamespace>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<InParentNamespace> CreateInParentNamespace(
+    flatbuffers::FlatBufferBuilder &_fbb) {
+  InParentNamespaceBuilder builder_(_fbb);
+  return builder_.Finish();
+}
+
+flatbuffers::Offset<InParentNamespace> CreateInParentNamespace(flatbuffers::FlatBufferBuilder &_fbb, const InParentNamespaceT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+namespace Example2 {
+
+struct MonsterT : public flatbuffers::NativeTable {
+  typedef Monster TableType;
+  MonsterT() {
+  }
+};
+
+inline bool operator==(const MonsterT &, const MonsterT &) {
+  return true;
+}
+
+inline bool operator!=(const MonsterT &lhs, const MonsterT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef MonsterT NativeTableType;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return MonsterTypeTable();
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           verifier.EndTable();
+  }
+  MonsterT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<Monster> Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct MonsterBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  explicit MonsterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  MonsterBuilder &operator=(const MonsterBuilder &);
+  flatbuffers::Offset<Monster> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Monster>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Monster> CreateMonster(
+    flatbuffers::FlatBufferBuilder &_fbb) {
+  MonsterBuilder builder_(_fbb);
+  return builder_.Finish();
+}
+
+flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+}  // namespace Example2
+
+namespace Example {
+
+struct TestSimpleTableWithEnumT : public flatbuffers::NativeTable {
+  typedef TestSimpleTableWithEnum TableType;
+  MyGame::Example::Color color;
+  TestSimpleTableWithEnumT()
+      : color(MyGame::Example::Color_Green) {
+  }
+};
+
+inline bool operator==(const TestSimpleTableWithEnumT &lhs, const TestSimpleTableWithEnumT &rhs) {
+  return
+      (lhs.color == rhs.color);
+}
+
+inline bool operator!=(const TestSimpleTableWithEnumT &lhs, const TestSimpleTableWithEnumT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct TestSimpleTableWithEnum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef TestSimpleTableWithEnumT NativeTableType;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return TestSimpleTableWithEnumTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_COLOR = 4
+  };
+  MyGame::Example::Color color() const {
+    return static_cast<MyGame::Example::Color>(GetField<uint8_t>(VT_COLOR, 2));
+  }
+  bool mutate_color(MyGame::Example::Color _color) {
+    return SetField<uint8_t>(VT_COLOR, static_cast<uint8_t>(_color), 2);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<uint8_t>(verifier, VT_COLOR) &&
+           verifier.EndTable();
+  }
+  TestSimpleTableWithEnumT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(TestSimpleTableWithEnumT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<TestSimpleTableWithEnum> Pack(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct TestSimpleTableWithEnumBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_color(MyGame::Example::Color color) {
+    fbb_.AddElement<uint8_t>(TestSimpleTableWithEnum::VT_COLOR, static_cast<uint8_t>(color), 2);
+  }
+  explicit TestSimpleTableWithEnumBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  TestSimpleTableWithEnumBuilder &operator=(const TestSimpleTableWithEnumBuilder &);
+  flatbuffers::Offset<TestSimpleTableWithEnum> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<TestSimpleTableWithEnum>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    MyGame::Example::Color color = MyGame::Example::Color_Green) {
+  TestSimpleTableWithEnumBuilder builder_(_fbb);
+  builder_.add_color(color);
+  return builder_.Finish();
+}
+
+flatbuffers::Offset<TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+struct StatT : public flatbuffers::NativeTable {
+  typedef Stat TableType;
+  std::string id;
+  int64_t val;
+  uint16_t count;
+  StatT()
+      : val(0),
+        count(0) {
+  }
+};
+
+inline bool operator==(const StatT &lhs, const StatT &rhs) {
+  return
+      (lhs.id == rhs.id) &&
+      (lhs.val == rhs.val) &&
+      (lhs.count == rhs.count);
+}
+
+inline bool operator!=(const StatT &lhs, const StatT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct Stat FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef StatT NativeTableType;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return StatTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_ID = 4,
+    VT_VAL = 6,
+    VT_COUNT = 8
+  };
+  const flatbuffers::String *id() const {
+    return GetPointer<const flatbuffers::String *>(VT_ID);
+  }
+  flatbuffers::String *mutable_id() {
+    return GetPointer<flatbuffers::String *>(VT_ID);
+  }
+  int64_t val() const {
+    return GetField<int64_t>(VT_VAL, 0);
+  }
+  bool mutate_val(int64_t _val) {
+    return SetField<int64_t>(VT_VAL, _val, 0);
+  }
+  uint16_t count() const {
+    return GetField<uint16_t>(VT_COUNT, 0);
+  }
+  bool mutate_count(uint16_t _count) {
+    return SetField<uint16_t>(VT_COUNT, _count, 0);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyOffset(verifier, VT_ID) &&
+           verifier.VerifyString(id()) &&
+           VerifyField<int64_t>(verifier, VT_VAL) &&
+           VerifyField<uint16_t>(verifier, VT_COUNT) &&
+           verifier.EndTable();
+  }
+  StatT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(StatT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<Stat> Pack(flatbuffers::FlatBufferBuilder &_fbb, const StatT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct StatBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_id(flatbuffers::Offset<flatbuffers::String> id) {
+    fbb_.AddOffset(Stat::VT_ID, id);
+  }
+  void add_val(int64_t val) {
+    fbb_.AddElement<int64_t>(Stat::VT_VAL, val, 0);
+  }
+  void add_count(uint16_t count) {
+    fbb_.AddElement<uint16_t>(Stat::VT_COUNT, count, 0);
+  }
+  explicit StatBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  StatBuilder &operator=(const StatBuilder &);
+  flatbuffers::Offset<Stat> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Stat>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Stat> CreateStat(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<flatbuffers::String> id = 0,
+    int64_t val = 0,
+    uint16_t count = 0) {
+  StatBuilder builder_(_fbb);
+  builder_.add_val(val);
+  builder_.add_id(id);
+  builder_.add_count(count);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<Stat> CreateStatDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const char *id = nullptr,
+    int64_t val = 0,
+    uint16_t count = 0) {
+  auto id__ = id ? _fbb.CreateString(id) : 0;
+  return MyGame::Example::CreateStat(
+      _fbb,
+      id__,
+      val,
+      count);
+}
+
+flatbuffers::Offset<Stat> CreateStat(flatbuffers::FlatBufferBuilder &_fbb, const StatT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+struct ReferrableT : public flatbuffers::NativeTable {
+  typedef Referrable TableType;
+  uint64_t id;
+  ReferrableT()
+      : id(0) {
+  }
+};
+
+inline bool operator==(const ReferrableT &lhs, const ReferrableT &rhs) {
+  return
+      (lhs.id == rhs.id);
+}
+
+inline bool operator!=(const ReferrableT &lhs, const ReferrableT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct Referrable FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef ReferrableT NativeTableType;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return ReferrableTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_ID = 4
+  };
+  uint64_t id() const {
+    return GetField<uint64_t>(VT_ID, 0);
+  }
+  bool mutate_id(uint64_t _id) {
+    return SetField<uint64_t>(VT_ID, _id, 0);
+  }
+  bool KeyCompareLessThan(const Referrable *o) const {
+    return id() < o->id();
+  }
+  int KeyCompareWithValue(uint64_t val) const {
+    return static_cast<int>(id() > val) - static_cast<int>(id() < val);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<uint64_t>(verifier, VT_ID) &&
+           verifier.EndTable();
+  }
+  ReferrableT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(ReferrableT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<Referrable> Pack(flatbuffers::FlatBufferBuilder &_fbb, const ReferrableT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct ReferrableBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_id(uint64_t id) {
+    fbb_.AddElement<uint64_t>(Referrable::VT_ID, id, 0);
+  }
+  explicit ReferrableBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  ReferrableBuilder &operator=(const ReferrableBuilder &);
+  flatbuffers::Offset<Referrable> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Referrable>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Referrable> CreateReferrable(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    uint64_t id = 0) {
+  ReferrableBuilder builder_(_fbb);
+  builder_.add_id(id);
+  return builder_.Finish();
+}
+
+flatbuffers::Offset<Referrable> CreateReferrable(flatbuffers::FlatBufferBuilder &_fbb, const ReferrableT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+struct MonsterT : public flatbuffers::NativeTable {
+  typedef Monster TableType;
+  flatbuffers::unique_ptr<MyGame::Example::Vec3> pos;
+  int16_t mana;
+  int16_t hp;
+  std::string name;
+  std::vector<uint8_t> inventory;
+  MyGame::Example::Color color;
+  AnyUnion test;
+  std::vector<MyGame::Example::Test> test4;
+  std::vector<std::string> testarrayofstring;
+  std::vector<flatbuffers::unique_ptr<MyGame::Example::MonsterT>> testarrayoftables;
+  flatbuffers::unique_ptr<MyGame::Example::MonsterT> enemy;
+  std::vector<uint8_t> testnestedflatbuffer;
+  flatbuffers::unique_ptr<MyGame::Example::StatT> testempty;
+  bool testbool;
+  int32_t testhashs32_fnv1;
+  uint32_t testhashu32_fnv1;
+  int64_t testhashs64_fnv1;
+  uint64_t testhashu64_fnv1;
+  int32_t testhashs32_fnv1a;
+  Stat *testhashu32_fnv1a;
+  int64_t testhashs64_fnv1a;
+  uint64_t testhashu64_fnv1a;
+  std::vector<bool> testarrayofbools;
+  float testf;
+  float testf2;
+  float testf3;
+  std::vector<std::string> testarrayofstring2;
+  std::vector<MyGame::Example::Ability> testarrayofsortedstruct;
+  std::vector<uint8_t> flex;
+  std::vector<MyGame::Example::Test> test5;
+  std::vector<int64_t> vector_of_longs;
+  std::vector<double> vector_of_doubles;
+  flatbuffers::unique_ptr<MyGame::InParentNamespaceT> parent_namespace_test;
+  std::vector<flatbuffers::unique_ptr<MyGame::Example::ReferrableT>> vector_of_referrables;
+  ReferrableT *single_weak_reference;
+  std::vector<ReferrableT *> vector_of_weak_references;
+  std::vector<flatbuffers::unique_ptr<MyGame::Example::ReferrableT>> vector_of_strong_referrables;
+  ReferrableT *co_owning_reference;
+  std::vector<flatbuffers::unique_ptr<ReferrableT>> vector_of_co_owning_references;
+  ReferrableT *non_owning_reference;
+  std::vector<ReferrableT *> vector_of_non_owning_references;
+  AnyUniqueAliasesUnion any_unique;
+  AnyAmbiguousAliasesUnion any_ambiguous;
+  std::vector<MyGame::Example::Color> vector_of_enums;
+  MonsterT()
+      : mana(150),
+        hp(100),
+        color(MyGame::Example::Color_Blue),
+        testbool(false),
+        testhashs32_fnv1(0),
+        testhashu32_fnv1(0),
+        testhashs64_fnv1(0),
+        testhashu64_fnv1(0),
+        testhashs32_fnv1a(0),
+        testhashu32_fnv1a(nullptr),
+        testhashs64_fnv1a(0),
+        testhashu64_fnv1a(0),
+        testf(3.14159f),
+        testf2(3.0f),
+        testf3(0.0f),
+        single_weak_reference(nullptr),
+        co_owning_reference(nullptr),
+        non_owning_reference(nullptr) {
+  }
+};
+
+inline bool operator==(const MonsterT &lhs, const MonsterT &rhs) {
+  return
+      (lhs.pos == rhs.pos) &&
+      (lhs.mana == rhs.mana) &&
+      (lhs.hp == rhs.hp) &&
+      (lhs.name == rhs.name) &&
+      (lhs.inventory == rhs.inventory) &&
+      (lhs.color == rhs.color) &&
+      (lhs.test == rhs.test) &&
+      (lhs.test4 == rhs.test4) &&
+      (lhs.testarrayofstring == rhs.testarrayofstring) &&
+      (lhs.testarrayoftables == rhs.testarrayoftables) &&
+      (lhs.enemy == rhs.enemy) &&
+      (lhs.testnestedflatbuffer == rhs.testnestedflatbuffer) &&
+      (lhs.testempty == rhs.testempty) &&
+      (lhs.testbool == rhs.testbool) &&
+      (lhs.testhashs32_fnv1 == rhs.testhashs32_fnv1) &&
+      (lhs.testhashu32_fnv1 == rhs.testhashu32_fnv1) &&
+      (lhs.testhashs64_fnv1 == rhs.testhashs64_fnv1) &&
+      (lhs.testhashu64_fnv1 == rhs.testhashu64_fnv1) &&
+      (lhs.testhashs32_fnv1a == rhs.testhashs32_fnv1a) &&
+      (lhs.testhashu32_fnv1a == rhs.testhashu32_fnv1a) &&
+      (lhs.testhashs64_fnv1a == rhs.testhashs64_fnv1a) &&
+      (lhs.testhashu64_fnv1a == rhs.testhashu64_fnv1a) &&
+      (lhs.testarrayofbools == rhs.testarrayofbools) &&
+      (lhs.testf == rhs.testf) &&
+      (lhs.testf2 == rhs.testf2) &&
+      (lhs.testf3 == rhs.testf3) &&
+      (lhs.testarrayofstring2 == rhs.testarrayofstring2) &&
+      (lhs.testarrayofsortedstruct == rhs.testarrayofsortedstruct) &&
+      (lhs.flex == rhs.flex) &&
+      (lhs.test5 == rhs.test5) &&
+      (lhs.vector_of_longs == rhs.vector_of_longs) &&
+      (lhs.vector_of_doubles == rhs.vector_of_doubles) &&
+      (lhs.parent_namespace_test == rhs.parent_namespace_test) &&
+      (lhs.vector_of_referrables == rhs.vector_of_referrables) &&
+      (lhs.single_weak_reference == rhs.single_weak_reference) &&
+      (lhs.vector_of_weak_references == rhs.vector_of_weak_references) &&
+      (lhs.vector_of_strong_referrables == rhs.vector_of_strong_referrables) &&
+      (lhs.co_owning_reference == rhs.co_owning_reference) &&
+      (lhs.vector_of_co_owning_references == rhs.vector_of_co_owning_references) &&
+      (lhs.non_owning_reference == rhs.non_owning_reference) &&
+      (lhs.vector_of_non_owning_references == rhs.vector_of_non_owning_references) &&
+      (lhs.any_unique == rhs.any_unique) &&
+      (lhs.any_ambiguous == rhs.any_ambiguous) &&
+      (lhs.vector_of_enums == rhs.vector_of_enums);
+}
+
+inline bool operator!=(const MonsterT &lhs, const MonsterT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+/// an example documentation comment: monster object
+struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef MonsterT NativeTableType;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return MonsterTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_POS = 4,
+    VT_MANA = 6,
+    VT_HP = 8,
+    VT_NAME = 10,
+    VT_INVENTORY = 14,
+    VT_COLOR = 16,
+    VT_TEST_TYPE = 18,
+    VT_TEST = 20,
+    VT_TEST4 = 22,
+    VT_TESTARRAYOFSTRING = 24,
+    VT_TESTARRAYOFTABLES = 26,
+    VT_ENEMY = 28,
+    VT_TESTNESTEDFLATBUFFER = 30,
+    VT_TESTEMPTY = 32,
+    VT_TESTBOOL = 34,
+    VT_TESTHASHS32_FNV1 = 36,
+    VT_TESTHASHU32_FNV1 = 38,
+    VT_TESTHASHS64_FNV1 = 40,
+    VT_TESTHASHU64_FNV1 = 42,
+    VT_TESTHASHS32_FNV1A = 44,
+    VT_TESTHASHU32_FNV1A = 46,
+    VT_TESTHASHS64_FNV1A = 48,
+    VT_TESTHASHU64_FNV1A = 50,
+    VT_TESTARRAYOFBOOLS = 52,
+    VT_TESTF = 54,
+    VT_TESTF2 = 56,
+    VT_TESTF3 = 58,
+    VT_TESTARRAYOFSTRING2 = 60,
+    VT_TESTARRAYOFSORTEDSTRUCT = 62,
+    VT_FLEX = 64,
+    VT_TEST5 = 66,
+    VT_VECTOR_OF_LONGS = 68,
+    VT_VECTOR_OF_DOUBLES = 70,
+    VT_PARENT_NAMESPACE_TEST = 72,
+    VT_VECTOR_OF_REFERRABLES = 74,
+    VT_SINGLE_WEAK_REFERENCE = 76,
+    VT_VECTOR_OF_WEAK_REFERENCES = 78,
+    VT_VECTOR_OF_STRONG_REFERRABLES = 80,
+    VT_CO_OWNING_REFERENCE = 82,
+    VT_VECTOR_OF_CO_OWNING_REFERENCES = 84,
+    VT_NON_OWNING_REFERENCE = 86,
+    VT_VECTOR_OF_NON_OWNING_REFERENCES = 88,
+    VT_ANY_UNIQUE_TYPE = 90,
+    VT_ANY_UNIQUE = 92,
+    VT_ANY_AMBIGUOUS_TYPE = 94,
+    VT_ANY_AMBIGUOUS = 96,
+    VT_VECTOR_OF_ENUMS = 98
+  };
+  const MyGame::Example::Vec3 *pos() const {
+    return GetStruct<const MyGame::Example::Vec3 *>(VT_POS);
+  }
+  MyGame::Example::Vec3 *mutable_pos() {
+    return GetStruct<MyGame::Example::Vec3 *>(VT_POS);
+  }
+  int16_t mana() const {
+    return GetField<int16_t>(VT_MANA, 150);
+  }
+  bool mutate_mana(int16_t _mana) {
+    return SetField<int16_t>(VT_MANA, _mana, 150);
+  }
+  int16_t hp() const {
+    return GetField<int16_t>(VT_HP, 100);
+  }
+  bool mutate_hp(int16_t _hp) {
+    return SetField<int16_t>(VT_HP, _hp, 100);
+  }
+  const flatbuffers::String *name() const {
+    return GetPointer<const flatbuffers::String *>(VT_NAME);
+  }
+  flatbuffers::String *mutable_name() {
+    return GetPointer<flatbuffers::String *>(VT_NAME);
+  }
+  bool KeyCompareLessThan(const Monster *o) const {
+    return *name() < *o->name();
+  }
+  int KeyCompareWithValue(const char *val) const {
+    return strcmp(name()->c_str(), val);
+  }
+  const flatbuffers::Vector<uint8_t> *inventory() const {
+    return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_INVENTORY);
+  }
+  flatbuffers::Vector<uint8_t> *mutable_inventory() {
+    return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_INVENTORY);
+  }
+  MyGame::Example::Color color() const {
+    return static_cast<MyGame::Example::Color>(GetField<uint8_t>(VT_COLOR, 8));
+  }
+  bool mutate_color(MyGame::Example::Color _color) {
+    return SetField<uint8_t>(VT_COLOR, static_cast<uint8_t>(_color), 8);
+  }
+  MyGame::Example::Any test_type() const {
+    return static_cast<MyGame::Example::Any>(GetField<uint8_t>(VT_TEST_TYPE, 0));
+  }
+  bool mutate_test_type(MyGame::Example::Any _test_type) {
+    return SetField<uint8_t>(VT_TEST_TYPE, static_cast<uint8_t>(_test_type), 0);
+  }
+  const void *test() const {
+    return GetPointer<const void *>(VT_TEST);
+  }
+  template<typename T> const T *test_as() const;
+  const MyGame::Example::Monster *test_as_Monster() const {
+    return test_type() == MyGame::Example::Any_Monster ? static_cast<const MyGame::Example::Monster *>(test()) : nullptr;
+  }
+  const MyGame::Example::TestSimpleTableWithEnum *test_as_TestSimpleTableWithEnum() const {
+    return test_type() == MyGame::Example::Any_TestSimpleTableWithEnum ? static_cast<const MyGame::Example::TestSimpleTableWithEnum *>(test()) : nullptr;
+  }
+  const MyGame::Example2::Monster *test_as_MyGame_Example2_Monster() const {
+    return test_type() == MyGame::Example::Any_MyGame_Example2_Monster ? static_cast<const MyGame::Example2::Monster *>(test()) : nullptr;
+  }
+  void *mutable_test() {
+    return GetPointer<void *>(VT_TEST);
+  }
+  const flatbuffers::Vector<const MyGame::Example::Test *> *test4() const {
+    return GetPointer<const flatbuffers::Vector<const MyGame::Example::Test *> *>(VT_TEST4);
+  }
+  flatbuffers::Vector<const MyGame::Example::Test *> *mutable_test4() {
+    return GetPointer<flatbuffers::Vector<const MyGame::Example::Test *> *>(VT_TEST4);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *testarrayofstring() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_TESTARRAYOFSTRING);
+  }
+  flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *mutable_testarrayofstring() {
+    return GetPointer<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_TESTARRAYOFSTRING);
+  }
+  /// an example documentation comment: this will end up in the generated code
+  /// multiline too
+  const flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Monster>> *testarrayoftables() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Monster>> *>(VT_TESTARRAYOFTABLES);
+  }
+  flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Monster>> *mutable_testarrayoftables() {
+    return GetPointer<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Monster>> *>(VT_TESTARRAYOFTABLES);
+  }
+  const MyGame::Example::Monster *enemy() const {
+    return GetPointer<const MyGame::Example::Monster *>(VT_ENEMY);
+  }
+  MyGame::Example::Monster *mutable_enemy() {
+    return GetPointer<MyGame::Example::Monster *>(VT_ENEMY);
+  }
+  const flatbuffers::Vector<uint8_t> *testnestedflatbuffer() const {
+    return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_TESTNESTEDFLATBUFFER);
+  }
+  flatbuffers::Vector<uint8_t> *mutable_testnestedflatbuffer() {
+    return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_TESTNESTEDFLATBUFFER);
+  }
+  const MyGame::Example::Monster *testnestedflatbuffer_nested_root() const {
+    return flatbuffers::GetRoot<MyGame::Example::Monster>(testnestedflatbuffer()->Data());
+  }
+  const MyGame::Example::Stat *testempty() const {
+    return GetPointer<const MyGame::Example::Stat *>(VT_TESTEMPTY);
+  }
+  MyGame::Example::Stat *mutable_testempty() {
+    return GetPointer<MyGame::Example::Stat *>(VT_TESTEMPTY);
+  }
+  bool testbool() const {
+    return GetField<uint8_t>(VT_TESTBOOL, 0) != 0;
+  }
+  bool mutate_testbool(bool _testbool) {
+    return SetField<uint8_t>(VT_TESTBOOL, static_cast<uint8_t>(_testbool), 0);
+  }
+  int32_t testhashs32_fnv1() const {
+    return GetField<int32_t>(VT_TESTHASHS32_FNV1, 0);
+  }
+  bool mutate_testhashs32_fnv1(int32_t _testhashs32_fnv1) {
+    return SetField<int32_t>(VT_TESTHASHS32_FNV1, _testhashs32_fnv1, 0);
+  }
+  uint32_t testhashu32_fnv1() const {
+    return GetField<uint32_t>(VT_TESTHASHU32_FNV1, 0);
+  }
+  bool mutate_testhashu32_fnv1(uint32_t _testhashu32_fnv1) {
+    return SetField<uint32_t>(VT_TESTHASHU32_FNV1, _testhashu32_fnv1, 0);
+  }
+  int64_t testhashs64_fnv1() const {
+    return GetField<int64_t>(VT_TESTHASHS64_FNV1, 0);
+  }
+  bool mutate_testhashs64_fnv1(int64_t _testhashs64_fnv1) {
+    return SetField<int64_t>(VT_TESTHASHS64_FNV1, _testhashs64_fnv1, 0);
+  }
+  uint64_t testhashu64_fnv1() const {
+    return GetField<uint64_t>(VT_TESTHASHU64_FNV1, 0);
+  }
+  bool mutate_testhashu64_fnv1(uint64_t _testhashu64_fnv1) {
+    return SetField<uint64_t>(VT_TESTHASHU64_FNV1, _testhashu64_fnv1, 0);
+  }
+  int32_t testhashs32_fnv1a() const {
+    return GetField<int32_t>(VT_TESTHASHS32_FNV1A, 0);
+  }
+  bool mutate_testhashs32_fnv1a(int32_t _testhashs32_fnv1a) {
+    return SetField<int32_t>(VT_TESTHASHS32_FNV1A, _testhashs32_fnv1a, 0);
+  }
+  uint32_t testhashu32_fnv1a() const {
+    return GetField<uint32_t>(VT_TESTHASHU32_FNV1A, 0);
+  }
+  bool mutate_testhashu32_fnv1a(uint32_t _testhashu32_fnv1a) {
+    return SetField<uint32_t>(VT_TESTHASHU32_FNV1A, _testhashu32_fnv1a, 0);
+  }
+  int64_t testhashs64_fnv1a() const {
+    return GetField<int64_t>(VT_TESTHASHS64_FNV1A, 0);
+  }
+  bool mutate_testhashs64_fnv1a(int64_t _testhashs64_fnv1a) {
+    return SetField<int64_t>(VT_TESTHASHS64_FNV1A, _testhashs64_fnv1a, 0);
+  }
+  uint64_t testhashu64_fnv1a() const {
+    return GetField<uint64_t>(VT_TESTHASHU64_FNV1A, 0);
+  }
+  bool mutate_testhashu64_fnv1a(uint64_t _testhashu64_fnv1a) {
+    return SetField<uint64_t>(VT_TESTHASHU64_FNV1A, _testhashu64_fnv1a, 0);
+  }
+  const flatbuffers::Vector<uint8_t> *testarrayofbools() const {
+    return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_TESTARRAYOFBOOLS);
+  }
+  flatbuffers::Vector<uint8_t> *mutable_testarrayofbools() {
+    return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_TESTARRAYOFBOOLS);
+  }
+  float testf() const {
+    return GetField<float>(VT_TESTF, 3.14159f);
+  }
+  bool mutate_testf(float _testf) {
+    return SetField<float>(VT_TESTF, _testf, 3.14159f);
+  }
+  float testf2() const {
+    return GetField<float>(VT_TESTF2, 3.0f);
+  }
+  bool mutate_testf2(float _testf2) {
+    return SetField<float>(VT_TESTF2, _testf2, 3.0f);
+  }
+  float testf3() const {
+    return GetField<float>(VT_TESTF3, 0.0f);
+  }
+  bool mutate_testf3(float _testf3) {
+    return SetField<float>(VT_TESTF3, _testf3, 0.0f);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *testarrayofstring2() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_TESTARRAYOFSTRING2);
+  }
+  flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *mutable_testarrayofstring2() {
+    return GetPointer<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_TESTARRAYOFSTRING2);
+  }
+  const flatbuffers::Vector<const MyGame::Example::Ability *> *testarrayofsortedstruct() const {
+    return GetPointer<const flatbuffers::Vector<const MyGame::Example::Ability *> *>(VT_TESTARRAYOFSORTEDSTRUCT);
+  }
+  flatbuffers::Vector<const MyGame::Example::Ability *> *mutable_testarrayofsortedstruct() {
+    return GetPointer<flatbuffers::Vector<const MyGame::Example::Ability *> *>(VT_TESTARRAYOFSORTEDSTRUCT);
+  }
+  const flatbuffers::Vector<uint8_t> *flex() const {
+    return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_FLEX);
+  }
+  flatbuffers::Vector<uint8_t> *mutable_flex() {
+    return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_FLEX);
+  }
+  flexbuffers::Reference flex_flexbuffer_root() const {
+    return flexbuffers::GetRoot(flex()->Data(), flex()->size());
+  }
+  const flatbuffers::Vector<const MyGame::Example::Test *> *test5() const {
+    return GetPointer<const flatbuffers::Vector<const MyGame::Example::Test *> *>(VT_TEST5);
+  }
+  flatbuffers::Vector<const MyGame::Example::Test *> *mutable_test5() {
+    return GetPointer<flatbuffers::Vector<const MyGame::Example::Test *> *>(VT_TEST5);
+  }
+  const flatbuffers::Vector<int64_t> *vector_of_longs() const {
+    return GetPointer<const flatbuffers::Vector<int64_t> *>(VT_VECTOR_OF_LONGS);
+  }
+  flatbuffers::Vector<int64_t> *mutable_vector_of_longs() {
+    return GetPointer<flatbuffers::Vector<int64_t> *>(VT_VECTOR_OF_LONGS);
+  }
+  const flatbuffers::Vector<double> *vector_of_doubles() const {
+    return GetPointer<const flatbuffers::Vector<double> *>(VT_VECTOR_OF_DOUBLES);
+  }
+  flatbuffers::Vector<double> *mutable_vector_of_doubles() {
+    return GetPointer<flatbuffers::Vector<double> *>(VT_VECTOR_OF_DOUBLES);
+  }
+  const MyGame::InParentNamespace *parent_namespace_test() const {
+    return GetPointer<const MyGame::InParentNamespace *>(VT_PARENT_NAMESPACE_TEST);
+  }
+  MyGame::InParentNamespace *mutable_parent_namespace_test() {
+    return GetPointer<MyGame::InParentNamespace *>(VT_PARENT_NAMESPACE_TEST);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *vector_of_referrables() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *>(VT_VECTOR_OF_REFERRABLES);
+  }
+  flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *mutable_vector_of_referrables() {
+    return GetPointer<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *>(VT_VECTOR_OF_REFERRABLES);
+  }
+  uint64_t single_weak_reference() const {
+    return GetField<uint64_t>(VT_SINGLE_WEAK_REFERENCE, 0);
+  }
+  bool mutate_single_weak_reference(uint64_t _single_weak_reference) {
+    return SetField<uint64_t>(VT_SINGLE_WEAK_REFERENCE, _single_weak_reference, 0);
+  }
+  const flatbuffers::Vector<uint64_t> *vector_of_weak_references() const {
+    return GetPointer<const flatbuffers::Vector<uint64_t> *>(VT_VECTOR_OF_WEAK_REFERENCES);
+  }
+  flatbuffers::Vector<uint64_t> *mutable_vector_of_weak_references() {
+    return GetPointer<flatbuffers::Vector<uint64_t> *>(VT_VECTOR_OF_WEAK_REFERENCES);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *vector_of_strong_referrables() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *>(VT_VECTOR_OF_STRONG_REFERRABLES);
+  }
+  flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *mutable_vector_of_strong_referrables() {
+    return GetPointer<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *>(VT_VECTOR_OF_STRONG_REFERRABLES);
+  }
+  uint64_t co_owning_reference() const {
+    return GetField<uint64_t>(VT_CO_OWNING_REFERENCE, 0);
+  }
+  bool mutate_co_owning_reference(uint64_t _co_owning_reference) {
+    return SetField<uint64_t>(VT_CO_OWNING_REFERENCE, _co_owning_reference, 0);
+  }
+  const flatbuffers::Vector<uint64_t> *vector_of_co_owning_references() const {
+    return GetPointer<const flatbuffers::Vector<uint64_t> *>(VT_VECTOR_OF_CO_OWNING_REFERENCES);
+  }
+  flatbuffers::Vector<uint64_t> *mutable_vector_of_co_owning_references() {
+    return GetPointer<flatbuffers::Vector<uint64_t> *>(VT_VECTOR_OF_CO_OWNING_REFERENCES);
+  }
+  uint64_t non_owning_reference() const {
+    return GetField<uint64_t>(VT_NON_OWNING_REFERENCE, 0);
+  }
+  bool mutate_non_owning_reference(uint64_t _non_owning_reference) {
+    return SetField<uint64_t>(VT_NON_OWNING_REFERENCE, _non_owning_reference, 0);
+  }
+  const flatbuffers::Vector<uint64_t> *vector_of_non_owning_references() const {
+    return GetPointer<const flatbuffers::Vector<uint64_t> *>(VT_VECTOR_OF_NON_OWNING_REFERENCES);
+  }
+  flatbuffers::Vector<uint64_t> *mutable_vector_of_non_owning_references() {
+    return GetPointer<flatbuffers::Vector<uint64_t> *>(VT_VECTOR_OF_NON_OWNING_REFERENCES);
+  }
+  MyGame::Example::AnyUniqueAliases any_unique_type() const {
+    return static_cast<MyGame::Example::AnyUniqueAliases>(GetField<uint8_t>(VT_ANY_UNIQUE_TYPE, 0));
+  }
+  bool mutate_any_unique_type(MyGame::Example::AnyUniqueAliases _any_unique_type) {
+    return SetField<uint8_t>(VT_ANY_UNIQUE_TYPE, static_cast<uint8_t>(_any_unique_type), 0);
+  }
+  const void *any_unique() const {
+    return GetPointer<const void *>(VT_ANY_UNIQUE);
+  }
+  template<typename T> const T *any_unique_as() const;
+  const MyGame::Example::Monster *any_unique_as_M() const {
+    return any_unique_type() == MyGame::Example::AnyUniqueAliases_M ? static_cast<const MyGame::Example::Monster *>(any_unique()) : nullptr;
+  }
+  const MyGame::Example::TestSimpleTableWithEnum *any_unique_as_TS() const {
+    return any_unique_type() == MyGame::Example::AnyUniqueAliases_TS ? static_cast<const MyGame::Example::TestSimpleTableWithEnum *>(any_unique()) : nullptr;
+  }
+  const MyGame::Example2::Monster *any_unique_as_M2() const {
+    return any_unique_type() == MyGame::Example::AnyUniqueAliases_M2 ? static_cast<const MyGame::Example2::Monster *>(any_unique()) : nullptr;
+  }
+  void *mutable_any_unique() {
+    return GetPointer<void *>(VT_ANY_UNIQUE);
+  }
+  MyGame::Example::AnyAmbiguousAliases any_ambiguous_type() const {
+    return static_cast<MyGame::Example::AnyAmbiguousAliases>(GetField<uint8_t>(VT_ANY_AMBIGUOUS_TYPE, 0));
+  }
+  bool mutate_any_ambiguous_type(MyGame::Example::AnyAmbiguousAliases _any_ambiguous_type) {
+    return SetField<uint8_t>(VT_ANY_AMBIGUOUS_TYPE, static_cast<uint8_t>(_any_ambiguous_type), 0);
+  }
+  const void *any_ambiguous() const {
+    return GetPointer<const void *>(VT_ANY_AMBIGUOUS);
+  }
+  const MyGame::Example::Monster *any_ambiguous_as_M1() const {
+    return any_ambiguous_type() == MyGame::Example::AnyAmbiguousAliases_M1 ? static_cast<const MyGame::Example::Monster *>(any_ambiguous()) : nullptr;
+  }
+  const MyGame::Example::Monster *any_ambiguous_as_M2() const {
+    return any_ambiguous_type() == MyGame::Example::AnyAmbiguousAliases_M2 ? static_cast<const MyGame::Example::Monster *>(any_ambiguous()) : nullptr;
+  }
+  const MyGame::Example::Monster *any_ambiguous_as_M3() const {
+    return any_ambiguous_type() == MyGame::Example::AnyAmbiguousAliases_M3 ? static_cast<const MyGame::Example::Monster *>(any_ambiguous()) : nullptr;
+  }
+  void *mutable_any_ambiguous() {
+    return GetPointer<void *>(VT_ANY_AMBIGUOUS);
+  }
+  const flatbuffers::Vector<uint8_t> *vector_of_enums() const {
+    return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_VECTOR_OF_ENUMS);
+  }
+  flatbuffers::Vector<uint8_t> *mutable_vector_of_enums() {
+    return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_VECTOR_OF_ENUMS);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<MyGame::Example::Vec3>(verifier, VT_POS) &&
+           VerifyField<int16_t>(verifier, VT_MANA) &&
+           VerifyField<int16_t>(verifier, VT_HP) &&
+           VerifyOffsetRequired(verifier, VT_NAME) &&
+           verifier.VerifyString(name()) &&
+           VerifyOffset(verifier, VT_INVENTORY) &&
+           verifier.VerifyVector(inventory()) &&
+           VerifyField<uint8_t>(verifier, VT_COLOR) &&
+           VerifyField<uint8_t>(verifier, VT_TEST_TYPE) &&
+           VerifyOffset(verifier, VT_TEST) &&
+           VerifyAny(verifier, test(), test_type()) &&
+           VerifyOffset(verifier, VT_TEST4) &&
+           verifier.VerifyVector(test4()) &&
+           VerifyOffset(verifier, VT_TESTARRAYOFSTRING) &&
+           verifier.VerifyVector(testarrayofstring()) &&
+           verifier.VerifyVectorOfStrings(testarrayofstring()) &&
+           VerifyOffset(verifier, VT_TESTARRAYOFTABLES) &&
+           verifier.VerifyVector(testarrayoftables()) &&
+           verifier.VerifyVectorOfTables(testarrayoftables()) &&
+           VerifyOffset(verifier, VT_ENEMY) &&
+           verifier.VerifyTable(enemy()) &&
+           VerifyOffset(verifier, VT_TESTNESTEDFLATBUFFER) &&
+           verifier.VerifyVector(testnestedflatbuffer()) &&
+           VerifyOffset(verifier, VT_TESTEMPTY) &&
+           verifier.VerifyTable(testempty()) &&
+           VerifyField<uint8_t>(verifier, VT_TESTBOOL) &&
+           VerifyField<int32_t>(verifier, VT_TESTHASHS32_FNV1) &&
+           VerifyField<uint32_t>(verifier, VT_TESTHASHU32_FNV1) &&
+           VerifyField<int64_t>(verifier, VT_TESTHASHS64_FNV1) &&
+           VerifyField<uint64_t>(verifier, VT_TESTHASHU64_FNV1) &&
+           VerifyField<int32_t>(verifier, VT_TESTHASHS32_FNV1A) &&
+           VerifyField<uint32_t>(verifier, VT_TESTHASHU32_FNV1A) &&
+           VerifyField<int64_t>(verifier, VT_TESTHASHS64_FNV1A) &&
+           VerifyField<uint64_t>(verifier, VT_TESTHASHU64_FNV1A) &&
+           VerifyOffset(verifier, VT_TESTARRAYOFBOOLS) &&
+           verifier.VerifyVector(testarrayofbools()) &&
+           VerifyField<float>(verifier, VT_TESTF) &&
+           VerifyField<float>(verifier, VT_TESTF2) &&
+           VerifyField<float>(verifier, VT_TESTF3) &&
+           VerifyOffset(verifier, VT_TESTARRAYOFSTRING2) &&
+           verifier.VerifyVector(testarrayofstring2()) &&
+           verifier.VerifyVectorOfStrings(testarrayofstring2()) &&
+           VerifyOffset(verifier, VT_TESTARRAYOFSORTEDSTRUCT) &&
+           verifier.VerifyVector(testarrayofsortedstruct()) &&
+           VerifyOffset(verifier, VT_FLEX) &&
+           verifier.VerifyVector(flex()) &&
+           VerifyOffset(verifier, VT_TEST5) &&
+           verifier.VerifyVector(test5()) &&
+           VerifyOffset(verifier, VT_VECTOR_OF_LONGS) &&
+           verifier.VerifyVector(vector_of_longs()) &&
+           VerifyOffset(verifier, VT_VECTOR_OF_DOUBLES) &&
+           verifier.VerifyVector(vector_of_doubles()) &&
+           VerifyOffset(verifier, VT_PARENT_NAMESPACE_TEST) &&
+           verifier.VerifyTable(parent_namespace_test()) &&
+           VerifyOffset(verifier, VT_VECTOR_OF_REFERRABLES) &&
+           verifier.VerifyVector(vector_of_referrables()) &&
+           verifier.VerifyVectorOfTables(vector_of_referrables()) &&
+           VerifyField<uint64_t>(verifier, VT_SINGLE_WEAK_REFERENCE) &&
+           VerifyOffset(verifier, VT_VECTOR_OF_WEAK_REFERENCES) &&
+           verifier.VerifyVector(vector_of_weak_references()) &&
+           VerifyOffset(verifier, VT_VECTOR_OF_STRONG_REFERRABLES) &&
+           verifier.VerifyVector(vector_of_strong_referrables()) &&
+           verifier.VerifyVectorOfTables(vector_of_strong_referrables()) &&
+           VerifyField<uint64_t>(verifier, VT_CO_OWNING_REFERENCE) &&
+           VerifyOffset(verifier, VT_VECTOR_OF_CO_OWNING_REFERENCES) &&
+           verifier.VerifyVector(vector_of_co_owning_references()) &&
+           VerifyField<uint64_t>(verifier, VT_NON_OWNING_REFERENCE) &&
+           VerifyOffset(verifier, VT_VECTOR_OF_NON_OWNING_REFERENCES) &&
+           verifier.VerifyVector(vector_of_non_owning_references()) &&
+           VerifyField<uint8_t>(verifier, VT_ANY_UNIQUE_TYPE) &&
+           VerifyOffset(verifier, VT_ANY_UNIQUE) &&
+           VerifyAnyUniqueAliases(verifier, any_unique(), any_unique_type()) &&
+           VerifyField<uint8_t>(verifier, VT_ANY_AMBIGUOUS_TYPE) &&
+           VerifyOffset(verifier, VT_ANY_AMBIGUOUS) &&
+           VerifyAnyAmbiguousAliases(verifier, any_ambiguous(), any_ambiguous_type()) &&
+           VerifyOffset(verifier, VT_VECTOR_OF_ENUMS) &&
+           verifier.VerifyVector(vector_of_enums()) &&
+           verifier.EndTable();
+  }
+  MonsterT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<Monster> Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+template<> inline const MyGame::Example::Monster *Monster::test_as<MyGame::Example::Monster>() const {
+  return test_as_Monster();
+}
+
+template<> inline const MyGame::Example::TestSimpleTableWithEnum *Monster::test_as<MyGame::Example::TestSimpleTableWithEnum>() const {
+  return test_as_TestSimpleTableWithEnum();
+}
+
+template<> inline const MyGame::Example2::Monster *Monster::test_as<MyGame::Example2::Monster>() const {
+  return test_as_MyGame_Example2_Monster();
+}
+
+template<> inline const MyGame::Example::Monster *Monster::any_unique_as<MyGame::Example::Monster>() const {
+  return any_unique_as_M();
+}
+
+template<> inline const MyGame::Example::TestSimpleTableWithEnum *Monster::any_unique_as<MyGame::Example::TestSimpleTableWithEnum>() const {
+  return any_unique_as_TS();
+}
+
+template<> inline const MyGame::Example2::Monster *Monster::any_unique_as<MyGame::Example2::Monster>() const {
+  return any_unique_as_M2();
+}
+
+struct MonsterBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_pos(const MyGame::Example::Vec3 *pos) {
+    fbb_.AddStruct(Monster::VT_POS, pos);
+  }
+  void add_mana(int16_t mana) {
+    fbb_.AddElement<int16_t>(Monster::VT_MANA, mana, 150);
+  }
+  void add_hp(int16_t hp) {
+    fbb_.AddElement<int16_t>(Monster::VT_HP, hp, 100);
+  }
+  void add_name(flatbuffers::Offset<flatbuffers::String> name) {
+    fbb_.AddOffset(Monster::VT_NAME, name);
+  }
+  void add_inventory(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> inventory) {
+    fbb_.AddOffset(Monster::VT_INVENTORY, inventory);
+  }
+  void add_color(MyGame::Example::Color color) {
+    fbb_.AddElement<uint8_t>(Monster::VT_COLOR, static_cast<uint8_t>(color), 8);
+  }
+  void add_test_type(MyGame::Example::Any test_type) {
+    fbb_.AddElement<uint8_t>(Monster::VT_TEST_TYPE, static_cast<uint8_t>(test_type), 0);
+  }
+  void add_test(flatbuffers::Offset<void> test) {
+    fbb_.AddOffset(Monster::VT_TEST, test);
+  }
+  void add_test4(flatbuffers::Offset<flatbuffers::Vector<const MyGame::Example::Test *>> test4) {
+    fbb_.AddOffset(Monster::VT_TEST4, test4);
+  }
+  void add_testarrayofstring(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> testarrayofstring) {
+    fbb_.AddOffset(Monster::VT_TESTARRAYOFSTRING, testarrayofstring);
+  }
+  void add_testarrayoftables(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Monster>>> testarrayoftables) {
+    fbb_.AddOffset(Monster::VT_TESTARRAYOFTABLES, testarrayoftables);
+  }
+  void add_enemy(flatbuffers::Offset<MyGame::Example::Monster> enemy) {
+    fbb_.AddOffset(Monster::VT_ENEMY, enemy);
+  }
+  void add_testnestedflatbuffer(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> testnestedflatbuffer) {
+    fbb_.AddOffset(Monster::VT_TESTNESTEDFLATBUFFER, testnestedflatbuffer);
+  }
+  void add_testempty(flatbuffers::Offset<MyGame::Example::Stat> testempty) {
+    fbb_.AddOffset(Monster::VT_TESTEMPTY, testempty);
+  }
+  void add_testbool(bool testbool) {
+    fbb_.AddElement<uint8_t>(Monster::VT_TESTBOOL, static_cast<uint8_t>(testbool), 0);
+  }
+  void add_testhashs32_fnv1(int32_t testhashs32_fnv1) {
+    fbb_.AddElement<int32_t>(Monster::VT_TESTHASHS32_FNV1, testhashs32_fnv1, 0);
+  }
+  void add_testhashu32_fnv1(uint32_t testhashu32_fnv1) {
+    fbb_.AddElement<uint32_t>(Monster::VT_TESTHASHU32_FNV1, testhashu32_fnv1, 0);
+  }
+  void add_testhashs64_fnv1(int64_t testhashs64_fnv1) {
+    fbb_.AddElement<int64_t>(Monster::VT_TESTHASHS64_FNV1, testhashs64_fnv1, 0);
+  }
+  void add_testhashu64_fnv1(uint64_t testhashu64_fnv1) {
+    fbb_.AddElement<uint64_t>(Monster::VT_TESTHASHU64_FNV1, testhashu64_fnv1, 0);
+  }
+  void add_testhashs32_fnv1a(int32_t testhashs32_fnv1a) {
+    fbb_.AddElement<int32_t>(Monster::VT_TESTHASHS32_FNV1A, testhashs32_fnv1a, 0);
+  }
+  void add_testhashu32_fnv1a(uint32_t testhashu32_fnv1a) {
+    fbb_.AddElement<uint32_t>(Monster::VT_TESTHASHU32_FNV1A, testhashu32_fnv1a, 0);
+  }
+  void add_testhashs64_fnv1a(int64_t testhashs64_fnv1a) {
+    fbb_.AddElement<int64_t>(Monster::VT_TESTHASHS64_FNV1A, testhashs64_fnv1a, 0);
+  }
+  void add_testhashu64_fnv1a(uint64_t testhashu64_fnv1a) {
+    fbb_.AddElement<uint64_t>(Monster::VT_TESTHASHU64_FNV1A, testhashu64_fnv1a, 0);
+  }
+  void add_testarrayofbools(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> testarrayofbools) {
+    fbb_.AddOffset(Monster::VT_TESTARRAYOFBOOLS, testarrayofbools);
+  }
+  void add_testf(float testf) {
+    fbb_.AddElement<float>(Monster::VT_TESTF, testf, 3.14159f);
+  }
+  void add_testf2(float testf2) {
+    fbb_.AddElement<float>(Monster::VT_TESTF2, testf2, 3.0f);
+  }
+  void add_testf3(float testf3) {
+    fbb_.AddElement<float>(Monster::VT_TESTF3, testf3, 0.0f);
+  }
+  void add_testarrayofstring2(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> testarrayofstring2) {
+    fbb_.AddOffset(Monster::VT_TESTARRAYOFSTRING2, testarrayofstring2);
+  }
+  void add_testarrayofsortedstruct(flatbuffers::Offset<flatbuffers::Vector<const MyGame::Example::Ability *>> testarrayofsortedstruct) {
+    fbb_.AddOffset(Monster::VT_TESTARRAYOFSORTEDSTRUCT, testarrayofsortedstruct);
+  }
+  void add_flex(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> flex) {
+    fbb_.AddOffset(Monster::VT_FLEX, flex);
+  }
+  void add_test5(flatbuffers::Offset<flatbuffers::Vector<const MyGame::Example::Test *>> test5) {
+    fbb_.AddOffset(Monster::VT_TEST5, test5);
+  }
+  void add_vector_of_longs(flatbuffers::Offset<flatbuffers::Vector<int64_t>> vector_of_longs) {
+    fbb_.AddOffset(Monster::VT_VECTOR_OF_LONGS, vector_of_longs);
+  }
+  void add_vector_of_doubles(flatbuffers::Offset<flatbuffers::Vector<double>> vector_of_doubles) {
+    fbb_.AddOffset(Monster::VT_VECTOR_OF_DOUBLES, vector_of_doubles);
+  }
+  void add_parent_namespace_test(flatbuffers::Offset<MyGame::InParentNamespace> parent_namespace_test) {
+    fbb_.AddOffset(Monster::VT_PARENT_NAMESPACE_TEST, parent_namespace_test);
+  }
+  void add_vector_of_referrables(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>>> vector_of_referrables) {
+    fbb_.AddOffset(Monster::VT_VECTOR_OF_REFERRABLES, vector_of_referrables);
+  }
+  void add_single_weak_reference(uint64_t single_weak_reference) {
+    fbb_.AddElement<uint64_t>(Monster::VT_SINGLE_WEAK_REFERENCE, single_weak_reference, 0);
+  }
+  void add_vector_of_weak_references(flatbuffers::Offset<flatbuffers::Vector<uint64_t>> vector_of_weak_references) {
+    fbb_.AddOffset(Monster::VT_VECTOR_OF_WEAK_REFERENCES, vector_of_weak_references);
+  }
+  void add_vector_of_strong_referrables(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>>> vector_of_strong_referrables) {
+    fbb_.AddOffset(Monster::VT_VECTOR_OF_STRONG_REFERRABLES, vector_of_strong_referrables);
+  }
+  void add_co_owning_reference(uint64_t co_owning_reference) {
+    fbb_.AddElement<uint64_t>(Monster::VT_CO_OWNING_REFERENCE, co_owning_reference, 0);
+  }
+  void add_vector_of_co_owning_references(flatbuffers::Offset<flatbuffers::Vector<uint64_t>> vector_of_co_owning_references) {
+    fbb_.AddOffset(Monster::VT_VECTOR_OF_CO_OWNING_REFERENCES, vector_of_co_owning_references);
+  }
+  void add_non_owning_reference(uint64_t non_owning_reference) {
+    fbb_.AddElement<uint64_t>(Monster::VT_NON_OWNING_REFERENCE, non_owning_reference, 0);
+  }
+  void add_vector_of_non_owning_references(flatbuffers::Offset<flatbuffers::Vector<uint64_t>> vector_of_non_owning_references) {
+    fbb_.AddOffset(Monster::VT_VECTOR_OF_NON_OWNING_REFERENCES, vector_of_non_owning_references);
+  }
+  void add_any_unique_type(MyGame::Example::AnyUniqueAliases any_unique_type) {
+    fbb_.AddElement<uint8_t>(Monster::VT_ANY_UNIQUE_TYPE, static_cast<uint8_t>(any_unique_type), 0);
+  }
+  void add_any_unique(flatbuffers::Offset<void> any_unique) {
+    fbb_.AddOffset(Monster::VT_ANY_UNIQUE, any_unique);
+  }
+  void add_any_ambiguous_type(MyGame::Example::AnyAmbiguousAliases any_ambiguous_type) {
+    fbb_.AddElement<uint8_t>(Monster::VT_ANY_AMBIGUOUS_TYPE, static_cast<uint8_t>(any_ambiguous_type), 0);
+  }
+  void add_any_ambiguous(flatbuffers::Offset<void> any_ambiguous) {
+    fbb_.AddOffset(Monster::VT_ANY_AMBIGUOUS, any_ambiguous);
+  }
+  void add_vector_of_enums(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> vector_of_enums) {
+    fbb_.AddOffset(Monster::VT_VECTOR_OF_ENUMS, vector_of_enums);
+  }
+  explicit MonsterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  MonsterBuilder &operator=(const MonsterBuilder &);
+  flatbuffers::Offset<Monster> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Monster>(end);
+    fbb_.Required(o, Monster::VT_NAME);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Monster> CreateMonster(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const MyGame::Example::Vec3 *pos = 0,
+    int16_t mana = 150,
+    int16_t hp = 100,
+    flatbuffers::Offset<flatbuffers::String> name = 0,
+    flatbuffers::Offset<flatbuffers::Vector<uint8_t>> inventory = 0,
+    MyGame::Example::Color color = MyGame::Example::Color_Blue,
+    MyGame::Example::Any test_type = MyGame::Example::Any_NONE,
+    flatbuffers::Offset<void> test = 0,
+    flatbuffers::Offset<flatbuffers::Vector<const MyGame::Example::Test *>> test4 = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> testarrayofstring = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Monster>>> testarrayoftables = 0,
+    flatbuffers::Offset<MyGame::Example::Monster> enemy = 0,
+    flatbuffers::Offset<flatbuffers::Vector<uint8_t>> testnestedflatbuffer = 0,
+    flatbuffers::Offset<MyGame::Example::Stat> testempty = 0,
+    bool testbool = false,
+    int32_t testhashs32_fnv1 = 0,
+    uint32_t testhashu32_fnv1 = 0,
+    int64_t testhashs64_fnv1 = 0,
+    uint64_t testhashu64_fnv1 = 0,
+    int32_t testhashs32_fnv1a = 0,
+    uint32_t testhashu32_fnv1a = 0,
+    int64_t testhashs64_fnv1a = 0,
+    uint64_t testhashu64_fnv1a = 0,
+    flatbuffers::Offset<flatbuffers::Vector<uint8_t>> testarrayofbools = 0,
+    float testf = 3.14159f,
+    float testf2 = 3.0f,
+    float testf3 = 0.0f,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> testarrayofstring2 = 0,
+    flatbuffers::Offset<flatbuffers::Vector<const MyGame::Example::Ability *>> testarrayofsortedstruct = 0,
+    flatbuffers::Offset<flatbuffers::Vector<uint8_t>> flex = 0,
+    flatbuffers::Offset<flatbuffers::Vector<const MyGame::Example::Test *>> test5 = 0,
+    flatbuffers::Offset<flatbuffers::Vector<int64_t>> vector_of_longs = 0,
+    flatbuffers::Offset<flatbuffers::Vector<double>> vector_of_doubles = 0,
+    flatbuffers::Offset<MyGame::InParentNamespace> parent_namespace_test = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>>> vector_of_referrables = 0,
+    uint64_t single_weak_reference = 0,
+    flatbuffers::Offset<flatbuffers::Vector<uint64_t>> vector_of_weak_references = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>>> vector_of_strong_referrables = 0,
+    uint64_t co_owning_reference = 0,
+    flatbuffers::Offset<flatbuffers::Vector<uint64_t>> vector_of_co_owning_references = 0,
+    uint64_t non_owning_reference = 0,
+    flatbuffers::Offset<flatbuffers::Vector<uint64_t>> vector_of_non_owning_references = 0,
+    MyGame::Example::AnyUniqueAliases any_unique_type = MyGame::Example::AnyUniqueAliases_NONE,
+    flatbuffers::Offset<void> any_unique = 0,
+    MyGame::Example::AnyAmbiguousAliases any_ambiguous_type = MyGame::Example::AnyAmbiguousAliases_NONE,
+    flatbuffers::Offset<void> any_ambiguous = 0,
+    flatbuffers::Offset<flatbuffers::Vector<uint8_t>> vector_of_enums = 0) {
+  MonsterBuilder builder_(_fbb);
+  builder_.add_non_owning_reference(non_owning_reference);
+  builder_.add_co_owning_reference(co_owning_reference);
+  builder_.add_single_weak_reference(single_weak_reference);
+  builder_.add_testhashu64_fnv1a(testhashu64_fnv1a);
+  builder_.add_testhashs64_fnv1a(testhashs64_fnv1a);
+  builder_.add_testhashu64_fnv1(testhashu64_fnv1);
+  builder_.add_testhashs64_fnv1(testhashs64_fnv1);
+  builder_.add_vector_of_enums(vector_of_enums);
+  builder_.add_any_ambiguous(any_ambiguous);
+  builder_.add_any_unique(any_unique);
+  builder_.add_vector_of_non_owning_references(vector_of_non_owning_references);
+  builder_.add_vector_of_co_owning_references(vector_of_co_owning_references);
+  builder_.add_vector_of_strong_referrables(vector_of_strong_referrables);
+  builder_.add_vector_of_weak_references(vector_of_weak_references);
+  builder_.add_vector_of_referrables(vector_of_referrables);
+  builder_.add_parent_namespace_test(parent_namespace_test);
+  builder_.add_vector_of_doubles(vector_of_doubles);
+  builder_.add_vector_of_longs(vector_of_longs);
+  builder_.add_test5(test5);
+  builder_.add_flex(flex);
+  builder_.add_testarrayofsortedstruct(testarrayofsortedstruct);
+  builder_.add_testarrayofstring2(testarrayofstring2);
+  builder_.add_testf3(testf3);
+  builder_.add_testf2(testf2);
+  builder_.add_testf(testf);
+  builder_.add_testarrayofbools(testarrayofbools);
+  builder_.add_testhashu32_fnv1a(testhashu32_fnv1a);
+  builder_.add_testhashs32_fnv1a(testhashs32_fnv1a);
+  builder_.add_testhashu32_fnv1(testhashu32_fnv1);
+  builder_.add_testhashs32_fnv1(testhashs32_fnv1);
+  builder_.add_testempty(testempty);
+  builder_.add_testnestedflatbuffer(testnestedflatbuffer);
+  builder_.add_enemy(enemy);
+  builder_.add_testarrayoftables(testarrayoftables);
+  builder_.add_testarrayofstring(testarrayofstring);
+  builder_.add_test4(test4);
+  builder_.add_test(test);
+  builder_.add_inventory(inventory);
+  builder_.add_name(name);
+  builder_.add_pos(pos);
+  builder_.add_hp(hp);
+  builder_.add_mana(mana);
+  builder_.add_any_ambiguous_type(any_ambiguous_type);
+  builder_.add_any_unique_type(any_unique_type);
+  builder_.add_testbool(testbool);
+  builder_.add_test_type(test_type);
+  builder_.add_color(color);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<Monster> CreateMonsterDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const MyGame::Example::Vec3 *pos = 0,
+    int16_t mana = 150,
+    int16_t hp = 100,
+    const char *name = nullptr,
+    const std::vector<uint8_t> *inventory = nullptr,
+    MyGame::Example::Color color = MyGame::Example::Color_Blue,
+    MyGame::Example::Any test_type = MyGame::Example::Any_NONE,
+    flatbuffers::Offset<void> test = 0,
+    const std::vector<MyGame::Example::Test> *test4 = nullptr,
+    const std::vector<flatbuffers::Offset<flatbuffers::String>> *testarrayofstring = nullptr,
+    const std::vector<flatbuffers::Offset<MyGame::Example::Monster>> *testarrayoftables = nullptr,
+    flatbuffers::Offset<MyGame::Example::Monster> enemy = 0,
+    const std::vector<uint8_t> *testnestedflatbuffer = nullptr,
+    flatbuffers::Offset<MyGame::Example::Stat> testempty = 0,
+    bool testbool = false,
+    int32_t testhashs32_fnv1 = 0,
+    uint32_t testhashu32_fnv1 = 0,
+    int64_t testhashs64_fnv1 = 0,
+    uint64_t testhashu64_fnv1 = 0,
+    int32_t testhashs32_fnv1a = 0,
+    uint32_t testhashu32_fnv1a = 0,
+    int64_t testhashs64_fnv1a = 0,
+    uint64_t testhashu64_fnv1a = 0,
+    const std::vector<uint8_t> *testarrayofbools = nullptr,
+    float testf = 3.14159f,
+    float testf2 = 3.0f,
+    float testf3 = 0.0f,
+    const std::vector<flatbuffers::Offset<flatbuffers::String>> *testarrayofstring2 = nullptr,
+    const std::vector<MyGame::Example::Ability> *testarrayofsortedstruct = nullptr,
+    const std::vector<uint8_t> *flex = nullptr,
+    const std::vector<MyGame::Example::Test> *test5 = nullptr,
+    const std::vector<int64_t> *vector_of_longs = nullptr,
+    const std::vector<double> *vector_of_doubles = nullptr,
+    flatbuffers::Offset<MyGame::InParentNamespace> parent_namespace_test = 0,
+    const std::vector<flatbuffers::Offset<MyGame::Example::Referrable>> *vector_of_referrables = nullptr,
+    uint64_t single_weak_reference = 0,
+    const std::vector<uint64_t> *vector_of_weak_references = nullptr,
+    const std::vector<flatbuffers::Offset<MyGame::Example::Referrable>> *vector_of_strong_referrables = nullptr,
+    uint64_t co_owning_reference = 0,
+    const std::vector<uint64_t> *vector_of_co_owning_references = nullptr,
+    uint64_t non_owning_reference = 0,
+    const std::vector<uint64_t> *vector_of_non_owning_references = nullptr,
+    MyGame::Example::AnyUniqueAliases any_unique_type = MyGame::Example::AnyUniqueAliases_NONE,
+    flatbuffers::Offset<void> any_unique = 0,
+    MyGame::Example::AnyAmbiguousAliases any_ambiguous_type = MyGame::Example::AnyAmbiguousAliases_NONE,
+    flatbuffers::Offset<void> any_ambiguous = 0,
+    const std::vector<uint8_t> *vector_of_enums = nullptr) {
+  auto name__ = name ? _fbb.CreateString(name) : 0;
+  auto inventory__ = inventory ? _fbb.CreateVector<uint8_t>(*inventory) : 0;
+  auto test4__ = test4 ? _fbb.CreateVectorOfStructs<MyGame::Example::Test>(*test4) : 0;
+  auto testarrayofstring__ = testarrayofstring ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*testarrayofstring) : 0;
+  auto testarrayoftables__ = testarrayoftables ? _fbb.CreateVector<flatbuffers::Offset<MyGame::Example::Monster>>(*testarrayoftables) : 0;
+  auto testnestedflatbuffer__ = testnestedflatbuffer ? _fbb.CreateVector<uint8_t>(*testnestedflatbuffer) : 0;
+  auto testarrayofbools__ = testarrayofbools ? _fbb.CreateVector<uint8_t>(*testarrayofbools) : 0;
+  auto testarrayofstring2__ = testarrayofstring2 ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*testarrayofstring2) : 0;
+  auto testarrayofsortedstruct__ = testarrayofsortedstruct ? _fbb.CreateVectorOfStructs<MyGame::Example::Ability>(*testarrayofsortedstruct) : 0;
+  auto flex__ = flex ? _fbb.CreateVector<uint8_t>(*flex) : 0;
+  auto test5__ = test5 ? _fbb.CreateVectorOfStructs<MyGame::Example::Test>(*test5) : 0;
+  auto vector_of_longs__ = vector_of_longs ? _fbb.CreateVector<int64_t>(*vector_of_longs) : 0;
+  auto vector_of_doubles__ = vector_of_doubles ? _fbb.CreateVector<double>(*vector_of_doubles) : 0;
+  auto vector_of_referrables__ = vector_of_referrables ? _fbb.CreateVector<flatbuffers::Offset<MyGame::Example::Referrable>>(*vector_of_referrables) : 0;
+  auto vector_of_weak_references__ = vector_of_weak_references ? _fbb.CreateVector<uint64_t>(*vector_of_weak_references) : 0;
+  auto vector_of_strong_referrables__ = vector_of_strong_referrables ? _fbb.CreateVector<flatbuffers::Offset<MyGame::Example::Referrable>>(*vector_of_strong_referrables) : 0;
+  auto vector_of_co_owning_references__ = vector_of_co_owning_references ? _fbb.CreateVector<uint64_t>(*vector_of_co_owning_references) : 0;
+  auto vector_of_non_owning_references__ = vector_of_non_owning_references ? _fbb.CreateVector<uint64_t>(*vector_of_non_owning_references) : 0;
+  auto vector_of_enums__ = vector_of_enums ? _fbb.CreateVector<uint8_t>(*vector_of_enums) : 0;
+  return MyGame::Example::CreateMonster(
+      _fbb,
+      pos,
+      mana,
+      hp,
+      name__,
+      inventory__,
+      color,
+      test_type,
+      test,
+      test4__,
+      testarrayofstring__,
+      testarrayoftables__,
+      enemy,
+      testnestedflatbuffer__,
+      testempty,
+      testbool,
+      testhashs32_fnv1,
+      testhashu32_fnv1,
+      testhashs64_fnv1,
+      testhashu64_fnv1,
+      testhashs32_fnv1a,
+      testhashu32_fnv1a,
+      testhashs64_fnv1a,
+      testhashu64_fnv1a,
+      testarrayofbools__,
+      testf,
+      testf2,
+      testf3,
+      testarrayofstring2__,
+      testarrayofsortedstruct__,
+      flex__,
+      test5__,
+      vector_of_longs__,
+      vector_of_doubles__,
+      parent_namespace_test,
+      vector_of_referrables__,
+      single_weak_reference,
+      vector_of_weak_references__,
+      vector_of_strong_referrables__,
+      co_owning_reference,
+      vector_of_co_owning_references__,
+      non_owning_reference,
+      vector_of_non_owning_references__,
+      any_unique_type,
+      any_unique,
+      any_ambiguous_type,
+      any_ambiguous,
+      vector_of_enums__);
+}
+
+flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+struct TypeAliasesT : public flatbuffers::NativeTable {
+  typedef TypeAliases TableType;
+  int8_t i8;
+  uint8_t u8;
+  int16_t i16;
+  uint16_t u16;
+  int32_t i32;
+  uint32_t u32;
+  int64_t i64;
+  uint64_t u64;
+  float f32;
+  double f64;
+  std::vector<int8_t> v8;
+  std::vector<double> vf64;
+  TypeAliasesT()
+      : i8(0),
+        u8(0),
+        i16(0),
+        u16(0),
+        i32(0),
+        u32(0),
+        i64(0),
+        u64(0),
+        f32(0.0f),
+        f64(0.0) {
+  }
+};
+
+inline bool operator==(const TypeAliasesT &lhs, const TypeAliasesT &rhs) {
+  return
+      (lhs.i8 == rhs.i8) &&
+      (lhs.u8 == rhs.u8) &&
+      (lhs.i16 == rhs.i16) &&
+      (lhs.u16 == rhs.u16) &&
+      (lhs.i32 == rhs.i32) &&
+      (lhs.u32 == rhs.u32) &&
+      (lhs.i64 == rhs.i64) &&
+      (lhs.u64 == rhs.u64) &&
+      (lhs.f32 == rhs.f32) &&
+      (lhs.f64 == rhs.f64) &&
+      (lhs.v8 == rhs.v8) &&
+      (lhs.vf64 == rhs.vf64);
+}
+
+inline bool operator!=(const TypeAliasesT &lhs, const TypeAliasesT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct TypeAliases FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef TypeAliasesT NativeTableType;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return TypeAliasesTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_I8 = 4,
+    VT_U8 = 6,
+    VT_I16 = 8,
+    VT_U16 = 10,
+    VT_I32 = 12,
+    VT_U32 = 14,
+    VT_I64 = 16,
+    VT_U64 = 18,
+    VT_F32 = 20,
+    VT_F64 = 22,
+    VT_V8 = 24,
+    VT_VF64 = 26
+  };
+  int8_t i8() const {
+    return GetField<int8_t>(VT_I8, 0);
+  }
+  bool mutate_i8(int8_t _i8) {
+    return SetField<int8_t>(VT_I8, _i8, 0);
+  }
+  uint8_t u8() const {
+    return GetField<uint8_t>(VT_U8, 0);
+  }
+  bool mutate_u8(uint8_t _u8) {
+    return SetField<uint8_t>(VT_U8, _u8, 0);
+  }
+  int16_t i16() const {
+    return GetField<int16_t>(VT_I16, 0);
+  }
+  bool mutate_i16(int16_t _i16) {
+    return SetField<int16_t>(VT_I16, _i16, 0);
+  }
+  uint16_t u16() const {
+    return GetField<uint16_t>(VT_U16, 0);
+  }
+  bool mutate_u16(uint16_t _u16) {
+    return SetField<uint16_t>(VT_U16, _u16, 0);
+  }
+  int32_t i32() const {
+    return GetField<int32_t>(VT_I32, 0);
+  }
+  bool mutate_i32(int32_t _i32) {
+    return SetField<int32_t>(VT_I32, _i32, 0);
+  }
+  uint32_t u32() const {
+    return GetField<uint32_t>(VT_U32, 0);
+  }
+  bool mutate_u32(uint32_t _u32) {
+    return SetField<uint32_t>(VT_U32, _u32, 0);
+  }
+  int64_t i64() const {
+    return GetField<int64_t>(VT_I64, 0);
+  }
+  bool mutate_i64(int64_t _i64) {
+    return SetField<int64_t>(VT_I64, _i64, 0);
+  }
+  uint64_t u64() const {
+    return GetField<uint64_t>(VT_U64, 0);
+  }
+  bool mutate_u64(uint64_t _u64) {
+    return SetField<uint64_t>(VT_U64, _u64, 0);
+  }
+  float f32() const {
+    return GetField<float>(VT_F32, 0.0f);
+  }
+  bool mutate_f32(float _f32) {
+    return SetField<float>(VT_F32, _f32, 0.0f);
+  }
+  double f64() const {
+    return GetField<double>(VT_F64, 0.0);
+  }
+  bool mutate_f64(double _f64) {
+    return SetField<double>(VT_F64, _f64, 0.0);
+  }
+  const flatbuffers::Vector<int8_t> *v8() const {
+    return GetPointer<const flatbuffers::Vector<int8_t> *>(VT_V8);
+  }
+  flatbuffers::Vector<int8_t> *mutable_v8() {
+    return GetPointer<flatbuffers::Vector<int8_t> *>(VT_V8);
+  }
+  const flatbuffers::Vector<double> *vf64() const {
+    return GetPointer<const flatbuffers::Vector<double> *>(VT_VF64);
+  }
+  flatbuffers::Vector<double> *mutable_vf64() {
+    return GetPointer<flatbuffers::Vector<double> *>(VT_VF64);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<int8_t>(verifier, VT_I8) &&
+           VerifyField<uint8_t>(verifier, VT_U8) &&
+           VerifyField<int16_t>(verifier, VT_I16) &&
+           VerifyField<uint16_t>(verifier, VT_U16) &&
+           VerifyField<int32_t>(verifier, VT_I32) &&
+           VerifyField<uint32_t>(verifier, VT_U32) &&
+           VerifyField<int64_t>(verifier, VT_I64) &&
+           VerifyField<uint64_t>(verifier, VT_U64) &&
+           VerifyField<float>(verifier, VT_F32) &&
+           VerifyField<double>(verifier, VT_F64) &&
+           VerifyOffset(verifier, VT_V8) &&
+           verifier.VerifyVector(v8()) &&
+           VerifyOffset(verifier, VT_VF64) &&
+           verifier.VerifyVector(vf64()) &&
+           verifier.EndTable();
+  }
+  TypeAliasesT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(TypeAliasesT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<TypeAliases> Pack(flatbuffers::FlatBufferBuilder &_fbb, const TypeAliasesT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct TypeAliasesBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_i8(int8_t i8) {
+    fbb_.AddElement<int8_t>(TypeAliases::VT_I8, i8, 0);
+  }
+  void add_u8(uint8_t u8) {
+    fbb_.AddElement<uint8_t>(TypeAliases::VT_U8, u8, 0);
+  }
+  void add_i16(int16_t i16) {
+    fbb_.AddElement<int16_t>(TypeAliases::VT_I16, i16, 0);
+  }
+  void add_u16(uint16_t u16) {
+    fbb_.AddElement<uint16_t>(TypeAliases::VT_U16, u16, 0);
+  }
+  void add_i32(int32_t i32) {
+    fbb_.AddElement<int32_t>(TypeAliases::VT_I32, i32, 0);
+  }
+  void add_u32(uint32_t u32) {
+    fbb_.AddElement<uint32_t>(TypeAliases::VT_U32, u32, 0);
+  }
+  void add_i64(int64_t i64) {
+    fbb_.AddElement<int64_t>(TypeAliases::VT_I64, i64, 0);
+  }
+  void add_u64(uint64_t u64) {
+    fbb_.AddElement<uint64_t>(TypeAliases::VT_U64, u64, 0);
+  }
+  void add_f32(float f32) {
+    fbb_.AddElement<float>(TypeAliases::VT_F32, f32, 0.0f);
+  }
+  void add_f64(double f64) {
+    fbb_.AddElement<double>(TypeAliases::VT_F64, f64, 0.0);
+  }
+  void add_v8(flatbuffers::Offset<flatbuffers::Vector<int8_t>> v8) {
+    fbb_.AddOffset(TypeAliases::VT_V8, v8);
+  }
+  void add_vf64(flatbuffers::Offset<flatbuffers::Vector<double>> vf64) {
+    fbb_.AddOffset(TypeAliases::VT_VF64, vf64);
+  }
+  explicit TypeAliasesBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  TypeAliasesBuilder &operator=(const TypeAliasesBuilder &);
+  flatbuffers::Offset<TypeAliases> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<TypeAliases>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<TypeAliases> CreateTypeAliases(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    int8_t i8 = 0,
+    uint8_t u8 = 0,
+    int16_t i16 = 0,
+    uint16_t u16 = 0,
+    int32_t i32 = 0,
+    uint32_t u32 = 0,
+    int64_t i64 = 0,
+    uint64_t u64 = 0,
+    float f32 = 0.0f,
+    double f64 = 0.0,
+    flatbuffers::Offset<flatbuffers::Vector<int8_t>> v8 = 0,
+    flatbuffers::Offset<flatbuffers::Vector<double>> vf64 = 0) {
+  TypeAliasesBuilder builder_(_fbb);
+  builder_.add_f64(f64);
+  builder_.add_u64(u64);
+  builder_.add_i64(i64);
+  builder_.add_vf64(vf64);
+  builder_.add_v8(v8);
+  builder_.add_f32(f32);
+  builder_.add_u32(u32);
+  builder_.add_i32(i32);
+  builder_.add_u16(u16);
+  builder_.add_i16(i16);
+  builder_.add_u8(u8);
+  builder_.add_i8(i8);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<TypeAliases> CreateTypeAliasesDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    int8_t i8 = 0,
+    uint8_t u8 = 0,
+    int16_t i16 = 0,
+    uint16_t u16 = 0,
+    int32_t i32 = 0,
+    uint32_t u32 = 0,
+    int64_t i64 = 0,
+    uint64_t u64 = 0,
+    float f32 = 0.0f,
+    double f64 = 0.0,
+    const std::vector<int8_t> *v8 = nullptr,
+    const std::vector<double> *vf64 = nullptr) {
+  auto v8__ = v8 ? _fbb.CreateVector<int8_t>(*v8) : 0;
+  auto vf64__ = vf64 ? _fbb.CreateVector<double>(*vf64) : 0;
+  return MyGame::Example::CreateTypeAliases(
+      _fbb,
+      i8,
+      u8,
+      i16,
+      u16,
+      i32,
+      u32,
+      i64,
+      u64,
+      f32,
+      f64,
+      v8__,
+      vf64__);
+}
+
+flatbuffers::Offset<TypeAliases> CreateTypeAliases(flatbuffers::FlatBufferBuilder &_fbb, const TypeAliasesT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+}  // namespace Example
+
+inline InParentNamespaceT *InParentNamespace::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = new InParentNamespaceT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+inline void InParentNamespace::UnPackTo(InParentNamespaceT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+}
+
+inline flatbuffers::Offset<InParentNamespace> InParentNamespace::Pack(flatbuffers::FlatBufferBuilder &_fbb, const InParentNamespaceT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateInParentNamespace(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<InParentNamespace> CreateInParentNamespace(flatbuffers::FlatBufferBuilder &_fbb, const InParentNamespaceT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const InParentNamespaceT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  return MyGame::CreateInParentNamespace(
+      _fbb);
+}
+
+namespace Example2 {
+
+inline MonsterT *Monster::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = new MonsterT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+inline void Monster::UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+}
+
+inline flatbuffers::Offset<Monster> Monster::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateMonster(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const MonsterT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  return MyGame::Example2::CreateMonster(
+      _fbb);
+}
+
+}  // namespace Example2
+
+namespace Example {
+
+inline TestSimpleTableWithEnumT *TestSimpleTableWithEnum::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = new TestSimpleTableWithEnumT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+inline void TestSimpleTableWithEnum::UnPackTo(TestSimpleTableWithEnumT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+  { auto _e = color(); _o->color = _e; };
+}
+
+inline flatbuffers::Offset<TestSimpleTableWithEnum> TestSimpleTableWithEnum::Pack(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateTestSimpleTableWithEnum(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const TestSimpleTableWithEnumT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  auto _color = _o->color;
+  return MyGame::Example::CreateTestSimpleTableWithEnum(
+      _fbb,
+      _color);
+}
+
+inline StatT *Stat::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = new StatT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+inline void Stat::UnPackTo(StatT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+  { auto _e = id(); if (_e) _o->id = _e->str(); };
+  { auto _e = val(); _o->val = _e; };
+  { auto _e = count(); _o->count = _e; };
+}
+
+inline flatbuffers::Offset<Stat> Stat::Pack(flatbuffers::FlatBufferBuilder &_fbb, const StatT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateStat(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<Stat> CreateStat(flatbuffers::FlatBufferBuilder &_fbb, const StatT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const StatT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  auto _id = _o->id.empty() ? 0 : _fbb.CreateString(_o->id);
+  auto _val = _o->val;
+  auto _count = _o->count;
+  return MyGame::Example::CreateStat(
+      _fbb,
+      _id,
+      _val,
+      _count);
+}
+
+inline ReferrableT *Referrable::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = new ReferrableT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+inline void Referrable::UnPackTo(ReferrableT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+  { auto _e = id(); _o->id = _e; };
+}
+
+inline flatbuffers::Offset<Referrable> Referrable::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ReferrableT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateReferrable(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<Referrable> CreateReferrable(flatbuffers::FlatBufferBuilder &_fbb, const ReferrableT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ReferrableT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  auto _id = _o->id;
+  return MyGame::Example::CreateReferrable(
+      _fbb,
+      _id);
+}
+
+inline MonsterT *Monster::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = new MonsterT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+inline void Monster::UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+  { auto _e = pos(); if (_e) _o->pos = flatbuffers::unique_ptr<MyGame::Example::Vec3>(new MyGame::Example::Vec3(*_e)); };
+  { auto _e = mana(); _o->mana = _e; };
+  { auto _e = hp(); _o->hp = _e; };
+  { auto _e = name(); if (_e) _o->name = _e->str(); };
+  { auto _e = inventory(); if (_e) { _o->inventory.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->inventory[_i] = _e->Get(_i); } } };
+  { auto _e = color(); _o->color = _e; };
+  { auto _e = test_type(); _o->test.type = _e; };
+  { auto _e = test(); if (_e) _o->test.value = AnyUnion::UnPack(_e, test_type(), _resolver); };
+  { auto _e = test4(); if (_e) { _o->test4.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->test4[_i] = *_e->Get(_i); } } };
+  { auto _e = testarrayofstring(); if (_e) { _o->testarrayofstring.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofstring[_i] = _e->Get(_i)->str(); } } };
+  { auto _e = testarrayoftables(); if (_e) { _o->testarrayoftables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayoftables[_i] = flatbuffers::unique_ptr<MyGame::Example::MonsterT>(_e->Get(_i)->UnPack(_resolver)); } } };
+  { auto _e = enemy(); if (_e) _o->enemy = flatbuffers::unique_ptr<MyGame::Example::MonsterT>(_e->UnPack(_resolver)); };
+  { auto _e = testnestedflatbuffer(); if (_e) { _o->testnestedflatbuffer.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testnestedflatbuffer[_i] = _e->Get(_i); } } };
+  { auto _e = testempty(); if (_e) _o->testempty = flatbuffers::unique_ptr<MyGame::Example::StatT>(_e->UnPack(_resolver)); };
+  { auto _e = testbool(); _o->testbool = _e; };
+  { auto _e = testhashs32_fnv1(); _o->testhashs32_fnv1 = _e; };
+  { auto _e = testhashu32_fnv1(); _o->testhashu32_fnv1 = _e; };
+  { auto _e = testhashs64_fnv1(); _o->testhashs64_fnv1 = _e; };
+  { auto _e = testhashu64_fnv1(); _o->testhashu64_fnv1 = _e; };
+  { auto _e = testhashs32_fnv1a(); _o->testhashs32_fnv1a = _e; };
+  { auto _e = testhashu32_fnv1a(); //scalar resolver, naked 
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->testhashu32_fnv1a), static_cast<flatbuffers::hash_value_t>(_e)); else _o->testhashu32_fnv1a = nullptr; };
+  { auto _e = testhashs64_fnv1a(); _o->testhashs64_fnv1a = _e; };
+  { auto _e = testhashu64_fnv1a(); _o->testhashu64_fnv1a = _e; };
+  { auto _e = testarrayofbools(); if (_e) { _o->testarrayofbools.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofbools[_i] = _e->Get(_i) != 0; } } };
+  { auto _e = testf(); _o->testf = _e; };
+  { auto _e = testf2(); _o->testf2 = _e; };
+  { auto _e = testf3(); _o->testf3 = _e; };
+  { auto _e = testarrayofstring2(); if (_e) { _o->testarrayofstring2.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofstring2[_i] = _e->Get(_i)->str(); } } };
+  { auto _e = testarrayofsortedstruct(); if (_e) { _o->testarrayofsortedstruct.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofsortedstruct[_i] = *_e->Get(_i); } } };
+  { auto _e = flex(); if (_e) { _o->flex.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->flex[_i] = _e->Get(_i); } } };
+  { auto _e = test5(); if (_e) { _o->test5.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->test5[_i] = *_e->Get(_i); } } };
+  { auto _e = vector_of_longs(); if (_e) { _o->vector_of_longs.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_longs[_i] = _e->Get(_i); } } };
+  { auto _e = vector_of_doubles(); if (_e) { _o->vector_of_doubles.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_doubles[_i] = _e->Get(_i); } } };
+  { auto _e = parent_namespace_test(); if (_e) _o->parent_namespace_test = flatbuffers::unique_ptr<MyGame::InParentNamespaceT>(_e->UnPack(_resolver)); };
+  { auto _e = vector_of_referrables(); if (_e) { _o->vector_of_referrables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_referrables[_i] = flatbuffers::unique_ptr<MyGame::Example::ReferrableT>(_e->Get(_i)->UnPack(_resolver)); } } };
+  { auto _e = single_weak_reference(); //scalar resolver, naked 
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->single_weak_reference), static_cast<flatbuffers::hash_value_t>(_e)); else _o->single_weak_reference = nullptr; };
+  { auto _e = vector_of_weak_references(); if (_e) { _o->vector_of_weak_references.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { //vector resolver, naked
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->vector_of_weak_references[_i]), static_cast<flatbuffers::hash_value_t>(_e->Get(_i))); else _o->vector_of_weak_references[_i] = nullptr; } } };
+  { auto _e = vector_of_strong_referrables(); if (_e) { _o->vector_of_strong_referrables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_strong_referrables[_i] = flatbuffers::unique_ptr<MyGame::Example::ReferrableT>(_e->Get(_i)->UnPack(_resolver)); } } };
+  { auto _e = co_owning_reference(); //scalar resolver, naked 
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->co_owning_reference), static_cast<flatbuffers::hash_value_t>(_e)); else _o->co_owning_reference = nullptr; };
+  { auto _e = vector_of_co_owning_references(); if (_e) { _o->vector_of_co_owning_references.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { //vector resolver, default_ptr_type
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->vector_of_co_owning_references[_i]), static_cast<flatbuffers::hash_value_t>(_e->Get(_i)));/* else do nothing */; } } };
+  { auto _e = non_owning_reference(); //scalar resolver, naked 
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->non_owning_reference), static_cast<flatbuffers::hash_value_t>(_e)); else _o->non_owning_reference = nullptr; };
+  { auto _e = vector_of_non_owning_references(); if (_e) { _o->vector_of_non_owning_references.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { //vector resolver, naked
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->vector_of_non_owning_references[_i]), static_cast<flatbuffers::hash_value_t>(_e->Get(_i))); else _o->vector_of_non_owning_references[_i] = nullptr; } } };
+  { auto _e = any_unique_type(); _o->any_unique.type = _e; };
+  { auto _e = any_unique(); if (_e) _o->any_unique.value = AnyUniqueAliasesUnion::UnPack(_e, any_unique_type(), _resolver); };
+  { auto _e = any_ambiguous_type(); _o->any_ambiguous.type = _e; };
+  { auto _e = any_ambiguous(); if (_e) _o->any_ambiguous.value = AnyAmbiguousAliasesUnion::UnPack(_e, any_ambiguous_type(), _resolver); };
+  { auto _e = vector_of_enums(); if (_e) { _o->vector_of_enums.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_enums[_i] = static_cast<MyGame::Example::Color>(_e->Get(_i)); } } };
+}
+
+inline flatbuffers::Offset<Monster> Monster::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateMonster(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const MonsterT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  auto _pos = _o->pos ? _o->pos.get() : 0;
+  auto _mana = _o->mana;
+  auto _hp = _o->hp;
+  auto _name = _fbb.CreateString(_o->name);
+  auto _inventory = _o->inventory.size() ? _fbb.CreateVector(_o->inventory) : 0;
+  auto _color = _o->color;
+  auto _test_type = _o->test.type;
+  auto _test = _o->test.Pack(_fbb);
+  auto _test4 = _o->test4.size() ? _fbb.CreateVectorOfStructs(_o->test4) : 0;
+  auto _testarrayofstring = _o->testarrayofstring.size() ? _fbb.CreateVectorOfStrings(_o->testarrayofstring) : 0;
+  auto _testarrayoftables = _o->testarrayoftables.size() ? _fbb.CreateVector<flatbuffers::Offset<MyGame::Example::Monster>> (_o->testarrayoftables.size(), [](size_t i, _VectorArgs *__va) { return CreateMonster(*__va->__fbb, __va->__o->testarrayoftables[i].get(), __va->__rehasher); }, &_va ) : 0;
+  auto _enemy = _o->enemy ? CreateMonster(_fbb, _o->enemy.get(), _rehasher) : 0;
+  auto _testnestedflatbuffer = _o->testnestedflatbuffer.size() ? _fbb.CreateVector(_o->testnestedflatbuffer) : 0;
+  auto _testempty = _o->testempty ? CreateStat(_fbb, _o->testempty.get(), _rehasher) : 0;
+  auto _testbool = _o->testbool;
+  auto _testhashs32_fnv1 = _o->testhashs32_fnv1;
+  auto _testhashu32_fnv1 = _o->testhashu32_fnv1;
+  auto _testhashs64_fnv1 = _o->testhashs64_fnv1;
+  auto _testhashu64_fnv1 = _o->testhashu64_fnv1;
+  auto _testhashs32_fnv1a = _o->testhashs32_fnv1a;
+  auto _testhashu32_fnv1a = _rehasher ? static_cast<uint32_t>((*_rehasher)(_o->testhashu32_fnv1a)) : 0;
+  auto _testhashs64_fnv1a = _o->testhashs64_fnv1a;
+  auto _testhashu64_fnv1a = _o->testhashu64_fnv1a;
+  auto _testarrayofbools = _o->testarrayofbools.size() ? _fbb.CreateVector(_o->testarrayofbools) : 0;
+  auto _testf = _o->testf;
+  auto _testf2 = _o->testf2;
+  auto _testf3 = _o->testf3;
+  auto _testarrayofstring2 = _o->testarrayofstring2.size() ? _fbb.CreateVectorOfStrings(_o->testarrayofstring2) : 0;
+  auto _testarrayofsortedstruct = _o->testarrayofsortedstruct.size() ? _fbb.CreateVectorOfStructs(_o->testarrayofsortedstruct) : 0;
+  auto _flex = _o->flex.size() ? _fbb.CreateVector(_o->flex) : 0;
+  auto _test5 = _o->test5.size() ? _fbb.CreateVectorOfStructs(_o->test5) : 0;
+  auto _vector_of_longs = _o->vector_of_longs.size() ? _fbb.CreateVector(_o->vector_of_longs) : 0;
+  auto _vector_of_doubles = _o->vector_of_doubles.size() ? _fbb.CreateVector(_o->vector_of_doubles) : 0;
+  auto _parent_namespace_test = _o->parent_namespace_test ? CreateInParentNamespace(_fbb, _o->parent_namespace_test.get(), _rehasher) : 0;
+  auto _vector_of_referrables = _o->vector_of_referrables.size() ? _fbb.CreateVector<flatbuffers::Offset<MyGame::Example::Referrable>> (_o->vector_of_referrables.size(), [](size_t i, _VectorArgs *__va) { return CreateReferrable(*__va->__fbb, __va->__o->vector_of_referrables[i].get(), __va->__rehasher); }, &_va ) : 0;
+  auto _single_weak_reference = _rehasher ? static_cast<uint64_t>((*_rehasher)(_o->single_weak_reference)) : 0;
+  auto _vector_of_weak_references = _o->vector_of_weak_references.size() ? _fbb.CreateVector<uint64_t>(_o->vector_of_weak_references.size(), [](size_t i, _VectorArgs *__va) { return __va->__rehasher ? static_cast<uint64_t>((*__va->__rehasher)(__va->__o->vector_of_weak_references[i])) : 0; }, &_va ) : 0;
+  auto _vector_of_strong_referrables = _o->vector_of_strong_referrables.size() ? _fbb.CreateVector<flatbuffers::Offset<MyGame::Example::Referrable>> (_o->vector_of_strong_referrables.size(), [](size_t i, _VectorArgs *__va) { return CreateReferrable(*__va->__fbb, __va->__o->vector_of_strong_referrables[i].get(), __va->__rehasher); }, &_va ) : 0;
+  auto _co_owning_reference = _rehasher ? static_cast<uint64_t>((*_rehasher)(_o->co_owning_reference)) : 0;
+  auto _vector_of_co_owning_references = _o->vector_of_co_owning_references.size() ? _fbb.CreateVector<uint64_t>(_o->vector_of_co_owning_references.size(), [](size_t i, _VectorArgs *__va) { return __va->__rehasher ? static_cast<uint64_t>((*__va->__rehasher)(__va->__o->vector_of_co_owning_references[i].get())) : 0; }, &_va ) : 0;
+  auto _non_owning_reference = _rehasher ? static_cast<uint64_t>((*_rehasher)(_o->non_owning_reference)) : 0;
+  auto _vector_of_non_owning_references = _o->vector_of_non_owning_references.size() ? _fbb.CreateVector<uint64_t>(_o->vector_of_non_owning_references.size(), [](size_t i, _VectorArgs *__va) { return __va->__rehasher ? static_cast<uint64_t>((*__va->__rehasher)(__va->__o->vector_of_non_owning_references[i])) : 0; }, &_va ) : 0;
+  auto _any_unique_type = _o->any_unique.type;
+  auto _any_unique = _o->any_unique.Pack(_fbb);
+  auto _any_ambiguous_type = _o->any_ambiguous.type;
+  auto _any_ambiguous = _o->any_ambiguous.Pack(_fbb);
+  auto _vector_of_enums = _o->vector_of_enums.size() ? _fbb.CreateVectorScalarCast<uint8_t>(flatbuffers::data(_o->vector_of_enums), _o->vector_of_enums.size()) : 0;
+  return MyGame::Example::CreateMonster(
+      _fbb,
+      _pos,
+      _mana,
+      _hp,
+      _name,
+      _inventory,
+      _color,
+      _test_type,
+      _test,
+      _test4,
+      _testarrayofstring,
+      _testarrayoftables,
+      _enemy,
+      _testnestedflatbuffer,
+      _testempty,
+      _testbool,
+      _testhashs32_fnv1,
+      _testhashu32_fnv1,
+      _testhashs64_fnv1,
+      _testhashu64_fnv1,
+      _testhashs32_fnv1a,
+      _testhashu32_fnv1a,
+      _testhashs64_fnv1a,
+      _testhashu64_fnv1a,
+      _testarrayofbools,
+      _testf,
+      _testf2,
+      _testf3,
+      _testarrayofstring2,
+      _testarrayofsortedstruct,
+      _flex,
+      _test5,
+      _vector_of_longs,
+      _vector_of_doubles,
+      _parent_namespace_test,
+      _vector_of_referrables,
+      _single_weak_reference,
+      _vector_of_weak_references,
+      _vector_of_strong_referrables,
+      _co_owning_reference,
+      _vector_of_co_owning_references,
+      _non_owning_reference,
+      _vector_of_non_owning_references,
+      _any_unique_type,
+      _any_unique,
+      _any_ambiguous_type,
+      _any_ambiguous,
+      _vector_of_enums);
+}
+
+inline TypeAliasesT *TypeAliases::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = new TypeAliasesT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+inline void TypeAliases::UnPackTo(TypeAliasesT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+  { auto _e = i8(); _o->i8 = _e; };
+  { auto _e = u8(); _o->u8 = _e; };
+  { auto _e = i16(); _o->i16 = _e; };
+  { auto _e = u16(); _o->u16 = _e; };
+  { auto _e = i32(); _o->i32 = _e; };
+  { auto _e = u32(); _o->u32 = _e; };
+  { auto _e = i64(); _o->i64 = _e; };
+  { auto _e = u64(); _o->u64 = _e; };
+  { auto _e = f32(); _o->f32 = _e; };
+  { auto _e = f64(); _o->f64 = _e; };
+  { auto _e = v8(); if (_e) { _o->v8.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->v8[_i] = _e->Get(_i); } } };
+  { auto _e = vf64(); if (_e) { _o->vf64.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vf64[_i] = _e->Get(_i); } } };
+}
+
+inline flatbuffers::Offset<TypeAliases> TypeAliases::Pack(flatbuffers::FlatBufferBuilder &_fbb, const TypeAliasesT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateTypeAliases(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<TypeAliases> CreateTypeAliases(flatbuffers::FlatBufferBuilder &_fbb, const TypeAliasesT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const TypeAliasesT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  auto _i8 = _o->i8;
+  auto _u8 = _o->u8;
+  auto _i16 = _o->i16;
+  auto _u16 = _o->u16;
+  auto _i32 = _o->i32;
+  auto _u32 = _o->u32;
+  auto _i64 = _o->i64;
+  auto _u64 = _o->u64;
+  auto _f32 = _o->f32;
+  auto _f64 = _o->f64;
+  auto _v8 = _o->v8.size() ? _fbb.CreateVector(_o->v8) : 0;
+  auto _vf64 = _o->vf64.size() ? _fbb.CreateVector(_o->vf64) : 0;
+  return MyGame::Example::CreateTypeAliases(
+      _fbb,
+      _i8,
+      _u8,
+      _i16,
+      _u16,
+      _i32,
+      _u32,
+      _i64,
+      _u64,
+      _f32,
+      _f64,
+      _v8,
+      _vf64);
+}
+
+inline bool VerifyAny(flatbuffers::Verifier &verifier, const void *obj, Any type) {
+  switch (type) {
+    case Any_NONE: {
+      return true;
+    }
+    case Any_Monster: {
+      auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    case Any_TestSimpleTableWithEnum: {
+      auto ptr = reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnum *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    case Any_MyGame_Example2_Monster: {
+      auto ptr = reinterpret_cast<const MyGame::Example2::Monster *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    default: return false;
+  }
+}
+
+inline bool VerifyAnyVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) {
+  if (!values || !types) return !values && !types;
+  if (values->size() != types->size()) return false;
+  for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
+    if (!VerifyAny(
+        verifier,  values->Get(i), types->GetEnum<Any>(i))) {
+      return false;
+    }
+  }
+  return true;
+}
+
+inline void *AnyUnion::UnPack(const void *obj, Any type, const flatbuffers::resolver_function_t *resolver) {
+  switch (type) {
+    case Any_Monster: {
+      auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+      return ptr->UnPack(resolver);
+    }
+    case Any_TestSimpleTableWithEnum: {
+      auto ptr = reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnum *>(obj);
+      return ptr->UnPack(resolver);
+    }
+    case Any_MyGame_Example2_Monster: {
+      auto ptr = reinterpret_cast<const MyGame::Example2::Monster *>(obj);
+      return ptr->UnPack(resolver);
+    }
+    default: return nullptr;
+  }
+}
+
+inline flatbuffers::Offset<void> AnyUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher) const {
+  switch (type) {
+    case Any_Monster: {
+      auto ptr = reinterpret_cast<const MyGame::Example::MonsterT *>(value);
+      return CreateMonster(_fbb, ptr, _rehasher).Union();
+    }
+    case Any_TestSimpleTableWithEnum: {
+      auto ptr = reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(value);
+      return CreateTestSimpleTableWithEnum(_fbb, ptr, _rehasher).Union();
+    }
+    case Any_MyGame_Example2_Monster: {
+      auto ptr = reinterpret_cast<const MyGame::Example2::MonsterT *>(value);
+      return CreateMonster(_fbb, ptr, _rehasher).Union();
+    }
+    default: return 0;
+  }
+}
+
+inline AnyUnion::AnyUnion(const AnyUnion &u) FLATBUFFERS_NOEXCEPT : type(u.type), value(nullptr) {
+  switch (type) {
+    case Any_Monster: {
+      FLATBUFFERS_ASSERT(false);  // MyGame::Example::MonsterT not copyable.
+      break;
+    }
+    case Any_TestSimpleTableWithEnum: {
+      value = new MyGame::Example::TestSimpleTableWithEnumT(*reinterpret_cast<MyGame::Example::TestSimpleTableWithEnumT *>(u.value));
+      break;
+    }
+    case Any_MyGame_Example2_Monster: {
+      value = new MyGame::Example2::MonsterT(*reinterpret_cast<MyGame::Example2::MonsterT *>(u.value));
+      break;
+    }
+    default:
+      break;
+  }
+}
+
+inline void AnyUnion::Reset() {
+  switch (type) {
+    case Any_Monster: {
+      auto ptr = reinterpret_cast<MyGame::Example::MonsterT *>(value);
+      delete ptr;
+      break;
+    }
+    case Any_TestSimpleTableWithEnum: {
+      auto ptr = reinterpret_cast<MyGame::Example::TestSimpleTableWithEnumT *>(value);
+      delete ptr;
+      break;
+    }
+    case Any_MyGame_Example2_Monster: {
+      auto ptr = reinterpret_cast<MyGame::Example2::MonsterT *>(value);
+      delete ptr;
+      break;
+    }
+    default: break;
+  }
+  value = nullptr;
+  type = Any_NONE;
+}
+
+inline bool VerifyAnyUniqueAliases(flatbuffers::Verifier &verifier, const void *obj, AnyUniqueAliases type) {
+  switch (type) {
+    case AnyUniqueAliases_NONE: {
+      return true;
+    }
+    case AnyUniqueAliases_M: {
+      auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    case AnyUniqueAliases_TS: {
+      auto ptr = reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnum *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    case AnyUniqueAliases_M2: {
+      auto ptr = reinterpret_cast<const MyGame::Example2::Monster *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    default: return false;
+  }
+}
+
+inline bool VerifyAnyUniqueAliasesVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) {
+  if (!values || !types) return !values && !types;
+  if (values->size() != types->size()) return false;
+  for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
+    if (!VerifyAnyUniqueAliases(
+        verifier,  values->Get(i), types->GetEnum<AnyUniqueAliases>(i))) {
+      return false;
+    }
+  }
+  return true;
+}
+
+inline void *AnyUniqueAliasesUnion::UnPack(const void *obj, AnyUniqueAliases type, const flatbuffers::resolver_function_t *resolver) {
+  switch (type) {
+    case AnyUniqueAliases_M: {
+      auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+      return ptr->UnPack(resolver);
+    }
+    case AnyUniqueAliases_TS: {
+      auto ptr = reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnum *>(obj);
+      return ptr->UnPack(resolver);
+    }
+    case AnyUniqueAliases_M2: {
+      auto ptr = reinterpret_cast<const MyGame::Example2::Monster *>(obj);
+      return ptr->UnPack(resolver);
+    }
+    default: return nullptr;
+  }
+}
+
+inline flatbuffers::Offset<void> AnyUniqueAliasesUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher) const {
+  switch (type) {
+    case AnyUniqueAliases_M: {
+      auto ptr = reinterpret_cast<const MyGame::Example::MonsterT *>(value);
+      return CreateMonster(_fbb, ptr, _rehasher).Union();
+    }
+    case AnyUniqueAliases_TS: {
+      auto ptr = reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(value);
+      return CreateTestSimpleTableWithEnum(_fbb, ptr, _rehasher).Union();
+    }
+    case AnyUniqueAliases_M2: {
+      auto ptr = reinterpret_cast<const MyGame::Example2::MonsterT *>(value);
+      return CreateMonster(_fbb, ptr, _rehasher).Union();
+    }
+    default: return 0;
+  }
+}
+
+inline AnyUniqueAliasesUnion::AnyUniqueAliasesUnion(const AnyUniqueAliasesUnion &u) FLATBUFFERS_NOEXCEPT : type(u.type), value(nullptr) {
+  switch (type) {
+    case AnyUniqueAliases_M: {
+      FLATBUFFERS_ASSERT(false);  // MyGame::Example::MonsterT not copyable.
+      break;
+    }
+    case AnyUniqueAliases_TS: {
+      value = new MyGame::Example::TestSimpleTableWithEnumT(*reinterpret_cast<MyGame::Example::TestSimpleTableWithEnumT *>(u.value));
+      break;
+    }
+    case AnyUniqueAliases_M2: {
+      value = new MyGame::Example2::MonsterT(*reinterpret_cast<MyGame::Example2::MonsterT *>(u.value));
+      break;
+    }
+    default:
+      break;
+  }
+}
+
+inline void AnyUniqueAliasesUnion::Reset() {
+  switch (type) {
+    case AnyUniqueAliases_M: {
+      auto ptr = reinterpret_cast<MyGame::Example::MonsterT *>(value);
+      delete ptr;
+      break;
+    }
+    case AnyUniqueAliases_TS: {
+      auto ptr = reinterpret_cast<MyGame::Example::TestSimpleTableWithEnumT *>(value);
+      delete ptr;
+      break;
+    }
+    case AnyUniqueAliases_M2: {
+      auto ptr = reinterpret_cast<MyGame::Example2::MonsterT *>(value);
+      delete ptr;
+      break;
+    }
+    default: break;
+  }
+  value = nullptr;
+  type = AnyUniqueAliases_NONE;
+}
+
+inline bool VerifyAnyAmbiguousAliases(flatbuffers::Verifier &verifier, const void *obj, AnyAmbiguousAliases type) {
+  switch (type) {
+    case AnyAmbiguousAliases_NONE: {
+      return true;
+    }
+    case AnyAmbiguousAliases_M1: {
+      auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    case AnyAmbiguousAliases_M2: {
+      auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    case AnyAmbiguousAliases_M3: {
+      auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    default: return false;
+  }
+}
+
+inline bool VerifyAnyAmbiguousAliasesVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) {
+  if (!values || !types) return !values && !types;
+  if (values->size() != types->size()) return false;
+  for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
+    if (!VerifyAnyAmbiguousAliases(
+        verifier,  values->Get(i), types->GetEnum<AnyAmbiguousAliases>(i))) {
+      return false;
+    }
+  }
+  return true;
+}
+
+inline void *AnyAmbiguousAliasesUnion::UnPack(const void *obj, AnyAmbiguousAliases type, const flatbuffers::resolver_function_t *resolver) {
+  switch (type) {
+    case AnyAmbiguousAliases_M1: {
+      auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+      return ptr->UnPack(resolver);
+    }
+    case AnyAmbiguousAliases_M2: {
+      auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+      return ptr->UnPack(resolver);
+    }
+    case AnyAmbiguousAliases_M3: {
+      auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+      return ptr->UnPack(resolver);
+    }
+    default: return nullptr;
+  }
+}
+
+inline flatbuffers::Offset<void> AnyAmbiguousAliasesUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher) const {
+  switch (type) {
+    case AnyAmbiguousAliases_M1: {
+      auto ptr = reinterpret_cast<const MyGame::Example::MonsterT *>(value);
+      return CreateMonster(_fbb, ptr, _rehasher).Union();
+    }
+    case AnyAmbiguousAliases_M2: {
+      auto ptr = reinterpret_cast<const MyGame::Example::MonsterT *>(value);
+      return CreateMonster(_fbb, ptr, _rehasher).Union();
+    }
+    case AnyAmbiguousAliases_M3: {
+      auto ptr = reinterpret_cast<const MyGame::Example::MonsterT *>(value);
+      return CreateMonster(_fbb, ptr, _rehasher).Union();
+    }
+    default: return 0;
+  }
+}
+
+inline AnyAmbiguousAliasesUnion::AnyAmbiguousAliasesUnion(const AnyAmbiguousAliasesUnion &u) FLATBUFFERS_NOEXCEPT : type(u.type), value(nullptr) {
+  switch (type) {
+    case AnyAmbiguousAliases_M1: {
+      FLATBUFFERS_ASSERT(false);  // MyGame::Example::MonsterT not copyable.
+      break;
+    }
+    case AnyAmbiguousAliases_M2: {
+      FLATBUFFERS_ASSERT(false);  // MyGame::Example::MonsterT not copyable.
+      break;
+    }
+    case AnyAmbiguousAliases_M3: {
+      FLATBUFFERS_ASSERT(false);  // MyGame::Example::MonsterT not copyable.
+      break;
+    }
+    default:
+      break;
+  }
+}
+
+inline void AnyAmbiguousAliasesUnion::Reset() {
+  switch (type) {
+    case AnyAmbiguousAliases_M1: {
+      auto ptr = reinterpret_cast<MyGame::Example::MonsterT *>(value);
+      delete ptr;
+      break;
+    }
+    case AnyAmbiguousAliases_M2: {
+      auto ptr = reinterpret_cast<MyGame::Example::MonsterT *>(value);
+      delete ptr;
+      break;
+    }
+    case AnyAmbiguousAliases_M3: {
+      auto ptr = reinterpret_cast<MyGame::Example::MonsterT *>(value);
+      delete ptr;
+      break;
+    }
+    default: break;
+  }
+  value = nullptr;
+  type = AnyAmbiguousAliases_NONE;
+}
+
+inline const flatbuffers::TypeTable *ColorTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_UCHAR, 0, 0 },
+    { flatbuffers::ET_UCHAR, 0, 0 },
+    { flatbuffers::ET_UCHAR, 0, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Example::ColorTypeTable
+  };
+  static const int64_t values[] = { 1, 2, 8 };
+  static const char * const names[] = {
+    "Red",
+    "Green",
+    "Blue"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_ENUM, 3, type_codes, type_refs, values, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *AnyTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SEQUENCE, 0, -1 },
+    { flatbuffers::ET_SEQUENCE, 0, 0 },
+    { flatbuffers::ET_SEQUENCE, 0, 1 },
+    { flatbuffers::ET_SEQUENCE, 0, 2 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Example::MonsterTypeTable,
+    MyGame::Example::TestSimpleTableWithEnumTypeTable,
+    MyGame::Example2::MonsterTypeTable
+  };
+  static const char * const names[] = {
+    "NONE",
+    "Monster",
+    "TestSimpleTableWithEnum",
+    "MyGame_Example2_Monster"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_UNION, 4, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *AnyUniqueAliasesTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SEQUENCE, 0, -1 },
+    { flatbuffers::ET_SEQUENCE, 0, 0 },
+    { flatbuffers::ET_SEQUENCE, 0, 1 },
+    { flatbuffers::ET_SEQUENCE, 0, 2 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Example::MonsterTypeTable,
+    MyGame::Example::TestSimpleTableWithEnumTypeTable,
+    MyGame::Example2::MonsterTypeTable
+  };
+  static const char * const names[] = {
+    "NONE",
+    "M",
+    "TS",
+    "M2"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_UNION, 4, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *AnyAmbiguousAliasesTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SEQUENCE, 0, -1 },
+    { flatbuffers::ET_SEQUENCE, 0, 0 },
+    { flatbuffers::ET_SEQUENCE, 0, 0 },
+    { flatbuffers::ET_SEQUENCE, 0, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Example::MonsterTypeTable
+  };
+  static const char * const names[] = {
+    "NONE",
+    "M1",
+    "M2",
+    "M3"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_UNION, 4, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+}  // namespace Example
+
+inline const flatbuffers::TypeTable *InParentNamespaceTypeTable() {
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 0, nullptr, nullptr, nullptr, nullptr
+  };
+  return &tt;
+}
+
+namespace Example2 {
+
+inline const flatbuffers::TypeTable *MonsterTypeTable() {
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 0, nullptr, nullptr, nullptr, nullptr
+  };
+  return &tt;
+}
+
+}  // namespace Example2
+
+namespace Example {
+
+inline const flatbuffers::TypeTable *TestTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SHORT, 0, -1 },
+    { flatbuffers::ET_CHAR, 0, -1 }
+  };
+  static const int64_t values[] = { 0, 2, 4 };
+  static const char * const names[] = {
+    "a",
+    "b"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_STRUCT, 2, type_codes, nullptr, values, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *TestSimpleTableWithEnumTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_UCHAR, 0, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Example::ColorTypeTable
+  };
+  static const char * const names[] = {
+    "color"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 1, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *Vec3TypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_DOUBLE, 0, -1 },
+    { flatbuffers::ET_UCHAR, 0, 0 },
+    { flatbuffers::ET_SEQUENCE, 0, 1 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Example::ColorTypeTable,
+    MyGame::Example::TestTypeTable
+  };
+  static const int64_t values[] = { 0, 4, 8, 16, 24, 26, 32 };
+  static const char * const names[] = {
+    "x",
+    "y",
+    "z",
+    "test1",
+    "test2",
+    "test3"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_STRUCT, 6, type_codes, type_refs, values, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *AbilityTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_UINT, 0, -1 },
+    { flatbuffers::ET_UINT, 0, -1 }
+  };
+  static const int64_t values[] = { 0, 4, 8 };
+  static const char * const names[] = {
+    "id",
+    "distance"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_STRUCT, 2, type_codes, nullptr, values, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *StatTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_STRING, 0, -1 },
+    { flatbuffers::ET_LONG, 0, -1 },
+    { flatbuffers::ET_USHORT, 0, -1 }
+  };
+  static const char * const names[] = {
+    "id",
+    "val",
+    "count"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 3, type_codes, nullptr, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *ReferrableTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_ULONG, 0, -1 }
+  };
+  static const char * const names[] = {
+    "id"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 1, type_codes, nullptr, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *MonsterTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SEQUENCE, 0, 0 },
+    { flatbuffers::ET_SHORT, 0, -1 },
+    { flatbuffers::ET_SHORT, 0, -1 },
+    { flatbuffers::ET_STRING, 0, -1 },
+    { flatbuffers::ET_BOOL, 0, -1 },
+    { flatbuffers::ET_UCHAR, 1, -1 },
+    { flatbuffers::ET_UCHAR, 0, 1 },
+    { flatbuffers::ET_UTYPE, 0, 2 },
+    { flatbuffers::ET_SEQUENCE, 0, 2 },
+    { flatbuffers::ET_SEQUENCE, 1, 3 },
+    { flatbuffers::ET_STRING, 1, -1 },
+    { flatbuffers::ET_SEQUENCE, 1, 4 },
+    { flatbuffers::ET_SEQUENCE, 0, 4 },
+    { flatbuffers::ET_UCHAR, 1, -1 },
+    { flatbuffers::ET_SEQUENCE, 0, 5 },
+    { flatbuffers::ET_BOOL, 0, -1 },
+    { flatbuffers::ET_INT, 0, -1 },
+    { flatbuffers::ET_UINT, 0, -1 },
+    { flatbuffers::ET_LONG, 0, -1 },
+    { flatbuffers::ET_ULONG, 0, -1 },
+    { flatbuffers::ET_INT, 0, -1 },
+    { flatbuffers::ET_UINT, 0, -1 },
+    { flatbuffers::ET_LONG, 0, -1 },
+    { flatbuffers::ET_ULONG, 0, -1 },
+    { flatbuffers::ET_BOOL, 1, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_STRING, 1, -1 },
+    { flatbuffers::ET_SEQUENCE, 1, 6 },
+    { flatbuffers::ET_UCHAR, 1, -1 },
+    { flatbuffers::ET_SEQUENCE, 1, 3 },
+    { flatbuffers::ET_LONG, 1, -1 },
+    { flatbuffers::ET_DOUBLE, 1, -1 },
+    { flatbuffers::ET_SEQUENCE, 0, 7 },
+    { flatbuffers::ET_SEQUENCE, 1, 8 },
+    { flatbuffers::ET_ULONG, 0, -1 },
+    { flatbuffers::ET_ULONG, 1, -1 },
+    { flatbuffers::ET_SEQUENCE, 1, 8 },
+    { flatbuffers::ET_ULONG, 0, -1 },
+    { flatbuffers::ET_ULONG, 1, -1 },
+    { flatbuffers::ET_ULONG, 0, -1 },
+    { flatbuffers::ET_ULONG, 1, -1 },
+    { flatbuffers::ET_UTYPE, 0, 9 },
+    { flatbuffers::ET_SEQUENCE, 0, 9 },
+    { flatbuffers::ET_UTYPE, 0, 10 },
+    { flatbuffers::ET_SEQUENCE, 0, 10 },
+    { flatbuffers::ET_UCHAR, 1, 1 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Example::Vec3TypeTable,
+    MyGame::Example::ColorTypeTable,
+    MyGame::Example::AnyTypeTable,
+    MyGame::Example::TestTypeTable,
+    MyGame::Example::MonsterTypeTable,
+    MyGame::Example::StatTypeTable,
+    MyGame::Example::AbilityTypeTable,
+    MyGame::InParentNamespaceTypeTable,
+    MyGame::Example::ReferrableTypeTable,
+    MyGame::Example::AnyUniqueAliasesTypeTable,
+    MyGame::Example::AnyAmbiguousAliasesTypeTable
+  };
+  static const char * const names[] = {
+    "pos",
+    "mana",
+    "hp",
+    "name",
+    "friendly",
+    "inventory",
+    "color",
+    "test_type",
+    "test",
+    "test4",
+    "testarrayofstring",
+    "testarrayoftables",
+    "enemy",
+    "testnestedflatbuffer",
+    "testempty",
+    "testbool",
+    "testhashs32_fnv1",
+    "testhashu32_fnv1",
+    "testhashs64_fnv1",
+    "testhashu64_fnv1",
+    "testhashs32_fnv1a",
+    "testhashu32_fnv1a",
+    "testhashs64_fnv1a",
+    "testhashu64_fnv1a",
+    "testarrayofbools",
+    "testf",
+    "testf2",
+    "testf3",
+    "testarrayofstring2",
+    "testarrayofsortedstruct",
+    "flex",
+    "test5",
+    "vector_of_longs",
+    "vector_of_doubles",
+    "parent_namespace_test",
+    "vector_of_referrables",
+    "single_weak_reference",
+    "vector_of_weak_references",
+    "vector_of_strong_referrables",
+    "co_owning_reference",
+    "vector_of_co_owning_references",
+    "non_owning_reference",
+    "vector_of_non_owning_references",
+    "any_unique_type",
+    "any_unique",
+    "any_ambiguous_type",
+    "any_ambiguous",
+    "vector_of_enums"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 48, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *TypeAliasesTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_CHAR, 0, -1 },
+    { flatbuffers::ET_UCHAR, 0, -1 },
+    { flatbuffers::ET_SHORT, 0, -1 },
+    { flatbuffers::ET_USHORT, 0, -1 },
+    { flatbuffers::ET_INT, 0, -1 },
+    { flatbuffers::ET_UINT, 0, -1 },
+    { flatbuffers::ET_LONG, 0, -1 },
+    { flatbuffers::ET_ULONG, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_DOUBLE, 0, -1 },
+    { flatbuffers::ET_CHAR, 1, -1 },
+    { flatbuffers::ET_DOUBLE, 1, -1 }
+  };
+  static const char * const names[] = {
+    "i8",
+    "u8",
+    "i16",
+    "u16",
+    "i32",
+    "u32",
+    "i64",
+    "u64",
+    "f32",
+    "f64",
+    "v8",
+    "vf64"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 12, type_codes, nullptr, nullptr, names
+  };
+  return &tt;
+}
+
+inline const MyGame::Example::Monster *GetMonster(const void *buf) {
+  return flatbuffers::GetRoot<MyGame::Example::Monster>(buf);
+}
+
+inline const MyGame::Example::Monster *GetSizePrefixedMonster(const void *buf) {
+  return flatbuffers::GetSizePrefixedRoot<MyGame::Example::Monster>(buf);
+}
+
+inline Monster *GetMutableMonster(void *buf) {
+  return flatbuffers::GetMutableRoot<Monster>(buf);
+}
+
+inline const char *MonsterIdentifier() {
+  return "MONS";
+}
+
+inline bool MonsterBufferHasIdentifier(const void *buf) {
+  return flatbuffers::BufferHasIdentifier(
+      buf, MonsterIdentifier());
+}
+
+inline bool VerifyMonsterBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifyBuffer<MyGame::Example::Monster>(MonsterIdentifier());
+}
+
+inline bool VerifySizePrefixedMonsterBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifySizePrefixedBuffer<MyGame::Example::Monster>(MonsterIdentifier());
+}
+
+inline const char *MonsterExtension() {
+  return "mon";
+}
+
+inline void FinishMonsterBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<MyGame::Example::Monster> root) {
+  fbb.Finish(root, MonsterIdentifier());
+}
+
+inline void FinishSizePrefixedMonsterBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<MyGame::Example::Monster> root) {
+  fbb.FinishSizePrefixed(root, MonsterIdentifier());
+}
+
+inline flatbuffers::unique_ptr<MyGame::Example::MonsterT> UnPackMonster(
+    const void *buf,
+    const flatbuffers::resolver_function_t *res = nullptr) {
+  return flatbuffers::unique_ptr<MyGame::Example::MonsterT>(GetMonster(buf)->UnPack(res));
+}
+
+inline flatbuffers::unique_ptr<MyGame::Example::MonsterT> UnPackSizePrefixedMonster(
+    const void *buf,
+    const flatbuffers::resolver_function_t *res = nullptr) {
+  return flatbuffers::unique_ptr<MyGame::Example::MonsterT>(GetSizePrefixedMonster(buf)->UnPack(res));
+}
+
+}  // namespace Example
+}  // namespace MyGame
+
+#endif  // FLATBUFFERS_GENERATED_MONSTERTEST_MYGAME_EXAMPLE_H_
diff --git a/tests/monster_test_generated.js b/tests/monster_test_generated.js
new file mode 100644
index 0000000..2a68288
--- /dev/null
+++ b/tests/monster_test_generated.js
@@ -0,0 +1,3299 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+/**
+ * @const
+ * @namespace
+ */
+var MyGame = MyGame || {};
+
+/**
+ * @const
+ * @namespace
+ */
+MyGame.Example = MyGame.Example || {};
+
+/**
+ * @const
+ * @namespace
+ */
+MyGame.Example2 = MyGame.Example2 || {};
+
+/**
+ * @const
+ * @namespace
+ */
+MyGame.OtherNameSpace = MyGame.OtherNameSpace || {};
+
+/**
+ * Composite components of Monster color.
+ *
+ * @enum {number}
+ */
+MyGame.Example.Color = {
+  Red: 1,
+
+  /**
+   * \brief color Green
+   * Green is bit_flag with value (1u << 1)
+   */
+  Green: 2,
+
+  /**
+   * \brief color Blue (1u << 3)
+   */
+  Blue: 8
+};
+
+/**
+ * Composite components of Monster color.
+ *
+ * @enum {string}
+ */
+MyGame.Example.ColorName = {
+  1: 'Red',
+
+  /**
+   * \brief color Green
+   * Green is bit_flag with value (1u << 1)
+   */
+  2: 'Green',
+
+  /**
+   * \brief color Blue (1u << 3)
+   */
+  8: 'Blue'
+};
+
+/**
+ * @enum {number}
+ */
+MyGame.Example.Any = {
+  NONE: 0,
+  Monster: 1,
+  TestSimpleTableWithEnum: 2,
+  MyGame_Example2_Monster: 3
+};
+
+/**
+ * @enum {string}
+ */
+MyGame.Example.AnyName = {
+  0: 'NONE',
+  1: 'Monster',
+  2: 'TestSimpleTableWithEnum',
+  3: 'MyGame_Example2_Monster'
+};
+
+/**
+ * @enum {number}
+ */
+MyGame.Example.AnyUniqueAliases = {
+  NONE: 0,
+  M: 1,
+  TS: 2,
+  M2: 3
+};
+
+/**
+ * @enum {string}
+ */
+MyGame.Example.AnyUniqueAliasesName = {
+  0: 'NONE',
+  1: 'M',
+  2: 'TS',
+  3: 'M2'
+};
+
+/**
+ * @enum {number}
+ */
+MyGame.Example.AnyAmbiguousAliases = {
+  NONE: 0,
+  M1: 1,
+  M2: 2,
+  M3: 3
+};
+
+/**
+ * @enum {string}
+ */
+MyGame.Example.AnyAmbiguousAliasesName = {
+  0: 'NONE',
+  1: 'M1',
+  2: 'M2',
+  3: 'M3'
+};
+
+/**
+ * @constructor
+ */
+MyGame.InParentNamespace = function() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+};
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {MyGame.InParentNamespace}
+ */
+MyGame.InParentNamespace.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.InParentNamespace=} obj
+ * @returns {MyGame.InParentNamespace}
+ */
+MyGame.InParentNamespace.getRootAsInParentNamespace = function(bb, obj) {
+  return (obj || new MyGame.InParentNamespace).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.InParentNamespace=} obj
+ * @returns {MyGame.InParentNamespace}
+ */
+MyGame.InParentNamespace.getSizePrefixedRootAsInParentNamespace = function(bb, obj) {
+  return (obj || new MyGame.InParentNamespace).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ */
+MyGame.InParentNamespace.startInParentNamespace = function(builder) {
+  builder.startObject(0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.InParentNamespace.endInParentNamespace = function(builder) {
+  var offset = builder.endObject();
+  return offset;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.InParentNamespace.createInParentNamespace = function(builder) {
+  MyGame.InParentNamespace.startInParentNamespace(builder);
+  return MyGame.InParentNamespace.endInParentNamespace(builder);
+}
+
+/**
+ * @constructor
+ */
+MyGame.Example2.Monster = function() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+};
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {MyGame.Example2.Monster}
+ */
+MyGame.Example2.Monster.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.Example2.Monster=} obj
+ * @returns {MyGame.Example2.Monster}
+ */
+MyGame.Example2.Monster.getRootAsMonster = function(bb, obj) {
+  return (obj || new MyGame.Example2.Monster).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.Example2.Monster=} obj
+ * @returns {MyGame.Example2.Monster}
+ */
+MyGame.Example2.Monster.getSizePrefixedRootAsMonster = function(bb, obj) {
+  return (obj || new MyGame.Example2.Monster).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ */
+MyGame.Example2.Monster.startMonster = function(builder) {
+  builder.startObject(0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example2.Monster.endMonster = function(builder) {
+  var offset = builder.endObject();
+  return offset;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example2.Monster.createMonster = function(builder) {
+  MyGame.Example2.Monster.startMonster(builder);
+  return MyGame.Example2.Monster.endMonster(builder);
+}
+
+/**
+ * @constructor
+ */
+MyGame.Example.Test = function() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+};
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {MyGame.Example.Test}
+ */
+MyGame.Example.Test.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Test.prototype.a = function() {
+  return this.bb.readInt16(this.bb_pos);
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Test.prototype.mutate_a = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 0);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt16(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Test.prototype.b = function() {
+  return this.bb.readInt8(this.bb_pos + 2);
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Test.prototype.mutate_b = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 2);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} a
+ * @param {number} b
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Test.createTest = function(builder, a, b) {
+  builder.prep(2, 4);
+  builder.pad(1);
+  builder.writeInt8(b);
+  builder.writeInt16(a);
+  return builder.offset();
+};
+
+/**
+ * @constructor
+ */
+MyGame.Example.TestSimpleTableWithEnum = function() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+};
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {MyGame.Example.TestSimpleTableWithEnum}
+ */
+MyGame.Example.TestSimpleTableWithEnum.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.Example.TestSimpleTableWithEnum=} obj
+ * @returns {MyGame.Example.TestSimpleTableWithEnum}
+ */
+MyGame.Example.TestSimpleTableWithEnum.getRootAsTestSimpleTableWithEnum = function(bb, obj) {
+  return (obj || new MyGame.Example.TestSimpleTableWithEnum).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.Example.TestSimpleTableWithEnum=} obj
+ * @returns {MyGame.Example.TestSimpleTableWithEnum}
+ */
+MyGame.Example.TestSimpleTableWithEnum.getSizePrefixedRootAsTestSimpleTableWithEnum = function(bb, obj) {
+  return (obj || new MyGame.Example.TestSimpleTableWithEnum).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @returns {MyGame.Example.Color}
+ */
+MyGame.Example.TestSimpleTableWithEnum.prototype.color = function() {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+  return offset ? /** @type {MyGame.Example.Color} */ (this.bb.readUint8(this.bb_pos + offset)) : MyGame.Example.Color.Green;
+};
+
+/**
+ * @param {MyGame.Example.Color} value
+ * @returns {boolean}
+ */
+MyGame.Example.TestSimpleTableWithEnum.prototype.mutate_color = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ */
+MyGame.Example.TestSimpleTableWithEnum.startTestSimpleTableWithEnum = function(builder) {
+  builder.startObject(1);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {MyGame.Example.Color} color
+ */
+MyGame.Example.TestSimpleTableWithEnum.addColor = function(builder, color) {
+  builder.addFieldInt8(0, color, MyGame.Example.Color.Green);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.TestSimpleTableWithEnum.endTestSimpleTableWithEnum = function(builder) {
+  var offset = builder.endObject();
+  return offset;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {MyGame.Example.Color} color
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.TestSimpleTableWithEnum.createTestSimpleTableWithEnum = function(builder, color) {
+  MyGame.Example.TestSimpleTableWithEnum.startTestSimpleTableWithEnum(builder);
+  MyGame.Example.TestSimpleTableWithEnum.addColor(builder, color);
+  return MyGame.Example.TestSimpleTableWithEnum.endTestSimpleTableWithEnum(builder);
+}
+
+/**
+ * @constructor
+ */
+MyGame.Example.Vec3 = function() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+};
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {MyGame.Example.Vec3}
+ */
+MyGame.Example.Vec3.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Vec3.prototype.x = function() {
+  return this.bb.readFloat32(this.bb_pos);
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Vec3.prototype.mutate_x = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 0);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeFloat32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Vec3.prototype.y = function() {
+  return this.bb.readFloat32(this.bb_pos + 4);
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Vec3.prototype.mutate_y = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeFloat32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Vec3.prototype.z = function() {
+  return this.bb.readFloat32(this.bb_pos + 8);
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Vec3.prototype.mutate_z = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 8);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeFloat32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Vec3.prototype.test1 = function() {
+  return this.bb.readFloat64(this.bb_pos + 16);
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Vec3.prototype.mutate_test1 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 16);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeFloat64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {MyGame.Example.Color}
+ */
+MyGame.Example.Vec3.prototype.test2 = function() {
+  return /** @type {MyGame.Example.Color} */ (this.bb.readUint8(this.bb_pos + 24));
+};
+
+/**
+ * @param {MyGame.Example.Color} value
+ * @returns {boolean}
+ */
+MyGame.Example.Vec3.prototype.mutate_test2 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 24);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {MyGame.Example.Test=} obj
+ * @returns {MyGame.Example.Test|null}
+ */
+MyGame.Example.Vec3.prototype.test3 = function(obj) {
+  return (obj || new MyGame.Example.Test).__init(this.bb_pos + 26, this.bb);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} x
+ * @param {number} y
+ * @param {number} z
+ * @param {number} test1
+ * @param {MyGame.Example.Color} test2
+ * @param {number} test3_a
+ * @param {number} test3_b
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Vec3.createVec3 = function(builder, x, y, z, test1, test2, test3_a, test3_b) {
+  builder.prep(8, 32);
+  builder.pad(2);
+  builder.prep(2, 4);
+  builder.pad(1);
+  builder.writeInt8(test3_b);
+  builder.writeInt16(test3_a);
+  builder.pad(1);
+  builder.writeInt8(test2);
+  builder.writeFloat64(test1);
+  builder.pad(4);
+  builder.writeFloat32(z);
+  builder.writeFloat32(y);
+  builder.writeFloat32(x);
+  return builder.offset();
+};
+
+/**
+ * @constructor
+ */
+MyGame.Example.Ability = function() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+};
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {MyGame.Example.Ability}
+ */
+MyGame.Example.Ability.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Ability.prototype.id = function() {
+  return this.bb.readUint32(this.bb_pos);
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Ability.prototype.mutate_id = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 0);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Ability.prototype.distance = function() {
+  return this.bb.readUint32(this.bb_pos + 4);
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Ability.prototype.mutate_distance = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} id
+ * @param {number} distance
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Ability.createAbility = function(builder, id, distance) {
+  builder.prep(4, 8);
+  builder.writeInt32(distance);
+  builder.writeInt32(id);
+  return builder.offset();
+};
+
+/**
+ * @constructor
+ */
+MyGame.Example.Stat = function() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+};
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {MyGame.Example.Stat}
+ */
+MyGame.Example.Stat.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.Example.Stat=} obj
+ * @returns {MyGame.Example.Stat}
+ */
+MyGame.Example.Stat.getRootAsStat = function(bb, obj) {
+  return (obj || new MyGame.Example.Stat).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.Example.Stat=} obj
+ * @returns {MyGame.Example.Stat}
+ */
+MyGame.Example.Stat.getSizePrefixedRootAsStat = function(bb, obj) {
+  return (obj || new MyGame.Example.Stat).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.Encoding=} optionalEncoding
+ * @returns {string|Uint8Array|null}
+ */
+MyGame.Example.Stat.prototype.id = function(optionalEncoding) {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+  return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
+};
+
+/**
+ * @returns {flatbuffers.Long}
+ */
+MyGame.Example.Stat.prototype.val = function() {
+  var offset = this.bb.__offset(this.bb_pos, 6);
+  return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0);
+};
+
+/**
+ * @param {flatbuffers.Long} value
+ * @returns {boolean}
+ */
+MyGame.Example.Stat.prototype.mutate_val = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 6);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Stat.prototype.count = function() {
+  var offset = this.bb.__offset(this.bb_pos, 8);
+  return offset ? this.bb.readUint16(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Stat.prototype.mutate_count = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 8);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint16(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ */
+MyGame.Example.Stat.startStat = function(builder) {
+  builder.startObject(3);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} idOffset
+ */
+MyGame.Example.Stat.addId = function(builder, idOffset) {
+  builder.addFieldOffset(0, idOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Long} val
+ */
+MyGame.Example.Stat.addVal = function(builder, val) {
+  builder.addFieldInt64(1, val, builder.createLong(0, 0));
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} count
+ */
+MyGame.Example.Stat.addCount = function(builder, count) {
+  builder.addFieldInt16(2, count, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Stat.endStat = function(builder) {
+  var offset = builder.endObject();
+  return offset;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} idOffset
+ * @param {flatbuffers.Long} val
+ * @param {number} count
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Stat.createStat = function(builder, idOffset, val, count) {
+  MyGame.Example.Stat.startStat(builder);
+  MyGame.Example.Stat.addId(builder, idOffset);
+  MyGame.Example.Stat.addVal(builder, val);
+  MyGame.Example.Stat.addCount(builder, count);
+  return MyGame.Example.Stat.endStat(builder);
+}
+
+/**
+ * @constructor
+ */
+MyGame.Example.Referrable = function() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+};
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {MyGame.Example.Referrable}
+ */
+MyGame.Example.Referrable.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.Example.Referrable=} obj
+ * @returns {MyGame.Example.Referrable}
+ */
+MyGame.Example.Referrable.getRootAsReferrable = function(bb, obj) {
+  return (obj || new MyGame.Example.Referrable).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.Example.Referrable=} obj
+ * @returns {MyGame.Example.Referrable}
+ */
+MyGame.Example.Referrable.getSizePrefixedRootAsReferrable = function(bb, obj) {
+  return (obj || new MyGame.Example.Referrable).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @returns {flatbuffers.Long}
+ */
+MyGame.Example.Referrable.prototype.id = function() {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+  return offset ? this.bb.readUint64(this.bb_pos + offset) : this.bb.createLong(0, 0);
+};
+
+/**
+ * @param {flatbuffers.Long} value
+ * @returns {boolean}
+ */
+MyGame.Example.Referrable.prototype.mutate_id = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ */
+MyGame.Example.Referrable.startReferrable = function(builder) {
+  builder.startObject(1);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Long} id
+ */
+MyGame.Example.Referrable.addId = function(builder, id) {
+  builder.addFieldInt64(0, id, builder.createLong(0, 0));
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Referrable.endReferrable = function(builder) {
+  var offset = builder.endObject();
+  return offset;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Long} id
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Referrable.createReferrable = function(builder, id) {
+  MyGame.Example.Referrable.startReferrable(builder);
+  MyGame.Example.Referrable.addId(builder, id);
+  return MyGame.Example.Referrable.endReferrable(builder);
+}
+
+/**
+ * an example documentation comment: monster object
+ *
+ * @constructor
+ */
+MyGame.Example.Monster = function() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+};
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {MyGame.Example.Monster}
+ */
+MyGame.Example.Monster.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.Example.Monster=} obj
+ * @returns {MyGame.Example.Monster}
+ */
+MyGame.Example.Monster.getRootAsMonster = function(bb, obj) {
+  return (obj || new MyGame.Example.Monster).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.Example.Monster=} obj
+ * @returns {MyGame.Example.Monster}
+ */
+MyGame.Example.Monster.getSizePrefixedRootAsMonster = function(bb, obj) {
+  return (obj || new MyGame.Example.Monster).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.bufferHasIdentifier = function(bb) {
+  return bb.__has_identifier('MONS');
+};
+
+/**
+ * @param {MyGame.Example.Vec3=} obj
+ * @returns {MyGame.Example.Vec3|null}
+ */
+MyGame.Example.Monster.prototype.pos = function(obj) {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+  return offset ? (obj || new MyGame.Example.Vec3).__init(this.bb_pos + offset, this.bb) : null;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.mana = function() {
+  var offset = this.bb.__offset(this.bb_pos, 6);
+  return offset ? this.bb.readInt16(this.bb_pos + offset) : 150;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_mana = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 6);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt16(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.hp = function() {
+  var offset = this.bb.__offset(this.bb_pos, 8);
+  return offset ? this.bb.readInt16(this.bb_pos + offset) : 100;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_hp = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 8);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt16(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {flatbuffers.Encoding=} optionalEncoding
+ * @returns {string|Uint8Array|null}
+ */
+MyGame.Example.Monster.prototype.name = function(optionalEncoding) {
+  var offset = this.bb.__offset(this.bb_pos, 10);
+  return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
+};
+
+/**
+ * @param {number} index
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.inventory = function(index) {
+  var offset = this.bb.__offset(this.bb_pos, 14);
+  return offset ? this.bb.readUint8(this.bb.__vector(this.bb_pos + offset) + index) : 0;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.inventoryLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 14);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns {Uint8Array}
+ */
+MyGame.Example.Monster.prototype.inventoryArray = function() {
+  var offset = this.bb.__offset(this.bb_pos, 14);
+  return offset ? new Uint8Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @returns {MyGame.Example.Color}
+ */
+MyGame.Example.Monster.prototype.color = function() {
+  var offset = this.bb.__offset(this.bb_pos, 16);
+  return offset ? /** @type {MyGame.Example.Color} */ (this.bb.readUint8(this.bb_pos + offset)) : MyGame.Example.Color.Blue;
+};
+
+/**
+ * @param {MyGame.Example.Color} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_color = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 16);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {MyGame.Example.Any}
+ */
+MyGame.Example.Monster.prototype.testType = function() {
+  var offset = this.bb.__offset(this.bb_pos, 18);
+  return offset ? /** @type {MyGame.Example.Any} */ (this.bb.readUint8(this.bb_pos + offset)) : MyGame.Example.Any.NONE;
+};
+
+/**
+ * @param {MyGame.Example.Any} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_test_type = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 18);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {flatbuffers.Table} obj
+ * @returns {?flatbuffers.Table}
+ */
+MyGame.Example.Monster.prototype.test = function(obj) {
+  var offset = this.bb.__offset(this.bb_pos, 20);
+  return offset ? this.bb.__union(obj, this.bb_pos + offset) : null;
+};
+
+/**
+ * @param {number} index
+ * @param {MyGame.Example.Test=} obj
+ * @returns {MyGame.Example.Test}
+ */
+MyGame.Example.Monster.prototype.test4 = function(index, obj) {
+  var offset = this.bb.__offset(this.bb_pos, 22);
+  return offset ? (obj || new MyGame.Example.Test).__init(this.bb.__vector(this.bb_pos + offset) + index * 4, this.bb) : null;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.test4Length = function() {
+  var offset = this.bb.__offset(this.bb_pos, 22);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} index
+ * @param {flatbuffers.Encoding=} optionalEncoding
+ * @returns {string|Uint8Array}
+ */
+MyGame.Example.Monster.prototype.testarrayofstring = function(index, optionalEncoding) {
+  var offset = this.bb.__offset(this.bb_pos, 24);
+  return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.testarrayofstringLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 24);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * an example documentation comment: this will end up in the generated code
+ * multiline too
+ *
+ * @param {number} index
+ * @param {MyGame.Example.Monster=} obj
+ * @returns {MyGame.Example.Monster}
+ */
+MyGame.Example.Monster.prototype.testarrayoftables = function(index, obj) {
+  var offset = this.bb.__offset(this.bb_pos, 26);
+  return offset ? (obj || new MyGame.Example.Monster).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.testarrayoftablesLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 26);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {MyGame.Example.Monster=} obj
+ * @returns {MyGame.Example.Monster|null}
+ */
+MyGame.Example.Monster.prototype.enemy = function(obj) {
+  var offset = this.bb.__offset(this.bb_pos, 28);
+  return offset ? (obj || new MyGame.Example.Monster).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null;
+};
+
+/**
+ * @param {number} index
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.testnestedflatbuffer = function(index) {
+  var offset = this.bb.__offset(this.bb_pos, 30);
+  return offset ? this.bb.readUint8(this.bb.__vector(this.bb_pos + offset) + index) : 0;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.testnestedflatbufferLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 30);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns {Uint8Array}
+ */
+MyGame.Example.Monster.prototype.testnestedflatbufferArray = function() {
+  var offset = this.bb.__offset(this.bb_pos, 30);
+  return offset ? new Uint8Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @param {MyGame.Example.Stat=} obj
+ * @returns {MyGame.Example.Stat|null}
+ */
+MyGame.Example.Monster.prototype.testempty = function(obj) {
+  var offset = this.bb.__offset(this.bb_pos, 32);
+  return offset ? (obj || new MyGame.Example.Stat).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null;
+};
+
+/**
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.testbool = function() {
+  var offset = this.bb.__offset(this.bb_pos, 34);
+  return offset ? !!this.bb.readInt8(this.bb_pos + offset) : false;
+};
+
+/**
+ * @param {boolean} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_testbool = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 34);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.testhashs32Fnv1 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 36);
+  return offset ? this.bb.readInt32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_testhashs32_fnv1 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 36);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.testhashu32Fnv1 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 38);
+  return offset ? this.bb.readUint32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_testhashu32_fnv1 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 38);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {flatbuffers.Long}
+ */
+MyGame.Example.Monster.prototype.testhashs64Fnv1 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 40);
+  return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0);
+};
+
+/**
+ * @param {flatbuffers.Long} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_testhashs64_fnv1 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 40);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {flatbuffers.Long}
+ */
+MyGame.Example.Monster.prototype.testhashu64Fnv1 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 42);
+  return offset ? this.bb.readUint64(this.bb_pos + offset) : this.bb.createLong(0, 0);
+};
+
+/**
+ * @param {flatbuffers.Long} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_testhashu64_fnv1 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 42);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.testhashs32Fnv1a = function() {
+  var offset = this.bb.__offset(this.bb_pos, 44);
+  return offset ? this.bb.readInt32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_testhashs32_fnv1a = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 44);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.testhashu32Fnv1a = function() {
+  var offset = this.bb.__offset(this.bb_pos, 46);
+  return offset ? this.bb.readUint32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_testhashu32_fnv1a = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 46);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {flatbuffers.Long}
+ */
+MyGame.Example.Monster.prototype.testhashs64Fnv1a = function() {
+  var offset = this.bb.__offset(this.bb_pos, 48);
+  return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0);
+};
+
+/**
+ * @param {flatbuffers.Long} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_testhashs64_fnv1a = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 48);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {flatbuffers.Long}
+ */
+MyGame.Example.Monster.prototype.testhashu64Fnv1a = function() {
+  var offset = this.bb.__offset(this.bb_pos, 50);
+  return offset ? this.bb.readUint64(this.bb_pos + offset) : this.bb.createLong(0, 0);
+};
+
+/**
+ * @param {flatbuffers.Long} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_testhashu64_fnv1a = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 50);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {number} index
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.testarrayofbools = function(index) {
+  var offset = this.bb.__offset(this.bb_pos, 52);
+  return offset ? !!this.bb.readInt8(this.bb.__vector(this.bb_pos + offset) + index) : false;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.testarrayofboolsLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 52);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns {Int8Array}
+ */
+MyGame.Example.Monster.prototype.testarrayofboolsArray = function() {
+  var offset = this.bb.__offset(this.bb_pos, 52);
+  return offset ? new Int8Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.testf = function() {
+  var offset = this.bb.__offset(this.bb_pos, 54);
+  return offset ? this.bb.readFloat32(this.bb_pos + offset) : 3.14159;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_testf = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 54);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeFloat32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.testf2 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 56);
+  return offset ? this.bb.readFloat32(this.bb_pos + offset) : 3.0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_testf2 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 56);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeFloat32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.testf3 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 58);
+  return offset ? this.bb.readFloat32(this.bb_pos + offset) : 0.0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_testf3 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 58);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeFloat32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {number} index
+ * @param {flatbuffers.Encoding=} optionalEncoding
+ * @returns {string|Uint8Array}
+ */
+MyGame.Example.Monster.prototype.testarrayofstring2 = function(index, optionalEncoding) {
+  var offset = this.bb.__offset(this.bb_pos, 60);
+  return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.testarrayofstring2Length = function() {
+  var offset = this.bb.__offset(this.bb_pos, 60);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} index
+ * @param {MyGame.Example.Ability=} obj
+ * @returns {MyGame.Example.Ability}
+ */
+MyGame.Example.Monster.prototype.testarrayofsortedstruct = function(index, obj) {
+  var offset = this.bb.__offset(this.bb_pos, 62);
+  return offset ? (obj || new MyGame.Example.Ability).__init(this.bb.__vector(this.bb_pos + offset) + index * 8, this.bb) : null;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.testarrayofsortedstructLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 62);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} index
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.flex = function(index) {
+  var offset = this.bb.__offset(this.bb_pos, 64);
+  return offset ? this.bb.readUint8(this.bb.__vector(this.bb_pos + offset) + index) : 0;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.flexLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 64);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns {Uint8Array}
+ */
+MyGame.Example.Monster.prototype.flexArray = function() {
+  var offset = this.bb.__offset(this.bb_pos, 64);
+  return offset ? new Uint8Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @param {number} index
+ * @param {MyGame.Example.Test=} obj
+ * @returns {MyGame.Example.Test}
+ */
+MyGame.Example.Monster.prototype.test5 = function(index, obj) {
+  var offset = this.bb.__offset(this.bb_pos, 66);
+  return offset ? (obj || new MyGame.Example.Test).__init(this.bb.__vector(this.bb_pos + offset) + index * 4, this.bb) : null;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.test5Length = function() {
+  var offset = this.bb.__offset(this.bb_pos, 66);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} index
+ * @returns {flatbuffers.Long}
+ */
+MyGame.Example.Monster.prototype.vectorOfLongs = function(index) {
+  var offset = this.bb.__offset(this.bb_pos, 68);
+  return offset ? this.bb.readInt64(this.bb.__vector(this.bb_pos + offset) + index * 8) : this.bb.createLong(0, 0);
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.vectorOfLongsLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 68);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} index
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.vectorOfDoubles = function(index) {
+  var offset = this.bb.__offset(this.bb_pos, 70);
+  return offset ? this.bb.readFloat64(this.bb.__vector(this.bb_pos + offset) + index * 8) : 0;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.vectorOfDoublesLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 70);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns {Float64Array}
+ */
+MyGame.Example.Monster.prototype.vectorOfDoublesArray = function() {
+  var offset = this.bb.__offset(this.bb_pos, 70);
+  return offset ? new Float64Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @param {MyGame.InParentNamespace=} obj
+ * @returns {MyGame.InParentNamespace|null}
+ */
+MyGame.Example.Monster.prototype.parentNamespaceTest = function(obj) {
+  var offset = this.bb.__offset(this.bb_pos, 72);
+  return offset ? (obj || new MyGame.InParentNamespace).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null;
+};
+
+/**
+ * @param {number} index
+ * @param {MyGame.Example.Referrable=} obj
+ * @returns {MyGame.Example.Referrable}
+ */
+MyGame.Example.Monster.prototype.vectorOfReferrables = function(index, obj) {
+  var offset = this.bb.__offset(this.bb_pos, 74);
+  return offset ? (obj || new MyGame.Example.Referrable).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.vectorOfReferrablesLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 74);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns {flatbuffers.Long}
+ */
+MyGame.Example.Monster.prototype.singleWeakReference = function() {
+  var offset = this.bb.__offset(this.bb_pos, 76);
+  return offset ? this.bb.readUint64(this.bb_pos + offset) : this.bb.createLong(0, 0);
+};
+
+/**
+ * @param {flatbuffers.Long} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_single_weak_reference = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 76);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {number} index
+ * @returns {flatbuffers.Long}
+ */
+MyGame.Example.Monster.prototype.vectorOfWeakReferences = function(index) {
+  var offset = this.bb.__offset(this.bb_pos, 78);
+  return offset ? this.bb.readUint64(this.bb.__vector(this.bb_pos + offset) + index * 8) : this.bb.createLong(0, 0);
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.vectorOfWeakReferencesLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 78);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} index
+ * @param {MyGame.Example.Referrable=} obj
+ * @returns {MyGame.Example.Referrable}
+ */
+MyGame.Example.Monster.prototype.vectorOfStrongReferrables = function(index, obj) {
+  var offset = this.bb.__offset(this.bb_pos, 80);
+  return offset ? (obj || new MyGame.Example.Referrable).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.vectorOfStrongReferrablesLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 80);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns {flatbuffers.Long}
+ */
+MyGame.Example.Monster.prototype.coOwningReference = function() {
+  var offset = this.bb.__offset(this.bb_pos, 82);
+  return offset ? this.bb.readUint64(this.bb_pos + offset) : this.bb.createLong(0, 0);
+};
+
+/**
+ * @param {flatbuffers.Long} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_co_owning_reference = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 82);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {number} index
+ * @returns {flatbuffers.Long}
+ */
+MyGame.Example.Monster.prototype.vectorOfCoOwningReferences = function(index) {
+  var offset = this.bb.__offset(this.bb_pos, 84);
+  return offset ? this.bb.readUint64(this.bb.__vector(this.bb_pos + offset) + index * 8) : this.bb.createLong(0, 0);
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.vectorOfCoOwningReferencesLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 84);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns {flatbuffers.Long}
+ */
+MyGame.Example.Monster.prototype.nonOwningReference = function() {
+  var offset = this.bb.__offset(this.bb_pos, 86);
+  return offset ? this.bb.readUint64(this.bb_pos + offset) : this.bb.createLong(0, 0);
+};
+
+/**
+ * @param {flatbuffers.Long} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_non_owning_reference = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 86);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {number} index
+ * @returns {flatbuffers.Long}
+ */
+MyGame.Example.Monster.prototype.vectorOfNonOwningReferences = function(index) {
+  var offset = this.bb.__offset(this.bb_pos, 88);
+  return offset ? this.bb.readUint64(this.bb.__vector(this.bb_pos + offset) + index * 8) : this.bb.createLong(0, 0);
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.vectorOfNonOwningReferencesLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 88);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns {MyGame.Example.AnyUniqueAliases}
+ */
+MyGame.Example.Monster.prototype.anyUniqueType = function() {
+  var offset = this.bb.__offset(this.bb_pos, 90);
+  return offset ? /** @type {MyGame.Example.AnyUniqueAliases} */ (this.bb.readUint8(this.bb_pos + offset)) : MyGame.Example.AnyUniqueAliases.NONE;
+};
+
+/**
+ * @param {MyGame.Example.AnyUniqueAliases} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_any_unique_type = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 90);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {flatbuffers.Table} obj
+ * @returns {?flatbuffers.Table}
+ */
+MyGame.Example.Monster.prototype.anyUnique = function(obj) {
+  var offset = this.bb.__offset(this.bb_pos, 92);
+  return offset ? this.bb.__union(obj, this.bb_pos + offset) : null;
+};
+
+/**
+ * @returns {MyGame.Example.AnyAmbiguousAliases}
+ */
+MyGame.Example.Monster.prototype.anyAmbiguousType = function() {
+  var offset = this.bb.__offset(this.bb_pos, 94);
+  return offset ? /** @type {MyGame.Example.AnyAmbiguousAliases} */ (this.bb.readUint8(this.bb_pos + offset)) : MyGame.Example.AnyAmbiguousAliases.NONE;
+};
+
+/**
+ * @param {MyGame.Example.AnyAmbiguousAliases} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_any_ambiguous_type = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 94);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {flatbuffers.Table} obj
+ * @returns {?flatbuffers.Table}
+ */
+MyGame.Example.Monster.prototype.anyAmbiguous = function(obj) {
+  var offset = this.bb.__offset(this.bb_pos, 96);
+  return offset ? this.bb.__union(obj, this.bb_pos + offset) : null;
+};
+
+/**
+ * @param {number} index
+ * @returns {MyGame.Example.Color}
+ */
+MyGame.Example.Monster.prototype.vectorOfEnums = function(index) {
+  var offset = this.bb.__offset(this.bb_pos, 98);
+  return offset ? /** @type {MyGame.Example.Color} */ (this.bb.readUint8(this.bb.__vector(this.bb_pos + offset) + index)) : /** @type {MyGame.Example.Color} */ (0);
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.vectorOfEnumsLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 98);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns {Uint8Array}
+ */
+MyGame.Example.Monster.prototype.vectorOfEnumsArray = function() {
+  var offset = this.bb.__offset(this.bb_pos, 98);
+  return offset ? new Uint8Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ */
+MyGame.Example.Monster.startMonster = function(builder) {
+  builder.startObject(48);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} posOffset
+ */
+MyGame.Example.Monster.addPos = function(builder, posOffset) {
+  builder.addFieldStruct(0, posOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} mana
+ */
+MyGame.Example.Monster.addMana = function(builder, mana) {
+  builder.addFieldInt16(1, mana, 150);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} hp
+ */
+MyGame.Example.Monster.addHp = function(builder, hp) {
+  builder.addFieldInt16(2, hp, 100);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} nameOffset
+ */
+MyGame.Example.Monster.addName = function(builder, nameOffset) {
+  builder.addFieldOffset(3, nameOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} inventoryOffset
+ */
+MyGame.Example.Monster.addInventory = function(builder, inventoryOffset) {
+  builder.addFieldOffset(5, inventoryOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<number>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createInventoryVector = function(builder, data) {
+  builder.startVector(1, data.length, 1);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt8(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startInventoryVector = function(builder, numElems) {
+  builder.startVector(1, numElems, 1);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {MyGame.Example.Color} color
+ */
+MyGame.Example.Monster.addColor = function(builder, color) {
+  builder.addFieldInt8(6, color, MyGame.Example.Color.Blue);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {MyGame.Example.Any} testType
+ */
+MyGame.Example.Monster.addTestType = function(builder, testType) {
+  builder.addFieldInt8(7, testType, MyGame.Example.Any.NONE);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} testOffset
+ */
+MyGame.Example.Monster.addTest = function(builder, testOffset) {
+  builder.addFieldOffset(8, testOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} test4Offset
+ */
+MyGame.Example.Monster.addTest4 = function(builder, test4Offset) {
+  builder.addFieldOffset(9, test4Offset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startTest4Vector = function(builder, numElems) {
+  builder.startVector(4, numElems, 2);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} testarrayofstringOffset
+ */
+MyGame.Example.Monster.addTestarrayofstring = function(builder, testarrayofstringOffset) {
+  builder.addFieldOffset(10, testarrayofstringOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<flatbuffers.Offset>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createTestarrayofstringVector = function(builder, data) {
+  builder.startVector(4, data.length, 4);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addOffset(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startTestarrayofstringVector = function(builder, numElems) {
+  builder.startVector(4, numElems, 4);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} testarrayoftablesOffset
+ */
+MyGame.Example.Monster.addTestarrayoftables = function(builder, testarrayoftablesOffset) {
+  builder.addFieldOffset(11, testarrayoftablesOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<flatbuffers.Offset>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createTestarrayoftablesVector = function(builder, data) {
+  builder.startVector(4, data.length, 4);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addOffset(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startTestarrayoftablesVector = function(builder, numElems) {
+  builder.startVector(4, numElems, 4);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} enemyOffset
+ */
+MyGame.Example.Monster.addEnemy = function(builder, enemyOffset) {
+  builder.addFieldOffset(12, enemyOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} testnestedflatbufferOffset
+ */
+MyGame.Example.Monster.addTestnestedflatbuffer = function(builder, testnestedflatbufferOffset) {
+  builder.addFieldOffset(13, testnestedflatbufferOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<number>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createTestnestedflatbufferVector = function(builder, data) {
+  builder.startVector(1, data.length, 1);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt8(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startTestnestedflatbufferVector = function(builder, numElems) {
+  builder.startVector(1, numElems, 1);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} testemptyOffset
+ */
+MyGame.Example.Monster.addTestempty = function(builder, testemptyOffset) {
+  builder.addFieldOffset(14, testemptyOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {boolean} testbool
+ */
+MyGame.Example.Monster.addTestbool = function(builder, testbool) {
+  builder.addFieldInt8(15, +testbool, +false);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} testhashs32Fnv1
+ */
+MyGame.Example.Monster.addTesthashs32Fnv1 = function(builder, testhashs32Fnv1) {
+  builder.addFieldInt32(16, testhashs32Fnv1, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} testhashu32Fnv1
+ */
+MyGame.Example.Monster.addTesthashu32Fnv1 = function(builder, testhashu32Fnv1) {
+  builder.addFieldInt32(17, testhashu32Fnv1, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Long} testhashs64Fnv1
+ */
+MyGame.Example.Monster.addTesthashs64Fnv1 = function(builder, testhashs64Fnv1) {
+  builder.addFieldInt64(18, testhashs64Fnv1, builder.createLong(0, 0));
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Long} testhashu64Fnv1
+ */
+MyGame.Example.Monster.addTesthashu64Fnv1 = function(builder, testhashu64Fnv1) {
+  builder.addFieldInt64(19, testhashu64Fnv1, builder.createLong(0, 0));
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} testhashs32Fnv1a
+ */
+MyGame.Example.Monster.addTesthashs32Fnv1a = function(builder, testhashs32Fnv1a) {
+  builder.addFieldInt32(20, testhashs32Fnv1a, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} testhashu32Fnv1a
+ */
+MyGame.Example.Monster.addTesthashu32Fnv1a = function(builder, testhashu32Fnv1a) {
+  builder.addFieldInt32(21, testhashu32Fnv1a, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Long} testhashs64Fnv1a
+ */
+MyGame.Example.Monster.addTesthashs64Fnv1a = function(builder, testhashs64Fnv1a) {
+  builder.addFieldInt64(22, testhashs64Fnv1a, builder.createLong(0, 0));
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Long} testhashu64Fnv1a
+ */
+MyGame.Example.Monster.addTesthashu64Fnv1a = function(builder, testhashu64Fnv1a) {
+  builder.addFieldInt64(23, testhashu64Fnv1a, builder.createLong(0, 0));
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} testarrayofboolsOffset
+ */
+MyGame.Example.Monster.addTestarrayofbools = function(builder, testarrayofboolsOffset) {
+  builder.addFieldOffset(24, testarrayofboolsOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<boolean>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createTestarrayofboolsVector = function(builder, data) {
+  builder.startVector(1, data.length, 1);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt8(+data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startTestarrayofboolsVector = function(builder, numElems) {
+  builder.startVector(1, numElems, 1);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} testf
+ */
+MyGame.Example.Monster.addTestf = function(builder, testf) {
+  builder.addFieldFloat32(25, testf, 3.14159);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} testf2
+ */
+MyGame.Example.Monster.addTestf2 = function(builder, testf2) {
+  builder.addFieldFloat32(26, testf2, 3.0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} testf3
+ */
+MyGame.Example.Monster.addTestf3 = function(builder, testf3) {
+  builder.addFieldFloat32(27, testf3, 0.0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} testarrayofstring2Offset
+ */
+MyGame.Example.Monster.addTestarrayofstring2 = function(builder, testarrayofstring2Offset) {
+  builder.addFieldOffset(28, testarrayofstring2Offset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<flatbuffers.Offset>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createTestarrayofstring2Vector = function(builder, data) {
+  builder.startVector(4, data.length, 4);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addOffset(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startTestarrayofstring2Vector = function(builder, numElems) {
+  builder.startVector(4, numElems, 4);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} testarrayofsortedstructOffset
+ */
+MyGame.Example.Monster.addTestarrayofsortedstruct = function(builder, testarrayofsortedstructOffset) {
+  builder.addFieldOffset(29, testarrayofsortedstructOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startTestarrayofsortedstructVector = function(builder, numElems) {
+  builder.startVector(8, numElems, 4);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} flexOffset
+ */
+MyGame.Example.Monster.addFlex = function(builder, flexOffset) {
+  builder.addFieldOffset(30, flexOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<number>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createFlexVector = function(builder, data) {
+  builder.startVector(1, data.length, 1);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt8(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startFlexVector = function(builder, numElems) {
+  builder.startVector(1, numElems, 1);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} test5Offset
+ */
+MyGame.Example.Monster.addTest5 = function(builder, test5Offset) {
+  builder.addFieldOffset(31, test5Offset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startTest5Vector = function(builder, numElems) {
+  builder.startVector(4, numElems, 2);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} vectorOfLongsOffset
+ */
+MyGame.Example.Monster.addVectorOfLongs = function(builder, vectorOfLongsOffset) {
+  builder.addFieldOffset(32, vectorOfLongsOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<flatbuffers.Long>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createVectorOfLongsVector = function(builder, data) {
+  builder.startVector(8, data.length, 8);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt64(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startVectorOfLongsVector = function(builder, numElems) {
+  builder.startVector(8, numElems, 8);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} vectorOfDoublesOffset
+ */
+MyGame.Example.Monster.addVectorOfDoubles = function(builder, vectorOfDoublesOffset) {
+  builder.addFieldOffset(33, vectorOfDoublesOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<number>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createVectorOfDoublesVector = function(builder, data) {
+  builder.startVector(8, data.length, 8);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addFloat64(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startVectorOfDoublesVector = function(builder, numElems) {
+  builder.startVector(8, numElems, 8);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} parentNamespaceTestOffset
+ */
+MyGame.Example.Monster.addParentNamespaceTest = function(builder, parentNamespaceTestOffset) {
+  builder.addFieldOffset(34, parentNamespaceTestOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} vectorOfReferrablesOffset
+ */
+MyGame.Example.Monster.addVectorOfReferrables = function(builder, vectorOfReferrablesOffset) {
+  builder.addFieldOffset(35, vectorOfReferrablesOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<flatbuffers.Offset>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createVectorOfReferrablesVector = function(builder, data) {
+  builder.startVector(4, data.length, 4);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addOffset(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startVectorOfReferrablesVector = function(builder, numElems) {
+  builder.startVector(4, numElems, 4);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Long} singleWeakReference
+ */
+MyGame.Example.Monster.addSingleWeakReference = function(builder, singleWeakReference) {
+  builder.addFieldInt64(36, singleWeakReference, builder.createLong(0, 0));
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} vectorOfWeakReferencesOffset
+ */
+MyGame.Example.Monster.addVectorOfWeakReferences = function(builder, vectorOfWeakReferencesOffset) {
+  builder.addFieldOffset(37, vectorOfWeakReferencesOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<flatbuffers.Long>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createVectorOfWeakReferencesVector = function(builder, data) {
+  builder.startVector(8, data.length, 8);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt64(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startVectorOfWeakReferencesVector = function(builder, numElems) {
+  builder.startVector(8, numElems, 8);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} vectorOfStrongReferrablesOffset
+ */
+MyGame.Example.Monster.addVectorOfStrongReferrables = function(builder, vectorOfStrongReferrablesOffset) {
+  builder.addFieldOffset(38, vectorOfStrongReferrablesOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<flatbuffers.Offset>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createVectorOfStrongReferrablesVector = function(builder, data) {
+  builder.startVector(4, data.length, 4);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addOffset(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startVectorOfStrongReferrablesVector = function(builder, numElems) {
+  builder.startVector(4, numElems, 4);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Long} coOwningReference
+ */
+MyGame.Example.Monster.addCoOwningReference = function(builder, coOwningReference) {
+  builder.addFieldInt64(39, coOwningReference, builder.createLong(0, 0));
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} vectorOfCoOwningReferencesOffset
+ */
+MyGame.Example.Monster.addVectorOfCoOwningReferences = function(builder, vectorOfCoOwningReferencesOffset) {
+  builder.addFieldOffset(40, vectorOfCoOwningReferencesOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<flatbuffers.Long>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createVectorOfCoOwningReferencesVector = function(builder, data) {
+  builder.startVector(8, data.length, 8);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt64(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startVectorOfCoOwningReferencesVector = function(builder, numElems) {
+  builder.startVector(8, numElems, 8);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Long} nonOwningReference
+ */
+MyGame.Example.Monster.addNonOwningReference = function(builder, nonOwningReference) {
+  builder.addFieldInt64(41, nonOwningReference, builder.createLong(0, 0));
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} vectorOfNonOwningReferencesOffset
+ */
+MyGame.Example.Monster.addVectorOfNonOwningReferences = function(builder, vectorOfNonOwningReferencesOffset) {
+  builder.addFieldOffset(42, vectorOfNonOwningReferencesOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<flatbuffers.Long>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createVectorOfNonOwningReferencesVector = function(builder, data) {
+  builder.startVector(8, data.length, 8);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt64(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startVectorOfNonOwningReferencesVector = function(builder, numElems) {
+  builder.startVector(8, numElems, 8);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {MyGame.Example.AnyUniqueAliases} anyUniqueType
+ */
+MyGame.Example.Monster.addAnyUniqueType = function(builder, anyUniqueType) {
+  builder.addFieldInt8(43, anyUniqueType, MyGame.Example.AnyUniqueAliases.NONE);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} anyUniqueOffset
+ */
+MyGame.Example.Monster.addAnyUnique = function(builder, anyUniqueOffset) {
+  builder.addFieldOffset(44, anyUniqueOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {MyGame.Example.AnyAmbiguousAliases} anyAmbiguousType
+ */
+MyGame.Example.Monster.addAnyAmbiguousType = function(builder, anyAmbiguousType) {
+  builder.addFieldInt8(45, anyAmbiguousType, MyGame.Example.AnyAmbiguousAliases.NONE);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} anyAmbiguousOffset
+ */
+MyGame.Example.Monster.addAnyAmbiguous = function(builder, anyAmbiguousOffset) {
+  builder.addFieldOffset(46, anyAmbiguousOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} vectorOfEnumsOffset
+ */
+MyGame.Example.Monster.addVectorOfEnums = function(builder, vectorOfEnumsOffset) {
+  builder.addFieldOffset(47, vectorOfEnumsOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<MyGame.Example.Color>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createVectorOfEnumsVector = function(builder, data) {
+  builder.startVector(1, data.length, 1);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt8(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startVectorOfEnumsVector = function(builder, numElems) {
+  builder.startVector(1, numElems, 1);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.endMonster = function(builder) {
+  var offset = builder.endObject();
+  builder.requiredField(offset, 10); // name
+  return offset;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} offset
+ */
+MyGame.Example.Monster.finishMonsterBuffer = function(builder, offset) {
+  builder.finish(offset, 'MONS');
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} offset
+ */
+MyGame.Example.Monster.finishSizePrefixedMonsterBuffer = function(builder, offset) {
+  builder.finish(offset, 'MONS', true);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} posOffset
+ * @param {number} mana
+ * @param {number} hp
+ * @param {flatbuffers.Offset} nameOffset
+ * @param {flatbuffers.Offset} inventoryOffset
+ * @param {MyGame.Example.Color} color
+ * @param {MyGame.Example.Any} testType
+ * @param {flatbuffers.Offset} testOffset
+ * @param {flatbuffers.Offset} test4Offset
+ * @param {flatbuffers.Offset} testarrayofstringOffset
+ * @param {flatbuffers.Offset} testarrayoftablesOffset
+ * @param {flatbuffers.Offset} enemyOffset
+ * @param {flatbuffers.Offset} testnestedflatbufferOffset
+ * @param {flatbuffers.Offset} testemptyOffset
+ * @param {boolean} testbool
+ * @param {number} testhashs32Fnv1
+ * @param {number} testhashu32Fnv1
+ * @param {flatbuffers.Long} testhashs64Fnv1
+ * @param {flatbuffers.Long} testhashu64Fnv1
+ * @param {number} testhashs32Fnv1a
+ * @param {number} testhashu32Fnv1a
+ * @param {flatbuffers.Long} testhashs64Fnv1a
+ * @param {flatbuffers.Long} testhashu64Fnv1a
+ * @param {flatbuffers.Offset} testarrayofboolsOffset
+ * @param {number} testf
+ * @param {number} testf2
+ * @param {number} testf3
+ * @param {flatbuffers.Offset} testarrayofstring2Offset
+ * @param {flatbuffers.Offset} testarrayofsortedstructOffset
+ * @param {flatbuffers.Offset} flexOffset
+ * @param {flatbuffers.Offset} test5Offset
+ * @param {flatbuffers.Offset} vectorOfLongsOffset
+ * @param {flatbuffers.Offset} vectorOfDoublesOffset
+ * @param {flatbuffers.Offset} parentNamespaceTestOffset
+ * @param {flatbuffers.Offset} vectorOfReferrablesOffset
+ * @param {flatbuffers.Long} singleWeakReference
+ * @param {flatbuffers.Offset} vectorOfWeakReferencesOffset
+ * @param {flatbuffers.Offset} vectorOfStrongReferrablesOffset
+ * @param {flatbuffers.Long} coOwningReference
+ * @param {flatbuffers.Offset} vectorOfCoOwningReferencesOffset
+ * @param {flatbuffers.Long} nonOwningReference
+ * @param {flatbuffers.Offset} vectorOfNonOwningReferencesOffset
+ * @param {MyGame.Example.AnyUniqueAliases} anyUniqueType
+ * @param {flatbuffers.Offset} anyUniqueOffset
+ * @param {MyGame.Example.AnyAmbiguousAliases} anyAmbiguousType
+ * @param {flatbuffers.Offset} anyAmbiguousOffset
+ * @param {flatbuffers.Offset} vectorOfEnumsOffset
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createMonster = function(builder, posOffset, mana, hp, nameOffset, inventoryOffset, color, testType, testOffset, test4Offset, testarrayofstringOffset, testarrayoftablesOffset, enemyOffset, testnestedflatbufferOffset, testemptyOffset, testbool, testhashs32Fnv1, testhashu32Fnv1, testhashs64Fnv1, testhashu64Fnv1, testhashs32Fnv1a, testhashu32Fnv1a, testhashs64Fnv1a, testhashu64Fnv1a, testarrayofboolsOffset, testf, testf2, testf3, testarrayofstring2Offset, testarrayofsortedstructOffset, flexOffset, test5Offset, vectorOfLongsOffset, vectorOfDoublesOffset, parentNamespaceTestOffset, vectorOfReferrablesOffset, singleWeakReference, vectorOfWeakReferencesOffset, vectorOfStrongReferrablesOffset, coOwningReference, vectorOfCoOwningReferencesOffset, nonOwningReference, vectorOfNonOwningReferencesOffset, anyUniqueType, anyUniqueOffset, anyAmbiguousType, anyAmbiguousOffset, vectorOfEnumsOffset) {
+  MyGame.Example.Monster.startMonster(builder);
+  MyGame.Example.Monster.addPos(builder, posOffset);
+  MyGame.Example.Monster.addMana(builder, mana);
+  MyGame.Example.Monster.addHp(builder, hp);
+  MyGame.Example.Monster.addName(builder, nameOffset);
+  MyGame.Example.Monster.addInventory(builder, inventoryOffset);
+  MyGame.Example.Monster.addColor(builder, color);
+  MyGame.Example.Monster.addTestType(builder, testType);
+  MyGame.Example.Monster.addTest(builder, testOffset);
+  MyGame.Example.Monster.addTest4(builder, test4Offset);
+  MyGame.Example.Monster.addTestarrayofstring(builder, testarrayofstringOffset);
+  MyGame.Example.Monster.addTestarrayoftables(builder, testarrayoftablesOffset);
+  MyGame.Example.Monster.addEnemy(builder, enemyOffset);
+  MyGame.Example.Monster.addTestnestedflatbuffer(builder, testnestedflatbufferOffset);
+  MyGame.Example.Monster.addTestempty(builder, testemptyOffset);
+  MyGame.Example.Monster.addTestbool(builder, testbool);
+  MyGame.Example.Monster.addTesthashs32Fnv1(builder, testhashs32Fnv1);
+  MyGame.Example.Monster.addTesthashu32Fnv1(builder, testhashu32Fnv1);
+  MyGame.Example.Monster.addTesthashs64Fnv1(builder, testhashs64Fnv1);
+  MyGame.Example.Monster.addTesthashu64Fnv1(builder, testhashu64Fnv1);
+  MyGame.Example.Monster.addTesthashs32Fnv1a(builder, testhashs32Fnv1a);
+  MyGame.Example.Monster.addTesthashu32Fnv1a(builder, testhashu32Fnv1a);
+  MyGame.Example.Monster.addTesthashs64Fnv1a(builder, testhashs64Fnv1a);
+  MyGame.Example.Monster.addTesthashu64Fnv1a(builder, testhashu64Fnv1a);
+  MyGame.Example.Monster.addTestarrayofbools(builder, testarrayofboolsOffset);
+  MyGame.Example.Monster.addTestf(builder, testf);
+  MyGame.Example.Monster.addTestf2(builder, testf2);
+  MyGame.Example.Monster.addTestf3(builder, testf3);
+  MyGame.Example.Monster.addTestarrayofstring2(builder, testarrayofstring2Offset);
+  MyGame.Example.Monster.addTestarrayofsortedstruct(builder, testarrayofsortedstructOffset);
+  MyGame.Example.Monster.addFlex(builder, flexOffset);
+  MyGame.Example.Monster.addTest5(builder, test5Offset);
+  MyGame.Example.Monster.addVectorOfLongs(builder, vectorOfLongsOffset);
+  MyGame.Example.Monster.addVectorOfDoubles(builder, vectorOfDoublesOffset);
+  MyGame.Example.Monster.addParentNamespaceTest(builder, parentNamespaceTestOffset);
+  MyGame.Example.Monster.addVectorOfReferrables(builder, vectorOfReferrablesOffset);
+  MyGame.Example.Monster.addSingleWeakReference(builder, singleWeakReference);
+  MyGame.Example.Monster.addVectorOfWeakReferences(builder, vectorOfWeakReferencesOffset);
+  MyGame.Example.Monster.addVectorOfStrongReferrables(builder, vectorOfStrongReferrablesOffset);
+  MyGame.Example.Monster.addCoOwningReference(builder, coOwningReference);
+  MyGame.Example.Monster.addVectorOfCoOwningReferences(builder, vectorOfCoOwningReferencesOffset);
+  MyGame.Example.Monster.addNonOwningReference(builder, nonOwningReference);
+  MyGame.Example.Monster.addVectorOfNonOwningReferences(builder, vectorOfNonOwningReferencesOffset);
+  MyGame.Example.Monster.addAnyUniqueType(builder, anyUniqueType);
+  MyGame.Example.Monster.addAnyUnique(builder, anyUniqueOffset);
+  MyGame.Example.Monster.addAnyAmbiguousType(builder, anyAmbiguousType);
+  MyGame.Example.Monster.addAnyAmbiguous(builder, anyAmbiguousOffset);
+  MyGame.Example.Monster.addVectorOfEnums(builder, vectorOfEnumsOffset);
+  return MyGame.Example.Monster.endMonster(builder);
+}
+
+/**
+ * @constructor
+ */
+MyGame.Example.TypeAliases = function() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+};
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {MyGame.Example.TypeAliases}
+ */
+MyGame.Example.TypeAliases.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.Example.TypeAliases=} obj
+ * @returns {MyGame.Example.TypeAliases}
+ */
+MyGame.Example.TypeAliases.getRootAsTypeAliases = function(bb, obj) {
+  return (obj || new MyGame.Example.TypeAliases).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.Example.TypeAliases=} obj
+ * @returns {MyGame.Example.TypeAliases}
+ */
+MyGame.Example.TypeAliases.getSizePrefixedRootAsTypeAliases = function(bb, obj) {
+  return (obj || new MyGame.Example.TypeAliases).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.TypeAliases.prototype.i8 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+  return offset ? this.bb.readInt8(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.TypeAliases.prototype.mutate_i8 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.TypeAliases.prototype.u8 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 6);
+  return offset ? this.bb.readUint8(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.TypeAliases.prototype.mutate_u8 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 6);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.TypeAliases.prototype.i16 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 8);
+  return offset ? this.bb.readInt16(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.TypeAliases.prototype.mutate_i16 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 8);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt16(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.TypeAliases.prototype.u16 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 10);
+  return offset ? this.bb.readUint16(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.TypeAliases.prototype.mutate_u16 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 10);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint16(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.TypeAliases.prototype.i32 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 12);
+  return offset ? this.bb.readInt32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.TypeAliases.prototype.mutate_i32 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 12);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.TypeAliases.prototype.u32 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 14);
+  return offset ? this.bb.readUint32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.TypeAliases.prototype.mutate_u32 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 14);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {flatbuffers.Long}
+ */
+MyGame.Example.TypeAliases.prototype.i64 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 16);
+  return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0);
+};
+
+/**
+ * @param {flatbuffers.Long} value
+ * @returns {boolean}
+ */
+MyGame.Example.TypeAliases.prototype.mutate_i64 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 16);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {flatbuffers.Long}
+ */
+MyGame.Example.TypeAliases.prototype.u64 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 18);
+  return offset ? this.bb.readUint64(this.bb_pos + offset) : this.bb.createLong(0, 0);
+};
+
+/**
+ * @param {flatbuffers.Long} value
+ * @returns {boolean}
+ */
+MyGame.Example.TypeAliases.prototype.mutate_u64 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 18);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.TypeAliases.prototype.f32 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 20);
+  return offset ? this.bb.readFloat32(this.bb_pos + offset) : 0.0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.TypeAliases.prototype.mutate_f32 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 20);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeFloat32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.TypeAliases.prototype.f64 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 22);
+  return offset ? this.bb.readFloat64(this.bb_pos + offset) : 0.0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.TypeAliases.prototype.mutate_f64 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 22);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeFloat64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {number} index
+ * @returns {number}
+ */
+MyGame.Example.TypeAliases.prototype.v8 = function(index) {
+  var offset = this.bb.__offset(this.bb_pos, 24);
+  return offset ? this.bb.readInt8(this.bb.__vector(this.bb_pos + offset) + index) : 0;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.TypeAliases.prototype.v8Length = function() {
+  var offset = this.bb.__offset(this.bb_pos, 24);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns {Int8Array}
+ */
+MyGame.Example.TypeAliases.prototype.v8Array = function() {
+  var offset = this.bb.__offset(this.bb_pos, 24);
+  return offset ? new Int8Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @param {number} index
+ * @returns {number}
+ */
+MyGame.Example.TypeAliases.prototype.vf64 = function(index) {
+  var offset = this.bb.__offset(this.bb_pos, 26);
+  return offset ? this.bb.readFloat64(this.bb.__vector(this.bb_pos + offset) + index * 8) : 0;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.TypeAliases.prototype.vf64Length = function() {
+  var offset = this.bb.__offset(this.bb_pos, 26);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns {Float64Array}
+ */
+MyGame.Example.TypeAliases.prototype.vf64Array = function() {
+  var offset = this.bb.__offset(this.bb_pos, 26);
+  return offset ? new Float64Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ */
+MyGame.Example.TypeAliases.startTypeAliases = function(builder) {
+  builder.startObject(12);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} i8
+ */
+MyGame.Example.TypeAliases.addI8 = function(builder, i8) {
+  builder.addFieldInt8(0, i8, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} u8
+ */
+MyGame.Example.TypeAliases.addU8 = function(builder, u8) {
+  builder.addFieldInt8(1, u8, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} i16
+ */
+MyGame.Example.TypeAliases.addI16 = function(builder, i16) {
+  builder.addFieldInt16(2, i16, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} u16
+ */
+MyGame.Example.TypeAliases.addU16 = function(builder, u16) {
+  builder.addFieldInt16(3, u16, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} i32
+ */
+MyGame.Example.TypeAliases.addI32 = function(builder, i32) {
+  builder.addFieldInt32(4, i32, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} u32
+ */
+MyGame.Example.TypeAliases.addU32 = function(builder, u32) {
+  builder.addFieldInt32(5, u32, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Long} i64
+ */
+MyGame.Example.TypeAliases.addI64 = function(builder, i64) {
+  builder.addFieldInt64(6, i64, builder.createLong(0, 0));
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Long} u64
+ */
+MyGame.Example.TypeAliases.addU64 = function(builder, u64) {
+  builder.addFieldInt64(7, u64, builder.createLong(0, 0));
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} f32
+ */
+MyGame.Example.TypeAliases.addF32 = function(builder, f32) {
+  builder.addFieldFloat32(8, f32, 0.0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} f64
+ */
+MyGame.Example.TypeAliases.addF64 = function(builder, f64) {
+  builder.addFieldFloat64(9, f64, 0.0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} v8Offset
+ */
+MyGame.Example.TypeAliases.addV8 = function(builder, v8Offset) {
+  builder.addFieldOffset(10, v8Offset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<number>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.TypeAliases.createV8Vector = function(builder, data) {
+  builder.startVector(1, data.length, 1);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt8(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.TypeAliases.startV8Vector = function(builder, numElems) {
+  builder.startVector(1, numElems, 1);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} vf64Offset
+ */
+MyGame.Example.TypeAliases.addVf64 = function(builder, vf64Offset) {
+  builder.addFieldOffset(11, vf64Offset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<number>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.TypeAliases.createVf64Vector = function(builder, data) {
+  builder.startVector(8, data.length, 8);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addFloat64(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.TypeAliases.startVf64Vector = function(builder, numElems) {
+  builder.startVector(8, numElems, 8);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.TypeAliases.endTypeAliases = function(builder) {
+  var offset = builder.endObject();
+  return offset;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} i8
+ * @param {number} u8
+ * @param {number} i16
+ * @param {number} u16
+ * @param {number} i32
+ * @param {number} u32
+ * @param {flatbuffers.Long} i64
+ * @param {flatbuffers.Long} u64
+ * @param {number} f32
+ * @param {number} f64
+ * @param {flatbuffers.Offset} v8Offset
+ * @param {flatbuffers.Offset} vf64Offset
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.TypeAliases.createTypeAliases = function(builder, i8, u8, i16, u16, i32, u32, i64, u64, f32, f64, v8Offset, vf64Offset) {
+  MyGame.Example.TypeAliases.startTypeAliases(builder);
+  MyGame.Example.TypeAliases.addI8(builder, i8);
+  MyGame.Example.TypeAliases.addU8(builder, u8);
+  MyGame.Example.TypeAliases.addI16(builder, i16);
+  MyGame.Example.TypeAliases.addU16(builder, u16);
+  MyGame.Example.TypeAliases.addI32(builder, i32);
+  MyGame.Example.TypeAliases.addU32(builder, u32);
+  MyGame.Example.TypeAliases.addI64(builder, i64);
+  MyGame.Example.TypeAliases.addU64(builder, u64);
+  MyGame.Example.TypeAliases.addF32(builder, f32);
+  MyGame.Example.TypeAliases.addF64(builder, f64);
+  MyGame.Example.TypeAliases.addV8(builder, v8Offset);
+  MyGame.Example.TypeAliases.addVf64(builder, vf64Offset);
+  return MyGame.Example.TypeAliases.endTypeAliases(builder);
+}
+
+// Exports for Node.js and RequireJS
+this.MyGame = MyGame;
diff --git a/tests/monster_test_generated.lobster b/tests/monster_test_generated.lobster
new file mode 100644
index 0000000..05e9cbe
--- /dev/null
+++ b/tests/monster_test_generated.lobster
@@ -0,0 +1,710 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+import flatbuffers
+
+namespace MyGame_Example
+
+/// Composite components of Monster color.
+enum Color:
+    Color_Red = 1
+    /// \brief color Green
+    /// Green is bit_flag with value (1u << 1)
+    Color_Green = 2
+    /// \brief color Blue (1u << 3)
+    Color_Blue = 8
+
+enum Any:
+    Any_NONE = 0
+    Any_Monster = 1
+    Any_TestSimpleTableWithEnum = 2
+    Any_MyGame_Example2_Monster = 3
+
+enum AnyUniqueAliases:
+    AnyUniqueAliases_NONE = 0
+    AnyUniqueAliases_M = 1
+    AnyUniqueAliases_TS = 2
+    AnyUniqueAliases_M2 = 3
+
+enum AnyAmbiguousAliases:
+    AnyAmbiguousAliases_NONE = 0
+    AnyAmbiguousAliases_M1 = 1
+    AnyAmbiguousAliases_M2 = 2
+    AnyAmbiguousAliases_M3 = 3
+
+namespace MyGame
+
+class InParentNamespace
+
+namespace MyGame_Example2
+
+class Monster
+
+namespace MyGame_Example
+
+class Test
+
+class TestSimpleTableWithEnum
+
+class Vec3
+
+class Ability
+
+class Stat
+
+class Referrable
+
+class Monster
+
+class TypeAliases
+
+namespace MyGame
+
+class InParentNamespace : flatbuffers_handle
+
+def GetRootAsInParentNamespace(buf:string): return InParentNamespace { buf, buf.flatbuffers_indirect(0) }
+
+struct InParentNamespaceBuilder:
+    b_:flatbuffers_builder
+    def start():
+        b_.StartObject(0)
+        return this
+    def end():
+        return b_.EndObject()
+
+namespace MyGame_Example2
+
+class Monster : flatbuffers_handle
+
+def GetRootAsMonster(buf:string): return Monster { buf, buf.flatbuffers_indirect(0) }
+
+struct MonsterBuilder:
+    b_:flatbuffers_builder
+    def start():
+        b_.StartObject(0)
+        return this
+    def end():
+        return b_.EndObject()
+
+namespace MyGame_Example
+
+class Test : flatbuffers_handle
+    def a():
+        return buf_.read_int16_le(pos_ + 0)
+    def b():
+        return buf_.read_int8_le(pos_ + 2)
+
+def CreateTest(b_:flatbuffers_builder, a:int, b:int):
+    b_.Prep(2, 4)
+    b_.Pad(1)
+    b_.PrependInt8(b)
+    b_.PrependInt16(a)
+    return b_.Offset()
+
+class TestSimpleTableWithEnum : flatbuffers_handle
+    def color():
+        return Color(buf_.flatbuffers_field_int8(pos_, 4, 2))
+
+def GetRootAsTestSimpleTableWithEnum(buf:string): return TestSimpleTableWithEnum { buf, buf.flatbuffers_indirect(0) }
+
+struct TestSimpleTableWithEnumBuilder:
+    b_:flatbuffers_builder
+    def start():
+        b_.StartObject(1)
+        return this
+    def add_color(color:Color):
+        b_.PrependUint8Slot(0, color, 2)
+        return this
+    def end():
+        return b_.EndObject()
+
+class Vec3 : flatbuffers_handle
+    def x():
+        return buf_.read_float32_le(pos_ + 0)
+    def y():
+        return buf_.read_float32_le(pos_ + 4)
+    def z():
+        return buf_.read_float32_le(pos_ + 8)
+    def test1():
+        return buf_.read_float64_le(pos_ + 16)
+    def test2():
+        return Color(buf_.read_int8_le(pos_ + 24))
+    def test3():
+        return MyGame_Example_Test{ buf_, pos_ + 26 }
+
+def CreateVec3(b_:flatbuffers_builder, x:float, y:float, z:float, test1:float, test2:Color, test3_a:int, test3_b:int):
+    b_.Prep(8, 32)
+    b_.Pad(2)
+    b_.Prep(2, 4)
+    b_.Pad(1)
+    b_.PrependInt8(test3_b)
+    b_.PrependInt16(test3_a)
+    b_.Pad(1)
+    b_.PrependUint8(test2)
+    b_.PrependFloat64(test1)
+    b_.Pad(4)
+    b_.PrependFloat32(z)
+    b_.PrependFloat32(y)
+    b_.PrependFloat32(x)
+    return b_.Offset()
+
+class Ability : flatbuffers_handle
+    def id():
+        return buf_.read_int32_le(pos_ + 0)
+    def distance():
+        return buf_.read_int32_le(pos_ + 4)
+
+def CreateAbility(b_:flatbuffers_builder, id:int, distance:int):
+    b_.Prep(4, 8)
+    b_.PrependUint32(distance)
+    b_.PrependUint32(id)
+    return b_.Offset()
+
+class Stat : flatbuffers_handle
+    def id():
+        return buf_.flatbuffers_field_string(pos_, 4)
+    def val():
+        return buf_.flatbuffers_field_int64(pos_, 6, 0)
+    def count():
+        return buf_.flatbuffers_field_int16(pos_, 8, 0)
+
+def GetRootAsStat(buf:string): return Stat { buf, buf.flatbuffers_indirect(0) }
+
+struct StatBuilder:
+    b_:flatbuffers_builder
+    def start():
+        b_.StartObject(3)
+        return this
+    def add_id(id:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(0, id)
+        return this
+    def add_val(val:int):
+        b_.PrependInt64Slot(1, val, 0)
+        return this
+    def add_count(count:int):
+        b_.PrependUint16Slot(2, count, 0)
+        return this
+    def end():
+        return b_.EndObject()
+
+class Referrable : flatbuffers_handle
+    def id():
+        return buf_.flatbuffers_field_int64(pos_, 4, 0)
+
+def GetRootAsReferrable(buf:string): return Referrable { buf, buf.flatbuffers_indirect(0) }
+
+struct ReferrableBuilder:
+    b_:flatbuffers_builder
+    def start():
+        b_.StartObject(1)
+        return this
+    def add_id(id:int):
+        b_.PrependUint64Slot(0, id, 0)
+        return this
+    def end():
+        return b_.EndObject()
+
+/// an example documentation comment: monster object
+class Monster : flatbuffers_handle
+    def pos():
+        let o = buf_.flatbuffers_field_struct(pos_, 4)
+        return if o: MyGame_Example_Vec3 { buf_, o } else: nil
+    def mana():
+        return buf_.flatbuffers_field_int16(pos_, 6, 150)
+    def hp():
+        return buf_.flatbuffers_field_int16(pos_, 8, 100)
+    def name():
+        return buf_.flatbuffers_field_string(pos_, 10)
+    def inventory(i:int):
+        return buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 14) + i * 1)
+    def inventory_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 14)
+    def color():
+        return Color(buf_.flatbuffers_field_int8(pos_, 16, 8))
+    def test_type():
+        return Any(buf_.flatbuffers_field_int8(pos_, 18, 0))
+    def test_as_Monster():
+        return MyGame_Example_Monster { buf_, buf_.flatbuffers_field_table(pos_, 20) }
+    def test_as_TestSimpleTableWithEnum():
+        return MyGame_Example_TestSimpleTableWithEnum { buf_, buf_.flatbuffers_field_table(pos_, 20) }
+    def test_as_MyGame_Example2_Monster():
+        return MyGame_Example2_Monster { buf_, buf_.flatbuffers_field_table(pos_, 20) }
+    def test4(i:int):
+        return MyGame_Example_Test { buf_, buf_.flatbuffers_field_vector(pos_, 22) + i * 4 }
+    def test4_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 22)
+    def testarrayofstring(i:int):
+        return buf_.flatbuffers_string(buf_.flatbuffers_field_vector(pos_, 24) + i * 4)
+    def testarrayofstring_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 24)
+    /// an example documentation comment: this will end up in the generated code
+    /// multiline too
+    def testarrayoftables(i:int):
+        return MyGame_Example_Monster { buf_, buf_.flatbuffers_indirect(buf_.flatbuffers_field_vector(pos_, 26) + i * 4) }
+    def testarrayoftables_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 26)
+    def enemy():
+        let o = buf_.flatbuffers_field_table(pos_, 28)
+        return if o: MyGame_Example_Monster { buf_, o } else: nil
+    def testnestedflatbuffer(i:int):
+        return buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 30) + i * 1)
+    def testnestedflatbuffer_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 30)
+    def testempty():
+        let o = buf_.flatbuffers_field_table(pos_, 32)
+        return if o: MyGame_Example_Stat { buf_, o } else: nil
+    def testbool():
+        return buf_.flatbuffers_field_int8(pos_, 34, 0)
+    def testhashs32_fnv1():
+        return buf_.flatbuffers_field_int32(pos_, 36, 0)
+    def testhashu32_fnv1():
+        return buf_.flatbuffers_field_int32(pos_, 38, 0)
+    def testhashs64_fnv1():
+        return buf_.flatbuffers_field_int64(pos_, 40, 0)
+    def testhashu64_fnv1():
+        return buf_.flatbuffers_field_int64(pos_, 42, 0)
+    def testhashs32_fnv1a():
+        return buf_.flatbuffers_field_int32(pos_, 44, 0)
+    def testhashu32_fnv1a():
+        return buf_.flatbuffers_field_int32(pos_, 46, 0)
+    def testhashs64_fnv1a():
+        return buf_.flatbuffers_field_int64(pos_, 48, 0)
+    def testhashu64_fnv1a():
+        return buf_.flatbuffers_field_int64(pos_, 50, 0)
+    def testarrayofbools(i:int):
+        return buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 52) + i * 1)
+    def testarrayofbools_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 52)
+    def testf():
+        return buf_.flatbuffers_field_float32(pos_, 54, 3.14159)
+    def testf2():
+        return buf_.flatbuffers_field_float32(pos_, 56, 3.0)
+    def testf3():
+        return buf_.flatbuffers_field_float32(pos_, 58, 0.0)
+    def testarrayofstring2(i:int):
+        return buf_.flatbuffers_string(buf_.flatbuffers_field_vector(pos_, 60) + i * 4)
+    def testarrayofstring2_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 60)
+    def testarrayofsortedstruct(i:int):
+        return MyGame_Example_Ability { buf_, buf_.flatbuffers_field_vector(pos_, 62) + i * 8 }
+    def testarrayofsortedstruct_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 62)
+    def flex(i:int):
+        return buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 64) + i * 1)
+    def flex_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 64)
+    def test5(i:int):
+        return MyGame_Example_Test { buf_, buf_.flatbuffers_field_vector(pos_, 66) + i * 4 }
+    def test5_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 66)
+    def vector_of_longs(i:int):
+        return buf_.read_int64_le(buf_.flatbuffers_field_vector(pos_, 68) + i * 8)
+    def vector_of_longs_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 68)
+    def vector_of_doubles(i:int):
+        return buf_.read_float64_le(buf_.flatbuffers_field_vector(pos_, 70) + i * 8)
+    def vector_of_doubles_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 70)
+    def parent_namespace_test():
+        let o = buf_.flatbuffers_field_table(pos_, 72)
+        return if o: MyGame_InParentNamespace { buf_, o } else: nil
+    def vector_of_referrables(i:int):
+        return MyGame_Example_Referrable { buf_, buf_.flatbuffers_indirect(buf_.flatbuffers_field_vector(pos_, 74) + i * 4) }
+    def vector_of_referrables_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 74)
+    def single_weak_reference():
+        return buf_.flatbuffers_field_int64(pos_, 76, 0)
+    def vector_of_weak_references(i:int):
+        return buf_.read_int64_le(buf_.flatbuffers_field_vector(pos_, 78) + i * 8)
+    def vector_of_weak_references_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 78)
+    def vector_of_strong_referrables(i:int):
+        return MyGame_Example_Referrable { buf_, buf_.flatbuffers_indirect(buf_.flatbuffers_field_vector(pos_, 80) + i * 4) }
+    def vector_of_strong_referrables_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 80)
+    def co_owning_reference():
+        return buf_.flatbuffers_field_int64(pos_, 82, 0)
+    def vector_of_co_owning_references(i:int):
+        return buf_.read_int64_le(buf_.flatbuffers_field_vector(pos_, 84) + i * 8)
+    def vector_of_co_owning_references_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 84)
+    def non_owning_reference():
+        return buf_.flatbuffers_field_int64(pos_, 86, 0)
+    def vector_of_non_owning_references(i:int):
+        return buf_.read_int64_le(buf_.flatbuffers_field_vector(pos_, 88) + i * 8)
+    def vector_of_non_owning_references_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 88)
+    def any_unique_type():
+        return AnyUniqueAliases(buf_.flatbuffers_field_int8(pos_, 90, 0))
+    def any_unique_as_M():
+        return MyGame_Example_Monster { buf_, buf_.flatbuffers_field_table(pos_, 92) }
+    def any_unique_as_TS():
+        return MyGame_Example_TestSimpleTableWithEnum { buf_, buf_.flatbuffers_field_table(pos_, 92) }
+    def any_unique_as_M2():
+        return MyGame_Example2_Monster { buf_, buf_.flatbuffers_field_table(pos_, 92) }
+    def any_ambiguous_type():
+        return AnyAmbiguousAliases(buf_.flatbuffers_field_int8(pos_, 94, 0))
+    def any_ambiguous_as_M1():
+        return MyGame_Example_Monster { buf_, buf_.flatbuffers_field_table(pos_, 96) }
+    def any_ambiguous_as_M2():
+        return MyGame_Example_Monster { buf_, buf_.flatbuffers_field_table(pos_, 96) }
+    def any_ambiguous_as_M3():
+        return MyGame_Example_Monster { buf_, buf_.flatbuffers_field_table(pos_, 96) }
+    def vector_of_enums(i:int):
+        return buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 98) + i * 1)
+    def vector_of_enums_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 98)
+
+def GetRootAsMonster(buf:string): return Monster { buf, buf.flatbuffers_indirect(0) }
+
+struct MonsterBuilder:
+    b_:flatbuffers_builder
+    def start():
+        b_.StartObject(48)
+        return this
+    def add_pos(pos:flatbuffers_offset):
+        b_.PrependStructSlot(0, pos)
+        return this
+    def add_mana(mana:int):
+        b_.PrependInt16Slot(1, mana, 150)
+        return this
+    def add_hp(hp:int):
+        b_.PrependInt16Slot(2, hp, 100)
+        return this
+    def add_name(name:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(3, name)
+        return this
+    def add_inventory(inventory:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(5, inventory)
+        return this
+    def add_color(color:Color):
+        b_.PrependUint8Slot(6, color, 8)
+        return this
+    def add_test_type(test_type:Any):
+        b_.PrependUint8Slot(7, test_type, 0)
+        return this
+    def add_test(test:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(8, test)
+        return this
+    def add_test4(test4:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(9, test4)
+        return this
+    def add_testarrayofstring(testarrayofstring:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(10, testarrayofstring)
+        return this
+    def add_testarrayoftables(testarrayoftables:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(11, testarrayoftables)
+        return this
+    def add_enemy(enemy:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(12, enemy)
+        return this
+    def add_testnestedflatbuffer(testnestedflatbuffer:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(13, testnestedflatbuffer)
+        return this
+    def add_testempty(testempty:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(14, testempty)
+        return this
+    def add_testbool(testbool:int):
+        b_.PrependBoolSlot(15, testbool, 0)
+        return this
+    def add_testhashs32_fnv1(testhashs32_fnv1:int):
+        b_.PrependInt32Slot(16, testhashs32_fnv1, 0)
+        return this
+    def add_testhashu32_fnv1(testhashu32_fnv1:int):
+        b_.PrependUint32Slot(17, testhashu32_fnv1, 0)
+        return this
+    def add_testhashs64_fnv1(testhashs64_fnv1:int):
+        b_.PrependInt64Slot(18, testhashs64_fnv1, 0)
+        return this
+    def add_testhashu64_fnv1(testhashu64_fnv1:int):
+        b_.PrependUint64Slot(19, testhashu64_fnv1, 0)
+        return this
+    def add_testhashs32_fnv1a(testhashs32_fnv1a:int):
+        b_.PrependInt32Slot(20, testhashs32_fnv1a, 0)
+        return this
+    def add_testhashu32_fnv1a(testhashu32_fnv1a:int):
+        b_.PrependUint32Slot(21, testhashu32_fnv1a, 0)
+        return this
+    def add_testhashs64_fnv1a(testhashs64_fnv1a:int):
+        b_.PrependInt64Slot(22, testhashs64_fnv1a, 0)
+        return this
+    def add_testhashu64_fnv1a(testhashu64_fnv1a:int):
+        b_.PrependUint64Slot(23, testhashu64_fnv1a, 0)
+        return this
+    def add_testarrayofbools(testarrayofbools:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(24, testarrayofbools)
+        return this
+    def add_testf(testf:float):
+        b_.PrependFloat32Slot(25, testf, 3.14159)
+        return this
+    def add_testf2(testf2:float):
+        b_.PrependFloat32Slot(26, testf2, 3.0)
+        return this
+    def add_testf3(testf3:float):
+        b_.PrependFloat32Slot(27, testf3, 0.0)
+        return this
+    def add_testarrayofstring2(testarrayofstring2:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(28, testarrayofstring2)
+        return this
+    def add_testarrayofsortedstruct(testarrayofsortedstruct:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(29, testarrayofsortedstruct)
+        return this
+    def add_flex(flex:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(30, flex)
+        return this
+    def add_test5(test5:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(31, test5)
+        return this
+    def add_vector_of_longs(vector_of_longs:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(32, vector_of_longs)
+        return this
+    def add_vector_of_doubles(vector_of_doubles:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(33, vector_of_doubles)
+        return this
+    def add_parent_namespace_test(parent_namespace_test:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(34, parent_namespace_test)
+        return this
+    def add_vector_of_referrables(vector_of_referrables:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(35, vector_of_referrables)
+        return this
+    def add_single_weak_reference(single_weak_reference:int):
+        b_.PrependUint64Slot(36, single_weak_reference, 0)
+        return this
+    def add_vector_of_weak_references(vector_of_weak_references:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(37, vector_of_weak_references)
+        return this
+    def add_vector_of_strong_referrables(vector_of_strong_referrables:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(38, vector_of_strong_referrables)
+        return this
+    def add_co_owning_reference(co_owning_reference:int):
+        b_.PrependUint64Slot(39, co_owning_reference, 0)
+        return this
+    def add_vector_of_co_owning_references(vector_of_co_owning_references:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(40, vector_of_co_owning_references)
+        return this
+    def add_non_owning_reference(non_owning_reference:int):
+        b_.PrependUint64Slot(41, non_owning_reference, 0)
+        return this
+    def add_vector_of_non_owning_references(vector_of_non_owning_references:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(42, vector_of_non_owning_references)
+        return this
+    def add_any_unique_type(any_unique_type:AnyUniqueAliases):
+        b_.PrependUint8Slot(43, any_unique_type, 0)
+        return this
+    def add_any_unique(any_unique:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(44, any_unique)
+        return this
+    def add_any_ambiguous_type(any_ambiguous_type:AnyAmbiguousAliases):
+        b_.PrependUint8Slot(45, any_ambiguous_type, 0)
+        return this
+    def add_any_ambiguous(any_ambiguous:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(46, any_ambiguous)
+        return this
+    def add_vector_of_enums(vector_of_enums:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(47, vector_of_enums)
+        return this
+    def end():
+        return b_.EndObject()
+
+def MonsterStartInventoryVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(1, n_, 1)
+def MonsterCreateInventoryVector(b_:flatbuffers_builder, v_:[int]):
+    b_.StartVector(1, v_.length, 1)
+    reverse(v_) e_: b_.PrependUint8(e_)
+    return b_.EndVector(v_.length)
+
+def MonsterStartTest4Vector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(4, n_, 2)
+
+def MonsterStartTestarrayofstringVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(4, n_, 4)
+def MonsterCreateTestarrayofstringVector(b_:flatbuffers_builder, v_:[flatbuffers_offset]):
+    b_.StartVector(4, v_.length, 4)
+    reverse(v_) e_: b_.PrependUOffsetTRelative(e_)
+    return b_.EndVector(v_.length)
+
+def MonsterStartTestarrayoftablesVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(4, n_, 4)
+def MonsterCreateTestarrayoftablesVector(b_:flatbuffers_builder, v_:[flatbuffers_offset]):
+    b_.StartVector(4, v_.length, 4)
+    reverse(v_) e_: b_.PrependUOffsetTRelative(e_)
+    return b_.EndVector(v_.length)
+
+def MonsterStartTestnestedflatbufferVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(1, n_, 1)
+def MonsterCreateTestnestedflatbufferVector(b_:flatbuffers_builder, v_:[int]):
+    b_.StartVector(1, v_.length, 1)
+    reverse(v_) e_: b_.PrependUint8(e_)
+    return b_.EndVector(v_.length)
+
+def MonsterStartTestarrayofboolsVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(1, n_, 1)
+def MonsterCreateTestarrayofboolsVector(b_:flatbuffers_builder, v_:[int]):
+    b_.StartVector(1, v_.length, 1)
+    reverse(v_) e_: b_.PrependBool(e_)
+    return b_.EndVector(v_.length)
+
+def MonsterStartTestarrayofstring2Vector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(4, n_, 4)
+def MonsterCreateTestarrayofstring2Vector(b_:flatbuffers_builder, v_:[flatbuffers_offset]):
+    b_.StartVector(4, v_.length, 4)
+    reverse(v_) e_: b_.PrependUOffsetTRelative(e_)
+    return b_.EndVector(v_.length)
+
+def MonsterStartTestarrayofsortedstructVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(8, n_, 4)
+
+def MonsterStartFlexVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(1, n_, 1)
+def MonsterCreateFlexVector(b_:flatbuffers_builder, v_:[int]):
+    b_.StartVector(1, v_.length, 1)
+    reverse(v_) e_: b_.PrependUint8(e_)
+    return b_.EndVector(v_.length)
+
+def MonsterStartTest5Vector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(4, n_, 2)
+
+def MonsterStartVectorOfLongsVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(8, n_, 8)
+def MonsterCreateVectorOfLongsVector(b_:flatbuffers_builder, v_:[int]):
+    b_.StartVector(8, v_.length, 8)
+    reverse(v_) e_: b_.PrependInt64(e_)
+    return b_.EndVector(v_.length)
+
+def MonsterStartVectorOfDoublesVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(8, n_, 8)
+def MonsterCreateVectorOfDoublesVector(b_:flatbuffers_builder, v_:[float]):
+    b_.StartVector(8, v_.length, 8)
+    reverse(v_) e_: b_.PrependFloat64(e_)
+    return b_.EndVector(v_.length)
+
+def MonsterStartVectorOfReferrablesVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(4, n_, 4)
+def MonsterCreateVectorOfReferrablesVector(b_:flatbuffers_builder, v_:[flatbuffers_offset]):
+    b_.StartVector(4, v_.length, 4)
+    reverse(v_) e_: b_.PrependUOffsetTRelative(e_)
+    return b_.EndVector(v_.length)
+
+def MonsterStartVectorOfWeakReferencesVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(8, n_, 8)
+def MonsterCreateVectorOfWeakReferencesVector(b_:flatbuffers_builder, v_:[int]):
+    b_.StartVector(8, v_.length, 8)
+    reverse(v_) e_: b_.PrependUint64(e_)
+    return b_.EndVector(v_.length)
+
+def MonsterStartVectorOfStrongReferrablesVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(4, n_, 4)
+def MonsterCreateVectorOfStrongReferrablesVector(b_:flatbuffers_builder, v_:[flatbuffers_offset]):
+    b_.StartVector(4, v_.length, 4)
+    reverse(v_) e_: b_.PrependUOffsetTRelative(e_)
+    return b_.EndVector(v_.length)
+
+def MonsterStartVectorOfCoOwningReferencesVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(8, n_, 8)
+def MonsterCreateVectorOfCoOwningReferencesVector(b_:flatbuffers_builder, v_:[int]):
+    b_.StartVector(8, v_.length, 8)
+    reverse(v_) e_: b_.PrependUint64(e_)
+    return b_.EndVector(v_.length)
+
+def MonsterStartVectorOfNonOwningReferencesVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(8, n_, 8)
+def MonsterCreateVectorOfNonOwningReferencesVector(b_:flatbuffers_builder, v_:[int]):
+    b_.StartVector(8, v_.length, 8)
+    reverse(v_) e_: b_.PrependUint64(e_)
+    return b_.EndVector(v_.length)
+
+def MonsterStartVectorOfEnumsVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(1, n_, 1)
+def MonsterCreateVectorOfEnumsVector(b_:flatbuffers_builder, v_:[Color]):
+    b_.StartVector(1, v_.length, 1)
+    reverse(v_) e_: b_.PrependUint8(e_)
+    return b_.EndVector(v_.length)
+
+class TypeAliases : flatbuffers_handle
+    def i8():
+        return buf_.flatbuffers_field_int8(pos_, 4, 0)
+    def u8():
+        return buf_.flatbuffers_field_int8(pos_, 6, 0)
+    def i16():
+        return buf_.flatbuffers_field_int16(pos_, 8, 0)
+    def u16():
+        return buf_.flatbuffers_field_int16(pos_, 10, 0)
+    def i32():
+        return buf_.flatbuffers_field_int32(pos_, 12, 0)
+    def u32():
+        return buf_.flatbuffers_field_int32(pos_, 14, 0)
+    def i64():
+        return buf_.flatbuffers_field_int64(pos_, 16, 0)
+    def u64():
+        return buf_.flatbuffers_field_int64(pos_, 18, 0)
+    def f32():
+        return buf_.flatbuffers_field_float32(pos_, 20, 0.0)
+    def f64():
+        return buf_.flatbuffers_field_float64(pos_, 22, 0.0)
+    def v8(i:int):
+        return buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 24) + i * 1)
+    def v8_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 24)
+    def vf64(i:int):
+        return buf_.read_float64_le(buf_.flatbuffers_field_vector(pos_, 26) + i * 8)
+    def vf64_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 26)
+
+def GetRootAsTypeAliases(buf:string): return TypeAliases { buf, buf.flatbuffers_indirect(0) }
+
+struct TypeAliasesBuilder:
+    b_:flatbuffers_builder
+    def start():
+        b_.StartObject(12)
+        return this
+    def add_i8(i8:int):
+        b_.PrependInt8Slot(0, i8, 0)
+        return this
+    def add_u8(u8:int):
+        b_.PrependUint8Slot(1, u8, 0)
+        return this
+    def add_i16(i16:int):
+        b_.PrependInt16Slot(2, i16, 0)
+        return this
+    def add_u16(u16:int):
+        b_.PrependUint16Slot(3, u16, 0)
+        return this
+    def add_i32(i32:int):
+        b_.PrependInt32Slot(4, i32, 0)
+        return this
+    def add_u32(u32:int):
+        b_.PrependUint32Slot(5, u32, 0)
+        return this
+    def add_i64(i64:int):
+        b_.PrependInt64Slot(6, i64, 0)
+        return this
+    def add_u64(u64:int):
+        b_.PrependUint64Slot(7, u64, 0)
+        return this
+    def add_f32(f32:float):
+        b_.PrependFloat32Slot(8, f32, 0.0)
+        return this
+    def add_f64(f64:float):
+        b_.PrependFloat64Slot(9, f64, 0.0)
+        return this
+    def add_v8(v8:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(10, v8)
+        return this
+    def add_vf64(vf64:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(11, vf64)
+        return this
+    def end():
+        return b_.EndObject()
+
+def TypeAliasesStartV8Vector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(1, n_, 1)
+def TypeAliasesCreateV8Vector(b_:flatbuffers_builder, v_:[int]):
+    b_.StartVector(1, v_.length, 1)
+    reverse(v_) e_: b_.PrependInt8(e_)
+    return b_.EndVector(v_.length)
+
+def TypeAliasesStartVf64Vector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(8, n_, 8)
+def TypeAliasesCreateVf64Vector(b_:flatbuffers_builder, v_:[float]):
+    b_.StartVector(8, v_.length, 8)
+    reverse(v_) e_: b_.PrependFloat64(e_)
+    return b_.EndVector(v_.length)
+
diff --git a/tests/monster_test_generated.rs b/tests/monster_test_generated.rs
new file mode 100644
index 0000000..59bbf37
--- /dev/null
+++ b/tests/monster_test_generated.rs
@@ -0,0 +1,1908 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+
+use std::mem;
+use std::cmp::Ordering;
+
+extern crate flatbuffers;
+use self::flatbuffers::EndianScalar;
+
+#[allow(unused_imports, dead_code)]
+pub mod my_game {
+
+  use std::mem;
+  use std::cmp::Ordering;
+
+  extern crate flatbuffers;
+  use self::flatbuffers::EndianScalar;
+
+pub enum InParentNamespaceOffset {}
+#[derive(Copy, Clone, Debug, PartialEq)]
+
+pub struct InParentNamespace<'a> {
+  pub _tab: flatbuffers::Table<'a>,
+}
+
+impl<'a> flatbuffers::Follow<'a> for InParentNamespace<'a> {
+    type Inner = InParentNamespace<'a>;
+    #[inline]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        Self {
+            _tab: flatbuffers::Table { buf: buf, loc: loc },
+        }
+    }
+}
+
+impl<'a> InParentNamespace<'a> {
+    #[inline]
+    pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
+        InParentNamespace {
+            _tab: table,
+        }
+    }
+    #[allow(unused_mut)]
+    pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
+        _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
+        _args: &'args InParentNamespaceArgs) -> flatbuffers::WIPOffset<InParentNamespace<'bldr>> {
+      let mut builder = InParentNamespaceBuilder::new(_fbb);
+      builder.finish()
+    }
+
+}
+
+pub struct InParentNamespaceArgs {
+}
+impl<'a> Default for InParentNamespaceArgs {
+    #[inline]
+    fn default() -> Self {
+        InParentNamespaceArgs {
+        }
+    }
+}
+pub struct InParentNamespaceBuilder<'a: 'b, 'b> {
+  fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
+  start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
+}
+impl<'a: 'b, 'b> InParentNamespaceBuilder<'a, 'b> {
+  #[inline]
+  pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> InParentNamespaceBuilder<'a, 'b> {
+    let start = _fbb.start_table();
+    InParentNamespaceBuilder {
+      fbb_: _fbb,
+      start_: start,
+    }
+  }
+  #[inline]
+  pub fn finish(self) -> flatbuffers::WIPOffset<InParentNamespace<'a>> {
+    let o = self.fbb_.end_table(self.start_);
+    flatbuffers::WIPOffset::new(o.value())
+  }
+}
+
+#[allow(unused_imports, dead_code)]
+pub mod example_2 {
+
+  use std::mem;
+  use std::cmp::Ordering;
+
+  extern crate flatbuffers;
+  use self::flatbuffers::EndianScalar;
+
+pub enum MonsterOffset {}
+#[derive(Copy, Clone, Debug, PartialEq)]
+
+pub struct Monster<'a> {
+  pub _tab: flatbuffers::Table<'a>,
+}
+
+impl<'a> flatbuffers::Follow<'a> for Monster<'a> {
+    type Inner = Monster<'a>;
+    #[inline]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        Self {
+            _tab: flatbuffers::Table { buf: buf, loc: loc },
+        }
+    }
+}
+
+impl<'a> Monster<'a> {
+    #[inline]
+    pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
+        Monster {
+            _tab: table,
+        }
+    }
+    #[allow(unused_mut)]
+    pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
+        _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
+        _args: &'args MonsterArgs) -> flatbuffers::WIPOffset<Monster<'bldr>> {
+      let mut builder = MonsterBuilder::new(_fbb);
+      builder.finish()
+    }
+
+}
+
+pub struct MonsterArgs {
+}
+impl<'a> Default for MonsterArgs {
+    #[inline]
+    fn default() -> Self {
+        MonsterArgs {
+        }
+    }
+}
+pub struct MonsterBuilder<'a: 'b, 'b> {
+  fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
+  start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
+}
+impl<'a: 'b, 'b> MonsterBuilder<'a, 'b> {
+  #[inline]
+  pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> MonsterBuilder<'a, 'b> {
+    let start = _fbb.start_table();
+    MonsterBuilder {
+      fbb_: _fbb,
+      start_: start,
+    }
+  }
+  #[inline]
+  pub fn finish(self) -> flatbuffers::WIPOffset<Monster<'a>> {
+    let o = self.fbb_.end_table(self.start_);
+    flatbuffers::WIPOffset::new(o.value())
+  }
+}
+
+}  // pub mod Example2
+
+#[allow(unused_imports, dead_code)]
+pub mod example {
+
+  use std::mem;
+  use std::cmp::Ordering;
+
+  extern crate flatbuffers;
+  use self::flatbuffers::EndianScalar;
+
+/// Composite components of Monster color.
+#[allow(non_camel_case_types)]
+#[repr(u8)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+pub enum Color {
+  Red = 1,
+  /// \brief color Green
+  /// Green is bit_flag with value (1u << 1)
+  Green = 2,
+  /// \brief color Blue (1u << 3)
+  Blue = 8,
+
+}
+
+const ENUM_MIN_COLOR: u8 = 1;
+const ENUM_MAX_COLOR: u8 = 8;
+
+impl<'a> flatbuffers::Follow<'a> for Color {
+  type Inner = Self;
+  #[inline]
+  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    flatbuffers::read_scalar_at::<Self>(buf, loc)
+  }
+}
+
+impl flatbuffers::EndianScalar for Color {
+  #[inline]
+  fn to_little_endian(self) -> Self {
+    let n = u8::to_le(self as u8);
+    let p = &n as *const u8 as *const Color;
+    unsafe { *p }
+  }
+  #[inline]
+  fn from_little_endian(self) -> Self {
+    let n = u8::from_le(self as u8);
+    let p = &n as *const u8 as *const Color;
+    unsafe { *p }
+  }
+}
+
+impl flatbuffers::Push for Color {
+    type Output = Color;
+    #[inline]
+    fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+        flatbuffers::emplace_scalar::<Color>(dst, *self);
+    }
+}
+
+#[allow(non_camel_case_types)]
+const ENUM_VALUES_COLOR:[Color; 3] = [
+  Color::Red,
+  Color::Green,
+  Color::Blue
+];
+
+#[allow(non_camel_case_types)]
+const ENUM_NAMES_COLOR:[&'static str; 8] = [
+    "Red",
+    "Green",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "Blue"
+];
+
+pub fn enum_name_color(e: Color) -> &'static str {
+  let index = e as u8 - Color::Red as u8;
+  ENUM_NAMES_COLOR[index as usize]
+}
+
+#[allow(non_camel_case_types)]
+#[repr(u8)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+pub enum Any {
+  NONE = 0,
+  Monster = 1,
+  TestSimpleTableWithEnum = 2,
+  MyGame_Example2_Monster = 3,
+
+}
+
+const ENUM_MIN_ANY: u8 = 0;
+const ENUM_MAX_ANY: u8 = 3;
+
+impl<'a> flatbuffers::Follow<'a> for Any {
+  type Inner = Self;
+  #[inline]
+  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    flatbuffers::read_scalar_at::<Self>(buf, loc)
+  }
+}
+
+impl flatbuffers::EndianScalar for Any {
+  #[inline]
+  fn to_little_endian(self) -> Self {
+    let n = u8::to_le(self as u8);
+    let p = &n as *const u8 as *const Any;
+    unsafe { *p }
+  }
+  #[inline]
+  fn from_little_endian(self) -> Self {
+    let n = u8::from_le(self as u8);
+    let p = &n as *const u8 as *const Any;
+    unsafe { *p }
+  }
+}
+
+impl flatbuffers::Push for Any {
+    type Output = Any;
+    #[inline]
+    fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+        flatbuffers::emplace_scalar::<Any>(dst, *self);
+    }
+}
+
+#[allow(non_camel_case_types)]
+const ENUM_VALUES_ANY:[Any; 4] = [
+  Any::NONE,
+  Any::Monster,
+  Any::TestSimpleTableWithEnum,
+  Any::MyGame_Example2_Monster
+];
+
+#[allow(non_camel_case_types)]
+const ENUM_NAMES_ANY:[&'static str; 4] = [
+    "NONE",
+    "Monster",
+    "TestSimpleTableWithEnum",
+    "MyGame_Example2_Monster"
+];
+
+pub fn enum_name_any(e: Any) -> &'static str {
+  let index = e as u8;
+  ENUM_NAMES_ANY[index as usize]
+}
+
+pub struct AnyUnionTableOffset {}
+#[allow(non_camel_case_types)]
+#[repr(u8)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+pub enum AnyUniqueAliases {
+  NONE = 0,
+  M = 1,
+  TS = 2,
+  M2 = 3,
+
+}
+
+const ENUM_MIN_ANY_UNIQUE_ALIASES: u8 = 0;
+const ENUM_MAX_ANY_UNIQUE_ALIASES: u8 = 3;
+
+impl<'a> flatbuffers::Follow<'a> for AnyUniqueAliases {
+  type Inner = Self;
+  #[inline]
+  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    flatbuffers::read_scalar_at::<Self>(buf, loc)
+  }
+}
+
+impl flatbuffers::EndianScalar for AnyUniqueAliases {
+  #[inline]
+  fn to_little_endian(self) -> Self {
+    let n = u8::to_le(self as u8);
+    let p = &n as *const u8 as *const AnyUniqueAliases;
+    unsafe { *p }
+  }
+  #[inline]
+  fn from_little_endian(self) -> Self {
+    let n = u8::from_le(self as u8);
+    let p = &n as *const u8 as *const AnyUniqueAliases;
+    unsafe { *p }
+  }
+}
+
+impl flatbuffers::Push for AnyUniqueAliases {
+    type Output = AnyUniqueAliases;
+    #[inline]
+    fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+        flatbuffers::emplace_scalar::<AnyUniqueAliases>(dst, *self);
+    }
+}
+
+#[allow(non_camel_case_types)]
+const ENUM_VALUES_ANY_UNIQUE_ALIASES:[AnyUniqueAliases; 4] = [
+  AnyUniqueAliases::NONE,
+  AnyUniqueAliases::M,
+  AnyUniqueAliases::TS,
+  AnyUniqueAliases::M2
+];
+
+#[allow(non_camel_case_types)]
+const ENUM_NAMES_ANY_UNIQUE_ALIASES:[&'static str; 4] = [
+    "NONE",
+    "M",
+    "TS",
+    "M2"
+];
+
+pub fn enum_name_any_unique_aliases(e: AnyUniqueAliases) -> &'static str {
+  let index = e as u8;
+  ENUM_NAMES_ANY_UNIQUE_ALIASES[index as usize]
+}
+
+pub struct AnyUniqueAliasesUnionTableOffset {}
+#[allow(non_camel_case_types)]
+#[repr(u8)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+pub enum AnyAmbiguousAliases {
+  NONE = 0,
+  M1 = 1,
+  M2 = 2,
+  M3 = 3,
+
+}
+
+const ENUM_MIN_ANY_AMBIGUOUS_ALIASES: u8 = 0;
+const ENUM_MAX_ANY_AMBIGUOUS_ALIASES: u8 = 3;
+
+impl<'a> flatbuffers::Follow<'a> for AnyAmbiguousAliases {
+  type Inner = Self;
+  #[inline]
+  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    flatbuffers::read_scalar_at::<Self>(buf, loc)
+  }
+}
+
+impl flatbuffers::EndianScalar for AnyAmbiguousAliases {
+  #[inline]
+  fn to_little_endian(self) -> Self {
+    let n = u8::to_le(self as u8);
+    let p = &n as *const u8 as *const AnyAmbiguousAliases;
+    unsafe { *p }
+  }
+  #[inline]
+  fn from_little_endian(self) -> Self {
+    let n = u8::from_le(self as u8);
+    let p = &n as *const u8 as *const AnyAmbiguousAliases;
+    unsafe { *p }
+  }
+}
+
+impl flatbuffers::Push for AnyAmbiguousAliases {
+    type Output = AnyAmbiguousAliases;
+    #[inline]
+    fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+        flatbuffers::emplace_scalar::<AnyAmbiguousAliases>(dst, *self);
+    }
+}
+
+#[allow(non_camel_case_types)]
+const ENUM_VALUES_ANY_AMBIGUOUS_ALIASES:[AnyAmbiguousAliases; 4] = [
+  AnyAmbiguousAliases::NONE,
+  AnyAmbiguousAliases::M1,
+  AnyAmbiguousAliases::M2,
+  AnyAmbiguousAliases::M3
+];
+
+#[allow(non_camel_case_types)]
+const ENUM_NAMES_ANY_AMBIGUOUS_ALIASES:[&'static str; 4] = [
+    "NONE",
+    "M1",
+    "M2",
+    "M3"
+];
+
+pub fn enum_name_any_ambiguous_aliases(e: AnyAmbiguousAliases) -> &'static str {
+  let index = e as u8;
+  ENUM_NAMES_ANY_AMBIGUOUS_ALIASES[index as usize]
+}
+
+pub struct AnyAmbiguousAliasesUnionTableOffset {}
+// struct Test, aligned to 2
+#[repr(C, align(2))]
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub struct Test {
+  a_: i16,
+  b_: i8,
+  padding0__: u8,
+} // pub struct Test
+impl flatbuffers::SafeSliceAccess for Test {}
+impl<'a> flatbuffers::Follow<'a> for Test {
+  type Inner = &'a Test;
+  #[inline]
+  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    <&'a Test>::follow(buf, loc)
+  }
+}
+impl<'a> flatbuffers::Follow<'a> for &'a Test {
+  type Inner = &'a Test;
+  #[inline]
+  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    flatbuffers::follow_cast_ref::<Test>(buf, loc)
+  }
+}
+impl<'b> flatbuffers::Push for Test {
+    type Output = Test;
+    #[inline]
+    fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+        let src = unsafe {
+            ::std::slice::from_raw_parts(self as *const Test as *const u8, Self::size())
+        };
+        dst.copy_from_slice(src);
+    }
+}
+impl<'b> flatbuffers::Push for &'b Test {
+    type Output = Test;
+
+    #[inline]
+    fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+        let src = unsafe {
+            ::std::slice::from_raw_parts(*self as *const Test as *const u8, Self::size())
+        };
+        dst.copy_from_slice(src);
+    }
+}
+
+
+impl Test {
+  pub fn new<'a>(_a: i16, _b: i8) -> Self {
+    Test {
+      a_: _a.to_little_endian(),
+      b_: _b.to_little_endian(),
+
+      padding0__: 0,
+    }
+  }
+  pub fn a<'a>(&'a self) -> i16 {
+    self.a_.from_little_endian()
+  }
+  pub fn b<'a>(&'a self) -> i8 {
+    self.b_.from_little_endian()
+  }
+}
+
+// struct Vec3, aligned to 8
+#[repr(C, align(8))]
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub struct Vec3 {
+  x_: f32,
+  y_: f32,
+  z_: f32,
+  padding0__: u32,
+  test1_: f64,
+  test2_: Color,
+  padding1__: u8,
+  test3_: Test,
+  padding2__: u16,
+} // pub struct Vec3
+impl flatbuffers::SafeSliceAccess for Vec3 {}
+impl<'a> flatbuffers::Follow<'a> for Vec3 {
+  type Inner = &'a Vec3;
+  #[inline]
+  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    <&'a Vec3>::follow(buf, loc)
+  }
+}
+impl<'a> flatbuffers::Follow<'a> for &'a Vec3 {
+  type Inner = &'a Vec3;
+  #[inline]
+  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    flatbuffers::follow_cast_ref::<Vec3>(buf, loc)
+  }
+}
+impl<'b> flatbuffers::Push for Vec3 {
+    type Output = Vec3;
+    #[inline]
+    fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+        let src = unsafe {
+            ::std::slice::from_raw_parts(self as *const Vec3 as *const u8, Self::size())
+        };
+        dst.copy_from_slice(src);
+    }
+}
+impl<'b> flatbuffers::Push for &'b Vec3 {
+    type Output = Vec3;
+
+    #[inline]
+    fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+        let src = unsafe {
+            ::std::slice::from_raw_parts(*self as *const Vec3 as *const u8, Self::size())
+        };
+        dst.copy_from_slice(src);
+    }
+}
+
+
+impl Vec3 {
+  pub fn new<'a>(_x: f32, _y: f32, _z: f32, _test1: f64, _test2: Color, _test3: &'a Test) -> Self {
+    Vec3 {
+      x_: _x.to_little_endian(),
+      y_: _y.to_little_endian(),
+      z_: _z.to_little_endian(),
+      test1_: _test1.to_little_endian(),
+      test2_: _test2.to_little_endian(),
+      test3_: *_test3,
+
+      padding0__: 0,
+      padding1__: 0,
+      padding2__: 0,
+    }
+  }
+  pub fn x<'a>(&'a self) -> f32 {
+    self.x_.from_little_endian()
+  }
+  pub fn y<'a>(&'a self) -> f32 {
+    self.y_.from_little_endian()
+  }
+  pub fn z<'a>(&'a self) -> f32 {
+    self.z_.from_little_endian()
+  }
+  pub fn test1<'a>(&'a self) -> f64 {
+    self.test1_.from_little_endian()
+  }
+  pub fn test2<'a>(&'a self) -> Color {
+    self.test2_.from_little_endian()
+  }
+  pub fn test3<'a>(&'a self) -> &'a Test {
+    &self.test3_
+  }
+}
+
+// struct Ability, aligned to 4
+#[repr(C, align(4))]
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub struct Ability {
+  id_: u32,
+  distance_: u32,
+} // pub struct Ability
+impl flatbuffers::SafeSliceAccess for Ability {}
+impl<'a> flatbuffers::Follow<'a> for Ability {
+  type Inner = &'a Ability;
+  #[inline]
+  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    <&'a Ability>::follow(buf, loc)
+  }
+}
+impl<'a> flatbuffers::Follow<'a> for &'a Ability {
+  type Inner = &'a Ability;
+  #[inline]
+  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    flatbuffers::follow_cast_ref::<Ability>(buf, loc)
+  }
+}
+impl<'b> flatbuffers::Push for Ability {
+    type Output = Ability;
+    #[inline]
+    fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+        let src = unsafe {
+            ::std::slice::from_raw_parts(self as *const Ability as *const u8, Self::size())
+        };
+        dst.copy_from_slice(src);
+    }
+}
+impl<'b> flatbuffers::Push for &'b Ability {
+    type Output = Ability;
+
+    #[inline]
+    fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+        let src = unsafe {
+            ::std::slice::from_raw_parts(*self as *const Ability as *const u8, Self::size())
+        };
+        dst.copy_from_slice(src);
+    }
+}
+
+
+impl Ability {
+  pub fn new<'a>(_id: u32, _distance: u32) -> Self {
+    Ability {
+      id_: _id.to_little_endian(),
+      distance_: _distance.to_little_endian(),
+
+    }
+  }
+  pub fn id<'a>(&'a self) -> u32 {
+    self.id_.from_little_endian()
+  }
+  #[inline]
+  pub fn key_compare_less_than(&self, o: &Ability) ->  bool {
+    self.id() < o.id()
+  }
+
+  #[inline]
+  pub fn key_compare_with_value(&self, val: u32) ->  ::std::cmp::Ordering {
+    let key = self.id();
+    key.cmp(&val)
+  }
+  pub fn distance<'a>(&'a self) -> u32 {
+    self.distance_.from_little_endian()
+  }
+}
+
+pub enum TestSimpleTableWithEnumOffset {}
+#[derive(Copy, Clone, Debug, PartialEq)]
+
+pub struct TestSimpleTableWithEnum<'a> {
+  pub _tab: flatbuffers::Table<'a>,
+}
+
+impl<'a> flatbuffers::Follow<'a> for TestSimpleTableWithEnum<'a> {
+    type Inner = TestSimpleTableWithEnum<'a>;
+    #[inline]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        Self {
+            _tab: flatbuffers::Table { buf: buf, loc: loc },
+        }
+    }
+}
+
+impl<'a> TestSimpleTableWithEnum<'a> {
+    #[inline]
+    pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
+        TestSimpleTableWithEnum {
+            _tab: table,
+        }
+    }
+    #[allow(unused_mut)]
+    pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
+        _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
+        args: &'args TestSimpleTableWithEnumArgs) -> flatbuffers::WIPOffset<TestSimpleTableWithEnum<'bldr>> {
+      let mut builder = TestSimpleTableWithEnumBuilder::new(_fbb);
+      builder.add_color(args.color);
+      builder.finish()
+    }
+
+    pub const VT_COLOR: flatbuffers::VOffsetT = 4;
+
+  #[inline]
+  pub fn color(&self) -> Color {
+    self._tab.get::<Color>(TestSimpleTableWithEnum::VT_COLOR, Some(Color::Green)).unwrap()
+  }
+}
+
+pub struct TestSimpleTableWithEnumArgs {
+    pub color: Color,
+}
+impl<'a> Default for TestSimpleTableWithEnumArgs {
+    #[inline]
+    fn default() -> Self {
+        TestSimpleTableWithEnumArgs {
+            color: Color::Green,
+        }
+    }
+}
+pub struct TestSimpleTableWithEnumBuilder<'a: 'b, 'b> {
+  fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
+  start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
+}
+impl<'a: 'b, 'b> TestSimpleTableWithEnumBuilder<'a, 'b> {
+  #[inline]
+  pub fn add_color(&mut self, color: Color) {
+    self.fbb_.push_slot::<Color>(TestSimpleTableWithEnum::VT_COLOR, color, Color::Green);
+  }
+  #[inline]
+  pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> TestSimpleTableWithEnumBuilder<'a, 'b> {
+    let start = _fbb.start_table();
+    TestSimpleTableWithEnumBuilder {
+      fbb_: _fbb,
+      start_: start,
+    }
+  }
+  #[inline]
+  pub fn finish(self) -> flatbuffers::WIPOffset<TestSimpleTableWithEnum<'a>> {
+    let o = self.fbb_.end_table(self.start_);
+    flatbuffers::WIPOffset::new(o.value())
+  }
+}
+
+pub enum StatOffset {}
+#[derive(Copy, Clone, Debug, PartialEq)]
+
+pub struct Stat<'a> {
+  pub _tab: flatbuffers::Table<'a>,
+}
+
+impl<'a> flatbuffers::Follow<'a> for Stat<'a> {
+    type Inner = Stat<'a>;
+    #[inline]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        Self {
+            _tab: flatbuffers::Table { buf: buf, loc: loc },
+        }
+    }
+}
+
+impl<'a> Stat<'a> {
+    #[inline]
+    pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
+        Stat {
+            _tab: table,
+        }
+    }
+    #[allow(unused_mut)]
+    pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
+        _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
+        args: &'args StatArgs<'args>) -> flatbuffers::WIPOffset<Stat<'bldr>> {
+      let mut builder = StatBuilder::new(_fbb);
+      builder.add_val(args.val);
+      if let Some(x) = args.id { builder.add_id(x); }
+      builder.add_count(args.count);
+      builder.finish()
+    }
+
+    pub const VT_ID: flatbuffers::VOffsetT = 4;
+    pub const VT_VAL: flatbuffers::VOffsetT = 6;
+    pub const VT_COUNT: flatbuffers::VOffsetT = 8;
+
+  #[inline]
+  pub fn id(&self) -> Option<&'a str> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(Stat::VT_ID, None)
+  }
+  #[inline]
+  pub fn val(&self) -> i64 {
+    self._tab.get::<i64>(Stat::VT_VAL, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn count(&self) -> u16 {
+    self._tab.get::<u16>(Stat::VT_COUNT, Some(0)).unwrap()
+  }
+}
+
+pub struct StatArgs<'a> {
+    pub id: Option<flatbuffers::WIPOffset<&'a  str>>,
+    pub val: i64,
+    pub count: u16,
+}
+impl<'a> Default for StatArgs<'a> {
+    #[inline]
+    fn default() -> Self {
+        StatArgs {
+            id: None,
+            val: 0,
+            count: 0,
+        }
+    }
+}
+pub struct StatBuilder<'a: 'b, 'b> {
+  fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
+  start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
+}
+impl<'a: 'b, 'b> StatBuilder<'a, 'b> {
+  #[inline]
+  pub fn add_id(&mut self, id: flatbuffers::WIPOffset<&'b  str>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Stat::VT_ID, id);
+  }
+  #[inline]
+  pub fn add_val(&mut self, val: i64) {
+    self.fbb_.push_slot::<i64>(Stat::VT_VAL, val, 0);
+  }
+  #[inline]
+  pub fn add_count(&mut self, count: u16) {
+    self.fbb_.push_slot::<u16>(Stat::VT_COUNT, count, 0);
+  }
+  #[inline]
+  pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> StatBuilder<'a, 'b> {
+    let start = _fbb.start_table();
+    StatBuilder {
+      fbb_: _fbb,
+      start_: start,
+    }
+  }
+  #[inline]
+  pub fn finish(self) -> flatbuffers::WIPOffset<Stat<'a>> {
+    let o = self.fbb_.end_table(self.start_);
+    flatbuffers::WIPOffset::new(o.value())
+  }
+}
+
+pub enum ReferrableOffset {}
+#[derive(Copy, Clone, Debug, PartialEq)]
+
+pub struct Referrable<'a> {
+  pub _tab: flatbuffers::Table<'a>,
+}
+
+impl<'a> flatbuffers::Follow<'a> for Referrable<'a> {
+    type Inner = Referrable<'a>;
+    #[inline]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        Self {
+            _tab: flatbuffers::Table { buf: buf, loc: loc },
+        }
+    }
+}
+
+impl<'a> Referrable<'a> {
+    #[inline]
+    pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
+        Referrable {
+            _tab: table,
+        }
+    }
+    #[allow(unused_mut)]
+    pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
+        _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
+        args: &'args ReferrableArgs) -> flatbuffers::WIPOffset<Referrable<'bldr>> {
+      let mut builder = ReferrableBuilder::new(_fbb);
+      builder.add_id(args.id);
+      builder.finish()
+    }
+
+    pub const VT_ID: flatbuffers::VOffsetT = 4;
+
+  #[inline]
+  pub fn id(&self) -> u64 {
+    self._tab.get::<u64>(Referrable::VT_ID, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn key_compare_less_than(&self, o: &Referrable) ->  bool {
+    self.id() < o.id()
+  }
+
+  #[inline]
+  pub fn key_compare_with_value(&self, val: u64) ->  ::std::cmp::Ordering {
+    let key = self.id();
+    key.cmp(&val)
+  }
+}
+
+pub struct ReferrableArgs {
+    pub id: u64,
+}
+impl<'a> Default for ReferrableArgs {
+    #[inline]
+    fn default() -> Self {
+        ReferrableArgs {
+            id: 0,
+        }
+    }
+}
+pub struct ReferrableBuilder<'a: 'b, 'b> {
+  fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
+  start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
+}
+impl<'a: 'b, 'b> ReferrableBuilder<'a, 'b> {
+  #[inline]
+  pub fn add_id(&mut self, id: u64) {
+    self.fbb_.push_slot::<u64>(Referrable::VT_ID, id, 0);
+  }
+  #[inline]
+  pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> ReferrableBuilder<'a, 'b> {
+    let start = _fbb.start_table();
+    ReferrableBuilder {
+      fbb_: _fbb,
+      start_: start,
+    }
+  }
+  #[inline]
+  pub fn finish(self) -> flatbuffers::WIPOffset<Referrable<'a>> {
+    let o = self.fbb_.end_table(self.start_);
+    flatbuffers::WIPOffset::new(o.value())
+  }
+}
+
+pub enum MonsterOffset {}
+#[derive(Copy, Clone, Debug, PartialEq)]
+
+/// an example documentation comment: monster object
+pub struct Monster<'a> {
+  pub _tab: flatbuffers::Table<'a>,
+}
+
+impl<'a> flatbuffers::Follow<'a> for Monster<'a> {
+    type Inner = Monster<'a>;
+    #[inline]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        Self {
+            _tab: flatbuffers::Table { buf: buf, loc: loc },
+        }
+    }
+}
+
+impl<'a> Monster<'a> {
+    #[inline]
+    pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
+        Monster {
+            _tab: table,
+        }
+    }
+    #[allow(unused_mut)]
+    pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
+        _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
+        args: &'args MonsterArgs<'args>) -> flatbuffers::WIPOffset<Monster<'bldr>> {
+      let mut builder = MonsterBuilder::new(_fbb);
+      builder.add_non_owning_reference(args.non_owning_reference);
+      builder.add_co_owning_reference(args.co_owning_reference);
+      builder.add_single_weak_reference(args.single_weak_reference);
+      builder.add_testhashu64_fnv1a(args.testhashu64_fnv1a);
+      builder.add_testhashs64_fnv1a(args.testhashs64_fnv1a);
+      builder.add_testhashu64_fnv1(args.testhashu64_fnv1);
+      builder.add_testhashs64_fnv1(args.testhashs64_fnv1);
+      if let Some(x) = args.vector_of_enums { builder.add_vector_of_enums(x); }
+      if let Some(x) = args.any_ambiguous { builder.add_any_ambiguous(x); }
+      if let Some(x) = args.any_unique { builder.add_any_unique(x); }
+      if let Some(x) = args.vector_of_non_owning_references { builder.add_vector_of_non_owning_references(x); }
+      if let Some(x) = args.vector_of_co_owning_references { builder.add_vector_of_co_owning_references(x); }
+      if let Some(x) = args.vector_of_strong_referrables { builder.add_vector_of_strong_referrables(x); }
+      if let Some(x) = args.vector_of_weak_references { builder.add_vector_of_weak_references(x); }
+      if let Some(x) = args.vector_of_referrables { builder.add_vector_of_referrables(x); }
+      if let Some(x) = args.parent_namespace_test { builder.add_parent_namespace_test(x); }
+      if let Some(x) = args.vector_of_doubles { builder.add_vector_of_doubles(x); }
+      if let Some(x) = args.vector_of_longs { builder.add_vector_of_longs(x); }
+      if let Some(x) = args.test5 { builder.add_test5(x); }
+      if let Some(x) = args.flex { builder.add_flex(x); }
+      if let Some(x) = args.testarrayofsortedstruct { builder.add_testarrayofsortedstruct(x); }
+      if let Some(x) = args.testarrayofstring2 { builder.add_testarrayofstring2(x); }
+      builder.add_testf3(args.testf3);
+      builder.add_testf2(args.testf2);
+      builder.add_testf(args.testf);
+      if let Some(x) = args.testarrayofbools { builder.add_testarrayofbools(x); }
+      builder.add_testhashu32_fnv1a(args.testhashu32_fnv1a);
+      builder.add_testhashs32_fnv1a(args.testhashs32_fnv1a);
+      builder.add_testhashu32_fnv1(args.testhashu32_fnv1);
+      builder.add_testhashs32_fnv1(args.testhashs32_fnv1);
+      if let Some(x) = args.testempty { builder.add_testempty(x); }
+      if let Some(x) = args.testnestedflatbuffer { builder.add_testnestedflatbuffer(x); }
+      if let Some(x) = args.enemy { builder.add_enemy(x); }
+      if let Some(x) = args.testarrayoftables { builder.add_testarrayoftables(x); }
+      if let Some(x) = args.testarrayofstring { builder.add_testarrayofstring(x); }
+      if let Some(x) = args.test4 { builder.add_test4(x); }
+      if let Some(x) = args.test { builder.add_test(x); }
+      if let Some(x) = args.inventory { builder.add_inventory(x); }
+      if let Some(x) = args.name { builder.add_name(x); }
+      if let Some(x) = args.pos { builder.add_pos(x); }
+      builder.add_hp(args.hp);
+      builder.add_mana(args.mana);
+      builder.add_any_ambiguous_type(args.any_ambiguous_type);
+      builder.add_any_unique_type(args.any_unique_type);
+      builder.add_testbool(args.testbool);
+      builder.add_test_type(args.test_type);
+      builder.add_color(args.color);
+      builder.finish()
+    }
+
+    pub const VT_POS: flatbuffers::VOffsetT = 4;
+    pub const VT_MANA: flatbuffers::VOffsetT = 6;
+    pub const VT_HP: flatbuffers::VOffsetT = 8;
+    pub const VT_NAME: flatbuffers::VOffsetT = 10;
+    pub const VT_INVENTORY: flatbuffers::VOffsetT = 14;
+    pub const VT_COLOR: flatbuffers::VOffsetT = 16;
+    pub const VT_TEST_TYPE: flatbuffers::VOffsetT = 18;
+    pub const VT_TEST: flatbuffers::VOffsetT = 20;
+    pub const VT_TEST4: flatbuffers::VOffsetT = 22;
+    pub const VT_TESTARRAYOFSTRING: flatbuffers::VOffsetT = 24;
+    pub const VT_TESTARRAYOFTABLES: flatbuffers::VOffsetT = 26;
+    pub const VT_ENEMY: flatbuffers::VOffsetT = 28;
+    pub const VT_TESTNESTEDFLATBUFFER: flatbuffers::VOffsetT = 30;
+    pub const VT_TESTEMPTY: flatbuffers::VOffsetT = 32;
+    pub const VT_TESTBOOL: flatbuffers::VOffsetT = 34;
+    pub const VT_TESTHASHS32_FNV1: flatbuffers::VOffsetT = 36;
+    pub const VT_TESTHASHU32_FNV1: flatbuffers::VOffsetT = 38;
+    pub const VT_TESTHASHS64_FNV1: flatbuffers::VOffsetT = 40;
+    pub const VT_TESTHASHU64_FNV1: flatbuffers::VOffsetT = 42;
+    pub const VT_TESTHASHS32_FNV1A: flatbuffers::VOffsetT = 44;
+    pub const VT_TESTHASHU32_FNV1A: flatbuffers::VOffsetT = 46;
+    pub const VT_TESTHASHS64_FNV1A: flatbuffers::VOffsetT = 48;
+    pub const VT_TESTHASHU64_FNV1A: flatbuffers::VOffsetT = 50;
+    pub const VT_TESTARRAYOFBOOLS: flatbuffers::VOffsetT = 52;
+    pub const VT_TESTF: flatbuffers::VOffsetT = 54;
+    pub const VT_TESTF2: flatbuffers::VOffsetT = 56;
+    pub const VT_TESTF3: flatbuffers::VOffsetT = 58;
+    pub const VT_TESTARRAYOFSTRING2: flatbuffers::VOffsetT = 60;
+    pub const VT_TESTARRAYOFSORTEDSTRUCT: flatbuffers::VOffsetT = 62;
+    pub const VT_FLEX: flatbuffers::VOffsetT = 64;
+    pub const VT_TEST5: flatbuffers::VOffsetT = 66;
+    pub const VT_VECTOR_OF_LONGS: flatbuffers::VOffsetT = 68;
+    pub const VT_VECTOR_OF_DOUBLES: flatbuffers::VOffsetT = 70;
+    pub const VT_PARENT_NAMESPACE_TEST: flatbuffers::VOffsetT = 72;
+    pub const VT_VECTOR_OF_REFERRABLES: flatbuffers::VOffsetT = 74;
+    pub const VT_SINGLE_WEAK_REFERENCE: flatbuffers::VOffsetT = 76;
+    pub const VT_VECTOR_OF_WEAK_REFERENCES: flatbuffers::VOffsetT = 78;
+    pub const VT_VECTOR_OF_STRONG_REFERRABLES: flatbuffers::VOffsetT = 80;
+    pub const VT_CO_OWNING_REFERENCE: flatbuffers::VOffsetT = 82;
+    pub const VT_VECTOR_OF_CO_OWNING_REFERENCES: flatbuffers::VOffsetT = 84;
+    pub const VT_NON_OWNING_REFERENCE: flatbuffers::VOffsetT = 86;
+    pub const VT_VECTOR_OF_NON_OWNING_REFERENCES: flatbuffers::VOffsetT = 88;
+    pub const VT_ANY_UNIQUE_TYPE: flatbuffers::VOffsetT = 90;
+    pub const VT_ANY_UNIQUE: flatbuffers::VOffsetT = 92;
+    pub const VT_ANY_AMBIGUOUS_TYPE: flatbuffers::VOffsetT = 94;
+    pub const VT_ANY_AMBIGUOUS: flatbuffers::VOffsetT = 96;
+    pub const VT_VECTOR_OF_ENUMS: flatbuffers::VOffsetT = 98;
+
+  #[inline]
+  pub fn pos(&self) -> Option<&'a Vec3> {
+    self._tab.get::<Vec3>(Monster::VT_POS, None)
+  }
+  #[inline]
+  pub fn mana(&self) -> i16 {
+    self._tab.get::<i16>(Monster::VT_MANA, Some(150)).unwrap()
+  }
+  #[inline]
+  pub fn hp(&self) -> i16 {
+    self._tab.get::<i16>(Monster::VT_HP, Some(100)).unwrap()
+  }
+  #[inline]
+  pub fn name(&self) -> &'a str {
+    self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(Monster::VT_NAME, None).unwrap()
+  }
+  #[inline]
+  pub fn key_compare_less_than(&self, o: &Monster) ->  bool {
+    self.name() < o.name()
+  }
+
+  #[inline]
+  pub fn key_compare_with_value(&self, val: & str) ->  ::std::cmp::Ordering {
+    let key = self.name();
+    key.cmp(&val)
+  }
+  #[inline]
+  pub fn inventory(&self) -> Option<&'a [u8]> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, u8>>>(Monster::VT_INVENTORY, None).map(|v| v.safe_slice())
+  }
+  #[inline]
+  pub fn color(&self) -> Color {
+    self._tab.get::<Color>(Monster::VT_COLOR, Some(Color::Blue)).unwrap()
+  }
+  #[inline]
+  pub fn test_type(&self) -> Any {
+    self._tab.get::<Any>(Monster::VT_TEST_TYPE, Some(Any::NONE)).unwrap()
+  }
+  #[inline]
+  pub fn test(&self) -> Option<flatbuffers::Table<'a>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Table<'a>>>(Monster::VT_TEST, None)
+  }
+  #[inline]
+  pub fn test4(&self) -> Option<&'a [Test]> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<Test>>>(Monster::VT_TEST4, None).map(|v| v.safe_slice() )
+  }
+  #[inline]
+  pub fn testarrayofstring(&self) -> Option<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<&'a str>>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<flatbuffers::ForwardsUOffset<&'a str>>>>(Monster::VT_TESTARRAYOFSTRING, None)
+  }
+  /// an example documentation comment: this will end up in the generated code
+  /// multiline too
+  #[inline]
+  pub fn testarrayoftables(&self) -> Option<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<Monster<'a>>>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<flatbuffers::ForwardsUOffset<Monster<'a>>>>>(Monster::VT_TESTARRAYOFTABLES, None)
+  }
+  #[inline]
+  pub fn enemy(&self) -> Option<Monster<'a>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<Monster<'a>>>(Monster::VT_ENEMY, None)
+  }
+  #[inline]
+  pub fn testnestedflatbuffer(&self) -> Option<&'a [u8]> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, u8>>>(Monster::VT_TESTNESTEDFLATBUFFER, None).map(|v| v.safe_slice())
+  }
+  pub fn testnestedflatbuffer_nested_flatbuffer(&'a self) ->  Option<Monster<'a>> {
+     match self.testnestedflatbuffer() {
+         None => { None }
+         Some(data) => {
+             use self::flatbuffers::Follow;
+             Some(<flatbuffers::ForwardsUOffset<Monster<'a>>>::follow(data, 0))
+         },
+     }
+  }
+  #[inline]
+  pub fn testempty(&self) -> Option<Stat<'a>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<Stat<'a>>>(Monster::VT_TESTEMPTY, None)
+  }
+  #[inline]
+  pub fn testbool(&self) -> bool {
+    self._tab.get::<bool>(Monster::VT_TESTBOOL, Some(false)).unwrap()
+  }
+  #[inline]
+  pub fn testhashs32_fnv1(&self) -> i32 {
+    self._tab.get::<i32>(Monster::VT_TESTHASHS32_FNV1, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn testhashu32_fnv1(&self) -> u32 {
+    self._tab.get::<u32>(Monster::VT_TESTHASHU32_FNV1, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn testhashs64_fnv1(&self) -> i64 {
+    self._tab.get::<i64>(Monster::VT_TESTHASHS64_FNV1, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn testhashu64_fnv1(&self) -> u64 {
+    self._tab.get::<u64>(Monster::VT_TESTHASHU64_FNV1, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn testhashs32_fnv1a(&self) -> i32 {
+    self._tab.get::<i32>(Monster::VT_TESTHASHS32_FNV1A, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn testhashu32_fnv1a(&self) -> u32 {
+    self._tab.get::<u32>(Monster::VT_TESTHASHU32_FNV1A, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn testhashs64_fnv1a(&self) -> i64 {
+    self._tab.get::<i64>(Monster::VT_TESTHASHS64_FNV1A, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn testhashu64_fnv1a(&self) -> u64 {
+    self._tab.get::<u64>(Monster::VT_TESTHASHU64_FNV1A, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn testarrayofbools(&self) -> Option<&'a [bool]> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, bool>>>(Monster::VT_TESTARRAYOFBOOLS, None).map(|v| v.safe_slice())
+  }
+  #[inline]
+  pub fn testf(&self) -> f32 {
+    self._tab.get::<f32>(Monster::VT_TESTF, Some(3.14159)).unwrap()
+  }
+  #[inline]
+  pub fn testf2(&self) -> f32 {
+    self._tab.get::<f32>(Monster::VT_TESTF2, Some(3.0)).unwrap()
+  }
+  #[inline]
+  pub fn testf3(&self) -> f32 {
+    self._tab.get::<f32>(Monster::VT_TESTF3, Some(0.0)).unwrap()
+  }
+  #[inline]
+  pub fn testarrayofstring2(&self) -> Option<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<&'a str>>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<flatbuffers::ForwardsUOffset<&'a str>>>>(Monster::VT_TESTARRAYOFSTRING2, None)
+  }
+  #[inline]
+  pub fn testarrayofsortedstruct(&self) -> Option<&'a [Ability]> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<Ability>>>(Monster::VT_TESTARRAYOFSORTEDSTRUCT, None).map(|v| v.safe_slice() )
+  }
+  #[inline]
+  pub fn flex(&self) -> Option<&'a [u8]> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, u8>>>(Monster::VT_FLEX, None).map(|v| v.safe_slice())
+  }
+  #[inline]
+  pub fn test5(&self) -> Option<&'a [Test]> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<Test>>>(Monster::VT_TEST5, None).map(|v| v.safe_slice() )
+  }
+  #[inline]
+  pub fn vector_of_longs(&self) -> Option<flatbuffers::Vector<'a, i64>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, i64>>>(Monster::VT_VECTOR_OF_LONGS, None)
+  }
+  #[inline]
+  pub fn vector_of_doubles(&self) -> Option<flatbuffers::Vector<'a, f64>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, f64>>>(Monster::VT_VECTOR_OF_DOUBLES, None)
+  }
+  #[inline]
+  pub fn parent_namespace_test(&self) -> Option<super::InParentNamespace<'a>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<super::InParentNamespace<'a>>>(Monster::VT_PARENT_NAMESPACE_TEST, None)
+  }
+  #[inline]
+  pub fn vector_of_referrables(&self) -> Option<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<Referrable<'a>>>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<flatbuffers::ForwardsUOffset<Referrable<'a>>>>>(Monster::VT_VECTOR_OF_REFERRABLES, None)
+  }
+  #[inline]
+  pub fn single_weak_reference(&self) -> u64 {
+    self._tab.get::<u64>(Monster::VT_SINGLE_WEAK_REFERENCE, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn vector_of_weak_references(&self) -> Option<flatbuffers::Vector<'a, u64>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, u64>>>(Monster::VT_VECTOR_OF_WEAK_REFERENCES, None)
+  }
+  #[inline]
+  pub fn vector_of_strong_referrables(&self) -> Option<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<Referrable<'a>>>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<flatbuffers::ForwardsUOffset<Referrable<'a>>>>>(Monster::VT_VECTOR_OF_STRONG_REFERRABLES, None)
+  }
+  #[inline]
+  pub fn co_owning_reference(&self) -> u64 {
+    self._tab.get::<u64>(Monster::VT_CO_OWNING_REFERENCE, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn vector_of_co_owning_references(&self) -> Option<flatbuffers::Vector<'a, u64>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, u64>>>(Monster::VT_VECTOR_OF_CO_OWNING_REFERENCES, None)
+  }
+  #[inline]
+  pub fn non_owning_reference(&self) -> u64 {
+    self._tab.get::<u64>(Monster::VT_NON_OWNING_REFERENCE, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn vector_of_non_owning_references(&self) -> Option<flatbuffers::Vector<'a, u64>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, u64>>>(Monster::VT_VECTOR_OF_NON_OWNING_REFERENCES, None)
+  }
+  #[inline]
+  pub fn any_unique_type(&self) -> AnyUniqueAliases {
+    self._tab.get::<AnyUniqueAliases>(Monster::VT_ANY_UNIQUE_TYPE, Some(AnyUniqueAliases::NONE)).unwrap()
+  }
+  #[inline]
+  pub fn any_unique(&self) -> Option<flatbuffers::Table<'a>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Table<'a>>>(Monster::VT_ANY_UNIQUE, None)
+  }
+  #[inline]
+  pub fn any_ambiguous_type(&self) -> AnyAmbiguousAliases {
+    self._tab.get::<AnyAmbiguousAliases>(Monster::VT_ANY_AMBIGUOUS_TYPE, Some(AnyAmbiguousAliases::NONE)).unwrap()
+  }
+  #[inline]
+  pub fn any_ambiguous(&self) -> Option<flatbuffers::Table<'a>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Table<'a>>>(Monster::VT_ANY_AMBIGUOUS, None)
+  }
+  #[inline]
+  pub fn vector_of_enums(&self) -> Option<flatbuffers::Vector<'a, Color>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, Color>>>(Monster::VT_VECTOR_OF_ENUMS, None)
+  }
+  #[inline]
+  #[allow(non_snake_case)]
+  pub fn test_as_monster(&self) -> Option<Monster<'a>> {
+    if self.test_type() == Any::Monster {
+      self.test().map(|u| Monster::init_from_table(u))
+    } else {
+      None
+    }
+  }
+
+  #[inline]
+  #[allow(non_snake_case)]
+  pub fn test_as_test_simple_table_with_enum(&self) -> Option<TestSimpleTableWithEnum<'a>> {
+    if self.test_type() == Any::TestSimpleTableWithEnum {
+      self.test().map(|u| TestSimpleTableWithEnum::init_from_table(u))
+    } else {
+      None
+    }
+  }
+
+  #[inline]
+  #[allow(non_snake_case)]
+  pub fn test_as_my_game_example_2_monster(&self) -> Option<super::example_2::Monster<'a>> {
+    if self.test_type() == Any::MyGame_Example2_Monster {
+      self.test().map(|u| super::example_2::Monster::init_from_table(u))
+    } else {
+      None
+    }
+  }
+
+  #[inline]
+  #[allow(non_snake_case)]
+  pub fn any_unique_as_m(&self) -> Option<Monster<'a>> {
+    if self.any_unique_type() == AnyUniqueAliases::M {
+      self.any_unique().map(|u| Monster::init_from_table(u))
+    } else {
+      None
+    }
+  }
+
+  #[inline]
+  #[allow(non_snake_case)]
+  pub fn any_unique_as_ts(&self) -> Option<TestSimpleTableWithEnum<'a>> {
+    if self.any_unique_type() == AnyUniqueAliases::TS {
+      self.any_unique().map(|u| TestSimpleTableWithEnum::init_from_table(u))
+    } else {
+      None
+    }
+  }
+
+  #[inline]
+  #[allow(non_snake_case)]
+  pub fn any_unique_as_m2(&self) -> Option<super::example_2::Monster<'a>> {
+    if self.any_unique_type() == AnyUniqueAliases::M2 {
+      self.any_unique().map(|u| super::example_2::Monster::init_from_table(u))
+    } else {
+      None
+    }
+  }
+
+  #[inline]
+  #[allow(non_snake_case)]
+  pub fn any_ambiguous_as_m1(&self) -> Option<Monster<'a>> {
+    if self.any_ambiguous_type() == AnyAmbiguousAliases::M1 {
+      self.any_ambiguous().map(|u| Monster::init_from_table(u))
+    } else {
+      None
+    }
+  }
+
+  #[inline]
+  #[allow(non_snake_case)]
+  pub fn any_ambiguous_as_m2(&self) -> Option<Monster<'a>> {
+    if self.any_ambiguous_type() == AnyAmbiguousAliases::M2 {
+      self.any_ambiguous().map(|u| Monster::init_from_table(u))
+    } else {
+      None
+    }
+  }
+
+  #[inline]
+  #[allow(non_snake_case)]
+  pub fn any_ambiguous_as_m3(&self) -> Option<Monster<'a>> {
+    if self.any_ambiguous_type() == AnyAmbiguousAliases::M3 {
+      self.any_ambiguous().map(|u| Monster::init_from_table(u))
+    } else {
+      None
+    }
+  }
+
+}
+
+pub struct MonsterArgs<'a> {
+    pub pos: Option<&'a  Vec3>,
+    pub mana: i16,
+    pub hp: i16,
+    pub name: Option<flatbuffers::WIPOffset<&'a  str>>,
+    pub inventory: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a ,  u8>>>,
+    pub color: Color,
+    pub test_type: Any,
+    pub test: Option<flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>>,
+    pub test4: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a , Test>>>,
+    pub testarrayofstring: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a , flatbuffers::ForwardsUOffset<&'a  str>>>>,
+    pub testarrayoftables: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a , flatbuffers::ForwardsUOffset<Monster<'a >>>>>,
+    pub enemy: Option<flatbuffers::WIPOffset<Monster<'a >>>,
+    pub testnestedflatbuffer: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a ,  u8>>>,
+    pub testempty: Option<flatbuffers::WIPOffset<Stat<'a >>>,
+    pub testbool: bool,
+    pub testhashs32_fnv1: i32,
+    pub testhashu32_fnv1: u32,
+    pub testhashs64_fnv1: i64,
+    pub testhashu64_fnv1: u64,
+    pub testhashs32_fnv1a: i32,
+    pub testhashu32_fnv1a: u32,
+    pub testhashs64_fnv1a: i64,
+    pub testhashu64_fnv1a: u64,
+    pub testarrayofbools: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a , bool>>>,
+    pub testf: f32,
+    pub testf2: f32,
+    pub testf3: f32,
+    pub testarrayofstring2: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a , flatbuffers::ForwardsUOffset<&'a  str>>>>,
+    pub testarrayofsortedstruct: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a , Ability>>>,
+    pub flex: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a ,  u8>>>,
+    pub test5: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a , Test>>>,
+    pub vector_of_longs: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a ,  i64>>>,
+    pub vector_of_doubles: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a ,  f64>>>,
+    pub parent_namespace_test: Option<flatbuffers::WIPOffset<super::InParentNamespace<'a >>>,
+    pub vector_of_referrables: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a , flatbuffers::ForwardsUOffset<Referrable<'a >>>>>,
+    pub single_weak_reference: u64,
+    pub vector_of_weak_references: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a ,  u64>>>,
+    pub vector_of_strong_referrables: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a , flatbuffers::ForwardsUOffset<Referrable<'a >>>>>,
+    pub co_owning_reference: u64,
+    pub vector_of_co_owning_references: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a ,  u64>>>,
+    pub non_owning_reference: u64,
+    pub vector_of_non_owning_references: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a ,  u64>>>,
+    pub any_unique_type: AnyUniqueAliases,
+    pub any_unique: Option<flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>>,
+    pub any_ambiguous_type: AnyAmbiguousAliases,
+    pub any_ambiguous: Option<flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>>,
+    pub vector_of_enums: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a , Color>>>,
+}
+impl<'a> Default for MonsterArgs<'a> {
+    #[inline]
+    fn default() -> Self {
+        MonsterArgs {
+            pos: None,
+            mana: 150,
+            hp: 100,
+            name: None, // required field
+            inventory: None,
+            color: Color::Blue,
+            test_type: Any::NONE,
+            test: None,
+            test4: None,
+            testarrayofstring: None,
+            testarrayoftables: None,
+            enemy: None,
+            testnestedflatbuffer: None,
+            testempty: None,
+            testbool: false,
+            testhashs32_fnv1: 0,
+            testhashu32_fnv1: 0,
+            testhashs64_fnv1: 0,
+            testhashu64_fnv1: 0,
+            testhashs32_fnv1a: 0,
+            testhashu32_fnv1a: 0,
+            testhashs64_fnv1a: 0,
+            testhashu64_fnv1a: 0,
+            testarrayofbools: None,
+            testf: 3.14159,
+            testf2: 3.0,
+            testf3: 0.0,
+            testarrayofstring2: None,
+            testarrayofsortedstruct: None,
+            flex: None,
+            test5: None,
+            vector_of_longs: None,
+            vector_of_doubles: None,
+            parent_namespace_test: None,
+            vector_of_referrables: None,
+            single_weak_reference: 0,
+            vector_of_weak_references: None,
+            vector_of_strong_referrables: None,
+            co_owning_reference: 0,
+            vector_of_co_owning_references: None,
+            non_owning_reference: 0,
+            vector_of_non_owning_references: None,
+            any_unique_type: AnyUniqueAliases::NONE,
+            any_unique: None,
+            any_ambiguous_type: AnyAmbiguousAliases::NONE,
+            any_ambiguous: None,
+            vector_of_enums: None,
+        }
+    }
+}
+pub struct MonsterBuilder<'a: 'b, 'b> {
+  fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
+  start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
+}
+impl<'a: 'b, 'b> MonsterBuilder<'a, 'b> {
+  #[inline]
+  pub fn add_pos(&mut self, pos: &'b  Vec3) {
+    self.fbb_.push_slot_always::<&Vec3>(Monster::VT_POS, pos);
+  }
+  #[inline]
+  pub fn add_mana(&mut self, mana: i16) {
+    self.fbb_.push_slot::<i16>(Monster::VT_MANA, mana, 150);
+  }
+  #[inline]
+  pub fn add_hp(&mut self, hp: i16) {
+    self.fbb_.push_slot::<i16>(Monster::VT_HP, hp, 100);
+  }
+  #[inline]
+  pub fn add_name(&mut self, name: flatbuffers::WIPOffset<&'b  str>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_NAME, name);
+  }
+  #[inline]
+  pub fn add_inventory(&mut self, inventory: flatbuffers::WIPOffset<flatbuffers::Vector<'b , u8>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_INVENTORY, inventory);
+  }
+  #[inline]
+  pub fn add_color(&mut self, color: Color) {
+    self.fbb_.push_slot::<Color>(Monster::VT_COLOR, color, Color::Blue);
+  }
+  #[inline]
+  pub fn add_test_type(&mut self, test_type: Any) {
+    self.fbb_.push_slot::<Any>(Monster::VT_TEST_TYPE, test_type, Any::NONE);
+  }
+  #[inline]
+  pub fn add_test(&mut self, test: flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_TEST, test);
+  }
+  #[inline]
+  pub fn add_test4(&mut self, test4: flatbuffers::WIPOffset<flatbuffers::Vector<'b , Test>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_TEST4, test4);
+  }
+  #[inline]
+  pub fn add_testarrayofstring(&mut self, testarrayofstring: flatbuffers::WIPOffset<flatbuffers::Vector<'b , flatbuffers::ForwardsUOffset<&'b  str>>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_TESTARRAYOFSTRING, testarrayofstring);
+  }
+  #[inline]
+  pub fn add_testarrayoftables(&mut self, testarrayoftables: flatbuffers::WIPOffset<flatbuffers::Vector<'b , flatbuffers::ForwardsUOffset<Monster<'b >>>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_TESTARRAYOFTABLES, testarrayoftables);
+  }
+  #[inline]
+  pub fn add_enemy(&mut self, enemy: flatbuffers::WIPOffset<Monster<'b >>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<Monster>>(Monster::VT_ENEMY, enemy);
+  }
+  #[inline]
+  pub fn add_testnestedflatbuffer(&mut self, testnestedflatbuffer: flatbuffers::WIPOffset<flatbuffers::Vector<'b , u8>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_TESTNESTEDFLATBUFFER, testnestedflatbuffer);
+  }
+  #[inline]
+  pub fn add_testempty(&mut self, testempty: flatbuffers::WIPOffset<Stat<'b >>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<Stat>>(Monster::VT_TESTEMPTY, testempty);
+  }
+  #[inline]
+  pub fn add_testbool(&mut self, testbool: bool) {
+    self.fbb_.push_slot::<bool>(Monster::VT_TESTBOOL, testbool, false);
+  }
+  #[inline]
+  pub fn add_testhashs32_fnv1(&mut self, testhashs32_fnv1: i32) {
+    self.fbb_.push_slot::<i32>(Monster::VT_TESTHASHS32_FNV1, testhashs32_fnv1, 0);
+  }
+  #[inline]
+  pub fn add_testhashu32_fnv1(&mut self, testhashu32_fnv1: u32) {
+    self.fbb_.push_slot::<u32>(Monster::VT_TESTHASHU32_FNV1, testhashu32_fnv1, 0);
+  }
+  #[inline]
+  pub fn add_testhashs64_fnv1(&mut self, testhashs64_fnv1: i64) {
+    self.fbb_.push_slot::<i64>(Monster::VT_TESTHASHS64_FNV1, testhashs64_fnv1, 0);
+  }
+  #[inline]
+  pub fn add_testhashu64_fnv1(&mut self, testhashu64_fnv1: u64) {
+    self.fbb_.push_slot::<u64>(Monster::VT_TESTHASHU64_FNV1, testhashu64_fnv1, 0);
+  }
+  #[inline]
+  pub fn add_testhashs32_fnv1a(&mut self, testhashs32_fnv1a: i32) {
+    self.fbb_.push_slot::<i32>(Monster::VT_TESTHASHS32_FNV1A, testhashs32_fnv1a, 0);
+  }
+  #[inline]
+  pub fn add_testhashu32_fnv1a(&mut self, testhashu32_fnv1a: u32) {
+    self.fbb_.push_slot::<u32>(Monster::VT_TESTHASHU32_FNV1A, testhashu32_fnv1a, 0);
+  }
+  #[inline]
+  pub fn add_testhashs64_fnv1a(&mut self, testhashs64_fnv1a: i64) {
+    self.fbb_.push_slot::<i64>(Monster::VT_TESTHASHS64_FNV1A, testhashs64_fnv1a, 0);
+  }
+  #[inline]
+  pub fn add_testhashu64_fnv1a(&mut self, testhashu64_fnv1a: u64) {
+    self.fbb_.push_slot::<u64>(Monster::VT_TESTHASHU64_FNV1A, testhashu64_fnv1a, 0);
+  }
+  #[inline]
+  pub fn add_testarrayofbools(&mut self, testarrayofbools: flatbuffers::WIPOffset<flatbuffers::Vector<'b , bool>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_TESTARRAYOFBOOLS, testarrayofbools);
+  }
+  #[inline]
+  pub fn add_testf(&mut self, testf: f32) {
+    self.fbb_.push_slot::<f32>(Monster::VT_TESTF, testf, 3.14159);
+  }
+  #[inline]
+  pub fn add_testf2(&mut self, testf2: f32) {
+    self.fbb_.push_slot::<f32>(Monster::VT_TESTF2, testf2, 3.0);
+  }
+  #[inline]
+  pub fn add_testf3(&mut self, testf3: f32) {
+    self.fbb_.push_slot::<f32>(Monster::VT_TESTF3, testf3, 0.0);
+  }
+  #[inline]
+  pub fn add_testarrayofstring2(&mut self, testarrayofstring2: flatbuffers::WIPOffset<flatbuffers::Vector<'b , flatbuffers::ForwardsUOffset<&'b  str>>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_TESTARRAYOFSTRING2, testarrayofstring2);
+  }
+  #[inline]
+  pub fn add_testarrayofsortedstruct(&mut self, testarrayofsortedstruct: flatbuffers::WIPOffset<flatbuffers::Vector<'b , Ability>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_TESTARRAYOFSORTEDSTRUCT, testarrayofsortedstruct);
+  }
+  #[inline]
+  pub fn add_flex(&mut self, flex: flatbuffers::WIPOffset<flatbuffers::Vector<'b , u8>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_FLEX, flex);
+  }
+  #[inline]
+  pub fn add_test5(&mut self, test5: flatbuffers::WIPOffset<flatbuffers::Vector<'b , Test>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_TEST5, test5);
+  }
+  #[inline]
+  pub fn add_vector_of_longs(&mut self, vector_of_longs: flatbuffers::WIPOffset<flatbuffers::Vector<'b , i64>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_VECTOR_OF_LONGS, vector_of_longs);
+  }
+  #[inline]
+  pub fn add_vector_of_doubles(&mut self, vector_of_doubles: flatbuffers::WIPOffset<flatbuffers::Vector<'b , f64>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_VECTOR_OF_DOUBLES, vector_of_doubles);
+  }
+  #[inline]
+  pub fn add_parent_namespace_test(&mut self, parent_namespace_test: flatbuffers::WIPOffset<super::InParentNamespace<'b >>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<super::InParentNamespace>>(Monster::VT_PARENT_NAMESPACE_TEST, parent_namespace_test);
+  }
+  #[inline]
+  pub fn add_vector_of_referrables(&mut self, vector_of_referrables: flatbuffers::WIPOffset<flatbuffers::Vector<'b , flatbuffers::ForwardsUOffset<Referrable<'b >>>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_VECTOR_OF_REFERRABLES, vector_of_referrables);
+  }
+  #[inline]
+  pub fn add_single_weak_reference(&mut self, single_weak_reference: u64) {
+    self.fbb_.push_slot::<u64>(Monster::VT_SINGLE_WEAK_REFERENCE, single_weak_reference, 0);
+  }
+  #[inline]
+  pub fn add_vector_of_weak_references(&mut self, vector_of_weak_references: flatbuffers::WIPOffset<flatbuffers::Vector<'b , u64>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_VECTOR_OF_WEAK_REFERENCES, vector_of_weak_references);
+  }
+  #[inline]
+  pub fn add_vector_of_strong_referrables(&mut self, vector_of_strong_referrables: flatbuffers::WIPOffset<flatbuffers::Vector<'b , flatbuffers::ForwardsUOffset<Referrable<'b >>>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_VECTOR_OF_STRONG_REFERRABLES, vector_of_strong_referrables);
+  }
+  #[inline]
+  pub fn add_co_owning_reference(&mut self, co_owning_reference: u64) {
+    self.fbb_.push_slot::<u64>(Monster::VT_CO_OWNING_REFERENCE, co_owning_reference, 0);
+  }
+  #[inline]
+  pub fn add_vector_of_co_owning_references(&mut self, vector_of_co_owning_references: flatbuffers::WIPOffset<flatbuffers::Vector<'b , u64>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_VECTOR_OF_CO_OWNING_REFERENCES, vector_of_co_owning_references);
+  }
+  #[inline]
+  pub fn add_non_owning_reference(&mut self, non_owning_reference: u64) {
+    self.fbb_.push_slot::<u64>(Monster::VT_NON_OWNING_REFERENCE, non_owning_reference, 0);
+  }
+  #[inline]
+  pub fn add_vector_of_non_owning_references(&mut self, vector_of_non_owning_references: flatbuffers::WIPOffset<flatbuffers::Vector<'b , u64>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_VECTOR_OF_NON_OWNING_REFERENCES, vector_of_non_owning_references);
+  }
+  #[inline]
+  pub fn add_any_unique_type(&mut self, any_unique_type: AnyUniqueAliases) {
+    self.fbb_.push_slot::<AnyUniqueAliases>(Monster::VT_ANY_UNIQUE_TYPE, any_unique_type, AnyUniqueAliases::NONE);
+  }
+  #[inline]
+  pub fn add_any_unique(&mut self, any_unique: flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_ANY_UNIQUE, any_unique);
+  }
+  #[inline]
+  pub fn add_any_ambiguous_type(&mut self, any_ambiguous_type: AnyAmbiguousAliases) {
+    self.fbb_.push_slot::<AnyAmbiguousAliases>(Monster::VT_ANY_AMBIGUOUS_TYPE, any_ambiguous_type, AnyAmbiguousAliases::NONE);
+  }
+  #[inline]
+  pub fn add_any_ambiguous(&mut self, any_ambiguous: flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_ANY_AMBIGUOUS, any_ambiguous);
+  }
+  #[inline]
+  pub fn add_vector_of_enums(&mut self, vector_of_enums: flatbuffers::WIPOffset<flatbuffers::Vector<'b , Color>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_VECTOR_OF_ENUMS, vector_of_enums);
+  }
+  #[inline]
+  pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> MonsterBuilder<'a, 'b> {
+    let start = _fbb.start_table();
+    MonsterBuilder {
+      fbb_: _fbb,
+      start_: start,
+    }
+  }
+  #[inline]
+  pub fn finish(self) -> flatbuffers::WIPOffset<Monster<'a>> {
+    let o = self.fbb_.end_table(self.start_);
+    self.fbb_.required(o, Monster::VT_NAME,"name");
+    flatbuffers::WIPOffset::new(o.value())
+  }
+}
+
+pub enum TypeAliasesOffset {}
+#[derive(Copy, Clone, Debug, PartialEq)]
+
+pub struct TypeAliases<'a> {
+  pub _tab: flatbuffers::Table<'a>,
+}
+
+impl<'a> flatbuffers::Follow<'a> for TypeAliases<'a> {
+    type Inner = TypeAliases<'a>;
+    #[inline]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        Self {
+            _tab: flatbuffers::Table { buf: buf, loc: loc },
+        }
+    }
+}
+
+impl<'a> TypeAliases<'a> {
+    #[inline]
+    pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
+        TypeAliases {
+            _tab: table,
+        }
+    }
+    #[allow(unused_mut)]
+    pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
+        _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
+        args: &'args TypeAliasesArgs<'args>) -> flatbuffers::WIPOffset<TypeAliases<'bldr>> {
+      let mut builder = TypeAliasesBuilder::new(_fbb);
+      builder.add_f64_(args.f64_);
+      builder.add_u64_(args.u64_);
+      builder.add_i64_(args.i64_);
+      if let Some(x) = args.vf64 { builder.add_vf64(x); }
+      if let Some(x) = args.v8 { builder.add_v8(x); }
+      builder.add_f32_(args.f32_);
+      builder.add_u32_(args.u32_);
+      builder.add_i32_(args.i32_);
+      builder.add_u16_(args.u16_);
+      builder.add_i16_(args.i16_);
+      builder.add_u8_(args.u8_);
+      builder.add_i8_(args.i8_);
+      builder.finish()
+    }
+
+    pub const VT_I8_: flatbuffers::VOffsetT = 4;
+    pub const VT_U8_: flatbuffers::VOffsetT = 6;
+    pub const VT_I16_: flatbuffers::VOffsetT = 8;
+    pub const VT_U16_: flatbuffers::VOffsetT = 10;
+    pub const VT_I32_: flatbuffers::VOffsetT = 12;
+    pub const VT_U32_: flatbuffers::VOffsetT = 14;
+    pub const VT_I64_: flatbuffers::VOffsetT = 16;
+    pub const VT_U64_: flatbuffers::VOffsetT = 18;
+    pub const VT_F32_: flatbuffers::VOffsetT = 20;
+    pub const VT_F64_: flatbuffers::VOffsetT = 22;
+    pub const VT_V8: flatbuffers::VOffsetT = 24;
+    pub const VT_VF64: flatbuffers::VOffsetT = 26;
+
+  #[inline]
+  pub fn i8_(&self) -> i8 {
+    self._tab.get::<i8>(TypeAliases::VT_I8_, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn u8_(&self) -> u8 {
+    self._tab.get::<u8>(TypeAliases::VT_U8_, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn i16_(&self) -> i16 {
+    self._tab.get::<i16>(TypeAliases::VT_I16_, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn u16_(&self) -> u16 {
+    self._tab.get::<u16>(TypeAliases::VT_U16_, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn i32_(&self) -> i32 {
+    self._tab.get::<i32>(TypeAliases::VT_I32_, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn u32_(&self) -> u32 {
+    self._tab.get::<u32>(TypeAliases::VT_U32_, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn i64_(&self) -> i64 {
+    self._tab.get::<i64>(TypeAliases::VT_I64_, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn u64_(&self) -> u64 {
+    self._tab.get::<u64>(TypeAliases::VT_U64_, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn f32_(&self) -> f32 {
+    self._tab.get::<f32>(TypeAliases::VT_F32_, Some(0.0)).unwrap()
+  }
+  #[inline]
+  pub fn f64_(&self) -> f64 {
+    self._tab.get::<f64>(TypeAliases::VT_F64_, Some(0.0)).unwrap()
+  }
+  #[inline]
+  pub fn v8(&self) -> Option<&'a [i8]> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, i8>>>(TypeAliases::VT_V8, None).map(|v| v.safe_slice())
+  }
+  #[inline]
+  pub fn vf64(&self) -> Option<flatbuffers::Vector<'a, f64>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, f64>>>(TypeAliases::VT_VF64, None)
+  }
+}
+
+pub struct TypeAliasesArgs<'a> {
+    pub i8_: i8,
+    pub u8_: u8,
+    pub i16_: i16,
+    pub u16_: u16,
+    pub i32_: i32,
+    pub u32_: u32,
+    pub i64_: i64,
+    pub u64_: u64,
+    pub f32_: f32,
+    pub f64_: f64,
+    pub v8: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a ,  i8>>>,
+    pub vf64: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a ,  f64>>>,
+}
+impl<'a> Default for TypeAliasesArgs<'a> {
+    #[inline]
+    fn default() -> Self {
+        TypeAliasesArgs {
+            i8_: 0,
+            u8_: 0,
+            i16_: 0,
+            u16_: 0,
+            i32_: 0,
+            u32_: 0,
+            i64_: 0,
+            u64_: 0,
+            f32_: 0.0,
+            f64_: 0.0,
+            v8: None,
+            vf64: None,
+        }
+    }
+}
+pub struct TypeAliasesBuilder<'a: 'b, 'b> {
+  fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
+  start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
+}
+impl<'a: 'b, 'b> TypeAliasesBuilder<'a, 'b> {
+  #[inline]
+  pub fn add_i8_(&mut self, i8_: i8) {
+    self.fbb_.push_slot::<i8>(TypeAliases::VT_I8_, i8_, 0);
+  }
+  #[inline]
+  pub fn add_u8_(&mut self, u8_: u8) {
+    self.fbb_.push_slot::<u8>(TypeAliases::VT_U8_, u8_, 0);
+  }
+  #[inline]
+  pub fn add_i16_(&mut self, i16_: i16) {
+    self.fbb_.push_slot::<i16>(TypeAliases::VT_I16_, i16_, 0);
+  }
+  #[inline]
+  pub fn add_u16_(&mut self, u16_: u16) {
+    self.fbb_.push_slot::<u16>(TypeAliases::VT_U16_, u16_, 0);
+  }
+  #[inline]
+  pub fn add_i32_(&mut self, i32_: i32) {
+    self.fbb_.push_slot::<i32>(TypeAliases::VT_I32_, i32_, 0);
+  }
+  #[inline]
+  pub fn add_u32_(&mut self, u32_: u32) {
+    self.fbb_.push_slot::<u32>(TypeAliases::VT_U32_, u32_, 0);
+  }
+  #[inline]
+  pub fn add_i64_(&mut self, i64_: i64) {
+    self.fbb_.push_slot::<i64>(TypeAliases::VT_I64_, i64_, 0);
+  }
+  #[inline]
+  pub fn add_u64_(&mut self, u64_: u64) {
+    self.fbb_.push_slot::<u64>(TypeAliases::VT_U64_, u64_, 0);
+  }
+  #[inline]
+  pub fn add_f32_(&mut self, f32_: f32) {
+    self.fbb_.push_slot::<f32>(TypeAliases::VT_F32_, f32_, 0.0);
+  }
+  #[inline]
+  pub fn add_f64_(&mut self, f64_: f64) {
+    self.fbb_.push_slot::<f64>(TypeAliases::VT_F64_, f64_, 0.0);
+  }
+  #[inline]
+  pub fn add_v8(&mut self, v8: flatbuffers::WIPOffset<flatbuffers::Vector<'b , i8>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(TypeAliases::VT_V8, v8);
+  }
+  #[inline]
+  pub fn add_vf64(&mut self, vf64: flatbuffers::WIPOffset<flatbuffers::Vector<'b , f64>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(TypeAliases::VT_VF64, vf64);
+  }
+  #[inline]
+  pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> TypeAliasesBuilder<'a, 'b> {
+    let start = _fbb.start_table();
+    TypeAliasesBuilder {
+      fbb_: _fbb,
+      start_: start,
+    }
+  }
+  #[inline]
+  pub fn finish(self) -> flatbuffers::WIPOffset<TypeAliases<'a>> {
+    let o = self.fbb_.end_table(self.start_);
+    flatbuffers::WIPOffset::new(o.value())
+  }
+}
+
+#[inline]
+pub fn get_root_as_monster<'a>(buf: &'a [u8]) -> Monster<'a> {
+  flatbuffers::get_root::<Monster<'a>>(buf)
+}
+
+#[inline]
+pub fn get_size_prefixed_root_as_monster<'a>(buf: &'a [u8]) -> Monster<'a> {
+  flatbuffers::get_size_prefixed_root::<Monster<'a>>(buf)
+}
+
+pub const MONSTER_IDENTIFIER: &'static str = "MONS";
+
+#[inline]
+pub fn monster_buffer_has_identifier(buf: &[u8]) -> bool {
+  return flatbuffers::buffer_has_identifier(buf, MONSTER_IDENTIFIER, false);
+}
+
+#[inline]
+pub fn monster_size_prefixed_buffer_has_identifier(buf: &[u8]) -> bool {
+  return flatbuffers::buffer_has_identifier(buf, MONSTER_IDENTIFIER, true);
+}
+
+pub const MONSTER_EXTENSION: &'static str = "mon";
+
+#[inline]
+pub fn finish_monster_buffer<'a, 'b>(
+    fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>,
+    root: flatbuffers::WIPOffset<Monster<'a>>) {
+  fbb.finish(root, Some(MONSTER_IDENTIFIER));
+}
+
+#[inline]
+pub fn finish_size_prefixed_monster_buffer<'a, 'b>(fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, root: flatbuffers::WIPOffset<Monster<'a>>) {
+  fbb.finish_size_prefixed(root, Some(MONSTER_IDENTIFIER));
+}
+}  // pub mod Example
+}  // pub mod MyGame
+
diff --git a/tests/monster_test_generated.ts b/tests/monster_test_generated.ts
new file mode 100644
index 0000000..5f51589
--- /dev/null
+++ b/tests/monster_test_generated.ts
@@ -0,0 +1,3086 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+/**
+ * Composite components of Monster color.
+ *
+ * @enum {number}
+ */
+export namespace MyGame.Example{
+export enum Color{
+  Red= 1,
+
+  /**
+   * \brief color Green
+   * Green is bit_flag with value (1u << 1)
+   */
+  Green= 2,
+
+  /**
+   * \brief color Blue (1u << 3)
+   */
+  Blue= 8
+}};
+
+/**
+ * @enum {number}
+ */
+export namespace MyGame.Example{
+export enum Any{
+  NONE= 0,
+  Monster= 1,
+  TestSimpleTableWithEnum= 2,
+  MyGame_Example2_Monster= 3
+}};
+
+/**
+ * @enum {number}
+ */
+export namespace MyGame.Example{
+export enum AnyUniqueAliases{
+  NONE= 0,
+  M= 1,
+  TS= 2,
+  M2= 3
+}};
+
+/**
+ * @enum {number}
+ */
+export namespace MyGame.Example{
+export enum AnyAmbiguousAliases{
+  NONE= 0,
+  M1= 1,
+  M2= 2,
+  M3= 3
+}};
+
+/**
+ * @constructor
+ */
+export namespace MyGame{
+export class InParentNamespace {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns InParentNamespace
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):InParentNamespace {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param InParentNamespace= obj
+ * @returns InParentNamespace
+ */
+static getRootAsInParentNamespace(bb:flatbuffers.ByteBuffer, obj?:InParentNamespace):InParentNamespace {
+  return (obj || new InParentNamespace).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param InParentNamespace= obj
+ * @returns InParentNamespace
+ */
+static getSizePrefixedRootAsInParentNamespace(bb:flatbuffers.ByteBuffer, obj?:InParentNamespace):InParentNamespace {
+  return (obj || new InParentNamespace).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ */
+static startInParentNamespace(builder:flatbuffers.Builder) {
+  builder.startObject(0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @returns flatbuffers.Offset
+ */
+static endInParentNamespace(builder:flatbuffers.Builder):flatbuffers.Offset {
+  var offset = builder.endObject();
+  return offset;
+};
+
+static createInParentNamespace(builder:flatbuffers.Builder):flatbuffers.Offset {
+  InParentNamespace.startInParentNamespace(builder);
+  return InParentNamespace.endInParentNamespace(builder);
+}
+}
+}
+/**
+ * @constructor
+ */
+export namespace MyGame.Example2{
+export class Monster {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns Monster
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):Monster {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param Monster= obj
+ * @returns Monster
+ */
+static getRootAsMonster(bb:flatbuffers.ByteBuffer, obj?:Monster):Monster {
+  return (obj || new Monster).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param Monster= obj
+ * @returns Monster
+ */
+static getSizePrefixedRootAsMonster(bb:flatbuffers.ByteBuffer, obj?:Monster):Monster {
+  return (obj || new Monster).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ */
+static startMonster(builder:flatbuffers.Builder) {
+  builder.startObject(0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @returns flatbuffers.Offset
+ */
+static endMonster(builder:flatbuffers.Builder):flatbuffers.Offset {
+  var offset = builder.endObject();
+  return offset;
+};
+
+static createMonster(builder:flatbuffers.Builder):flatbuffers.Offset {
+  Monster.startMonster(builder);
+  return Monster.endMonster(builder);
+}
+}
+}
+/**
+ * @constructor
+ */
+export namespace MyGame.Example{
+export class Test {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns Test
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):Test {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @returns number
+ */
+a():number {
+  return this.bb!.readInt16(this.bb_pos);
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_a(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 0);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt16(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+b():number {
+  return this.bb!.readInt8(this.bb_pos + 2);
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_b(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 2);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number a
+ * @param number b
+ * @returns flatbuffers.Offset
+ */
+static createTest(builder:flatbuffers.Builder, a: number, b: number):flatbuffers.Offset {
+  builder.prep(2, 4);
+  builder.pad(1);
+  builder.writeInt8(b);
+  builder.writeInt16(a);
+  return builder.offset();
+};
+
+}
+}
+/**
+ * @constructor
+ */
+export namespace MyGame.Example{
+export class TestSimpleTableWithEnum {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns TestSimpleTableWithEnum
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):TestSimpleTableWithEnum {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param TestSimpleTableWithEnum= obj
+ * @returns TestSimpleTableWithEnum
+ */
+static getRootAsTestSimpleTableWithEnum(bb:flatbuffers.ByteBuffer, obj?:TestSimpleTableWithEnum):TestSimpleTableWithEnum {
+  return (obj || new TestSimpleTableWithEnum).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param TestSimpleTableWithEnum= obj
+ * @returns TestSimpleTableWithEnum
+ */
+static getSizePrefixedRootAsTestSimpleTableWithEnum(bb:flatbuffers.ByteBuffer, obj?:TestSimpleTableWithEnum):TestSimpleTableWithEnum {
+  return (obj || new TestSimpleTableWithEnum).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @returns MyGame.Example.Color
+ */
+color():MyGame.Example.Color {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+  return offset ? /**  */ (this.bb!.readUint8(this.bb_pos + offset)) : MyGame.Example.Color.Green;
+};
+
+/**
+ * @param MyGame.Example.Color value
+ * @returns boolean
+ */
+mutate_color(value:MyGame.Example.Color):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ */
+static startTestSimpleTableWithEnum(builder:flatbuffers.Builder) {
+  builder.startObject(1);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param MyGame.Example.Color color
+ */
+static addColor(builder:flatbuffers.Builder, color:MyGame.Example.Color) {
+  builder.addFieldInt8(0, color, MyGame.Example.Color.Green);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @returns flatbuffers.Offset
+ */
+static endTestSimpleTableWithEnum(builder:flatbuffers.Builder):flatbuffers.Offset {
+  var offset = builder.endObject();
+  return offset;
+};
+
+static createTestSimpleTableWithEnum(builder:flatbuffers.Builder, color:MyGame.Example.Color):flatbuffers.Offset {
+  TestSimpleTableWithEnum.startTestSimpleTableWithEnum(builder);
+  TestSimpleTableWithEnum.addColor(builder, color);
+  return TestSimpleTableWithEnum.endTestSimpleTableWithEnum(builder);
+}
+}
+}
+/**
+ * @constructor
+ */
+export namespace MyGame.Example{
+export class Vec3 {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns Vec3
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):Vec3 {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @returns number
+ */
+x():number {
+  return this.bb!.readFloat32(this.bb_pos);
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_x(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 0);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeFloat32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+y():number {
+  return this.bb!.readFloat32(this.bb_pos + 4);
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_y(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeFloat32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+z():number {
+  return this.bb!.readFloat32(this.bb_pos + 8);
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_z(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 8);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeFloat32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+test1():number {
+  return this.bb!.readFloat64(this.bb_pos + 16);
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_test1(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 16);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeFloat64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns MyGame.Example.Color
+ */
+test2():MyGame.Example.Color {
+  return /**  */ (this.bb!.readUint8(this.bb_pos + 24));
+};
+
+/**
+ * @param MyGame.Example.Color value
+ * @returns boolean
+ */
+mutate_test2(value:MyGame.Example.Color):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 24);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param MyGame.Example.Test= obj
+ * @returns MyGame.Example.Test|null
+ */
+test3(obj?:MyGame.Example.Test):MyGame.Example.Test|null {
+  return (obj || new MyGame.Example.Test).__init(this.bb_pos + 26, this.bb!);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number x
+ * @param number y
+ * @param number z
+ * @param number test1
+ * @param MyGame.Example.Color test2
+ * @param number test3_a
+ * @param number test3_b
+ * @returns flatbuffers.Offset
+ */
+static createVec3(builder:flatbuffers.Builder, x: number, y: number, z: number, test1: number, test2: MyGame.Example.Color, test3_a: number, test3_b: number):flatbuffers.Offset {
+  builder.prep(8, 32);
+  builder.pad(2);
+  builder.prep(2, 4);
+  builder.pad(1);
+  builder.writeInt8(test3_b);
+  builder.writeInt16(test3_a);
+  builder.pad(1);
+  builder.writeInt8(test2);
+  builder.writeFloat64(test1);
+  builder.pad(4);
+  builder.writeFloat32(z);
+  builder.writeFloat32(y);
+  builder.writeFloat32(x);
+  return builder.offset();
+};
+
+}
+}
+/**
+ * @constructor
+ */
+export namespace MyGame.Example{
+export class Ability {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns Ability
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):Ability {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @returns number
+ */
+id():number {
+  return this.bb!.readUint32(this.bb_pos);
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_id(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 0);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+distance():number {
+  return this.bb!.readUint32(this.bb_pos + 4);
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_distance(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number id
+ * @param number distance
+ * @returns flatbuffers.Offset
+ */
+static createAbility(builder:flatbuffers.Builder, id: number, distance: number):flatbuffers.Offset {
+  builder.prep(4, 8);
+  builder.writeInt32(distance);
+  builder.writeInt32(id);
+  return builder.offset();
+};
+
+}
+}
+/**
+ * @constructor
+ */
+export namespace MyGame.Example{
+export class Stat {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns Stat
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):Stat {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param Stat= obj
+ * @returns Stat
+ */
+static getRootAsStat(bb:flatbuffers.ByteBuffer, obj?:Stat):Stat {
+  return (obj || new Stat).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param Stat= obj
+ * @returns Stat
+ */
+static getSizePrefixedRootAsStat(bb:flatbuffers.ByteBuffer, obj?:Stat):Stat {
+  return (obj || new Stat).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.Encoding= optionalEncoding
+ * @returns string|Uint8Array|null
+ */
+id():string|null
+id(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
+id(optionalEncoding?:any):string|Uint8Array|null {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+  return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
+};
+
+/**
+ * @returns flatbuffers.Long
+ */
+val():flatbuffers.Long {
+  var offset = this.bb!.__offset(this.bb_pos, 6);
+  return offset ? this.bb!.readInt64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
+};
+
+/**
+ * @param flatbuffers.Long value
+ * @returns boolean
+ */
+mutate_val(value:flatbuffers.Long):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 6);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+count():number {
+  var offset = this.bb!.__offset(this.bb_pos, 8);
+  return offset ? this.bb!.readUint16(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_count(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 8);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint16(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ */
+static startStat(builder:flatbuffers.Builder) {
+  builder.startObject(3);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset idOffset
+ */
+static addId(builder:flatbuffers.Builder, idOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(0, idOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Long val
+ */
+static addVal(builder:flatbuffers.Builder, val:flatbuffers.Long) {
+  builder.addFieldInt64(1, val, builder.createLong(0, 0));
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number count
+ */
+static addCount(builder:flatbuffers.Builder, count:number) {
+  builder.addFieldInt16(2, count, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @returns flatbuffers.Offset
+ */
+static endStat(builder:flatbuffers.Builder):flatbuffers.Offset {
+  var offset = builder.endObject();
+  return offset;
+};
+
+static createStat(builder:flatbuffers.Builder, idOffset:flatbuffers.Offset, val:flatbuffers.Long, count:number):flatbuffers.Offset {
+  Stat.startStat(builder);
+  Stat.addId(builder, idOffset);
+  Stat.addVal(builder, val);
+  Stat.addCount(builder, count);
+  return Stat.endStat(builder);
+}
+}
+}
+/**
+ * @constructor
+ */
+export namespace MyGame.Example{
+export class Referrable {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns Referrable
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):Referrable {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param Referrable= obj
+ * @returns Referrable
+ */
+static getRootAsReferrable(bb:flatbuffers.ByteBuffer, obj?:Referrable):Referrable {
+  return (obj || new Referrable).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param Referrable= obj
+ * @returns Referrable
+ */
+static getSizePrefixedRootAsReferrable(bb:flatbuffers.ByteBuffer, obj?:Referrable):Referrable {
+  return (obj || new Referrable).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @returns flatbuffers.Long
+ */
+id():flatbuffers.Long {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+  return offset ? this.bb!.readUint64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
+};
+
+/**
+ * @param flatbuffers.Long value
+ * @returns boolean
+ */
+mutate_id(value:flatbuffers.Long):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ */
+static startReferrable(builder:flatbuffers.Builder) {
+  builder.startObject(1);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Long id
+ */
+static addId(builder:flatbuffers.Builder, id:flatbuffers.Long) {
+  builder.addFieldInt64(0, id, builder.createLong(0, 0));
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @returns flatbuffers.Offset
+ */
+static endReferrable(builder:flatbuffers.Builder):flatbuffers.Offset {
+  var offset = builder.endObject();
+  return offset;
+};
+
+static createReferrable(builder:flatbuffers.Builder, id:flatbuffers.Long):flatbuffers.Offset {
+  Referrable.startReferrable(builder);
+  Referrable.addId(builder, id);
+  return Referrable.endReferrable(builder);
+}
+}
+}
+/**
+ * an example documentation comment: monster object
+ *
+ * @constructor
+ */
+export namespace MyGame.Example{
+export class Monster {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns Monster
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):Monster {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param Monster= obj
+ * @returns Monster
+ */
+static getRootAsMonster(bb:flatbuffers.ByteBuffer, obj?:Monster):Monster {
+  return (obj || new Monster).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param Monster= obj
+ * @returns Monster
+ */
+static getSizePrefixedRootAsMonster(bb:flatbuffers.ByteBuffer, obj?:Monster):Monster {
+  return (obj || new Monster).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @returns boolean
+ */
+static bufferHasIdentifier(bb:flatbuffers.ByteBuffer):boolean {
+  return bb.__has_identifier('MONS');
+};
+
+/**
+ * @param MyGame.Example.Vec3= obj
+ * @returns MyGame.Example.Vec3|null
+ */
+pos(obj?:MyGame.Example.Vec3):MyGame.Example.Vec3|null {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+  return offset ? (obj || new MyGame.Example.Vec3).__init(this.bb_pos + offset, this.bb!) : null;
+};
+
+/**
+ * @returns number
+ */
+mana():number {
+  var offset = this.bb!.__offset(this.bb_pos, 6);
+  return offset ? this.bb!.readInt16(this.bb_pos + offset) : 150;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_mana(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 6);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt16(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+hp():number {
+  var offset = this.bb!.__offset(this.bb_pos, 8);
+  return offset ? this.bb!.readInt16(this.bb_pos + offset) : 100;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_hp(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 8);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt16(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param flatbuffers.Encoding= optionalEncoding
+ * @returns string|Uint8Array|null
+ */
+name():string|null
+name(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
+name(optionalEncoding?:any):string|Uint8Array|null {
+  var offset = this.bb!.__offset(this.bb_pos, 10);
+  return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
+};
+
+/**
+ * @param number index
+ * @returns number
+ */
+inventory(index: number):number|null {
+  var offset = this.bb!.__offset(this.bb_pos, 14);
+  return offset ? this.bb!.readUint8(this.bb!.__vector(this.bb_pos + offset) + index) : 0;
+};
+
+/**
+ * @returns number
+ */
+inventoryLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 14);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns Uint8Array
+ */
+inventoryArray():Uint8Array|null {
+  var offset = this.bb!.__offset(this.bb_pos, 14);
+  return offset ? new Uint8Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @returns MyGame.Example.Color
+ */
+color():MyGame.Example.Color {
+  var offset = this.bb!.__offset(this.bb_pos, 16);
+  return offset ? /**  */ (this.bb!.readUint8(this.bb_pos + offset)) : MyGame.Example.Color.Blue;
+};
+
+/**
+ * @param MyGame.Example.Color value
+ * @returns boolean
+ */
+mutate_color(value:MyGame.Example.Color):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 16);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns MyGame.Example.Any
+ */
+testType():MyGame.Example.Any {
+  var offset = this.bb!.__offset(this.bb_pos, 18);
+  return offset ? /**  */ (this.bb!.readUint8(this.bb_pos + offset)) : MyGame.Example.Any.NONE;
+};
+
+/**
+ * @param MyGame.Example.Any value
+ * @returns boolean
+ */
+mutate_test_type(value:MyGame.Example.Any):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 18);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param flatbuffers.Table obj
+ * @returns ?flatbuffers.Table
+ */
+test<T extends flatbuffers.Table>(obj:T):T|null {
+  var offset = this.bb!.__offset(this.bb_pos, 20);
+  return offset ? this.bb!.__union(obj, this.bb_pos + offset) : null;
+};
+
+/**
+ * @param number index
+ * @param MyGame.Example.Test= obj
+ * @returns MyGame.Example.Test
+ */
+test4(index: number, obj?:MyGame.Example.Test):MyGame.Example.Test|null {
+  var offset = this.bb!.__offset(this.bb_pos, 22);
+  return offset ? (obj || new MyGame.Example.Test).__init(this.bb!.__vector(this.bb_pos + offset) + index * 4, this.bb!) : null;
+};
+
+/**
+ * @returns number
+ */
+test4Length():number {
+  var offset = this.bb!.__offset(this.bb_pos, 22);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number index
+ * @param flatbuffers.Encoding= optionalEncoding
+ * @returns string|Uint8Array
+ */
+testarrayofstring(index: number):string
+testarrayofstring(index: number,optionalEncoding:flatbuffers.Encoding):string|Uint8Array
+testarrayofstring(index: number,optionalEncoding?:any):string|Uint8Array|null {
+  var offset = this.bb!.__offset(this.bb_pos, 24);
+  return offset ? this.bb!.__string(this.bb!.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null;
+};
+
+/**
+ * @returns number
+ */
+testarrayofstringLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 24);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * an example documentation comment: this will end up in the generated code
+ * multiline too
+ *
+ * @param number index
+ * @param MyGame.Example.Monster= obj
+ * @returns MyGame.Example.Monster
+ */
+testarrayoftables(index: number, obj?:MyGame.Example.Monster):MyGame.Example.Monster|null {
+  var offset = this.bb!.__offset(this.bb_pos, 26);
+  return offset ? (obj || new MyGame.Example.Monster).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
+};
+
+/**
+ * @returns number
+ */
+testarrayoftablesLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 26);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param MyGame.Example.Monster= obj
+ * @returns MyGame.Example.Monster|null
+ */
+enemy(obj?:MyGame.Example.Monster):MyGame.Example.Monster|null {
+  var offset = this.bb!.__offset(this.bb_pos, 28);
+  return offset ? (obj || new MyGame.Example.Monster).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
+};
+
+/**
+ * @param number index
+ * @returns number
+ */
+testnestedflatbuffer(index: number):number|null {
+  var offset = this.bb!.__offset(this.bb_pos, 30);
+  return offset ? this.bb!.readUint8(this.bb!.__vector(this.bb_pos + offset) + index) : 0;
+};
+
+/**
+ * @returns number
+ */
+testnestedflatbufferLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 30);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns Uint8Array
+ */
+testnestedflatbufferArray():Uint8Array|null {
+  var offset = this.bb!.__offset(this.bb_pos, 30);
+  return offset ? new Uint8Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @param MyGame.Example.Stat= obj
+ * @returns MyGame.Example.Stat|null
+ */
+testempty(obj?:MyGame.Example.Stat):MyGame.Example.Stat|null {
+  var offset = this.bb!.__offset(this.bb_pos, 32);
+  return offset ? (obj || new MyGame.Example.Stat).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
+};
+
+/**
+ * @returns boolean
+ */
+testbool():boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 34);
+  return offset ? !!this.bb!.readInt8(this.bb_pos + offset) : false;
+};
+
+/**
+ * @param boolean value
+ * @returns boolean
+ */
+mutate_testbool(value:boolean):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 34);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt8(this.bb_pos + offset, +value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+testhashs32Fnv1():number {
+  var offset = this.bb!.__offset(this.bb_pos, 36);
+  return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_testhashs32_fnv1(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 36);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+testhashu32Fnv1():number {
+  var offset = this.bb!.__offset(this.bb_pos, 38);
+  return offset ? this.bb!.readUint32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_testhashu32_fnv1(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 38);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns flatbuffers.Long
+ */
+testhashs64Fnv1():flatbuffers.Long {
+  var offset = this.bb!.__offset(this.bb_pos, 40);
+  return offset ? this.bb!.readInt64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
+};
+
+/**
+ * @param flatbuffers.Long value
+ * @returns boolean
+ */
+mutate_testhashs64_fnv1(value:flatbuffers.Long):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 40);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns flatbuffers.Long
+ */
+testhashu64Fnv1():flatbuffers.Long {
+  var offset = this.bb!.__offset(this.bb_pos, 42);
+  return offset ? this.bb!.readUint64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
+};
+
+/**
+ * @param flatbuffers.Long value
+ * @returns boolean
+ */
+mutate_testhashu64_fnv1(value:flatbuffers.Long):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 42);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+testhashs32Fnv1a():number {
+  var offset = this.bb!.__offset(this.bb_pos, 44);
+  return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_testhashs32_fnv1a(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 44);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+testhashu32Fnv1a():number {
+  var offset = this.bb!.__offset(this.bb_pos, 46);
+  return offset ? this.bb!.readUint32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_testhashu32_fnv1a(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 46);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns flatbuffers.Long
+ */
+testhashs64Fnv1a():flatbuffers.Long {
+  var offset = this.bb!.__offset(this.bb_pos, 48);
+  return offset ? this.bb!.readInt64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
+};
+
+/**
+ * @param flatbuffers.Long value
+ * @returns boolean
+ */
+mutate_testhashs64_fnv1a(value:flatbuffers.Long):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 48);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns flatbuffers.Long
+ */
+testhashu64Fnv1a():flatbuffers.Long {
+  var offset = this.bb!.__offset(this.bb_pos, 50);
+  return offset ? this.bb!.readUint64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
+};
+
+/**
+ * @param flatbuffers.Long value
+ * @returns boolean
+ */
+mutate_testhashu64_fnv1a(value:flatbuffers.Long):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 50);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param number index
+ * @returns boolean
+ */
+testarrayofbools(index: number):boolean|null {
+  var offset = this.bb!.__offset(this.bb_pos, 52);
+  return offset ? !!this.bb!.readInt8(this.bb!.__vector(this.bb_pos + offset) + index) : false;
+};
+
+/**
+ * @returns number
+ */
+testarrayofboolsLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 52);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns Int8Array
+ */
+testarrayofboolsArray():Int8Array|null {
+  var offset = this.bb!.__offset(this.bb_pos, 52);
+  return offset ? new Int8Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @returns number
+ */
+testf():number {
+  var offset = this.bb!.__offset(this.bb_pos, 54);
+  return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 3.14159;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_testf(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 54);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeFloat32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+testf2():number {
+  var offset = this.bb!.__offset(this.bb_pos, 56);
+  return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 3.0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_testf2(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 56);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeFloat32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+testf3():number {
+  var offset = this.bb!.__offset(this.bb_pos, 58);
+  return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_testf3(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 58);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeFloat32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param number index
+ * @param flatbuffers.Encoding= optionalEncoding
+ * @returns string|Uint8Array
+ */
+testarrayofstring2(index: number):string
+testarrayofstring2(index: number,optionalEncoding:flatbuffers.Encoding):string|Uint8Array
+testarrayofstring2(index: number,optionalEncoding?:any):string|Uint8Array|null {
+  var offset = this.bb!.__offset(this.bb_pos, 60);
+  return offset ? this.bb!.__string(this.bb!.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null;
+};
+
+/**
+ * @returns number
+ */
+testarrayofstring2Length():number {
+  var offset = this.bb!.__offset(this.bb_pos, 60);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number index
+ * @param MyGame.Example.Ability= obj
+ * @returns MyGame.Example.Ability
+ */
+testarrayofsortedstruct(index: number, obj?:MyGame.Example.Ability):MyGame.Example.Ability|null {
+  var offset = this.bb!.__offset(this.bb_pos, 62);
+  return offset ? (obj || new MyGame.Example.Ability).__init(this.bb!.__vector(this.bb_pos + offset) + index * 8, this.bb!) : null;
+};
+
+/**
+ * @returns number
+ */
+testarrayofsortedstructLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 62);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number index
+ * @returns number
+ */
+flex(index: number):number|null {
+  var offset = this.bb!.__offset(this.bb_pos, 64);
+  return offset ? this.bb!.readUint8(this.bb!.__vector(this.bb_pos + offset) + index) : 0;
+};
+
+/**
+ * @returns number
+ */
+flexLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 64);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns Uint8Array
+ */
+flexArray():Uint8Array|null {
+  var offset = this.bb!.__offset(this.bb_pos, 64);
+  return offset ? new Uint8Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @param number index
+ * @param MyGame.Example.Test= obj
+ * @returns MyGame.Example.Test
+ */
+test5(index: number, obj?:MyGame.Example.Test):MyGame.Example.Test|null {
+  var offset = this.bb!.__offset(this.bb_pos, 66);
+  return offset ? (obj || new MyGame.Example.Test).__init(this.bb!.__vector(this.bb_pos + offset) + index * 4, this.bb!) : null;
+};
+
+/**
+ * @returns number
+ */
+test5Length():number {
+  var offset = this.bb!.__offset(this.bb_pos, 66);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number index
+ * @returns flatbuffers.Long
+ */
+vectorOfLongs(index: number):flatbuffers.Long|null {
+  var offset = this.bb!.__offset(this.bb_pos, 68);
+  return offset ? this.bb!.readInt64(this.bb!.__vector(this.bb_pos + offset) + index * 8) : this.bb!.createLong(0, 0);
+};
+
+/**
+ * @returns number
+ */
+vectorOfLongsLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 68);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number index
+ * @returns number
+ */
+vectorOfDoubles(index: number):number|null {
+  var offset = this.bb!.__offset(this.bb_pos, 70);
+  return offset ? this.bb!.readFloat64(this.bb!.__vector(this.bb_pos + offset) + index * 8) : 0;
+};
+
+/**
+ * @returns number
+ */
+vectorOfDoublesLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 70);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns Float64Array
+ */
+vectorOfDoublesArray():Float64Array|null {
+  var offset = this.bb!.__offset(this.bb_pos, 70);
+  return offset ? new Float64Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @param MyGame.InParentNamespace= obj
+ * @returns MyGame.InParentNamespace|null
+ */
+parentNamespaceTest(obj?:MyGame.InParentNamespace):MyGame.InParentNamespace|null {
+  var offset = this.bb!.__offset(this.bb_pos, 72);
+  return offset ? (obj || new MyGame.InParentNamespace).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
+};
+
+/**
+ * @param number index
+ * @param MyGame.Example.Referrable= obj
+ * @returns MyGame.Example.Referrable
+ */
+vectorOfReferrables(index: number, obj?:MyGame.Example.Referrable):MyGame.Example.Referrable|null {
+  var offset = this.bb!.__offset(this.bb_pos, 74);
+  return offset ? (obj || new MyGame.Example.Referrable).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
+};
+
+/**
+ * @returns number
+ */
+vectorOfReferrablesLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 74);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns flatbuffers.Long
+ */
+singleWeakReference():flatbuffers.Long {
+  var offset = this.bb!.__offset(this.bb_pos, 76);
+  return offset ? this.bb!.readUint64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
+};
+
+/**
+ * @param flatbuffers.Long value
+ * @returns boolean
+ */
+mutate_single_weak_reference(value:flatbuffers.Long):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 76);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param number index
+ * @returns flatbuffers.Long
+ */
+vectorOfWeakReferences(index: number):flatbuffers.Long|null {
+  var offset = this.bb!.__offset(this.bb_pos, 78);
+  return offset ? this.bb!.readUint64(this.bb!.__vector(this.bb_pos + offset) + index * 8) : this.bb!.createLong(0, 0);
+};
+
+/**
+ * @returns number
+ */
+vectorOfWeakReferencesLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 78);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number index
+ * @param MyGame.Example.Referrable= obj
+ * @returns MyGame.Example.Referrable
+ */
+vectorOfStrongReferrables(index: number, obj?:MyGame.Example.Referrable):MyGame.Example.Referrable|null {
+  var offset = this.bb!.__offset(this.bb_pos, 80);
+  return offset ? (obj || new MyGame.Example.Referrable).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
+};
+
+/**
+ * @returns number
+ */
+vectorOfStrongReferrablesLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 80);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns flatbuffers.Long
+ */
+coOwningReference():flatbuffers.Long {
+  var offset = this.bb!.__offset(this.bb_pos, 82);
+  return offset ? this.bb!.readUint64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
+};
+
+/**
+ * @param flatbuffers.Long value
+ * @returns boolean
+ */
+mutate_co_owning_reference(value:flatbuffers.Long):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 82);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param number index
+ * @returns flatbuffers.Long
+ */
+vectorOfCoOwningReferences(index: number):flatbuffers.Long|null {
+  var offset = this.bb!.__offset(this.bb_pos, 84);
+  return offset ? this.bb!.readUint64(this.bb!.__vector(this.bb_pos + offset) + index * 8) : this.bb!.createLong(0, 0);
+};
+
+/**
+ * @returns number
+ */
+vectorOfCoOwningReferencesLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 84);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns flatbuffers.Long
+ */
+nonOwningReference():flatbuffers.Long {
+  var offset = this.bb!.__offset(this.bb_pos, 86);
+  return offset ? this.bb!.readUint64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
+};
+
+/**
+ * @param flatbuffers.Long value
+ * @returns boolean
+ */
+mutate_non_owning_reference(value:flatbuffers.Long):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 86);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param number index
+ * @returns flatbuffers.Long
+ */
+vectorOfNonOwningReferences(index: number):flatbuffers.Long|null {
+  var offset = this.bb!.__offset(this.bb_pos, 88);
+  return offset ? this.bb!.readUint64(this.bb!.__vector(this.bb_pos + offset) + index * 8) : this.bb!.createLong(0, 0);
+};
+
+/**
+ * @returns number
+ */
+vectorOfNonOwningReferencesLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 88);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns MyGame.Example.AnyUniqueAliases
+ */
+anyUniqueType():MyGame.Example.AnyUniqueAliases {
+  var offset = this.bb!.__offset(this.bb_pos, 90);
+  return offset ? /**  */ (this.bb!.readUint8(this.bb_pos + offset)) : MyGame.Example.AnyUniqueAliases.NONE;
+};
+
+/**
+ * @param MyGame.Example.AnyUniqueAliases value
+ * @returns boolean
+ */
+mutate_any_unique_type(value:MyGame.Example.AnyUniqueAliases):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 90);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param flatbuffers.Table obj
+ * @returns ?flatbuffers.Table
+ */
+anyUnique<T extends flatbuffers.Table>(obj:T):T|null {
+  var offset = this.bb!.__offset(this.bb_pos, 92);
+  return offset ? this.bb!.__union(obj, this.bb_pos + offset) : null;
+};
+
+/**
+ * @returns MyGame.Example.AnyAmbiguousAliases
+ */
+anyAmbiguousType():MyGame.Example.AnyAmbiguousAliases {
+  var offset = this.bb!.__offset(this.bb_pos, 94);
+  return offset ? /**  */ (this.bb!.readUint8(this.bb_pos + offset)) : MyGame.Example.AnyAmbiguousAliases.NONE;
+};
+
+/**
+ * @param MyGame.Example.AnyAmbiguousAliases value
+ * @returns boolean
+ */
+mutate_any_ambiguous_type(value:MyGame.Example.AnyAmbiguousAliases):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 94);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param flatbuffers.Table obj
+ * @returns ?flatbuffers.Table
+ */
+anyAmbiguous<T extends flatbuffers.Table>(obj:T):T|null {
+  var offset = this.bb!.__offset(this.bb_pos, 96);
+  return offset ? this.bb!.__union(obj, this.bb_pos + offset) : null;
+};
+
+/**
+ * @param number index
+ * @returns MyGame.Example.Color
+ */
+vectorOfEnums(index: number):MyGame.Example.Color|null {
+  var offset = this.bb!.__offset(this.bb_pos, 98);
+  return offset ? /**  */ (this.bb!.readUint8(this.bb!.__vector(this.bb_pos + offset) + index)) : /**  */ (0);
+};
+
+/**
+ * @returns number
+ */
+vectorOfEnumsLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 98);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns Uint8Array
+ */
+vectorOfEnumsArray():Uint8Array|null {
+  var offset = this.bb!.__offset(this.bb_pos, 98);
+  return offset ? new Uint8Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ */
+static startMonster(builder:flatbuffers.Builder) {
+  builder.startObject(48);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset posOffset
+ */
+static addPos(builder:flatbuffers.Builder, posOffset:flatbuffers.Offset) {
+  builder.addFieldStruct(0, posOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number mana
+ */
+static addMana(builder:flatbuffers.Builder, mana:number) {
+  builder.addFieldInt16(1, mana, 150);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number hp
+ */
+static addHp(builder:flatbuffers.Builder, hp:number) {
+  builder.addFieldInt16(2, hp, 100);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset nameOffset
+ */
+static addName(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(3, nameOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset inventoryOffset
+ */
+static addInventory(builder:flatbuffers.Builder, inventoryOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(5, inventoryOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<number> data
+ * @returns flatbuffers.Offset
+ */
+static createInventoryVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset {
+  builder.startVector(1, data.length, 1);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt8(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startInventoryVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(1, numElems, 1);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param MyGame.Example.Color color
+ */
+static addColor(builder:flatbuffers.Builder, color:MyGame.Example.Color) {
+  builder.addFieldInt8(6, color, MyGame.Example.Color.Blue);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param MyGame.Example.Any testType
+ */
+static addTestType(builder:flatbuffers.Builder, testType:MyGame.Example.Any) {
+  builder.addFieldInt8(7, testType, MyGame.Example.Any.NONE);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset testOffset
+ */
+static addTest(builder:flatbuffers.Builder, testOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(8, testOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset test4Offset
+ */
+static addTest4(builder:flatbuffers.Builder, test4Offset:flatbuffers.Offset) {
+  builder.addFieldOffset(9, test4Offset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startTest4Vector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(4, numElems, 2);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset testarrayofstringOffset
+ */
+static addTestarrayofstring(builder:flatbuffers.Builder, testarrayofstringOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(10, testarrayofstringOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<flatbuffers.Offset> data
+ * @returns flatbuffers.Offset
+ */
+static createTestarrayofstringVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
+  builder.startVector(4, data.length, 4);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addOffset(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startTestarrayofstringVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(4, numElems, 4);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset testarrayoftablesOffset
+ */
+static addTestarrayoftables(builder:flatbuffers.Builder, testarrayoftablesOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(11, testarrayoftablesOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<flatbuffers.Offset> data
+ * @returns flatbuffers.Offset
+ */
+static createTestarrayoftablesVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
+  builder.startVector(4, data.length, 4);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addOffset(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startTestarrayoftablesVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(4, numElems, 4);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset enemyOffset
+ */
+static addEnemy(builder:flatbuffers.Builder, enemyOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(12, enemyOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset testnestedflatbufferOffset
+ */
+static addTestnestedflatbuffer(builder:flatbuffers.Builder, testnestedflatbufferOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(13, testnestedflatbufferOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<number> data
+ * @returns flatbuffers.Offset
+ */
+static createTestnestedflatbufferVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset {
+  builder.startVector(1, data.length, 1);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt8(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startTestnestedflatbufferVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(1, numElems, 1);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset testemptyOffset
+ */
+static addTestempty(builder:flatbuffers.Builder, testemptyOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(14, testemptyOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param boolean testbool
+ */
+static addTestbool(builder:flatbuffers.Builder, testbool:boolean) {
+  builder.addFieldInt8(15, +testbool, +false);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number testhashs32Fnv1
+ */
+static addTesthashs32Fnv1(builder:flatbuffers.Builder, testhashs32Fnv1:number) {
+  builder.addFieldInt32(16, testhashs32Fnv1, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number testhashu32Fnv1
+ */
+static addTesthashu32Fnv1(builder:flatbuffers.Builder, testhashu32Fnv1:number) {
+  builder.addFieldInt32(17, testhashu32Fnv1, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Long testhashs64Fnv1
+ */
+static addTesthashs64Fnv1(builder:flatbuffers.Builder, testhashs64Fnv1:flatbuffers.Long) {
+  builder.addFieldInt64(18, testhashs64Fnv1, builder.createLong(0, 0));
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Long testhashu64Fnv1
+ */
+static addTesthashu64Fnv1(builder:flatbuffers.Builder, testhashu64Fnv1:flatbuffers.Long) {
+  builder.addFieldInt64(19, testhashu64Fnv1, builder.createLong(0, 0));
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number testhashs32Fnv1a
+ */
+static addTesthashs32Fnv1a(builder:flatbuffers.Builder, testhashs32Fnv1a:number) {
+  builder.addFieldInt32(20, testhashs32Fnv1a, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number testhashu32Fnv1a
+ */
+static addTesthashu32Fnv1a(builder:flatbuffers.Builder, testhashu32Fnv1a:number) {
+  builder.addFieldInt32(21, testhashu32Fnv1a, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Long testhashs64Fnv1a
+ */
+static addTesthashs64Fnv1a(builder:flatbuffers.Builder, testhashs64Fnv1a:flatbuffers.Long) {
+  builder.addFieldInt64(22, testhashs64Fnv1a, builder.createLong(0, 0));
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Long testhashu64Fnv1a
+ */
+static addTesthashu64Fnv1a(builder:flatbuffers.Builder, testhashu64Fnv1a:flatbuffers.Long) {
+  builder.addFieldInt64(23, testhashu64Fnv1a, builder.createLong(0, 0));
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset testarrayofboolsOffset
+ */
+static addTestarrayofbools(builder:flatbuffers.Builder, testarrayofboolsOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(24, testarrayofboolsOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<boolean> data
+ * @returns flatbuffers.Offset
+ */
+static createTestarrayofboolsVector(builder:flatbuffers.Builder, data:boolean[]):flatbuffers.Offset {
+  builder.startVector(1, data.length, 1);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt8(+data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startTestarrayofboolsVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(1, numElems, 1);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number testf
+ */
+static addTestf(builder:flatbuffers.Builder, testf:number) {
+  builder.addFieldFloat32(25, testf, 3.14159);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number testf2
+ */
+static addTestf2(builder:flatbuffers.Builder, testf2:number) {
+  builder.addFieldFloat32(26, testf2, 3.0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number testf3
+ */
+static addTestf3(builder:flatbuffers.Builder, testf3:number) {
+  builder.addFieldFloat32(27, testf3, 0.0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset testarrayofstring2Offset
+ */
+static addTestarrayofstring2(builder:flatbuffers.Builder, testarrayofstring2Offset:flatbuffers.Offset) {
+  builder.addFieldOffset(28, testarrayofstring2Offset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<flatbuffers.Offset> data
+ * @returns flatbuffers.Offset
+ */
+static createTestarrayofstring2Vector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
+  builder.startVector(4, data.length, 4);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addOffset(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startTestarrayofstring2Vector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(4, numElems, 4);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset testarrayofsortedstructOffset
+ */
+static addTestarrayofsortedstruct(builder:flatbuffers.Builder, testarrayofsortedstructOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(29, testarrayofsortedstructOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startTestarrayofsortedstructVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(8, numElems, 4);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset flexOffset
+ */
+static addFlex(builder:flatbuffers.Builder, flexOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(30, flexOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<number> data
+ * @returns flatbuffers.Offset
+ */
+static createFlexVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset {
+  builder.startVector(1, data.length, 1);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt8(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startFlexVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(1, numElems, 1);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset test5Offset
+ */
+static addTest5(builder:flatbuffers.Builder, test5Offset:flatbuffers.Offset) {
+  builder.addFieldOffset(31, test5Offset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startTest5Vector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(4, numElems, 2);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset vectorOfLongsOffset
+ */
+static addVectorOfLongs(builder:flatbuffers.Builder, vectorOfLongsOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(32, vectorOfLongsOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<flatbuffers.Long> data
+ * @returns flatbuffers.Offset
+ */
+static createVectorOfLongsVector(builder:flatbuffers.Builder, data:flatbuffers.Long[]):flatbuffers.Offset {
+  builder.startVector(8, data.length, 8);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt64(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startVectorOfLongsVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(8, numElems, 8);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset vectorOfDoublesOffset
+ */
+static addVectorOfDoubles(builder:flatbuffers.Builder, vectorOfDoublesOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(33, vectorOfDoublesOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<number> data
+ * @returns flatbuffers.Offset
+ */
+static createVectorOfDoublesVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset {
+  builder.startVector(8, data.length, 8);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addFloat64(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startVectorOfDoublesVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(8, numElems, 8);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset parentNamespaceTestOffset
+ */
+static addParentNamespaceTest(builder:flatbuffers.Builder, parentNamespaceTestOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(34, parentNamespaceTestOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset vectorOfReferrablesOffset
+ */
+static addVectorOfReferrables(builder:flatbuffers.Builder, vectorOfReferrablesOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(35, vectorOfReferrablesOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<flatbuffers.Offset> data
+ * @returns flatbuffers.Offset
+ */
+static createVectorOfReferrablesVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
+  builder.startVector(4, data.length, 4);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addOffset(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startVectorOfReferrablesVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(4, numElems, 4);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Long singleWeakReference
+ */
+static addSingleWeakReference(builder:flatbuffers.Builder, singleWeakReference:flatbuffers.Long) {
+  builder.addFieldInt64(36, singleWeakReference, builder.createLong(0, 0));
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset vectorOfWeakReferencesOffset
+ */
+static addVectorOfWeakReferences(builder:flatbuffers.Builder, vectorOfWeakReferencesOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(37, vectorOfWeakReferencesOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<flatbuffers.Long> data
+ * @returns flatbuffers.Offset
+ */
+static createVectorOfWeakReferencesVector(builder:flatbuffers.Builder, data:flatbuffers.Long[]):flatbuffers.Offset {
+  builder.startVector(8, data.length, 8);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt64(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startVectorOfWeakReferencesVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(8, numElems, 8);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset vectorOfStrongReferrablesOffset
+ */
+static addVectorOfStrongReferrables(builder:flatbuffers.Builder, vectorOfStrongReferrablesOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(38, vectorOfStrongReferrablesOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<flatbuffers.Offset> data
+ * @returns flatbuffers.Offset
+ */
+static createVectorOfStrongReferrablesVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
+  builder.startVector(4, data.length, 4);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addOffset(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startVectorOfStrongReferrablesVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(4, numElems, 4);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Long coOwningReference
+ */
+static addCoOwningReference(builder:flatbuffers.Builder, coOwningReference:flatbuffers.Long) {
+  builder.addFieldInt64(39, coOwningReference, builder.createLong(0, 0));
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset vectorOfCoOwningReferencesOffset
+ */
+static addVectorOfCoOwningReferences(builder:flatbuffers.Builder, vectorOfCoOwningReferencesOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(40, vectorOfCoOwningReferencesOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<flatbuffers.Long> data
+ * @returns flatbuffers.Offset
+ */
+static createVectorOfCoOwningReferencesVector(builder:flatbuffers.Builder, data:flatbuffers.Long[]):flatbuffers.Offset {
+  builder.startVector(8, data.length, 8);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt64(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startVectorOfCoOwningReferencesVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(8, numElems, 8);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Long nonOwningReference
+ */
+static addNonOwningReference(builder:flatbuffers.Builder, nonOwningReference:flatbuffers.Long) {
+  builder.addFieldInt64(41, nonOwningReference, builder.createLong(0, 0));
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset vectorOfNonOwningReferencesOffset
+ */
+static addVectorOfNonOwningReferences(builder:flatbuffers.Builder, vectorOfNonOwningReferencesOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(42, vectorOfNonOwningReferencesOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<flatbuffers.Long> data
+ * @returns flatbuffers.Offset
+ */
+static createVectorOfNonOwningReferencesVector(builder:flatbuffers.Builder, data:flatbuffers.Long[]):flatbuffers.Offset {
+  builder.startVector(8, data.length, 8);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt64(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startVectorOfNonOwningReferencesVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(8, numElems, 8);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param MyGame.Example.AnyUniqueAliases anyUniqueType
+ */
+static addAnyUniqueType(builder:flatbuffers.Builder, anyUniqueType:MyGame.Example.AnyUniqueAliases) {
+  builder.addFieldInt8(43, anyUniqueType, MyGame.Example.AnyUniqueAliases.NONE);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset anyUniqueOffset
+ */
+static addAnyUnique(builder:flatbuffers.Builder, anyUniqueOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(44, anyUniqueOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param MyGame.Example.AnyAmbiguousAliases anyAmbiguousType
+ */
+static addAnyAmbiguousType(builder:flatbuffers.Builder, anyAmbiguousType:MyGame.Example.AnyAmbiguousAliases) {
+  builder.addFieldInt8(45, anyAmbiguousType, MyGame.Example.AnyAmbiguousAliases.NONE);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset anyAmbiguousOffset
+ */
+static addAnyAmbiguous(builder:flatbuffers.Builder, anyAmbiguousOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(46, anyAmbiguousOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset vectorOfEnumsOffset
+ */
+static addVectorOfEnums(builder:flatbuffers.Builder, vectorOfEnumsOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(47, vectorOfEnumsOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<MyGame.Example.Color> data
+ * @returns flatbuffers.Offset
+ */
+static createVectorOfEnumsVector(builder:flatbuffers.Builder, data:MyGame.Example.Color[]):flatbuffers.Offset {
+  builder.startVector(1, data.length, 1);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt8(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startVectorOfEnumsVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(1, numElems, 1);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @returns flatbuffers.Offset
+ */
+static endMonster(builder:flatbuffers.Builder):flatbuffers.Offset {
+  var offset = builder.endObject();
+  builder.requiredField(offset, 10); // name
+  return offset;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset offset
+ */
+static finishMonsterBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {
+  builder.finish(offset, 'MONS');
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset offset
+ */
+static finishSizePrefixedMonsterBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {
+  builder.finish(offset, 'MONS', true);
+};
+
+static createMonster(builder:flatbuffers.Builder, posOffset:flatbuffers.Offset, mana:number, hp:number, nameOffset:flatbuffers.Offset, inventoryOffset:flatbuffers.Offset, color:MyGame.Example.Color, testType:MyGame.Example.Any, testOffset:flatbuffers.Offset, test4Offset:flatbuffers.Offset, testarrayofstringOffset:flatbuffers.Offset, testarrayoftablesOffset:flatbuffers.Offset, enemyOffset:flatbuffers.Offset, testnestedflatbufferOffset:flatbuffers.Offset, testemptyOffset:flatbuffers.Offset, testbool:boolean, testhashs32Fnv1:number, testhashu32Fnv1:number, testhashs64Fnv1:flatbuffers.Long, testhashu64Fnv1:flatbuffers.Long, testhashs32Fnv1a:number, testhashu32Fnv1a:number, testhashs64Fnv1a:flatbuffers.Long, testhashu64Fnv1a:flatbuffers.Long, testarrayofboolsOffset:flatbuffers.Offset, testf:number, testf2:number, testf3:number, testarrayofstring2Offset:flatbuffers.Offset, testarrayofsortedstructOffset:flatbuffers.Offset, flexOffset:flatbuffers.Offset, test5Offset:flatbuffers.Offset, vectorOfLongsOffset:flatbuffers.Offset, vectorOfDoublesOffset:flatbuffers.Offset, parentNamespaceTestOffset:flatbuffers.Offset, vectorOfReferrablesOffset:flatbuffers.Offset, singleWeakReference:flatbuffers.Long, vectorOfWeakReferencesOffset:flatbuffers.Offset, vectorOfStrongReferrablesOffset:flatbuffers.Offset, coOwningReference:flatbuffers.Long, vectorOfCoOwningReferencesOffset:flatbuffers.Offset, nonOwningReference:flatbuffers.Long, vectorOfNonOwningReferencesOffset:flatbuffers.Offset, anyUniqueType:MyGame.Example.AnyUniqueAliases, anyUniqueOffset:flatbuffers.Offset, anyAmbiguousType:MyGame.Example.AnyAmbiguousAliases, anyAmbiguousOffset:flatbuffers.Offset, vectorOfEnumsOffset:flatbuffers.Offset):flatbuffers.Offset {
+  Monster.startMonster(builder);
+  Monster.addPos(builder, posOffset);
+  Monster.addMana(builder, mana);
+  Monster.addHp(builder, hp);
+  Monster.addName(builder, nameOffset);
+  Monster.addInventory(builder, inventoryOffset);
+  Monster.addColor(builder, color);
+  Monster.addTestType(builder, testType);
+  Monster.addTest(builder, testOffset);
+  Monster.addTest4(builder, test4Offset);
+  Monster.addTestarrayofstring(builder, testarrayofstringOffset);
+  Monster.addTestarrayoftables(builder, testarrayoftablesOffset);
+  Monster.addEnemy(builder, enemyOffset);
+  Monster.addTestnestedflatbuffer(builder, testnestedflatbufferOffset);
+  Monster.addTestempty(builder, testemptyOffset);
+  Monster.addTestbool(builder, testbool);
+  Monster.addTesthashs32Fnv1(builder, testhashs32Fnv1);
+  Monster.addTesthashu32Fnv1(builder, testhashu32Fnv1);
+  Monster.addTesthashs64Fnv1(builder, testhashs64Fnv1);
+  Monster.addTesthashu64Fnv1(builder, testhashu64Fnv1);
+  Monster.addTesthashs32Fnv1a(builder, testhashs32Fnv1a);
+  Monster.addTesthashu32Fnv1a(builder, testhashu32Fnv1a);
+  Monster.addTesthashs64Fnv1a(builder, testhashs64Fnv1a);
+  Monster.addTesthashu64Fnv1a(builder, testhashu64Fnv1a);
+  Monster.addTestarrayofbools(builder, testarrayofboolsOffset);
+  Monster.addTestf(builder, testf);
+  Monster.addTestf2(builder, testf2);
+  Monster.addTestf3(builder, testf3);
+  Monster.addTestarrayofstring2(builder, testarrayofstring2Offset);
+  Monster.addTestarrayofsortedstruct(builder, testarrayofsortedstructOffset);
+  Monster.addFlex(builder, flexOffset);
+  Monster.addTest5(builder, test5Offset);
+  Monster.addVectorOfLongs(builder, vectorOfLongsOffset);
+  Monster.addVectorOfDoubles(builder, vectorOfDoublesOffset);
+  Monster.addParentNamespaceTest(builder, parentNamespaceTestOffset);
+  Monster.addVectorOfReferrables(builder, vectorOfReferrablesOffset);
+  Monster.addSingleWeakReference(builder, singleWeakReference);
+  Monster.addVectorOfWeakReferences(builder, vectorOfWeakReferencesOffset);
+  Monster.addVectorOfStrongReferrables(builder, vectorOfStrongReferrablesOffset);
+  Monster.addCoOwningReference(builder, coOwningReference);
+  Monster.addVectorOfCoOwningReferences(builder, vectorOfCoOwningReferencesOffset);
+  Monster.addNonOwningReference(builder, nonOwningReference);
+  Monster.addVectorOfNonOwningReferences(builder, vectorOfNonOwningReferencesOffset);
+  Monster.addAnyUniqueType(builder, anyUniqueType);
+  Monster.addAnyUnique(builder, anyUniqueOffset);
+  Monster.addAnyAmbiguousType(builder, anyAmbiguousType);
+  Monster.addAnyAmbiguous(builder, anyAmbiguousOffset);
+  Monster.addVectorOfEnums(builder, vectorOfEnumsOffset);
+  return Monster.endMonster(builder);
+}
+}
+}
+/**
+ * @constructor
+ */
+export namespace MyGame.Example{
+export class TypeAliases {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns TypeAliases
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):TypeAliases {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param TypeAliases= obj
+ * @returns TypeAliases
+ */
+static getRootAsTypeAliases(bb:flatbuffers.ByteBuffer, obj?:TypeAliases):TypeAliases {
+  return (obj || new TypeAliases).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param TypeAliases= obj
+ * @returns TypeAliases
+ */
+static getSizePrefixedRootAsTypeAliases(bb:flatbuffers.ByteBuffer, obj?:TypeAliases):TypeAliases {
+  return (obj || new TypeAliases).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @returns number
+ */
+i8():number {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+  return offset ? this.bb!.readInt8(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_i8(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+u8():number {
+  var offset = this.bb!.__offset(this.bb_pos, 6);
+  return offset ? this.bb!.readUint8(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_u8(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 6);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+i16():number {
+  var offset = this.bb!.__offset(this.bb_pos, 8);
+  return offset ? this.bb!.readInt16(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_i16(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 8);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt16(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+u16():number {
+  var offset = this.bb!.__offset(this.bb_pos, 10);
+  return offset ? this.bb!.readUint16(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_u16(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 10);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint16(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+i32():number {
+  var offset = this.bb!.__offset(this.bb_pos, 12);
+  return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_i32(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 12);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+u32():number {
+  var offset = this.bb!.__offset(this.bb_pos, 14);
+  return offset ? this.bb!.readUint32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_u32(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 14);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns flatbuffers.Long
+ */
+i64():flatbuffers.Long {
+  var offset = this.bb!.__offset(this.bb_pos, 16);
+  return offset ? this.bb!.readInt64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
+};
+
+/**
+ * @param flatbuffers.Long value
+ * @returns boolean
+ */
+mutate_i64(value:flatbuffers.Long):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 16);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns flatbuffers.Long
+ */
+u64():flatbuffers.Long {
+  var offset = this.bb!.__offset(this.bb_pos, 18);
+  return offset ? this.bb!.readUint64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
+};
+
+/**
+ * @param flatbuffers.Long value
+ * @returns boolean
+ */
+mutate_u64(value:flatbuffers.Long):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 18);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+f32():number {
+  var offset = this.bb!.__offset(this.bb_pos, 20);
+  return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_f32(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 20);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeFloat32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+f64():number {
+  var offset = this.bb!.__offset(this.bb_pos, 22);
+  return offset ? this.bb!.readFloat64(this.bb_pos + offset) : 0.0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_f64(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 22);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeFloat64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param number index
+ * @returns number
+ */
+v8(index: number):number|null {
+  var offset = this.bb!.__offset(this.bb_pos, 24);
+  return offset ? this.bb!.readInt8(this.bb!.__vector(this.bb_pos + offset) + index) : 0;
+};
+
+/**
+ * @returns number
+ */
+v8Length():number {
+  var offset = this.bb!.__offset(this.bb_pos, 24);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns Int8Array
+ */
+v8Array():Int8Array|null {
+  var offset = this.bb!.__offset(this.bb_pos, 24);
+  return offset ? new Int8Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @param number index
+ * @returns number
+ */
+vf64(index: number):number|null {
+  var offset = this.bb!.__offset(this.bb_pos, 26);
+  return offset ? this.bb!.readFloat64(this.bb!.__vector(this.bb_pos + offset) + index * 8) : 0;
+};
+
+/**
+ * @returns number
+ */
+vf64Length():number {
+  var offset = this.bb!.__offset(this.bb_pos, 26);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns Float64Array
+ */
+vf64Array():Float64Array|null {
+  var offset = this.bb!.__offset(this.bb_pos, 26);
+  return offset ? new Float64Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ */
+static startTypeAliases(builder:flatbuffers.Builder) {
+  builder.startObject(12);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number i8
+ */
+static addI8(builder:flatbuffers.Builder, i8:number) {
+  builder.addFieldInt8(0, i8, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number u8
+ */
+static addU8(builder:flatbuffers.Builder, u8:number) {
+  builder.addFieldInt8(1, u8, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number i16
+ */
+static addI16(builder:flatbuffers.Builder, i16:number) {
+  builder.addFieldInt16(2, i16, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number u16
+ */
+static addU16(builder:flatbuffers.Builder, u16:number) {
+  builder.addFieldInt16(3, u16, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number i32
+ */
+static addI32(builder:flatbuffers.Builder, i32:number) {
+  builder.addFieldInt32(4, i32, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number u32
+ */
+static addU32(builder:flatbuffers.Builder, u32:number) {
+  builder.addFieldInt32(5, u32, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Long i64
+ */
+static addI64(builder:flatbuffers.Builder, i64:flatbuffers.Long) {
+  builder.addFieldInt64(6, i64, builder.createLong(0, 0));
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Long u64
+ */
+static addU64(builder:flatbuffers.Builder, u64:flatbuffers.Long) {
+  builder.addFieldInt64(7, u64, builder.createLong(0, 0));
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number f32
+ */
+static addF32(builder:flatbuffers.Builder, f32:number) {
+  builder.addFieldFloat32(8, f32, 0.0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number f64
+ */
+static addF64(builder:flatbuffers.Builder, f64:number) {
+  builder.addFieldFloat64(9, f64, 0.0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset v8Offset
+ */
+static addV8(builder:flatbuffers.Builder, v8Offset:flatbuffers.Offset) {
+  builder.addFieldOffset(10, v8Offset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<number> data
+ * @returns flatbuffers.Offset
+ */
+static createV8Vector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset {
+  builder.startVector(1, data.length, 1);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt8(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startV8Vector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(1, numElems, 1);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset vf64Offset
+ */
+static addVf64(builder:flatbuffers.Builder, vf64Offset:flatbuffers.Offset) {
+  builder.addFieldOffset(11, vf64Offset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<number> data
+ * @returns flatbuffers.Offset
+ */
+static createVf64Vector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset {
+  builder.startVector(8, data.length, 8);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addFloat64(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startVf64Vector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(8, numElems, 8);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @returns flatbuffers.Offset
+ */
+static endTypeAliases(builder:flatbuffers.Builder):flatbuffers.Offset {
+  var offset = builder.endObject();
+  return offset;
+};
+
+static createTypeAliases(builder:flatbuffers.Builder, i8:number, u8:number, i16:number, u16:number, i32:number, u32:number, i64:flatbuffers.Long, u64:flatbuffers.Long, f32:number, f64:number, v8Offset:flatbuffers.Offset, vf64Offset:flatbuffers.Offset):flatbuffers.Offset {
+  TypeAliases.startTypeAliases(builder);
+  TypeAliases.addI8(builder, i8);
+  TypeAliases.addU8(builder, u8);
+  TypeAliases.addI16(builder, i16);
+  TypeAliases.addU16(builder, u16);
+  TypeAliases.addI32(builder, i32);
+  TypeAliases.addU32(builder, u32);
+  TypeAliases.addI64(builder, i64);
+  TypeAliases.addU64(builder, u64);
+  TypeAliases.addF32(builder, f32);
+  TypeAliases.addF64(builder, f64);
+  TypeAliases.addV8(builder, v8Offset);
+  TypeAliases.addVf64(builder, vf64Offset);
+  return TypeAliases.endTypeAliases(builder);
+}
+}
+}
diff --git a/tests/monster_test_my_game.example2_generated.dart b/tests/monster_test_my_game.example2_generated.dart
new file mode 100644
index 0000000..eed14bc
--- /dev/null
+++ b/tests/monster_test_my_game.example2_generated.dart
@@ -0,0 +1,60 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+// ignore_for_file: unused_import, unused_field, unused_local_variable
+
+library my_game.example2;
+
+import 'dart:typed_data' show Uint8List;
+import 'package:flat_buffers/flat_buffers.dart' as fb;
+
+import './monster_test_my_game_generated.dart' as my_game;
+import './monster_test_my_game.example_generated.dart' as my_game_example;
+
+class Monster {
+  Monster._(this._bc, this._bcOffset);
+  factory Monster(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<Monster> reader = const _MonsterReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+
+  @override
+  String toString() {
+    return 'Monster{}';
+  }
+}
+
+class _MonsterReader extends fb.TableReader<Monster> {
+  const _MonsterReader();
+
+  @override
+  Monster createObject(fb.BufferContext bc, int offset) => 
+    new Monster._(bc, offset);
+}
+
+class MonsterObjectBuilder extends fb.ObjectBuilder {
+
+  MonsterObjectBuilder();
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+
+    fbBuilder.startTable();
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
diff --git a/tests/monster_test_my_game.example_generated.dart b/tests/monster_test_my_game.example_generated.dart
new file mode 100644
index 0000000..13b7f4a
--- /dev/null
+++ b/tests/monster_test_my_game.example_generated.dart
@@ -0,0 +1,1490 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+// ignore_for_file: unused_import, unused_field, unused_local_variable
+
+library my_game.example;
+
+import 'dart:typed_data' show Uint8List;
+import 'package:flat_buffers/flat_buffers.dart' as fb;
+
+import './monster_test_my_game_generated.dart' as my_game;
+import './monster_test_my_game.example2_generated.dart' as my_game_example2;
+
+///  Composite components of Monster color.
+class Color {
+  final int value;
+  const Color._(this.value);
+
+  factory Color.fromValue(int value) {
+    if (value == null) value = 0;
+    if (!values.containsKey(value)) {
+      throw new StateError('Invalid value $value for bit flag enum Color');
+    }
+    return values[value];
+  }
+
+  static bool containsValue(int value) => values.containsKey(value);
+
+  static const Color Red = const Color._(1);
+
+  ///  \brief color Green
+  ///  Green is bit_flag with value (1u << 1)
+  static const Color Green = const Color._(2);
+
+  ///  \brief color Blue (1u << 3)
+  static const Color Blue = const Color._(8);
+  static get values => {1: Red,2: Green,8: Blue,};
+
+  static const fb.Reader<Color> reader = const _ColorReader();
+
+  @override
+  String toString() {
+    return 'Color{value: $value}';
+  }
+}
+
+class _ColorReader extends fb.Reader<Color> {
+  const _ColorReader();
+
+  @override
+  int get size => 1;
+
+  @override
+  Color read(fb.BufferContext bc, int offset) =>
+      new Color.fromValue(const fb.Uint8Reader().read(bc, offset));
+}
+
+class AnyTypeId {
+  final int value;
+  const AnyTypeId._(this.value);
+
+  factory AnyTypeId.fromValue(int value) {
+    if (value == null) value = 0;
+    if (!values.containsKey(value)) {
+      throw new StateError('Invalid value $value for bit flag enum AnyTypeId');
+    }
+    return values[value];
+  }
+
+  static const int minValue = 0;
+  static const int maxValue = 3;
+  static bool containsValue(int value) => values.containsKey(value);
+
+  static const AnyTypeId NONE = const AnyTypeId._(0);
+  static const AnyTypeId Monster = const AnyTypeId._(1);
+  static const AnyTypeId TestSimpleTableWithEnum = const AnyTypeId._(2);
+  static const AnyTypeId MyGame_Example2_Monster = const AnyTypeId._(3);
+  static get values => {0: NONE,1: Monster,2: TestSimpleTableWithEnum,3: MyGame_Example2_Monster,};
+
+  static const fb.Reader<AnyTypeId> reader = const _AnyTypeIdReader();
+
+  @override
+  String toString() {
+    return 'AnyTypeId{value: $value}';
+  }
+}
+
+class _AnyTypeIdReader extends fb.Reader<AnyTypeId> {
+  const _AnyTypeIdReader();
+
+  @override
+  int get size => 1;
+
+  @override
+  AnyTypeId read(fb.BufferContext bc, int offset) =>
+      new AnyTypeId.fromValue(const fb.Uint8Reader().read(bc, offset));
+}
+
+class AnyUniqueAliasesTypeId {
+  final int value;
+  const AnyUniqueAliasesTypeId._(this.value);
+
+  factory AnyUniqueAliasesTypeId.fromValue(int value) {
+    if (value == null) value = 0;
+    if (!values.containsKey(value)) {
+      throw new StateError('Invalid value $value for bit flag enum AnyUniqueAliasesTypeId');
+    }
+    return values[value];
+  }
+
+  static const int minValue = 0;
+  static const int maxValue = 3;
+  static bool containsValue(int value) => values.containsKey(value);
+
+  static const AnyUniqueAliasesTypeId NONE = const AnyUniqueAliasesTypeId._(0);
+  static const AnyUniqueAliasesTypeId M = const AnyUniqueAliasesTypeId._(1);
+  static const AnyUniqueAliasesTypeId TS = const AnyUniqueAliasesTypeId._(2);
+  static const AnyUniqueAliasesTypeId M2 = const AnyUniqueAliasesTypeId._(3);
+  static get values => {0: NONE,1: M,2: TS,3: M2,};
+
+  static const fb.Reader<AnyUniqueAliasesTypeId> reader = const _AnyUniqueAliasesTypeIdReader();
+
+  @override
+  String toString() {
+    return 'AnyUniqueAliasesTypeId{value: $value}';
+  }
+}
+
+class _AnyUniqueAliasesTypeIdReader extends fb.Reader<AnyUniqueAliasesTypeId> {
+  const _AnyUniqueAliasesTypeIdReader();
+
+  @override
+  int get size => 1;
+
+  @override
+  AnyUniqueAliasesTypeId read(fb.BufferContext bc, int offset) =>
+      new AnyUniqueAliasesTypeId.fromValue(const fb.Uint8Reader().read(bc, offset));
+}
+
+class AnyAmbiguousAliasesTypeId {
+  final int value;
+  const AnyAmbiguousAliasesTypeId._(this.value);
+
+  factory AnyAmbiguousAliasesTypeId.fromValue(int value) {
+    if (value == null) value = 0;
+    if (!values.containsKey(value)) {
+      throw new StateError('Invalid value $value for bit flag enum AnyAmbiguousAliasesTypeId');
+    }
+    return values[value];
+  }
+
+  static const int minValue = 0;
+  static const int maxValue = 3;
+  static bool containsValue(int value) => values.containsKey(value);
+
+  static const AnyAmbiguousAliasesTypeId NONE = const AnyAmbiguousAliasesTypeId._(0);
+  static const AnyAmbiguousAliasesTypeId M1 = const AnyAmbiguousAliasesTypeId._(1);
+  static const AnyAmbiguousAliasesTypeId M2 = const AnyAmbiguousAliasesTypeId._(2);
+  static const AnyAmbiguousAliasesTypeId M3 = const AnyAmbiguousAliasesTypeId._(3);
+  static get values => {0: NONE,1: M1,2: M2,3: M3,};
+
+  static const fb.Reader<AnyAmbiguousAliasesTypeId> reader = const _AnyAmbiguousAliasesTypeIdReader();
+
+  @override
+  String toString() {
+    return 'AnyAmbiguousAliasesTypeId{value: $value}';
+  }
+}
+
+class _AnyAmbiguousAliasesTypeIdReader extends fb.Reader<AnyAmbiguousAliasesTypeId> {
+  const _AnyAmbiguousAliasesTypeIdReader();
+
+  @override
+  int get size => 1;
+
+  @override
+  AnyAmbiguousAliasesTypeId read(fb.BufferContext bc, int offset) =>
+      new AnyAmbiguousAliasesTypeId.fromValue(const fb.Uint8Reader().read(bc, offset));
+}
+
+class Test {
+  Test._(this._bc, this._bcOffset);
+
+  static const fb.Reader<Test> reader = const _TestReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  int get a => const fb.Int16Reader().read(_bc, _bcOffset + 0);
+  int get b => const fb.Int8Reader().read(_bc, _bcOffset + 2);
+
+  @override
+  String toString() {
+    return 'Test{a: $a, b: $b}';
+  }
+}
+
+class _TestReader extends fb.StructReader<Test> {
+  const _TestReader();
+
+  @override
+  int get size => 4;
+
+  @override
+  Test createObject(fb.BufferContext bc, int offset) => 
+    new Test._(bc, offset);
+}
+
+class TestBuilder {
+  TestBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  int finish(int a, int b) {
+    fbBuilder.pad(1);
+    fbBuilder.putInt8(b);
+    fbBuilder.putInt16(a);
+    return fbBuilder.offset;
+  }
+
+}
+
+class TestObjectBuilder extends fb.ObjectBuilder {
+  final int _a;
+  final int _b;
+
+  TestObjectBuilder({
+    int a,
+    int b,
+  })
+      : _a = a,
+        _b = b;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+
+    fbBuilder.pad(1);
+    fbBuilder.putInt8(_b);
+    fbBuilder.putInt16(_a);
+    return fbBuilder.offset;
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
+class TestSimpleTableWithEnum {
+  TestSimpleTableWithEnum._(this._bc, this._bcOffset);
+  factory TestSimpleTableWithEnum(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<TestSimpleTableWithEnum> reader = const _TestSimpleTableWithEnumReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  Color get color => new Color.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 4, 2));
+
+  @override
+  String toString() {
+    return 'TestSimpleTableWithEnum{color: $color}';
+  }
+}
+
+class _TestSimpleTableWithEnumReader extends fb.TableReader<TestSimpleTableWithEnum> {
+  const _TestSimpleTableWithEnumReader();
+
+  @override
+  TestSimpleTableWithEnum createObject(fb.BufferContext bc, int offset) => 
+    new TestSimpleTableWithEnum._(bc, offset);
+}
+
+class TestSimpleTableWithEnumBuilder {
+  TestSimpleTableWithEnumBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  void begin() {
+    fbBuilder.startTable();
+  }
+
+  int addColor(Color color) {
+    fbBuilder.addUint8(0, color?.value);
+    return fbBuilder.offset;
+  }
+
+  int finish() {
+    return fbBuilder.endTable();
+  }
+}
+
+class TestSimpleTableWithEnumObjectBuilder extends fb.ObjectBuilder {
+  final Color _color;
+
+  TestSimpleTableWithEnumObjectBuilder({
+    Color color,
+  })
+      : _color = color;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+
+    fbBuilder.startTable();
+    fbBuilder.addUint8(0, _color?.value);
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
+class Vec3 {
+  Vec3._(this._bc, this._bcOffset);
+
+  static const fb.Reader<Vec3> reader = const _Vec3Reader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  double get x => const fb.Float32Reader().read(_bc, _bcOffset + 0);
+  double get y => const fb.Float32Reader().read(_bc, _bcOffset + 4);
+  double get z => const fb.Float32Reader().read(_bc, _bcOffset + 8);
+  double get test1 => const fb.Float64Reader().read(_bc, _bcOffset + 16);
+  Color get test2 => new Color.fromValue(const fb.Uint8Reader().read(_bc, _bcOffset + 24));
+  Test get test3 => Test.reader.read(_bc, _bcOffset + 26);
+
+  @override
+  String toString() {
+    return 'Vec3{x: $x, y: $y, z: $z, test1: $test1, test2: $test2, test3: $test3}';
+  }
+}
+
+class _Vec3Reader extends fb.StructReader<Vec3> {
+  const _Vec3Reader();
+
+  @override
+  int get size => 32;
+
+  @override
+  Vec3 createObject(fb.BufferContext bc, int offset) => 
+    new Vec3._(bc, offset);
+}
+
+class Vec3Builder {
+  Vec3Builder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  int finish(double x, double y, double z, double test1, Color test2, fb.StructBuilder test3) {
+    fbBuilder.pad(2);
+    test3();
+    fbBuilder.pad(1);
+    fbBuilder.putUint8(test2?.value);
+    fbBuilder.putFloat64(test1);
+    fbBuilder.pad(4);
+    fbBuilder.putFloat32(z);
+    fbBuilder.putFloat32(y);
+    fbBuilder.putFloat32(x);
+    return fbBuilder.offset;
+  }
+
+}
+
+class Vec3ObjectBuilder extends fb.ObjectBuilder {
+  final double _x;
+  final double _y;
+  final double _z;
+  final double _test1;
+  final Color _test2;
+  final TestObjectBuilder _test3;
+
+  Vec3ObjectBuilder({
+    double x,
+    double y,
+    double z,
+    double test1,
+    Color test2,
+    TestObjectBuilder test3,
+  })
+      : _x = x,
+        _y = y,
+        _z = z,
+        _test1 = test1,
+        _test2 = test2,
+        _test3 = test3;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+
+    fbBuilder.pad(2);
+    _test3.finish(fbBuilder);
+    fbBuilder.pad(1);
+    fbBuilder.putUint8(_test2?.value);
+    fbBuilder.putFloat64(_test1);
+    fbBuilder.pad(4);
+    fbBuilder.putFloat32(_z);
+    fbBuilder.putFloat32(_y);
+    fbBuilder.putFloat32(_x);
+    return fbBuilder.offset;
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
+class Ability {
+  Ability._(this._bc, this._bcOffset);
+
+  static const fb.Reader<Ability> reader = const _AbilityReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  int get id => const fb.Uint32Reader().read(_bc, _bcOffset + 0);
+  int get distance => const fb.Uint32Reader().read(_bc, _bcOffset + 4);
+
+  @override
+  String toString() {
+    return 'Ability{id: $id, distance: $distance}';
+  }
+}
+
+class _AbilityReader extends fb.StructReader<Ability> {
+  const _AbilityReader();
+
+  @override
+  int get size => 8;
+
+  @override
+  Ability createObject(fb.BufferContext bc, int offset) => 
+    new Ability._(bc, offset);
+}
+
+class AbilityBuilder {
+  AbilityBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  int finish(int id, int distance) {
+    fbBuilder.putUint32(distance);
+    fbBuilder.putUint32(id);
+    return fbBuilder.offset;
+  }
+
+}
+
+class AbilityObjectBuilder extends fb.ObjectBuilder {
+  final int _id;
+  final int _distance;
+
+  AbilityObjectBuilder({
+    int id,
+    int distance,
+  })
+      : _id = id,
+        _distance = distance;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+
+    fbBuilder.putUint32(_distance);
+    fbBuilder.putUint32(_id);
+    return fbBuilder.offset;
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
+class Stat {
+  Stat._(this._bc, this._bcOffset);
+  factory Stat(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<Stat> reader = const _StatReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  String get id => const fb.StringReader().vTableGet(_bc, _bcOffset, 4, null);
+  int get val => const fb.Int64Reader().vTableGet(_bc, _bcOffset, 6, 0);
+  int get count => const fb.Uint16Reader().vTableGet(_bc, _bcOffset, 8, 0);
+
+  @override
+  String toString() {
+    return 'Stat{id: $id, val: $val, count: $count}';
+  }
+}
+
+class _StatReader extends fb.TableReader<Stat> {
+  const _StatReader();
+
+  @override
+  Stat createObject(fb.BufferContext bc, int offset) => 
+    new Stat._(bc, offset);
+}
+
+class StatBuilder {
+  StatBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  void begin() {
+    fbBuilder.startTable();
+  }
+
+  int addIdOffset(int offset) {
+    fbBuilder.addOffset(0, offset);
+    return fbBuilder.offset;
+  }
+  int addVal(int val) {
+    fbBuilder.addInt64(1, val);
+    return fbBuilder.offset;
+  }
+  int addCount(int count) {
+    fbBuilder.addUint16(2, count);
+    return fbBuilder.offset;
+  }
+
+  int finish() {
+    return fbBuilder.endTable();
+  }
+}
+
+class StatObjectBuilder extends fb.ObjectBuilder {
+  final String _id;
+  final int _val;
+  final int _count;
+
+  StatObjectBuilder({
+    String id,
+    int val,
+    int count,
+  })
+      : _id = id,
+        _val = val,
+        _count = count;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+    final int idOffset = fbBuilder.writeString(_id);
+
+    fbBuilder.startTable();
+    if (idOffset != null) {
+      fbBuilder.addOffset(0, idOffset);
+    }
+    fbBuilder.addInt64(1, _val);
+    fbBuilder.addUint16(2, _count);
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
+class Referrable {
+  Referrable._(this._bc, this._bcOffset);
+  factory Referrable(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<Referrable> reader = const _ReferrableReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  int get id => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 4, 0);
+
+  @override
+  String toString() {
+    return 'Referrable{id: $id}';
+  }
+}
+
+class _ReferrableReader extends fb.TableReader<Referrable> {
+  const _ReferrableReader();
+
+  @override
+  Referrable createObject(fb.BufferContext bc, int offset) => 
+    new Referrable._(bc, offset);
+}
+
+class ReferrableBuilder {
+  ReferrableBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  void begin() {
+    fbBuilder.startTable();
+  }
+
+  int addId(int id) {
+    fbBuilder.addUint64(0, id);
+    return fbBuilder.offset;
+  }
+
+  int finish() {
+    return fbBuilder.endTable();
+  }
+}
+
+class ReferrableObjectBuilder extends fb.ObjectBuilder {
+  final int _id;
+
+  ReferrableObjectBuilder({
+    int id,
+  })
+      : _id = id;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+
+    fbBuilder.startTable();
+    fbBuilder.addUint64(0, _id);
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
+///  an example documentation comment: monster object
+class Monster {
+  Monster._(this._bc, this._bcOffset);
+  factory Monster(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<Monster> reader = const _MonsterReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  Vec3 get pos => Vec3.reader.vTableGet(_bc, _bcOffset, 4, null);
+  int get mana => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 6, 150);
+  int get hp => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 8, 100);
+  String get name => const fb.StringReader().vTableGet(_bc, _bcOffset, 10, null);
+  List<int> get inventory => const fb.ListReader<int>(const fb.Uint8Reader()).vTableGet(_bc, _bcOffset, 14, null);
+  Color get color => new Color.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 16, 8));
+  AnyTypeId get testType => new AnyTypeId.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 18, 0));
+  dynamic get test {
+    switch (testType?.value) {
+      case 1: return Monster.reader.vTableGet(_bc, _bcOffset, 20, null);
+      case 2: return TestSimpleTableWithEnum.reader.vTableGet(_bc, _bcOffset, 20, null);
+      case 3: return my_game_example2.Monster.reader.vTableGet(_bc, _bcOffset, 20, null);
+      default: return null;
+    }
+  }
+  List<Test> get test4 => const fb.ListReader<Test>(Test.reader).vTableGet(_bc, _bcOffset, 22, null);
+  List<String> get testarrayofstring => const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bc, _bcOffset, 24, null);
+  ///  an example documentation comment: this will end up in the generated code
+  ///  multiline too
+  List<Monster> get testarrayoftables => const fb.ListReader<Monster>(Monster.reader).vTableGet(_bc, _bcOffset, 26, null);
+  Monster get enemy => Monster.reader.vTableGet(_bc, _bcOffset, 28, null);
+  List<int> get testnestedflatbuffer => const fb.ListReader<int>(const fb.Uint8Reader()).vTableGet(_bc, _bcOffset, 30, null);
+  Stat get testempty => Stat.reader.vTableGet(_bc, _bcOffset, 32, null);
+  bool get testbool => const fb.BoolReader().vTableGet(_bc, _bcOffset, 34, false);
+  int get testhashs32Fnv1 => const fb.Int32Reader().vTableGet(_bc, _bcOffset, 36, 0);
+  int get testhashu32Fnv1 => const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 38, 0);
+  int get testhashs64Fnv1 => const fb.Int64Reader().vTableGet(_bc, _bcOffset, 40, 0);
+  int get testhashu64Fnv1 => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 42, 0);
+  int get testhashs32Fnv1a => const fb.Int32Reader().vTableGet(_bc, _bcOffset, 44, 0);
+  int get testhashu32Fnv1a => const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 46, 0);
+  int get testhashs64Fnv1a => const fb.Int64Reader().vTableGet(_bc, _bcOffset, 48, 0);
+  int get testhashu64Fnv1a => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 50, 0);
+  List<bool> get testarrayofbools => const fb.ListReader<bool>(const fb.BoolReader()).vTableGet(_bc, _bcOffset, 52, null);
+  double get testf => const fb.Float32Reader().vTableGet(_bc, _bcOffset, 54, 3.14159);
+  double get testf2 => const fb.Float32Reader().vTableGet(_bc, _bcOffset, 56, 3.0);
+  double get testf3 => const fb.Float32Reader().vTableGet(_bc, _bcOffset, 58, 0.0);
+  List<String> get testarrayofstring2 => const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bc, _bcOffset, 60, null);
+  List<Ability> get testarrayofsortedstruct => const fb.ListReader<Ability>(Ability.reader).vTableGet(_bc, _bcOffset, 62, null);
+  List<int> get flex => const fb.ListReader<int>(const fb.Uint8Reader()).vTableGet(_bc, _bcOffset, 64, null);
+  List<Test> get test5 => const fb.ListReader<Test>(Test.reader).vTableGet(_bc, _bcOffset, 66, null);
+  List<int> get vectorOfLongs => const fb.ListReader<int>(const fb.Int64Reader()).vTableGet(_bc, _bcOffset, 68, null);
+  List<double> get vectorOfDoubles => const fb.ListReader<double>(const fb.Float64Reader()).vTableGet(_bc, _bcOffset, 70, null);
+  my_game.InParentNamespace get parentNamespaceTest => my_game.InParentNamespace.reader.vTableGet(_bc, _bcOffset, 72, null);
+  List<Referrable> get vectorOfReferrables => const fb.ListReader<Referrable>(Referrable.reader).vTableGet(_bc, _bcOffset, 74, null);
+  int get singleWeakReference => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 76, 0);
+  List<int> get vectorOfWeakReferences => const fb.ListReader<int>(const fb.Uint64Reader()).vTableGet(_bc, _bcOffset, 78, null);
+  List<Referrable> get vectorOfStrongReferrables => const fb.ListReader<Referrable>(Referrable.reader).vTableGet(_bc, _bcOffset, 80, null);
+  int get coOwningReference => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 82, 0);
+  List<int> get vectorOfCoOwningReferences => const fb.ListReader<int>(const fb.Uint64Reader()).vTableGet(_bc, _bcOffset, 84, null);
+  int get nonOwningReference => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 86, 0);
+  List<int> get vectorOfNonOwningReferences => const fb.ListReader<int>(const fb.Uint64Reader()).vTableGet(_bc, _bcOffset, 88, null);
+  AnyUniqueAliasesTypeId get anyUniqueType => new AnyUniqueAliasesTypeId.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 90, 0));
+  dynamic get anyUnique {
+    switch (anyUniqueType?.value) {
+      case 1: return M.reader.vTableGet(_bc, _bcOffset, 92, null);
+      case 2: return TS.reader.vTableGet(_bc, _bcOffset, 92, null);
+      case 3: return M2.reader.vTableGet(_bc, _bcOffset, 92, null);
+      default: return null;
+    }
+  }
+  AnyAmbiguousAliasesTypeId get anyAmbiguousType => new AnyAmbiguousAliasesTypeId.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 94, 0));
+  dynamic get anyAmbiguous {
+    switch (anyAmbiguousType?.value) {
+      case 1: return M1.reader.vTableGet(_bc, _bcOffset, 96, null);
+      case 2: return M2.reader.vTableGet(_bc, _bcOffset, 96, null);
+      case 3: return M3.reader.vTableGet(_bc, _bcOffset, 96, null);
+      default: return null;
+    }
+  }
+  List<Color> get vectorOfEnums => const fb.ListReader<Color>(Color.reader).vTableGet(_bc, _bcOffset, 98, null);
+
+  @override
+  String toString() {
+    return 'Monster{pos: $pos, mana: $mana, hp: $hp, name: $name, inventory: $inventory, color: $color, testType: $testType, test: $test, test4: $test4, testarrayofstring: $testarrayofstring, testarrayoftables: $testarrayoftables, enemy: $enemy, testnestedflatbuffer: $testnestedflatbuffer, testempty: $testempty, testbool: $testbool, testhashs32Fnv1: $testhashs32Fnv1, testhashu32Fnv1: $testhashu32Fnv1, testhashs64Fnv1: $testhashs64Fnv1, testhashu64Fnv1: $testhashu64Fnv1, testhashs32Fnv1a: $testhashs32Fnv1a, testhashu32Fnv1a: $testhashu32Fnv1a, testhashs64Fnv1a: $testhashs64Fnv1a, testhashu64Fnv1a: $testhashu64Fnv1a, testarrayofbools: $testarrayofbools, testf: $testf, testf2: $testf2, testf3: $testf3, testarrayofstring2: $testarrayofstring2, testarrayofsortedstruct: $testarrayofsortedstruct, flex: $flex, test5: $test5, vectorOfLongs: $vectorOfLongs, vectorOfDoubles: $vectorOfDoubles, parentNamespaceTest: $parentNamespaceTest, vectorOfReferrables: $vectorOfReferrables, singleWeakReference: $singleWeakReference, vectorOfWeakReferences: $vectorOfWeakReferences, vectorOfStrongReferrables: $vectorOfStrongReferrables, coOwningReference: $coOwningReference, vectorOfCoOwningReferences: $vectorOfCoOwningReferences, nonOwningReference: $nonOwningReference, vectorOfNonOwningReferences: $vectorOfNonOwningReferences, anyUniqueType: $anyUniqueType, anyUnique: $anyUnique, anyAmbiguousType: $anyAmbiguousType, anyAmbiguous: $anyAmbiguous, vectorOfEnums: $vectorOfEnums}';
+  }
+}
+
+class _MonsterReader extends fb.TableReader<Monster> {
+  const _MonsterReader();
+
+  @override
+  Monster createObject(fb.BufferContext bc, int offset) => 
+    new Monster._(bc, offset);
+}
+
+class MonsterBuilder {
+  MonsterBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  void begin() {
+    fbBuilder.startTable();
+  }
+
+  int addPos(int offset) {
+    fbBuilder.addStruct(0, offset);
+    return fbBuilder.offset;
+  }
+  int addMana(int mana) {
+    fbBuilder.addInt16(1, mana);
+    return fbBuilder.offset;
+  }
+  int addHp(int hp) {
+    fbBuilder.addInt16(2, hp);
+    return fbBuilder.offset;
+  }
+  int addNameOffset(int offset) {
+    fbBuilder.addOffset(3, offset);
+    return fbBuilder.offset;
+  }
+  int addInventoryOffset(int offset) {
+    fbBuilder.addOffset(5, offset);
+    return fbBuilder.offset;
+  }
+  int addColor(Color color) {
+    fbBuilder.addUint8(6, color?.value);
+    return fbBuilder.offset;
+  }
+  int addTestType(AnyTypeId testType) {
+    fbBuilder.addUint8(7, testType?.value);
+    return fbBuilder.offset;
+  }
+  int addTestOffset(int offset) {
+    fbBuilder.addOffset(8, offset);
+    return fbBuilder.offset;
+  }
+  int addTest4Offset(int offset) {
+    fbBuilder.addOffset(9, offset);
+    return fbBuilder.offset;
+  }
+  int addTestarrayofstringOffset(int offset) {
+    fbBuilder.addOffset(10, offset);
+    return fbBuilder.offset;
+  }
+  int addTestarrayoftablesOffset(int offset) {
+    fbBuilder.addOffset(11, offset);
+    return fbBuilder.offset;
+  }
+  int addEnemyOffset(int offset) {
+    fbBuilder.addOffset(12, offset);
+    return fbBuilder.offset;
+  }
+  int addTestnestedflatbufferOffset(int offset) {
+    fbBuilder.addOffset(13, offset);
+    return fbBuilder.offset;
+  }
+  int addTestemptyOffset(int offset) {
+    fbBuilder.addOffset(14, offset);
+    return fbBuilder.offset;
+  }
+  int addTestbool(bool testbool) {
+    fbBuilder.addBool(15, testbool);
+    return fbBuilder.offset;
+  }
+  int addTesthashs32Fnv1(int testhashs32Fnv1) {
+    fbBuilder.addInt32(16, testhashs32Fnv1);
+    return fbBuilder.offset;
+  }
+  int addTesthashu32Fnv1(int testhashu32Fnv1) {
+    fbBuilder.addUint32(17, testhashu32Fnv1);
+    return fbBuilder.offset;
+  }
+  int addTesthashs64Fnv1(int testhashs64Fnv1) {
+    fbBuilder.addInt64(18, testhashs64Fnv1);
+    return fbBuilder.offset;
+  }
+  int addTesthashu64Fnv1(int testhashu64Fnv1) {
+    fbBuilder.addUint64(19, testhashu64Fnv1);
+    return fbBuilder.offset;
+  }
+  int addTesthashs32Fnv1a(int testhashs32Fnv1a) {
+    fbBuilder.addInt32(20, testhashs32Fnv1a);
+    return fbBuilder.offset;
+  }
+  int addTesthashu32Fnv1a(int testhashu32Fnv1a) {
+    fbBuilder.addUint32(21, testhashu32Fnv1a);
+    return fbBuilder.offset;
+  }
+  int addTesthashs64Fnv1a(int testhashs64Fnv1a) {
+    fbBuilder.addInt64(22, testhashs64Fnv1a);
+    return fbBuilder.offset;
+  }
+  int addTesthashu64Fnv1a(int testhashu64Fnv1a) {
+    fbBuilder.addUint64(23, testhashu64Fnv1a);
+    return fbBuilder.offset;
+  }
+  int addTestarrayofboolsOffset(int offset) {
+    fbBuilder.addOffset(24, offset);
+    return fbBuilder.offset;
+  }
+  int addTestf(double testf) {
+    fbBuilder.addFloat32(25, testf);
+    return fbBuilder.offset;
+  }
+  int addTestf2(double testf2) {
+    fbBuilder.addFloat32(26, testf2);
+    return fbBuilder.offset;
+  }
+  int addTestf3(double testf3) {
+    fbBuilder.addFloat32(27, testf3);
+    return fbBuilder.offset;
+  }
+  int addTestarrayofstring2Offset(int offset) {
+    fbBuilder.addOffset(28, offset);
+    return fbBuilder.offset;
+  }
+  int addTestarrayofsortedstructOffset(int offset) {
+    fbBuilder.addOffset(29, offset);
+    return fbBuilder.offset;
+  }
+  int addFlexOffset(int offset) {
+    fbBuilder.addOffset(30, offset);
+    return fbBuilder.offset;
+  }
+  int addTest5Offset(int offset) {
+    fbBuilder.addOffset(31, offset);
+    return fbBuilder.offset;
+  }
+  int addVectorOfLongsOffset(int offset) {
+    fbBuilder.addOffset(32, offset);
+    return fbBuilder.offset;
+  }
+  int addVectorOfDoublesOffset(int offset) {
+    fbBuilder.addOffset(33, offset);
+    return fbBuilder.offset;
+  }
+  int addParentNamespaceTestOffset(int offset) {
+    fbBuilder.addOffset(34, offset);
+    return fbBuilder.offset;
+  }
+  int addVectorOfReferrablesOffset(int offset) {
+    fbBuilder.addOffset(35, offset);
+    return fbBuilder.offset;
+  }
+  int addSingleWeakReference(int singleWeakReference) {
+    fbBuilder.addUint64(36, singleWeakReference);
+    return fbBuilder.offset;
+  }
+  int addVectorOfWeakReferencesOffset(int offset) {
+    fbBuilder.addOffset(37, offset);
+    return fbBuilder.offset;
+  }
+  int addVectorOfStrongReferrablesOffset(int offset) {
+    fbBuilder.addOffset(38, offset);
+    return fbBuilder.offset;
+  }
+  int addCoOwningReference(int coOwningReference) {
+    fbBuilder.addUint64(39, coOwningReference);
+    return fbBuilder.offset;
+  }
+  int addVectorOfCoOwningReferencesOffset(int offset) {
+    fbBuilder.addOffset(40, offset);
+    return fbBuilder.offset;
+  }
+  int addNonOwningReference(int nonOwningReference) {
+    fbBuilder.addUint64(41, nonOwningReference);
+    return fbBuilder.offset;
+  }
+  int addVectorOfNonOwningReferencesOffset(int offset) {
+    fbBuilder.addOffset(42, offset);
+    return fbBuilder.offset;
+  }
+  int addAnyUniqueType(AnyUniqueAliasesTypeId anyUniqueType) {
+    fbBuilder.addUint8(43, anyUniqueType?.value);
+    return fbBuilder.offset;
+  }
+  int addAnyUniqueOffset(int offset) {
+    fbBuilder.addOffset(44, offset);
+    return fbBuilder.offset;
+  }
+  int addAnyAmbiguousType(AnyAmbiguousAliasesTypeId anyAmbiguousType) {
+    fbBuilder.addUint8(45, anyAmbiguousType?.value);
+    return fbBuilder.offset;
+  }
+  int addAnyAmbiguousOffset(int offset) {
+    fbBuilder.addOffset(46, offset);
+    return fbBuilder.offset;
+  }
+  int addVectorOfEnumsOffset(int offset) {
+    fbBuilder.addOffset(47, offset);
+    return fbBuilder.offset;
+  }
+
+  int finish() {
+    return fbBuilder.endTable();
+  }
+}
+
+class MonsterObjectBuilder extends fb.ObjectBuilder {
+  final Vec3ObjectBuilder _pos;
+  final int _mana;
+  final int _hp;
+  final String _name;
+  final List<int> _inventory;
+  final Color _color;
+  final AnyTypeId _testType;
+  final dynamic _test;
+  final List<TestObjectBuilder> _test4;
+  final List<String> _testarrayofstring;
+  final List<MonsterObjectBuilder> _testarrayoftables;
+  final MonsterObjectBuilder _enemy;
+  final List<int> _testnestedflatbuffer;
+  final StatObjectBuilder _testempty;
+  final bool _testbool;
+  final int _testhashs32Fnv1;
+  final int _testhashu32Fnv1;
+  final int _testhashs64Fnv1;
+  final int _testhashu64Fnv1;
+  final int _testhashs32Fnv1a;
+  final int _testhashu32Fnv1a;
+  final int _testhashs64Fnv1a;
+  final int _testhashu64Fnv1a;
+  final List<bool> _testarrayofbools;
+  final double _testf;
+  final double _testf2;
+  final double _testf3;
+  final List<String> _testarrayofstring2;
+  final List<AbilityObjectBuilder> _testarrayofsortedstruct;
+  final List<int> _flex;
+  final List<TestObjectBuilder> _test5;
+  final List<int> _vectorOfLongs;
+  final List<double> _vectorOfDoubles;
+  final my_game.InParentNamespaceObjectBuilder _parentNamespaceTest;
+  final List<ReferrableObjectBuilder> _vectorOfReferrables;
+  final int _singleWeakReference;
+  final List<int> _vectorOfWeakReferences;
+  final List<ReferrableObjectBuilder> _vectorOfStrongReferrables;
+  final int _coOwningReference;
+  final List<int> _vectorOfCoOwningReferences;
+  final int _nonOwningReference;
+  final List<int> _vectorOfNonOwningReferences;
+  final AnyUniqueAliasesTypeId _anyUniqueType;
+  final dynamic _anyUnique;
+  final AnyAmbiguousAliasesTypeId _anyAmbiguousType;
+  final dynamic _anyAmbiguous;
+  final List<Color> _vectorOfEnums;
+
+  MonsterObjectBuilder({
+    Vec3ObjectBuilder pos,
+    int mana,
+    int hp,
+    String name,
+    List<int> inventory,
+    Color color,
+    AnyTypeId testType,
+    dynamic test,
+    List<TestObjectBuilder> test4,
+    List<String> testarrayofstring,
+    List<MonsterObjectBuilder> testarrayoftables,
+    MonsterObjectBuilder enemy,
+    List<int> testnestedflatbuffer,
+    StatObjectBuilder testempty,
+    bool testbool,
+    int testhashs32Fnv1,
+    int testhashu32Fnv1,
+    int testhashs64Fnv1,
+    int testhashu64Fnv1,
+    int testhashs32Fnv1a,
+    int testhashu32Fnv1a,
+    int testhashs64Fnv1a,
+    int testhashu64Fnv1a,
+    List<bool> testarrayofbools,
+    double testf,
+    double testf2,
+    double testf3,
+    List<String> testarrayofstring2,
+    List<AbilityObjectBuilder> testarrayofsortedstruct,
+    List<int> flex,
+    List<TestObjectBuilder> test5,
+    List<int> vectorOfLongs,
+    List<double> vectorOfDoubles,
+    my_game.InParentNamespaceObjectBuilder parentNamespaceTest,
+    List<ReferrableObjectBuilder> vectorOfReferrables,
+    int singleWeakReference,
+    List<int> vectorOfWeakReferences,
+    List<ReferrableObjectBuilder> vectorOfStrongReferrables,
+    int coOwningReference,
+    List<int> vectorOfCoOwningReferences,
+    int nonOwningReference,
+    List<int> vectorOfNonOwningReferences,
+    AnyUniqueAliasesTypeId anyUniqueType,
+    dynamic anyUnique,
+    AnyAmbiguousAliasesTypeId anyAmbiguousType,
+    dynamic anyAmbiguous,
+    List<Color> vectorOfEnums,
+  })
+      : _pos = pos,
+        _mana = mana,
+        _hp = hp,
+        _name = name,
+        _inventory = inventory,
+        _color = color,
+        _testType = testType,
+        _test = test,
+        _test4 = test4,
+        _testarrayofstring = testarrayofstring,
+        _testarrayoftables = testarrayoftables,
+        _enemy = enemy,
+        _testnestedflatbuffer = testnestedflatbuffer,
+        _testempty = testempty,
+        _testbool = testbool,
+        _testhashs32Fnv1 = testhashs32Fnv1,
+        _testhashu32Fnv1 = testhashu32Fnv1,
+        _testhashs64Fnv1 = testhashs64Fnv1,
+        _testhashu64Fnv1 = testhashu64Fnv1,
+        _testhashs32Fnv1a = testhashs32Fnv1a,
+        _testhashu32Fnv1a = testhashu32Fnv1a,
+        _testhashs64Fnv1a = testhashs64Fnv1a,
+        _testhashu64Fnv1a = testhashu64Fnv1a,
+        _testarrayofbools = testarrayofbools,
+        _testf = testf,
+        _testf2 = testf2,
+        _testf3 = testf3,
+        _testarrayofstring2 = testarrayofstring2,
+        _testarrayofsortedstruct = testarrayofsortedstruct,
+        _flex = flex,
+        _test5 = test5,
+        _vectorOfLongs = vectorOfLongs,
+        _vectorOfDoubles = vectorOfDoubles,
+        _parentNamespaceTest = parentNamespaceTest,
+        _vectorOfReferrables = vectorOfReferrables,
+        _singleWeakReference = singleWeakReference,
+        _vectorOfWeakReferences = vectorOfWeakReferences,
+        _vectorOfStrongReferrables = vectorOfStrongReferrables,
+        _coOwningReference = coOwningReference,
+        _vectorOfCoOwningReferences = vectorOfCoOwningReferences,
+        _nonOwningReference = nonOwningReference,
+        _vectorOfNonOwningReferences = vectorOfNonOwningReferences,
+        _anyUniqueType = anyUniqueType,
+        _anyUnique = anyUnique,
+        _anyAmbiguousType = anyAmbiguousType,
+        _anyAmbiguous = anyAmbiguous,
+        _vectorOfEnums = vectorOfEnums;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+    final int nameOffset = fbBuilder.writeString(_name);
+    final int inventoryOffset = _inventory?.isNotEmpty == true
+        ? fbBuilder.writeListUint8(_inventory)
+        : null;
+    final int testOffset = _test?.getOrCreateOffset(fbBuilder);
+    final int test4Offset = _test4?.isNotEmpty == true
+        ? fbBuilder.writeListOfStructs(_test4)
+        : null;
+    final int testarrayofstringOffset = _testarrayofstring?.isNotEmpty == true
+        ? fbBuilder.writeList(_testarrayofstring.map((b) => fbBuilder.writeString(b)).toList())
+        : null;
+    final int testarrayoftablesOffset = _testarrayoftables?.isNotEmpty == true
+        ? fbBuilder.writeList(_testarrayoftables.map((b) => b.getOrCreateOffset(fbBuilder)).toList())
+        : null;
+    final int enemyOffset = _enemy?.getOrCreateOffset(fbBuilder);
+    final int testnestedflatbufferOffset = _testnestedflatbuffer?.isNotEmpty == true
+        ? fbBuilder.writeListUint8(_testnestedflatbuffer)
+        : null;
+    final int testemptyOffset = _testempty?.getOrCreateOffset(fbBuilder);
+    final int testarrayofboolsOffset = _testarrayofbools?.isNotEmpty == true
+        ? fbBuilder.writeListBool(_testarrayofbools)
+        : null;
+    final int testarrayofstring2Offset = _testarrayofstring2?.isNotEmpty == true
+        ? fbBuilder.writeList(_testarrayofstring2.map((b) => fbBuilder.writeString(b)).toList())
+        : null;
+    final int testarrayofsortedstructOffset = _testarrayofsortedstruct?.isNotEmpty == true
+        ? fbBuilder.writeListOfStructs(_testarrayofsortedstruct)
+        : null;
+    final int flexOffset = _flex?.isNotEmpty == true
+        ? fbBuilder.writeListUint8(_flex)
+        : null;
+    final int test5Offset = _test5?.isNotEmpty == true
+        ? fbBuilder.writeListOfStructs(_test5)
+        : null;
+    final int vectorOfLongsOffset = _vectorOfLongs?.isNotEmpty == true
+        ? fbBuilder.writeListInt64(_vectorOfLongs)
+        : null;
+    final int vectorOfDoublesOffset = _vectorOfDoubles?.isNotEmpty == true
+        ? fbBuilder.writeListFloat64(_vectorOfDoubles)
+        : null;
+    final int parentNamespaceTestOffset = _parentNamespaceTest?.getOrCreateOffset(fbBuilder);
+    final int vectorOfReferrablesOffset = _vectorOfReferrables?.isNotEmpty == true
+        ? fbBuilder.writeList(_vectorOfReferrables.map((b) => b.getOrCreateOffset(fbBuilder)).toList())
+        : null;
+    final int vectorOfWeakReferencesOffset = _vectorOfWeakReferences?.isNotEmpty == true
+        ? fbBuilder.writeListUint64(_vectorOfWeakReferences)
+        : null;
+    final int vectorOfStrongReferrablesOffset = _vectorOfStrongReferrables?.isNotEmpty == true
+        ? fbBuilder.writeList(_vectorOfStrongReferrables.map((b) => b.getOrCreateOffset(fbBuilder)).toList())
+        : null;
+    final int vectorOfCoOwningReferencesOffset = _vectorOfCoOwningReferences?.isNotEmpty == true
+        ? fbBuilder.writeListUint64(_vectorOfCoOwningReferences)
+        : null;
+    final int vectorOfNonOwningReferencesOffset = _vectorOfNonOwningReferences?.isNotEmpty == true
+        ? fbBuilder.writeListUint64(_vectorOfNonOwningReferences)
+        : null;
+    final int anyUniqueOffset = _anyUnique?.getOrCreateOffset(fbBuilder);
+    final int anyAmbiguousOffset = _anyAmbiguous?.getOrCreateOffset(fbBuilder);
+    final int vectorOfEnumsOffset = _vectorOfEnums?.isNotEmpty == true
+        ? fbBuilder.writeListUint8(_vectorOfEnums.map((f) => f.value))
+        : null;
+
+    fbBuilder.startTable();
+    if (_pos != null) {
+      fbBuilder.addStruct(0, _pos.finish(fbBuilder));
+    }
+    fbBuilder.addInt16(1, _mana);
+    fbBuilder.addInt16(2, _hp);
+    if (nameOffset != null) {
+      fbBuilder.addOffset(3, nameOffset);
+    }
+    if (inventoryOffset != null) {
+      fbBuilder.addOffset(5, inventoryOffset);
+    }
+    fbBuilder.addUint8(6, _color?.value);
+    fbBuilder.addUint8(7, _testType?.value);
+    if (testOffset != null) {
+      fbBuilder.addOffset(8, testOffset);
+    }
+    if (test4Offset != null) {
+      fbBuilder.addOffset(9, test4Offset);
+    }
+    if (testarrayofstringOffset != null) {
+      fbBuilder.addOffset(10, testarrayofstringOffset);
+    }
+    if (testarrayoftablesOffset != null) {
+      fbBuilder.addOffset(11, testarrayoftablesOffset);
+    }
+    if (enemyOffset != null) {
+      fbBuilder.addOffset(12, enemyOffset);
+    }
+    if (testnestedflatbufferOffset != null) {
+      fbBuilder.addOffset(13, testnestedflatbufferOffset);
+    }
+    if (testemptyOffset != null) {
+      fbBuilder.addOffset(14, testemptyOffset);
+    }
+    fbBuilder.addBool(15, _testbool);
+    fbBuilder.addInt32(16, _testhashs32Fnv1);
+    fbBuilder.addUint32(17, _testhashu32Fnv1);
+    fbBuilder.addInt64(18, _testhashs64Fnv1);
+    fbBuilder.addUint64(19, _testhashu64Fnv1);
+    fbBuilder.addInt32(20, _testhashs32Fnv1a);
+    fbBuilder.addUint32(21, _testhashu32Fnv1a);
+    fbBuilder.addInt64(22, _testhashs64Fnv1a);
+    fbBuilder.addUint64(23, _testhashu64Fnv1a);
+    if (testarrayofboolsOffset != null) {
+      fbBuilder.addOffset(24, testarrayofboolsOffset);
+    }
+    fbBuilder.addFloat32(25, _testf);
+    fbBuilder.addFloat32(26, _testf2);
+    fbBuilder.addFloat32(27, _testf3);
+    if (testarrayofstring2Offset != null) {
+      fbBuilder.addOffset(28, testarrayofstring2Offset);
+    }
+    if (testarrayofsortedstructOffset != null) {
+      fbBuilder.addOffset(29, testarrayofsortedstructOffset);
+    }
+    if (flexOffset != null) {
+      fbBuilder.addOffset(30, flexOffset);
+    }
+    if (test5Offset != null) {
+      fbBuilder.addOffset(31, test5Offset);
+    }
+    if (vectorOfLongsOffset != null) {
+      fbBuilder.addOffset(32, vectorOfLongsOffset);
+    }
+    if (vectorOfDoublesOffset != null) {
+      fbBuilder.addOffset(33, vectorOfDoublesOffset);
+    }
+    if (parentNamespaceTestOffset != null) {
+      fbBuilder.addOffset(34, parentNamespaceTestOffset);
+    }
+    if (vectorOfReferrablesOffset != null) {
+      fbBuilder.addOffset(35, vectorOfReferrablesOffset);
+    }
+    fbBuilder.addUint64(36, _singleWeakReference);
+    if (vectorOfWeakReferencesOffset != null) {
+      fbBuilder.addOffset(37, vectorOfWeakReferencesOffset);
+    }
+    if (vectorOfStrongReferrablesOffset != null) {
+      fbBuilder.addOffset(38, vectorOfStrongReferrablesOffset);
+    }
+    fbBuilder.addUint64(39, _coOwningReference);
+    if (vectorOfCoOwningReferencesOffset != null) {
+      fbBuilder.addOffset(40, vectorOfCoOwningReferencesOffset);
+    }
+    fbBuilder.addUint64(41, _nonOwningReference);
+    if (vectorOfNonOwningReferencesOffset != null) {
+      fbBuilder.addOffset(42, vectorOfNonOwningReferencesOffset);
+    }
+    fbBuilder.addUint8(43, _anyUniqueType?.value);
+    if (anyUniqueOffset != null) {
+      fbBuilder.addOffset(44, anyUniqueOffset);
+    }
+    fbBuilder.addUint8(45, _anyAmbiguousType?.value);
+    if (anyAmbiguousOffset != null) {
+      fbBuilder.addOffset(46, anyAmbiguousOffset);
+    }
+    if (vectorOfEnumsOffset != null) {
+      fbBuilder.addOffset(47, vectorOfEnumsOffset);
+    }
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
+class TypeAliases {
+  TypeAliases._(this._bc, this._bcOffset);
+  factory TypeAliases(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<TypeAliases> reader = const _TypeAliasesReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  int get i8 => const fb.Int8Reader().vTableGet(_bc, _bcOffset, 4, 0);
+  int get u8 => const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 6, 0);
+  int get i16 => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 8, 0);
+  int get u16 => const fb.Uint16Reader().vTableGet(_bc, _bcOffset, 10, 0);
+  int get i32 => const fb.Int32Reader().vTableGet(_bc, _bcOffset, 12, 0);
+  int get u32 => const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 14, 0);
+  int get i64 => const fb.Int64Reader().vTableGet(_bc, _bcOffset, 16, 0);
+  int get u64 => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 18, 0);
+  double get f32 => const fb.Float32Reader().vTableGet(_bc, _bcOffset, 20, 0.0);
+  double get f64 => const fb.Float64Reader().vTableGet(_bc, _bcOffset, 22, 0.0);
+  List<int> get v8 => const fb.ListReader<int>(const fb.Int8Reader()).vTableGet(_bc, _bcOffset, 24, null);
+  List<double> get vf64 => const fb.ListReader<double>(const fb.Float64Reader()).vTableGet(_bc, _bcOffset, 26, null);
+
+  @override
+  String toString() {
+    return 'TypeAliases{i8: $i8, u8: $u8, i16: $i16, u16: $u16, i32: $i32, u32: $u32, i64: $i64, u64: $u64, f32: $f32, f64: $f64, v8: $v8, vf64: $vf64}';
+  }
+}
+
+class _TypeAliasesReader extends fb.TableReader<TypeAliases> {
+  const _TypeAliasesReader();
+
+  @override
+  TypeAliases createObject(fb.BufferContext bc, int offset) => 
+    new TypeAliases._(bc, offset);
+}
+
+class TypeAliasesBuilder {
+  TypeAliasesBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  void begin() {
+    fbBuilder.startTable();
+  }
+
+  int addI8(int i8) {
+    fbBuilder.addInt8(0, i8);
+    return fbBuilder.offset;
+  }
+  int addU8(int u8) {
+    fbBuilder.addUint8(1, u8);
+    return fbBuilder.offset;
+  }
+  int addI16(int i16) {
+    fbBuilder.addInt16(2, i16);
+    return fbBuilder.offset;
+  }
+  int addU16(int u16) {
+    fbBuilder.addUint16(3, u16);
+    return fbBuilder.offset;
+  }
+  int addI32(int i32) {
+    fbBuilder.addInt32(4, i32);
+    return fbBuilder.offset;
+  }
+  int addU32(int u32) {
+    fbBuilder.addUint32(5, u32);
+    return fbBuilder.offset;
+  }
+  int addI64(int i64) {
+    fbBuilder.addInt64(6, i64);
+    return fbBuilder.offset;
+  }
+  int addU64(int u64) {
+    fbBuilder.addUint64(7, u64);
+    return fbBuilder.offset;
+  }
+  int addF32(double f32) {
+    fbBuilder.addFloat32(8, f32);
+    return fbBuilder.offset;
+  }
+  int addF64(double f64) {
+    fbBuilder.addFloat64(9, f64);
+    return fbBuilder.offset;
+  }
+  int addV8Offset(int offset) {
+    fbBuilder.addOffset(10, offset);
+    return fbBuilder.offset;
+  }
+  int addVf64Offset(int offset) {
+    fbBuilder.addOffset(11, offset);
+    return fbBuilder.offset;
+  }
+
+  int finish() {
+    return fbBuilder.endTable();
+  }
+}
+
+class TypeAliasesObjectBuilder extends fb.ObjectBuilder {
+  final int _i8;
+  final int _u8;
+  final int _i16;
+  final int _u16;
+  final int _i32;
+  final int _u32;
+  final int _i64;
+  final int _u64;
+  final double _f32;
+  final double _f64;
+  final List<int> _v8;
+  final List<double> _vf64;
+
+  TypeAliasesObjectBuilder({
+    int i8,
+    int u8,
+    int i16,
+    int u16,
+    int i32,
+    int u32,
+    int i64,
+    int u64,
+    double f32,
+    double f64,
+    List<int> v8,
+    List<double> vf64,
+  })
+      : _i8 = i8,
+        _u8 = u8,
+        _i16 = i16,
+        _u16 = u16,
+        _i32 = i32,
+        _u32 = u32,
+        _i64 = i64,
+        _u64 = u64,
+        _f32 = f32,
+        _f64 = f64,
+        _v8 = v8,
+        _vf64 = vf64;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+    final int v8Offset = _v8?.isNotEmpty == true
+        ? fbBuilder.writeListInt8(_v8)
+        : null;
+    final int vf64Offset = _vf64?.isNotEmpty == true
+        ? fbBuilder.writeListFloat64(_vf64)
+        : null;
+
+    fbBuilder.startTable();
+    fbBuilder.addInt8(0, _i8);
+    fbBuilder.addUint8(1, _u8);
+    fbBuilder.addInt16(2, _i16);
+    fbBuilder.addUint16(3, _u16);
+    fbBuilder.addInt32(4, _i32);
+    fbBuilder.addUint32(5, _u32);
+    fbBuilder.addInt64(6, _i64);
+    fbBuilder.addUint64(7, _u64);
+    fbBuilder.addFloat32(8, _f32);
+    fbBuilder.addFloat64(9, _f64);
+    if (v8Offset != null) {
+      fbBuilder.addOffset(10, v8Offset);
+    }
+    if (vf64Offset != null) {
+      fbBuilder.addOffset(11, vf64Offset);
+    }
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
diff --git a/tests/monster_test_my_game_generated.dart b/tests/monster_test_my_game_generated.dart
new file mode 100644
index 0000000..abd538c
--- /dev/null
+++ b/tests/monster_test_my_game_generated.dart
@@ -0,0 +1,60 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+// ignore_for_file: unused_import, unused_field, unused_local_variable
+
+library my_game;
+
+import 'dart:typed_data' show Uint8List;
+import 'package:flat_buffers/flat_buffers.dart' as fb;
+
+import './monster_test_my_game.example_generated.dart' as my_game_example;
+import './monster_test_my_game.example2_generated.dart' as my_game_example2;
+
+class InParentNamespace {
+  InParentNamespace._(this._bc, this._bcOffset);
+  factory InParentNamespace(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<InParentNamespace> reader = const _InParentNamespaceReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+
+  @override
+  String toString() {
+    return 'InParentNamespace{}';
+  }
+}
+
+class _InParentNamespaceReader extends fb.TableReader<InParentNamespace> {
+  const _InParentNamespaceReader();
+
+  @override
+  InParentNamespace createObject(fb.BufferContext bc, int offset) => 
+    new InParentNamespace._(bc, offset);
+}
+
+class InParentNamespaceObjectBuilder extends fb.ObjectBuilder {
+
+  InParentNamespaceObjectBuilder();
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+
+    fbBuilder.startTable();
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
diff --git a/tests/monsterdata_extra.json b/tests/monsterdata_extra.json
new file mode 100644
index 0000000..53045cd
--- /dev/null
+++ b/tests/monsterdata_extra.json
@@ -0,0 +1,15 @@
+{
+  // Initialize with non-default values.
+  d0 : -nan, // match with default
+  d1 : +inf,
+  d2 : -inf,
+  d3:   nan,
+  f0 : +nan, // match with default
+  f1 : -nan, // match with default
+  f2 : +inf, // match with default
+  f3 : -inf, // match with default
+  // Values should have exact binary representation 
+  // to avoid rounding effects in tests.
+  dvec : [2.0, +inf, -inf, nan,],
+  fvec : [1.0, -inf, +inf, nan],
+}
diff --git a/tests/monsterdata_python_wire.mon b/tests/monsterdata_python_wire.mon
new file mode 100644
index 0000000..2fb956d
--- /dev/null
+++ b/tests/monsterdata_python_wire.mon
Binary files differ
diff --git a/tests/monsterdata_test.golden b/tests/monsterdata_test.golden
new file mode 100644
index 0000000..4bead97
--- /dev/null
+++ b/tests/monsterdata_test.golden
@@ -0,0 +1,82 @@
+{
+  pos: {
+    x: 1.0,
+    y: 2.0,
+    z: 3.0,
+    test1: 3.14159265359,
+    test2: "Green",
+    test3: {
+      a: 10,
+      b: 20
+    }
+  },
+  hp: 80,
+  name: "MyMonster",
+  inventory: [
+    0,
+    1,
+    2,
+    3,
+    4,
+    5,
+    6,
+    7,
+    8,
+    9
+  ],
+  test_type: "Monster",
+  test: {
+    name: "Fred"
+  },
+  test4: [
+    {
+      a: 10,
+      b: 20
+    },
+    {
+      a: 30,
+      b: 40
+    }
+  ],
+  testarrayofstring: [
+    "bob",
+    "fred",
+    "bob",
+    "fred"
+  ],
+  testarrayoftables: [
+    {
+      hp: 1000,
+      name: "Barney"
+    },
+    {
+      name: "Fred"
+    },
+    {
+      name: "Wilma"
+    }
+  ],
+  testnestedflatbuffer: {
+    name: "NestedMonster"
+  },
+  testbool: true,
+  testhashs32_fnv1: -579221183,
+  testhashu32_fnv1: 3715746113,
+  testhashs64_fnv1: 7930699090847568257,
+  testhashu64_fnv1: 7930699090847568257,
+  testhashs32_fnv1a: -1904106383,
+  testhashu32_fnv1a: 2390860913,
+  testhashs64_fnv1a: 4898026182817603057,
+  testhashu64_fnv1a: 4898026182817603057,
+  flex: 1234,
+  test5: [
+    {
+      a: 10,
+      b: 20
+    },
+    {
+      a: 30,
+      b: 40
+    }
+  ]
+}
diff --git a/tests/monsterdata_test.json b/tests/monsterdata_test.json
new file mode 100644
index 0000000..d3028b5
--- /dev/null
+++ b/tests/monsterdata_test.json
@@ -0,0 +1,78 @@
+{
+  pos: {
+    x: 1,
+    y: "2",
+    z: 3,
+    test1: 3,
+    test2: Green,
+    test3: {
+      a: 5,
+      b: 6
+    }
+  },
+  hp: 80,
+  name: "MyMonster",
+  inventory: [
+    0,
+    1,
+    2,
+    3,
+    4
+  ],
+  vector_of_longs: [
+      1,
+      100,
+      10000,
+      1000000,
+      100000000
+  ],
+  vector_of_doubles: [
+      -1.7976931348623157e+308,
+      0,
+      1.7976931348623157e+308
+  ],
+  test_type: Monster,
+  test: {
+    name: "Fred",
+    pos: null
+  },
+  test4: [
+    {
+      a: 10,
+      b: 20
+    },
+    {
+      b: "40",
+      a: 30
+    }
+  ],
+  test5: [
+    {
+      a: 10,
+      b: 20
+    },
+    {
+      b: "40",
+      a: 30
+    }
+  ],
+  testarrayofstring: [
+    "test1",
+    "test2"
+  ],
+  enemy: {
+    name: "Fred"
+  },
+  testarrayofbools:[
+    true, false, true
+  ],
+  testbool: true,
+  testhashs32_fnv1: "This string is being hashed!",
+  testhashu32_fnv1: "This string is being hashed!",
+  testhashs64_fnv1: "This string is being hashed!",
+  testhashu64_fnv1: "This string is being hashed!",
+  testhashs32_fnv1a: "This string is being hashed!",
+  testhashu32_fnv1a: "This string is being hashed!",
+  testhashs64_fnv1a: "This string is being hashed!",
+  testhashu64_fnv1a: "This string is being hashed!",
+}
diff --git a/tests/monsterdata_test.mon b/tests/monsterdata_test.mon
new file mode 100644
index 0000000..ba6cf27
--- /dev/null
+++ b/tests/monsterdata_test.mon
Binary files differ
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.cs b/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.cs
new file mode 100644
index 0000000..ff44023
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.cs
@@ -0,0 +1,16 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace NamespaceA.NamespaceB
+{
+
+public enum EnumInNestedNS : sbyte
+{
+  A = 0,
+  B = 1,
+  C = 2,
+};
+
+
+}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.go b/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.go
new file mode 100644
index 0000000..6cec5ff
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.go
@@ -0,0 +1,32 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package NamespaceB
+
+import "strconv"
+
+type EnumInNestedNS int8
+
+const (
+	EnumInNestedNSA EnumInNestedNS = 0
+	EnumInNestedNSB EnumInNestedNS = 1
+	EnumInNestedNSC EnumInNestedNS = 2
+)
+
+var EnumNamesEnumInNestedNS = map[EnumInNestedNS]string{
+	EnumInNestedNSA: "A",
+	EnumInNestedNSB: "B",
+	EnumInNestedNSC: "C",
+}
+
+var EnumValuesEnumInNestedNS = map[string]EnumInNestedNS{
+	"A": EnumInNestedNSA,
+	"B": EnumInNestedNSB,
+	"C": EnumInNestedNSC,
+}
+
+func (v EnumInNestedNS) String() string {
+	if s, ok := EnumNamesEnumInNestedNS[v]; ok {
+		return s
+	}
+	return "EnumInNestedNS(" + strconv.FormatInt(int64(v), 10) + ")"
+}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.java b/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.java
new file mode 100644
index 0000000..e23cecc
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.java
@@ -0,0 +1,15 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceA.NamespaceB;
+
+public final class EnumInNestedNS {
+  private EnumInNestedNS() { }
+  public static final byte A = 0;
+  public static final byte B = 1;
+  public static final byte C = 2;
+
+  public static final String[] names = { "A", "B", "C", };
+
+  public static String name(int e) { return names[e]; }
+}
+
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.kt b/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.kt
new file mode 100644
index 0000000..0ede58c
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.kt
@@ -0,0 +1,15 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceA.NamespaceB
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class EnumInNestedNS private constructor() {
+    companion object {
+        const val A: Byte = 0
+        const val B: Byte = 1
+        const val C: Byte = 2
+        val names : Array<String> = arrayOf("A", "B", "C")
+        fun name(e: Int) : String = names[e]
+    }
+}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.lua b/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.lua
new file mode 100644
index 0000000..60b1fb1
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.lua
@@ -0,0 +1,11 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: NamespaceB
+
+local EnumInNestedNS = {
+    A = 0,
+    B = 1,
+    C = 2,
+}
+
+return EnumInNestedNS -- return the module
\ No newline at end of file
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.php b/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.php
new file mode 100644
index 0000000..bcb22b7
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.php
@@ -0,0 +1,25 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace NamespaceA\NamespaceB;
+
+class EnumInNestedNS
+{
+    const A = 0;
+    const B = 1;
+    const C = 2;
+
+    private static $names = array(
+        EnumInNestedNS::A=>"A",
+        EnumInNestedNS::B=>"B",
+        EnumInNestedNS::C=>"C",
+    );
+
+    public static function Name($e)
+    {
+        if (!isset(self::$names[$e])) {
+            throw new \Exception();
+        }
+        return self::$names[$e];
+    }
+}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.py b/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.py
new file mode 100644
index 0000000..cb8218f
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.py
@@ -0,0 +1,9 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: NamespaceB
+
+class EnumInNestedNS(object):
+    A = 0
+    B = 1
+    C = 2
+
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.cs b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.cs
new file mode 100644
index 0000000..9aba8db
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.cs
@@ -0,0 +1,32 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace NamespaceA.NamespaceB
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct StructInNestedNS : IFlatbufferObject
+{
+  private Struct __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
+  public StructInNestedNS __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public int A { get { return __p.bb.GetInt(__p.bb_pos + 0); } }
+  public void MutateA(int a) { __p.bb.PutInt(__p.bb_pos + 0, a); }
+  public int B { get { return __p.bb.GetInt(__p.bb_pos + 4); } }
+  public void MutateB(int b) { __p.bb.PutInt(__p.bb_pos + 4, b); }
+
+  public static Offset<NamespaceA.NamespaceB.StructInNestedNS> CreateStructInNestedNS(FlatBufferBuilder builder, int A, int B) {
+    builder.Prep(4, 8);
+    builder.PutInt(B);
+    builder.PutInt(A);
+    return new Offset<NamespaceA.NamespaceB.StructInNestedNS>(builder.Offset);
+  }
+};
+
+
+}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.go b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.go
new file mode 100644
index 0000000..e985fbf
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.go
@@ -0,0 +1,41 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package NamespaceB
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+)
+
+type StructInNestedNS struct {
+	_tab flatbuffers.Struct
+}
+
+func (rcv *StructInNestedNS) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *StructInNestedNS) Table() flatbuffers.Table {
+	return rcv._tab.Table
+}
+
+func (rcv *StructInNestedNS) A() int32 {
+	return rcv._tab.GetInt32(rcv._tab.Pos + flatbuffers.UOffsetT(0))
+}
+func (rcv *StructInNestedNS) MutateA(n int32) bool {
+	return rcv._tab.MutateInt32(rcv._tab.Pos+flatbuffers.UOffsetT(0), n)
+}
+
+func (rcv *StructInNestedNS) B() int32 {
+	return rcv._tab.GetInt32(rcv._tab.Pos + flatbuffers.UOffsetT(4))
+}
+func (rcv *StructInNestedNS) MutateB(n int32) bool {
+	return rcv._tab.MutateInt32(rcv._tab.Pos+flatbuffers.UOffsetT(4), n)
+}
+
+func CreateStructInNestedNS(builder *flatbuffers.Builder, a int32, b int32) flatbuffers.UOffsetT {
+	builder.Prep(4, 8)
+	builder.PrependInt32(b)
+	builder.PrependInt32(a)
+	return builder.Offset()
+}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.java b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.java
new file mode 100644
index 0000000..284f89a
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.java
@@ -0,0 +1,27 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceA.NamespaceB;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class StructInNestedNS extends Struct {
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public StructInNestedNS __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public int a() { return bb.getInt(bb_pos + 0); }
+  public void mutateA(int a) { bb.putInt(bb_pos + 0, a); }
+  public int b() { return bb.getInt(bb_pos + 4); }
+  public void mutateB(int b) { bb.putInt(bb_pos + 4, b); }
+
+  public static int createStructInNestedNS(FlatBufferBuilder builder, int a, int b) {
+    builder.prep(4, 8);
+    builder.putInt(b);
+    builder.putInt(a);
+    return builder.offset();
+  }
+}
+
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.kt b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.kt
new file mode 100644
index 0000000..0273bb1
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.kt
@@ -0,0 +1,32 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceA.NamespaceB
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class StructInNestedNS : Struct() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : StructInNestedNS {
+        __init(_i, _bb)
+        return this
+    }
+    val a : Int get() = bb.getInt(bb_pos + 0)
+    fun mutateA(a: Int) : ByteBuffer = bb.putInt(bb_pos + 0, a)
+    val b : Int get() = bb.getInt(bb_pos + 4)
+    fun mutateB(b: Int) : ByteBuffer = bb.putInt(bb_pos + 4, b)
+    companion object {
+        fun createStructInNestedNS(builder: FlatBufferBuilder, a: Int, b: Int) : Int {
+            builder.prep(4, 8)
+            builder.putInt(b)
+            builder.putInt(a)
+            return builder.offset()
+        }
+    }
+}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.lua b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.lua
new file mode 100644
index 0000000..9ca7541
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.lua
@@ -0,0 +1,31 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: NamespaceB
+
+local flatbuffers = require('flatbuffers')
+
+local StructInNestedNS = {} -- the module
+local StructInNestedNS_mt = {} -- the class metatable
+
+function StructInNestedNS.New()
+    local o = {}
+    setmetatable(o, {__index = StructInNestedNS_mt})
+    return o
+end
+function StructInNestedNS_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function StructInNestedNS_mt:A()
+    return self.view:Get(flatbuffers.N.Int32, self.view.pos + 0)
+end
+function StructInNestedNS_mt:B()
+    return self.view:Get(flatbuffers.N.Int32, self.view.pos + 4)
+end
+function StructInNestedNS.CreateStructInNestedNS(builder, a, b)
+    builder:Prep(4, 8)
+    builder:PrependInt32(b)
+    builder:PrependInt32(a)
+    return builder:Offset()
+end
+
+return StructInNestedNS -- return the module
\ No newline at end of file
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.php b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.php
new file mode 100644
index 0000000..d305484
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.php
@@ -0,0 +1,52 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace NamespaceA\NamespaceB;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class StructInNestedNS extends Struct
+{
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return StructInNestedNS
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    /**
+     * @return int
+     */
+    public function GetA()
+    {
+        return $this->bb->getInt($this->bb_pos + 0);
+    }
+
+    /**
+     * @return int
+     */
+    public function GetB()
+    {
+        return $this->bb->getInt($this->bb_pos + 4);
+    }
+
+
+    /**
+     * @return int offset
+     */
+    public static function createStructInNestedNS(FlatBufferBuilder $builder, $a, $b)
+    {
+        $builder->prep(4, 8);
+        $builder->putInt($b);
+        $builder->putInt($a);
+        return $builder->offset();
+    }
+}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.py b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.py
new file mode 100644
index 0000000..59cceaa
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.py
@@ -0,0 +1,23 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: NamespaceB
+
+import flatbuffers
+
+class StructInNestedNS(object):
+    __slots__ = ['_tab']
+
+    # StructInNestedNS
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # StructInNestedNS
+    def A(self): return self._tab.Get(flatbuffers.number_types.Int32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(0))
+    # StructInNestedNS
+    def B(self): return self._tab.Get(flatbuffers.number_types.Int32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(4))
+
+def CreateStructInNestedNS(builder, a, b):
+    builder.Prep(4, 8)
+    builder.PrependInt32(b)
+    builder.PrependInt32(a)
+    return builder.Offset()
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.cs b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.cs
new file mode 100644
index 0000000..f8ea32b
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.cs
@@ -0,0 +1,40 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace NamespaceA.NamespaceB
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct TableInNestedNS : IFlatbufferObject
+{
+  private Table __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_11_1(); }
+  public static TableInNestedNS GetRootAsTableInNestedNS(ByteBuffer _bb) { return GetRootAsTableInNestedNS(_bb, new TableInNestedNS()); }
+  public static TableInNestedNS GetRootAsTableInNestedNS(ByteBuffer _bb, TableInNestedNS obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+  public TableInNestedNS __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public int Foo { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetInt(o + __p.bb_pos) : (int)0; } }
+  public bool MutateFoo(int foo) { int o = __p.__offset(4); if (o != 0) { __p.bb.PutInt(o + __p.bb_pos, foo); return true; } else { return false; } }
+
+  public static Offset<NamespaceA.NamespaceB.TableInNestedNS> CreateTableInNestedNS(FlatBufferBuilder builder,
+      int foo = 0) {
+    builder.StartTable(1);
+    TableInNestedNS.AddFoo(builder, foo);
+    return TableInNestedNS.EndTableInNestedNS(builder);
+  }
+
+  public static void StartTableInNestedNS(FlatBufferBuilder builder) { builder.StartTable(1); }
+  public static void AddFoo(FlatBufferBuilder builder, int foo) { builder.AddInt(0, foo, 0); }
+  public static Offset<NamespaceA.NamespaceB.TableInNestedNS> EndTableInNestedNS(FlatBufferBuilder builder) {
+    int o = builder.EndTable();
+    return new Offset<NamespaceA.NamespaceB.TableInNestedNS>(o);
+  }
+};
+
+
+}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.go b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.go
new file mode 100644
index 0000000..75f7a55
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.go
@@ -0,0 +1,49 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package NamespaceB
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+)
+
+type TableInNestedNS struct {
+	_tab flatbuffers.Table
+}
+
+func GetRootAsTableInNestedNS(buf []byte, offset flatbuffers.UOffsetT) *TableInNestedNS {
+	n := flatbuffers.GetUOffsetT(buf[offset:])
+	x := &TableInNestedNS{}
+	x.Init(buf, n+offset)
+	return x
+}
+
+func (rcv *TableInNestedNS) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *TableInNestedNS) Table() flatbuffers.Table {
+	return rcv._tab
+}
+
+func (rcv *TableInNestedNS) Foo() int32 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
+	if o != 0 {
+		return rcv._tab.GetInt32(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *TableInNestedNS) MutateFoo(n int32) bool {
+	return rcv._tab.MutateInt32Slot(4, n)
+}
+
+func TableInNestedNSStart(builder *flatbuffers.Builder) {
+	builder.StartObject(1)
+}
+func TableInNestedNSAddFoo(builder *flatbuffers.Builder, foo int32) {
+	builder.PrependInt32Slot(0, foo, 0)
+}
+func TableInNestedNSEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+	return builder.EndObject()
+}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.java b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.java
new file mode 100644
index 0000000..af1449b
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.java
@@ -0,0 +1,35 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceA.NamespaceB;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class TableInNestedNS extends Table {
+  public static void ValidateVersion() { Constants.FLATBUFFERS_1_11_1(); }
+  public static TableInNestedNS getRootAsTableInNestedNS(ByteBuffer _bb) { return getRootAsTableInNestedNS(_bb, new TableInNestedNS()); }
+  public static TableInNestedNS getRootAsTableInNestedNS(ByteBuffer _bb, TableInNestedNS obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public TableInNestedNS __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public int foo() { int o = __offset(4); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
+  public boolean mutateFoo(int foo) { int o = __offset(4); if (o != 0) { bb.putInt(o + bb_pos, foo); return true; } else { return false; } }
+
+  public static int createTableInNestedNS(FlatBufferBuilder builder,
+      int foo) {
+    builder.startTable(1);
+    TableInNestedNS.addFoo(builder, foo);
+    return TableInNestedNS.endTableInNestedNS(builder);
+  }
+
+  public static void startTableInNestedNS(FlatBufferBuilder builder) { builder.startTable(1); }
+  public static void addFoo(FlatBufferBuilder builder, int foo) { builder.addInt(0, foo, 0); }
+  public static int endTableInNestedNS(FlatBufferBuilder builder) {
+    int o = builder.endTable();
+    return o;
+  }
+}
+
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.kt b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.kt
new file mode 100644
index 0000000..59ebdc9
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.kt
@@ -0,0 +1,53 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceA.NamespaceB
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class TableInNestedNS : Table() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : TableInNestedNS {
+        __init(_i, _bb)
+        return this
+    }
+    val foo : Int
+        get() {
+            val o = __offset(4)
+            return if(o != 0) bb.getInt(o + bb_pos) else 0
+        }
+    fun mutateFoo(foo: Int) : Boolean {
+        val o = __offset(4)
+        return if (o != 0) {
+            bb.putInt(o + bb_pos, foo)
+            true
+        } else {
+            false
+        }
+    }
+    companion object {
+        fun validateVersion() = Constants.FLATBUFFERS_1_11_1()
+        fun getRootAsTableInNestedNS(_bb: ByteBuffer): TableInNestedNS = getRootAsTableInNestedNS(_bb, TableInNestedNS())
+        fun getRootAsTableInNestedNS(_bb: ByteBuffer, obj: TableInNestedNS): TableInNestedNS {
+            _bb.order(ByteOrder.LITTLE_ENDIAN)
+            return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+        }
+        fun createTableInNestedNS(builder: FlatBufferBuilder, foo: Int) : Int {
+            builder.startTable(1)
+            addFoo(builder, foo)
+            return endTableInNestedNS(builder)
+        }
+        fun startTableInNestedNS(builder: FlatBufferBuilder) = builder.startTable(1)
+        fun addFoo(builder: FlatBufferBuilder, foo: Int) = builder.addInt(0, foo, 0)
+        fun endTableInNestedNS(builder: FlatBufferBuilder) : Int {
+            val o = builder.endTable()
+            return o
+        }
+    }
+}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.lua b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.lua
new file mode 100644
index 0000000..dd45e58
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.lua
@@ -0,0 +1,35 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: NamespaceB
+
+local flatbuffers = require('flatbuffers')
+
+local TableInNestedNS = {} -- the module
+local TableInNestedNS_mt = {} -- the class metatable
+
+function TableInNestedNS.New()
+    local o = {}
+    setmetatable(o, {__index = TableInNestedNS_mt})
+    return o
+end
+function TableInNestedNS.GetRootAsTableInNestedNS(buf, offset)
+    local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)
+    local o = TableInNestedNS.New()
+    o:Init(buf, n + offset)
+    return o
+end
+function TableInNestedNS_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function TableInNestedNS_mt:Foo()
+    local o = self.view:Offset(4)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Int32, o + self.view.pos)
+    end
+    return 0
+end
+function TableInNestedNS.Start(builder) builder:StartObject(1) end
+function TableInNestedNS.AddFoo(builder, foo) builder:PrependInt32Slot(0, foo, 0) end
+function TableInNestedNS.End(builder) return builder:EndObject() end
+
+return TableInNestedNS -- return the module
\ No newline at end of file
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.php b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.php
new file mode 100644
index 0000000..d16379d
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.php
@@ -0,0 +1,84 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace NamespaceA\NamespaceB;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class TableInNestedNS extends Table
+{
+    /**
+     * @param ByteBuffer $bb
+     * @return TableInNestedNS
+     */
+    public static function getRootAsTableInNestedNS(ByteBuffer $bb)
+    {
+        $obj = new TableInNestedNS();
+        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
+    }
+
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return TableInNestedNS
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    /**
+     * @return int
+     */
+    public function getFoo()
+    {
+        $o = $this->__offset(4);
+        return $o != 0 ? $this->bb->getInt($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return void
+     */
+    public static function startTableInNestedNS(FlatBufferBuilder $builder)
+    {
+        $builder->StartObject(1);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return TableInNestedNS
+     */
+    public static function createTableInNestedNS(FlatBufferBuilder $builder, $foo)
+    {
+        $builder->startObject(1);
+        self::addFoo($builder, $foo);
+        $o = $builder->endObject();
+        return $o;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addFoo(FlatBufferBuilder $builder, $foo)
+    {
+        $builder->addIntX(0, $foo, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return int table offset
+     */
+    public static function endTableInNestedNS(FlatBufferBuilder $builder)
+    {
+        $o = $builder->endObject();
+        return $o;
+    }
+}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.py b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.py
new file mode 100644
index 0000000..d6d1674
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.py
@@ -0,0 +1,30 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: NamespaceB
+
+import flatbuffers
+
+class TableInNestedNS(object):
+    __slots__ = ['_tab']
+
+    @classmethod
+    def GetRootAsTableInNestedNS(cls, buf, offset):
+        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
+        x = TableInNestedNS()
+        x.Init(buf, n + offset)
+        return x
+
+    # TableInNestedNS
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # TableInNestedNS
+    def Foo(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
+        return 0
+
+def TableInNestedNSStart(builder): builder.StartObject(1)
+def TableInNestedNSAddFoo(builder, foo): builder.PrependInt32Slot(0, foo, 0)
+def TableInNestedNSEnd(builder): return builder.EndObject()
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/__init__.py b/tests/namespace_test/NamespaceA/NamespaceB/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/NamespaceB/__init__.py
diff --git a/tests/namespace_test/NamespaceA/SecondTableInA.cs b/tests/namespace_test/NamespaceA/SecondTableInA.cs
new file mode 100644
index 0000000..7e08de8
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/SecondTableInA.cs
@@ -0,0 +1,39 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace NamespaceA
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct SecondTableInA : IFlatbufferObject
+{
+  private Table __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_11_1(); }
+  public static SecondTableInA GetRootAsSecondTableInA(ByteBuffer _bb) { return GetRootAsSecondTableInA(_bb, new SecondTableInA()); }
+  public static SecondTableInA GetRootAsSecondTableInA(ByteBuffer _bb, SecondTableInA obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+  public SecondTableInA __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public NamespaceC.TableInC? ReferToC { get { int o = __p.__offset(4); return o != 0 ? (NamespaceC.TableInC?)(new NamespaceC.TableInC()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
+
+  public static Offset<NamespaceA.SecondTableInA> CreateSecondTableInA(FlatBufferBuilder builder,
+      Offset<NamespaceC.TableInC> refer_to_cOffset = default(Offset<NamespaceC.TableInC>)) {
+    builder.StartTable(1);
+    SecondTableInA.AddReferToC(builder, refer_to_cOffset);
+    return SecondTableInA.EndSecondTableInA(builder);
+  }
+
+  public static void StartSecondTableInA(FlatBufferBuilder builder) { builder.StartTable(1); }
+  public static void AddReferToC(FlatBufferBuilder builder, Offset<NamespaceC.TableInC> referToCOffset) { builder.AddOffset(0, referToCOffset.Value, 0); }
+  public static Offset<NamespaceA.SecondTableInA> EndSecondTableInA(FlatBufferBuilder builder) {
+    int o = builder.EndTable();
+    return new Offset<NamespaceA.SecondTableInA>(o);
+  }
+};
+
+
+}
diff --git a/tests/namespace_test/NamespaceA/SecondTableInA.go b/tests/namespace_test/NamespaceA/SecondTableInA.go
new file mode 100644
index 0000000..6dd1eef
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/SecondTableInA.go
@@ -0,0 +1,52 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package NamespaceA
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+
+	NamespaceC "NamespaceC"
+)
+
+type SecondTableInA struct {
+	_tab flatbuffers.Table
+}
+
+func GetRootAsSecondTableInA(buf []byte, offset flatbuffers.UOffsetT) *SecondTableInA {
+	n := flatbuffers.GetUOffsetT(buf[offset:])
+	x := &SecondTableInA{}
+	x.Init(buf, n+offset)
+	return x
+}
+
+func (rcv *SecondTableInA) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *SecondTableInA) Table() flatbuffers.Table {
+	return rcv._tab
+}
+
+func (rcv *SecondTableInA) ReferToC(obj *NamespaceC.TableInC) *NamespaceC.TableInC {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
+	if o != 0 {
+		x := rcv._tab.Indirect(o + rcv._tab.Pos)
+		if obj == nil {
+			obj = new(NamespaceC.TableInC)
+		}
+		obj.Init(rcv._tab.Bytes, x)
+		return obj
+	}
+	return nil
+}
+
+func SecondTableInAStart(builder *flatbuffers.Builder) {
+	builder.StartObject(1)
+}
+func SecondTableInAAddReferToC(builder *flatbuffers.Builder, referToC flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(referToC), 0)
+}
+func SecondTableInAEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+	return builder.EndObject()
+}
diff --git a/tests/namespace_test/NamespaceA/SecondTableInA.java b/tests/namespace_test/NamespaceA/SecondTableInA.java
new file mode 100644
index 0000000..a655199
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/SecondTableInA.java
@@ -0,0 +1,35 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceA;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class SecondTableInA extends Table {
+  public static void ValidateVersion() { Constants.FLATBUFFERS_1_11_1(); }
+  public static SecondTableInA getRootAsSecondTableInA(ByteBuffer _bb) { return getRootAsSecondTableInA(_bb, new SecondTableInA()); }
+  public static SecondTableInA getRootAsSecondTableInA(ByteBuffer _bb, SecondTableInA obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public SecondTableInA __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public NamespaceC.TableInC referToC() { return referToC(new NamespaceC.TableInC()); }
+  public NamespaceC.TableInC referToC(NamespaceC.TableInC obj) { int o = __offset(4); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; }
+
+  public static int createSecondTableInA(FlatBufferBuilder builder,
+      int refer_to_cOffset) {
+    builder.startTable(1);
+    SecondTableInA.addReferToC(builder, refer_to_cOffset);
+    return SecondTableInA.endSecondTableInA(builder);
+  }
+
+  public static void startSecondTableInA(FlatBufferBuilder builder) { builder.startTable(1); }
+  public static void addReferToC(FlatBufferBuilder builder, int referToCOffset) { builder.addOffset(0, referToCOffset, 0); }
+  public static int endSecondTableInA(FlatBufferBuilder builder) {
+    int o = builder.endTable();
+    return o;
+  }
+}
+
diff --git a/tests/namespace_test/NamespaceA/SecondTableInA.kt b/tests/namespace_test/NamespaceA/SecondTableInA.kt
new file mode 100644
index 0000000..8261443
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/SecondTableInA.kt
@@ -0,0 +1,48 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceA
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class SecondTableInA : Table() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : SecondTableInA {
+        __init(_i, _bb)
+        return this
+    }
+    val referToC : NamespaceC.TableInC? get() = referToC(NamespaceC.TableInC())
+    fun referToC(obj: NamespaceC.TableInC) : NamespaceC.TableInC? {
+        val o = __offset(4)
+        return if (o != 0) {
+            obj.__assign(__indirect(o + bb_pos), bb)
+        } else {
+            null
+        }
+    }
+    companion object {
+        fun validateVersion() = Constants.FLATBUFFERS_1_11_1()
+        fun getRootAsSecondTableInA(_bb: ByteBuffer): SecondTableInA = getRootAsSecondTableInA(_bb, SecondTableInA())
+        fun getRootAsSecondTableInA(_bb: ByteBuffer, obj: SecondTableInA): SecondTableInA {
+            _bb.order(ByteOrder.LITTLE_ENDIAN)
+            return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+        }
+        fun createSecondTableInA(builder: FlatBufferBuilder, referToCOffset: Int) : Int {
+            builder.startTable(1)
+            addReferToC(builder, referToCOffset)
+            return endSecondTableInA(builder)
+        }
+        fun startSecondTableInA(builder: FlatBufferBuilder) = builder.startTable(1)
+        fun addReferToC(builder: FlatBufferBuilder, referToC: Int) = builder.addOffset(0, referToC, 0)
+        fun endSecondTableInA(builder: FlatBufferBuilder) : Int {
+            val o = builder.endTable()
+            return o
+        }
+    }
+}
diff --git a/tests/namespace_test/NamespaceA/SecondTableInA.lua b/tests/namespace_test/NamespaceA/SecondTableInA.lua
new file mode 100644
index 0000000..9a60e4b
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/SecondTableInA.lua
@@ -0,0 +1,37 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: NamespaceA
+
+local flatbuffers = require('flatbuffers')
+
+local SecondTableInA = {} -- the module
+local SecondTableInA_mt = {} -- the class metatable
+
+function SecondTableInA.New()
+    local o = {}
+    setmetatable(o, {__index = SecondTableInA_mt})
+    return o
+end
+function SecondTableInA.GetRootAsSecondTableInA(buf, offset)
+    local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)
+    local o = SecondTableInA.New()
+    o:Init(buf, n + offset)
+    return o
+end
+function SecondTableInA_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function SecondTableInA_mt:ReferToC()
+    local o = self.view:Offset(4)
+    if o ~= 0 then
+        local x = self.view:Indirect(o + self.view.pos)
+        local obj = require('NamespaceC.TableInC').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function SecondTableInA.Start(builder) builder:StartObject(1) end
+function SecondTableInA.AddReferToC(builder, referToC) builder:PrependUOffsetTRelativeSlot(0, referToC, 0) end
+function SecondTableInA.End(builder) return builder:EndObject() end
+
+return SecondTableInA -- return the module
\ No newline at end of file
diff --git a/tests/namespace_test/NamespaceA/SecondTableInA.php b/tests/namespace_test/NamespaceA/SecondTableInA.php
new file mode 100644
index 0000000..c9bc65c
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/SecondTableInA.php
@@ -0,0 +1,82 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace NamespaceA;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class SecondTableInA extends Table
+{
+    /**
+     * @param ByteBuffer $bb
+     * @return SecondTableInA
+     */
+    public static function getRootAsSecondTableInA(ByteBuffer $bb)
+    {
+        $obj = new SecondTableInA();
+        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
+    }
+
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return SecondTableInA
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    public function getReferToC()
+    {
+        $obj = new TableInC();
+        $o = $this->__offset(4);
+        return $o != 0 ? $obj->init($this->__indirect($o + $this->bb_pos), $this->bb) : 0;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return void
+     */
+    public static function startSecondTableInA(FlatBufferBuilder $builder)
+    {
+        $builder->StartObject(1);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return SecondTableInA
+     */
+    public static function createSecondTableInA(FlatBufferBuilder $builder, $refer_to_c)
+    {
+        $builder->startObject(1);
+        self::addReferToC($builder, $refer_to_c);
+        $o = $builder->endObject();
+        return $o;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addReferToC(FlatBufferBuilder $builder, $referToC)
+    {
+        $builder->addOffsetX(0, $referToC, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return int table offset
+     */
+    public static function endSecondTableInA(FlatBufferBuilder $builder)
+    {
+        $o = $builder->endObject();
+        return $o;
+    }
+}
diff --git a/tests/namespace_test/NamespaceA/SecondTableInA.py b/tests/namespace_test/NamespaceA/SecondTableInA.py
new file mode 100644
index 0000000..20dac3e
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/SecondTableInA.py
@@ -0,0 +1,34 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: NamespaceA
+
+import flatbuffers
+
+class SecondTableInA(object):
+    __slots__ = ['_tab']
+
+    @classmethod
+    def GetRootAsSecondTableInA(cls, buf, offset):
+        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
+        x = SecondTableInA()
+        x.Init(buf, n + offset)
+        return x
+
+    # SecondTableInA
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # SecondTableInA
+    def ReferToC(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+        if o != 0:
+            x = self._tab.Indirect(o + self._tab.Pos)
+            from .TableInC import TableInC
+            obj = TableInC()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+def SecondTableInAStart(builder): builder.StartObject(1)
+def SecondTableInAAddReferToC(builder, referToC): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(referToC), 0)
+def SecondTableInAEnd(builder): return builder.EndObject()
diff --git a/tests/namespace_test/NamespaceA/TableInC.cs b/tests/namespace_test/NamespaceA/TableInC.cs
new file mode 100644
index 0000000..98f4e13
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/TableInC.cs
@@ -0,0 +1,38 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace NamespaceA
+{
+
+using System;
+using FlatBuffers;
+
+public sealed class TableInC : Table {
+  public static TableInC GetRootAsTableInC(ByteBuffer _bb) { return GetRootAsTableInC(_bb, new TableInC()); }
+  public static TableInC GetRootAsTableInC(ByteBuffer _bb, TableInC obj) { return (obj.__init(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public TableInC __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
+
+  public NamespaceA.TableInFirstNS ReferToA1 { get { return GetReferToA1(new NamespaceA.TableInFirstNS()); } }
+  public NamespaceA.TableInFirstNS GetReferToA1(NamespaceA.TableInFirstNS obj) { int o = __offset(4); return o != 0 ? obj.__init(__indirect(o + bb_pos), bb) : null; }
+  public SecondTableInA ReferToA2 { get { return GetReferToA2(new SecondTableInA()); } }
+  public SecondTableInA GetReferToA2(SecondTableInA obj) { int o = __offset(6); return o != 0 ? obj.__init(__indirect(o + bb_pos), bb) : null; }
+
+  public static Offset<NamespaceC.TableInC> CreateTableInC(FlatBufferBuilder builder,
+      Offset<NamespaceA.TableInFirstNS> refer_to_a1Offset = default(Offset<NamespaceA.TableInFirstNS>),
+      Offset<SecondTableInA> refer_to_a2Offset = default(Offset<SecondTableInA>)) {
+    builder.StartObject(2);
+    TableInC.AddReferToA2(builder, refer_to_a2Offset);
+    TableInC.AddReferToA1(builder, refer_to_a1Offset);
+    return TableInC.EndTableInC(builder);
+  }
+
+  public static void StartTableInC(FlatBufferBuilder builder) { builder.StartObject(2); }
+  public static void AddReferToA1(FlatBufferBuilder builder, Offset<NamespaceA.TableInFirstNS> referToA1Offset) { builder.AddOffset(0, referToA1Offset.Value, 0); }
+  public static void AddReferToA2(FlatBufferBuilder builder, Offset<SecondTableInA> referToA2Offset) { builder.AddOffset(1, referToA2Offset.Value, 0); }
+  public static Offset<NamespaceC.TableInC> EndTableInC(FlatBufferBuilder builder) {
+    int o = builder.EndObject();
+    return new Offset<NamespaceC.TableInC>(o);
+  }
+};
+
+
+}
diff --git a/tests/namespace_test/NamespaceA/TableInC.go b/tests/namespace_test/NamespaceA/TableInC.go
new file mode 100644
index 0000000..6f3d3f2
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/TableInC.go
@@ -0,0 +1,46 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceA
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+)
+type TableInC struct {
+	_tab flatbuffers.Table
+}
+
+func (rcv *TableInC) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *TableInC) ReferToA1(obj *TableInFirstNS) *TableInFirstNS {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
+	if o != 0 {
+		x := rcv._tab.Indirect(o + rcv._tab.Pos)
+		if obj == nil {
+			obj = new(TableInFirstNS)
+		}
+		obj.Init(rcv._tab.Bytes, x)
+		return obj
+	}
+	return nil
+}
+
+func (rcv *TableInC) ReferToA2(obj *SecondTableInA) *SecondTableInA {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
+	if o != 0 {
+		x := rcv._tab.Indirect(o + rcv._tab.Pos)
+		if obj == nil {
+			obj = new(SecondTableInA)
+		}
+		obj.Init(rcv._tab.Bytes, x)
+		return obj
+	}
+	return nil
+}
+
+func TableInCStart(builder *flatbuffers.Builder) { builder.StartObject(2) }
+func TableInCAddReferToA1(builder *flatbuffers.Builder, referToA1 flatbuffers.UOffsetT) { builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(referToA1), 0) }
+func TableInCAddReferToA2(builder *flatbuffers.Builder, referToA2 flatbuffers.UOffsetT) { builder.PrependUOffsetTSlot(1, flatbuffers.UOffsetT(referToA2), 0) }
+func TableInCEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT { return builder.EndObject() }
diff --git a/tests/namespace_test/NamespaceA/TableInC.php b/tests/namespace_test/NamespaceA/TableInC.php
new file mode 100644
index 0000000..49705f8
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/TableInC.php
@@ -0,0 +1,100 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace NamespaceA;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class TableInC extends Table
+{
+    /**
+     * @param ByteBuffer $bb
+     * @return TableInC
+     */
+    public static function getRootAsTableInC(ByteBuffer $bb)
+    {
+        $obj = new TableInC();
+        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
+    }
+
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return TableInC
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    public function getReferToA1()
+    {
+        $obj = new TableInFirstNS();
+        $o = $this->__offset(4);
+        return $o != 0 ? $obj->init($this->__indirect($o + $this->bb_pos), $this->bb) : 0;
+    }
+
+    public function getReferToA2()
+    {
+        $obj = new SecondTableInA();
+        $o = $this->__offset(6);
+        return $o != 0 ? $obj->init($this->__indirect($o + $this->bb_pos), $this->bb) : 0;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return void
+     */
+    public static function startTableInC(FlatBufferBuilder $builder)
+    {
+        $builder->StartObject(2);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return TableInC
+     */
+    public static function createTableInC(FlatBufferBuilder $builder, $refer_to_a1, $refer_to_a2)
+    {
+        $builder->startObject(2);
+        self::addReferToA1($builder, $refer_to_a1);
+        self::addReferToA2($builder, $refer_to_a2);
+        $o = $builder->endObject();
+        return $o;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addReferToA1(FlatBufferBuilder $builder, $referToA1)
+    {
+        $builder->addOffsetX(0, $referToA1, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addReferToA2(FlatBufferBuilder $builder, $referToA2)
+    {
+        $builder->addOffsetX(1, $referToA2, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return int table offset
+     */
+    public static function endTableInC(FlatBufferBuilder $builder)
+    {
+        $o = $builder->endObject();
+        return $o;
+    }
+}
diff --git a/tests/namespace_test/NamespaceA/TableInC.py b/tests/namespace_test/NamespaceA/TableInC.py
new file mode 100644
index 0000000..4afea1a
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/TableInC.py
@@ -0,0 +1,39 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: NamespaceA
+
+import flatbuffers
+
+class TableInC(object):
+    __slots__ = ['_tab']
+
+    # TableInC
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # TableInC
+    def ReferToA1(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+        if o != 0:
+            x = self._tab.Indirect(o + self._tab.Pos)
+            from .TableInFirstNS import TableInFirstNS
+            obj = TableInFirstNS()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+    # TableInC
+    def ReferToA2(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
+        if o != 0:
+            x = self._tab.Indirect(o + self._tab.Pos)
+            from .SecondTableInA import SecondTableInA
+            obj = SecondTableInA()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+def TableInCStart(builder): builder.StartObject(2)
+def TableInCAddReferToA1(builder, referToA1): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(referToA1), 0)
+def TableInCAddReferToA2(builder, referToA2): builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(referToA2), 0)
+def TableInCEnd(builder): return builder.EndObject()
diff --git a/tests/namespace_test/NamespaceA/TableInFirstNS.cs b/tests/namespace_test/NamespaceA/TableInFirstNS.cs
new file mode 100644
index 0000000..d0d8ed0
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/TableInFirstNS.cs
@@ -0,0 +1,37 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace NamespaceA
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct TableInFirstNS : IFlatbufferObject
+{
+  private Table __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_11_1(); }
+  public static TableInFirstNS GetRootAsTableInFirstNS(ByteBuffer _bb) { return GetRootAsTableInFirstNS(_bb, new TableInFirstNS()); }
+  public static TableInFirstNS GetRootAsTableInFirstNS(ByteBuffer _bb, TableInFirstNS obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+  public TableInFirstNS __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public NamespaceA.NamespaceB.TableInNestedNS? FooTable { get { int o = __p.__offset(4); return o != 0 ? (NamespaceA.NamespaceB.TableInNestedNS?)(new NamespaceA.NamespaceB.TableInNestedNS()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
+  public NamespaceA.NamespaceB.EnumInNestedNS FooEnum { get { int o = __p.__offset(6); return o != 0 ? (NamespaceA.NamespaceB.EnumInNestedNS)__p.bb.GetSbyte(o + __p.bb_pos) : NamespaceA.NamespaceB.EnumInNestedNS.A; } }
+  public bool MutateFooEnum(NamespaceA.NamespaceB.EnumInNestedNS foo_enum) { int o = __p.__offset(6); if (o != 0) { __p.bb.PutSbyte(o + __p.bb_pos, (sbyte)foo_enum); return true; } else { return false; } }
+  public NamespaceA.NamespaceB.StructInNestedNS? FooStruct { get { int o = __p.__offset(8); return o != 0 ? (NamespaceA.NamespaceB.StructInNestedNS?)(new NamespaceA.NamespaceB.StructInNestedNS()).__assign(o + __p.bb_pos, __p.bb) : null; } }
+
+  public static void StartTableInFirstNS(FlatBufferBuilder builder) { builder.StartTable(3); }
+  public static void AddFooTable(FlatBufferBuilder builder, Offset<NamespaceA.NamespaceB.TableInNestedNS> fooTableOffset) { builder.AddOffset(0, fooTableOffset.Value, 0); }
+  public static void AddFooEnum(FlatBufferBuilder builder, NamespaceA.NamespaceB.EnumInNestedNS fooEnum) { builder.AddSbyte(1, (sbyte)fooEnum, 0); }
+  public static void AddFooStruct(FlatBufferBuilder builder, Offset<NamespaceA.NamespaceB.StructInNestedNS> fooStructOffset) { builder.AddStruct(2, fooStructOffset.Value, 0); }
+  public static Offset<NamespaceA.TableInFirstNS> EndTableInFirstNS(FlatBufferBuilder builder) {
+    int o = builder.EndTable();
+    return new Offset<NamespaceA.TableInFirstNS>(o);
+  }
+};
+
+
+}
diff --git a/tests/namespace_test/NamespaceA/TableInFirstNS.go b/tests/namespace_test/NamespaceA/TableInFirstNS.go
new file mode 100644
index 0000000..bbcbdc6
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/TableInFirstNS.go
@@ -0,0 +1,83 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package NamespaceA
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+
+	NamespaceA__NamespaceB "NamespaceA/NamespaceB"
+)
+
+type TableInFirstNS struct {
+	_tab flatbuffers.Table
+}
+
+func GetRootAsTableInFirstNS(buf []byte, offset flatbuffers.UOffsetT) *TableInFirstNS {
+	n := flatbuffers.GetUOffsetT(buf[offset:])
+	x := &TableInFirstNS{}
+	x.Init(buf, n+offset)
+	return x
+}
+
+func (rcv *TableInFirstNS) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *TableInFirstNS) Table() flatbuffers.Table {
+	return rcv._tab
+}
+
+func (rcv *TableInFirstNS) FooTable(obj *NamespaceA__NamespaceB.TableInNestedNS) *NamespaceA__NamespaceB.TableInNestedNS {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
+	if o != 0 {
+		x := rcv._tab.Indirect(o + rcv._tab.Pos)
+		if obj == nil {
+			obj = new(NamespaceA__NamespaceB.TableInNestedNS)
+		}
+		obj.Init(rcv._tab.Bytes, x)
+		return obj
+	}
+	return nil
+}
+
+func (rcv *TableInFirstNS) FooEnum() NamespaceA__NamespaceB.EnumInNestedNS {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
+	if o != 0 {
+		return NamespaceA__NamespaceB.EnumInNestedNS(rcv._tab.GetInt8(o + rcv._tab.Pos))
+	}
+	return 0
+}
+
+func (rcv *TableInFirstNS) MutateFooEnum(n NamespaceA__NamespaceB.EnumInNestedNS) bool {
+	return rcv._tab.MutateInt8Slot(6, int8(n))
+}
+
+func (rcv *TableInFirstNS) FooStruct(obj *NamespaceA__NamespaceB.StructInNestedNS) *NamespaceA__NamespaceB.StructInNestedNS {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(8))
+	if o != 0 {
+		x := o + rcv._tab.Pos
+		if obj == nil {
+			obj = new(NamespaceA__NamespaceB.StructInNestedNS)
+		}
+		obj.Init(rcv._tab.Bytes, x)
+		return obj
+	}
+	return nil
+}
+
+func TableInFirstNSStart(builder *flatbuffers.Builder) {
+	builder.StartObject(3)
+}
+func TableInFirstNSAddFooTable(builder *flatbuffers.Builder, fooTable flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(fooTable), 0)
+}
+func TableInFirstNSAddFooEnum(builder *flatbuffers.Builder, fooEnum NamespaceA__NamespaceB.EnumInNestedNS) {
+	builder.PrependInt8Slot(1, int8(fooEnum), 0)
+}
+func TableInFirstNSAddFooStruct(builder *flatbuffers.Builder, fooStruct flatbuffers.UOffsetT) {
+	builder.PrependStructSlot(2, flatbuffers.UOffsetT(fooStruct), 0)
+}
+func TableInFirstNSEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+	return builder.EndObject()
+}
diff --git a/tests/namespace_test/NamespaceA/TableInFirstNS.java b/tests/namespace_test/NamespaceA/TableInFirstNS.java
new file mode 100644
index 0000000..e097381
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/TableInFirstNS.java
@@ -0,0 +1,34 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceA;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class TableInFirstNS extends Table {
+  public static void ValidateVersion() { Constants.FLATBUFFERS_1_11_1(); }
+  public static TableInFirstNS getRootAsTableInFirstNS(ByteBuffer _bb) { return getRootAsTableInFirstNS(_bb, new TableInFirstNS()); }
+  public static TableInFirstNS getRootAsTableInFirstNS(ByteBuffer _bb, TableInFirstNS obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public TableInFirstNS __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public NamespaceA.NamespaceB.TableInNestedNS fooTable() { return fooTable(new NamespaceA.NamespaceB.TableInNestedNS()); }
+  public NamespaceA.NamespaceB.TableInNestedNS fooTable(NamespaceA.NamespaceB.TableInNestedNS obj) { int o = __offset(4); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; }
+  public byte fooEnum() { int o = __offset(6); return o != 0 ? bb.get(o + bb_pos) : 0; }
+  public boolean mutateFooEnum(byte foo_enum) { int o = __offset(6); if (o != 0) { bb.put(o + bb_pos, foo_enum); return true; } else { return false; } }
+  public NamespaceA.NamespaceB.StructInNestedNS fooStruct() { return fooStruct(new NamespaceA.NamespaceB.StructInNestedNS()); }
+  public NamespaceA.NamespaceB.StructInNestedNS fooStruct(NamespaceA.NamespaceB.StructInNestedNS obj) { int o = __offset(8); return o != 0 ? obj.__assign(o + bb_pos, bb) : null; }
+
+  public static void startTableInFirstNS(FlatBufferBuilder builder) { builder.startTable(3); }
+  public static void addFooTable(FlatBufferBuilder builder, int fooTableOffset) { builder.addOffset(0, fooTableOffset, 0); }
+  public static void addFooEnum(FlatBufferBuilder builder, byte fooEnum) { builder.addByte(1, fooEnum, 0); }
+  public static void addFooStruct(FlatBufferBuilder builder, int fooStructOffset) { builder.addStruct(2, fooStructOffset, 0); }
+  public static int endTableInFirstNS(FlatBufferBuilder builder) {
+    int o = builder.endTable();
+    return o;
+  }
+}
+
diff --git a/tests/namespace_test/NamespaceA/TableInFirstNS.kt b/tests/namespace_test/NamespaceA/TableInFirstNS.kt
new file mode 100644
index 0000000..1ba0afc
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/TableInFirstNS.kt
@@ -0,0 +1,68 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceA
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class TableInFirstNS : Table() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : TableInFirstNS {
+        __init(_i, _bb)
+        return this
+    }
+    val fooTable : NamespaceA.NamespaceB.TableInNestedNS? get() = fooTable(NamespaceA.NamespaceB.TableInNestedNS())
+    fun fooTable(obj: NamespaceA.NamespaceB.TableInNestedNS) : NamespaceA.NamespaceB.TableInNestedNS? {
+        val o = __offset(4)
+        return if (o != 0) {
+            obj.__assign(__indirect(o + bb_pos), bb)
+        } else {
+            null
+        }
+    }
+    val fooEnum : Byte
+        get() {
+            val o = __offset(6)
+            return if(o != 0) bb.get(o + bb_pos) else 0
+        }
+    fun mutateFooEnum(fooEnum: Byte) : Boolean {
+        val o = __offset(6)
+        return if (o != 0) {
+            bb.put(o + bb_pos, fooEnum)
+            true
+        } else {
+            false
+        }
+    }
+    val fooStruct : NamespaceA.NamespaceB.StructInNestedNS? get() = fooStruct(NamespaceA.NamespaceB.StructInNestedNS())
+    fun fooStruct(obj: NamespaceA.NamespaceB.StructInNestedNS) : NamespaceA.NamespaceB.StructInNestedNS? {
+        val o = __offset(8)
+        return if (o != 0) {
+            obj.__assign(o + bb_pos, bb)
+        } else {
+            null
+        }
+    }
+    companion object {
+        fun validateVersion() = Constants.FLATBUFFERS_1_11_1()
+        fun getRootAsTableInFirstNS(_bb: ByteBuffer): TableInFirstNS = getRootAsTableInFirstNS(_bb, TableInFirstNS())
+        fun getRootAsTableInFirstNS(_bb: ByteBuffer, obj: TableInFirstNS): TableInFirstNS {
+            _bb.order(ByteOrder.LITTLE_ENDIAN)
+            return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+        }
+        fun startTableInFirstNS(builder: FlatBufferBuilder) = builder.startTable(3)
+        fun addFooTable(builder: FlatBufferBuilder, fooTable: Int) = builder.addOffset(0, fooTable, 0)
+        fun addFooEnum(builder: FlatBufferBuilder, fooEnum: Byte) = builder.addByte(1, fooEnum, 0)
+        fun addFooStruct(builder: FlatBufferBuilder, fooStruct: Int) = builder.addStruct(2, fooStruct, 0)
+        fun endTableInFirstNS(builder: FlatBufferBuilder) : Int {
+            val o = builder.endTable()
+            return o
+        }
+    }
+}
diff --git a/tests/namespace_test/NamespaceA/TableInFirstNS.lua b/tests/namespace_test/NamespaceA/TableInFirstNS.lua
new file mode 100644
index 0000000..f70f2c7
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/TableInFirstNS.lua
@@ -0,0 +1,55 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: NamespaceA
+
+local flatbuffers = require('flatbuffers')
+
+local TableInFirstNS = {} -- the module
+local TableInFirstNS_mt = {} -- the class metatable
+
+function TableInFirstNS.New()
+    local o = {}
+    setmetatable(o, {__index = TableInFirstNS_mt})
+    return o
+end
+function TableInFirstNS.GetRootAsTableInFirstNS(buf, offset)
+    local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)
+    local o = TableInFirstNS.New()
+    o:Init(buf, n + offset)
+    return o
+end
+function TableInFirstNS_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function TableInFirstNS_mt:FooTable()
+    local o = self.view:Offset(4)
+    if o ~= 0 then
+        local x = self.view:Indirect(o + self.view.pos)
+        local obj = require('NamespaceA.NamespaceB.TableInNestedNS').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function TableInFirstNS_mt:FooEnum()
+    local o = self.view:Offset(6)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Int8, o + self.view.pos)
+    end
+    return 0
+end
+function TableInFirstNS_mt:FooStruct()
+    local o = self.view:Offset(8)
+    if o ~= 0 then
+        local x = o + self.view.pos
+        local obj = require('NamespaceA.NamespaceB.StructInNestedNS').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function TableInFirstNS.Start(builder) builder:StartObject(3) end
+function TableInFirstNS.AddFooTable(builder, fooTable) builder:PrependUOffsetTRelativeSlot(0, fooTable, 0) end
+function TableInFirstNS.AddFooEnum(builder, fooEnum) builder:PrependInt8Slot(1, fooEnum, 0) end
+function TableInFirstNS.AddFooStruct(builder, fooStruct) builder:PrependStructSlot(2, fooStruct, 0) end
+function TableInFirstNS.End(builder) return builder:EndObject() end
+
+return TableInFirstNS -- return the module
\ No newline at end of file
diff --git a/tests/namespace_test/NamespaceA/TableInFirstNS.php b/tests/namespace_test/NamespaceA/TableInFirstNS.php
new file mode 100644
index 0000000..9fb29c3
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/TableInFirstNS.php
@@ -0,0 +1,120 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace NamespaceA;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class TableInFirstNS extends Table
+{
+    /**
+     * @param ByteBuffer $bb
+     * @return TableInFirstNS
+     */
+    public static function getRootAsTableInFirstNS(ByteBuffer $bb)
+    {
+        $obj = new TableInFirstNS();
+        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
+    }
+
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return TableInFirstNS
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    public function getFooTable()
+    {
+        $obj = new TableInNestedNS();
+        $o = $this->__offset(4);
+        return $o != 0 ? $obj->init($this->__indirect($o + $this->bb_pos), $this->bb) : 0;
+    }
+
+    /**
+     * @return sbyte
+     */
+    public function getFooEnum()
+    {
+        $o = $this->__offset(6);
+        return $o != 0 ? $this->bb->getSbyte($o + $this->bb_pos) : \NamespaceA\NamespaceB\EnumInNestedNS::A;
+    }
+
+    public function getFooStruct()
+    {
+        $obj = new StructInNestedNS();
+        $o = $this->__offset(8);
+        return $o != 0 ? $obj->init($o + $this->bb_pos, $this->bb) : 0;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return void
+     */
+    public static function startTableInFirstNS(FlatBufferBuilder $builder)
+    {
+        $builder->StartObject(3);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return TableInFirstNS
+     */
+    public static function createTableInFirstNS(FlatBufferBuilder $builder, $foo_table, $foo_enum, $foo_struct)
+    {
+        $builder->startObject(3);
+        self::addFooTable($builder, $foo_table);
+        self::addFooEnum($builder, $foo_enum);
+        self::addFooStruct($builder, $foo_struct);
+        $o = $builder->endObject();
+        return $o;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addFooTable(FlatBufferBuilder $builder, $fooTable)
+    {
+        $builder->addOffsetX(0, $fooTable, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param sbyte
+     * @return void
+     */
+    public static function addFooEnum(FlatBufferBuilder $builder, $fooEnum)
+    {
+        $builder->addSbyteX(1, $fooEnum, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addFooStruct(FlatBufferBuilder $builder, $fooStruct)
+    {
+        $builder->addStructX(2, $fooStruct, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return int table offset
+     */
+    public static function endTableInFirstNS(FlatBufferBuilder $builder)
+    {
+        $o = $builder->endObject();
+        return $o;
+    }
+}
diff --git a/tests/namespace_test/NamespaceA/TableInFirstNS.py b/tests/namespace_test/NamespaceA/TableInFirstNS.py
new file mode 100644
index 0000000..40cbeba
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/TableInFirstNS.py
@@ -0,0 +1,54 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: NamespaceA
+
+import flatbuffers
+
+class TableInFirstNS(object):
+    __slots__ = ['_tab']
+
+    @classmethod
+    def GetRootAsTableInFirstNS(cls, buf, offset):
+        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
+        x = TableInFirstNS()
+        x.Init(buf, n + offset)
+        return x
+
+    # TableInFirstNS
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # TableInFirstNS
+    def FooTable(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+        if o != 0:
+            x = self._tab.Indirect(o + self._tab.Pos)
+            from .TableInNestedNS import TableInNestedNS
+            obj = TableInNestedNS()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+    # TableInFirstNS
+    def FooEnum(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Int8Flags, o + self._tab.Pos)
+        return 0
+
+    # TableInFirstNS
+    def FooStruct(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
+        if o != 0:
+            x = o + self._tab.Pos
+            from .StructInNestedNS import StructInNestedNS
+            obj = StructInNestedNS()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+def TableInFirstNSStart(builder): builder.StartObject(3)
+def TableInFirstNSAddFooTable(builder, fooTable): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(fooTable), 0)
+def TableInFirstNSAddFooEnum(builder, fooEnum): builder.PrependInt8Slot(1, fooEnum, 0)
+def TableInFirstNSAddFooStruct(builder, fooStruct): builder.PrependStructSlot(2, flatbuffers.number_types.UOffsetTFlags.py_type(fooStruct), 0)
+def TableInFirstNSEnd(builder): return builder.EndObject()
diff --git a/tests/namespace_test/NamespaceA/__init__.py b/tests/namespace_test/NamespaceA/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/__init__.py
diff --git a/tests/namespace_test/NamespaceC/TableInC.cs b/tests/namespace_test/NamespaceC/TableInC.cs
new file mode 100644
index 0000000..74b85a4
--- /dev/null
+++ b/tests/namespace_test/NamespaceC/TableInC.cs
@@ -0,0 +1,43 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace NamespaceC
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct TableInC : IFlatbufferObject
+{
+  private Table __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_11_1(); }
+  public static TableInC GetRootAsTableInC(ByteBuffer _bb) { return GetRootAsTableInC(_bb, new TableInC()); }
+  public static TableInC GetRootAsTableInC(ByteBuffer _bb, TableInC obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+  public TableInC __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public NamespaceA.TableInFirstNS? ReferToA1 { get { int o = __p.__offset(4); return o != 0 ? (NamespaceA.TableInFirstNS?)(new NamespaceA.TableInFirstNS()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
+  public NamespaceA.SecondTableInA? ReferToA2 { get { int o = __p.__offset(6); return o != 0 ? (NamespaceA.SecondTableInA?)(new NamespaceA.SecondTableInA()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
+
+  public static Offset<NamespaceC.TableInC> CreateTableInC(FlatBufferBuilder builder,
+      Offset<NamespaceA.TableInFirstNS> refer_to_a1Offset = default(Offset<NamespaceA.TableInFirstNS>),
+      Offset<NamespaceA.SecondTableInA> refer_to_a2Offset = default(Offset<NamespaceA.SecondTableInA>)) {
+    builder.StartTable(2);
+    TableInC.AddReferToA2(builder, refer_to_a2Offset);
+    TableInC.AddReferToA1(builder, refer_to_a1Offset);
+    return TableInC.EndTableInC(builder);
+  }
+
+  public static void StartTableInC(FlatBufferBuilder builder) { builder.StartTable(2); }
+  public static void AddReferToA1(FlatBufferBuilder builder, Offset<NamespaceA.TableInFirstNS> referToA1Offset) { builder.AddOffset(0, referToA1Offset.Value, 0); }
+  public static void AddReferToA2(FlatBufferBuilder builder, Offset<NamespaceA.SecondTableInA> referToA2Offset) { builder.AddOffset(1, referToA2Offset.Value, 0); }
+  public static Offset<NamespaceC.TableInC> EndTableInC(FlatBufferBuilder builder) {
+    int o = builder.EndTable();
+    return new Offset<NamespaceC.TableInC>(o);
+  }
+};
+
+
+}
diff --git a/tests/namespace_test/NamespaceC/TableInC.go b/tests/namespace_test/NamespaceC/TableInC.go
new file mode 100644
index 0000000..59b3e48
--- /dev/null
+++ b/tests/namespace_test/NamespaceC/TableInC.go
@@ -0,0 +1,68 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package NamespaceC
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+
+	NamespaceA "NamespaceA"
+)
+
+type TableInC struct {
+	_tab flatbuffers.Table
+}
+
+func GetRootAsTableInC(buf []byte, offset flatbuffers.UOffsetT) *TableInC {
+	n := flatbuffers.GetUOffsetT(buf[offset:])
+	x := &TableInC{}
+	x.Init(buf, n+offset)
+	return x
+}
+
+func (rcv *TableInC) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *TableInC) Table() flatbuffers.Table {
+	return rcv._tab
+}
+
+func (rcv *TableInC) ReferToA1(obj *NamespaceA.TableInFirstNS) *NamespaceA.TableInFirstNS {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
+	if o != 0 {
+		x := rcv._tab.Indirect(o + rcv._tab.Pos)
+		if obj == nil {
+			obj = new(NamespaceA.TableInFirstNS)
+		}
+		obj.Init(rcv._tab.Bytes, x)
+		return obj
+	}
+	return nil
+}
+
+func (rcv *TableInC) ReferToA2(obj *NamespaceA.SecondTableInA) *NamespaceA.SecondTableInA {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
+	if o != 0 {
+		x := rcv._tab.Indirect(o + rcv._tab.Pos)
+		if obj == nil {
+			obj = new(NamespaceA.SecondTableInA)
+		}
+		obj.Init(rcv._tab.Bytes, x)
+		return obj
+	}
+	return nil
+}
+
+func TableInCStart(builder *flatbuffers.Builder) {
+	builder.StartObject(2)
+}
+func TableInCAddReferToA1(builder *flatbuffers.Builder, referToA1 flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(referToA1), 0)
+}
+func TableInCAddReferToA2(builder *flatbuffers.Builder, referToA2 flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(1, flatbuffers.UOffsetT(referToA2), 0)
+}
+func TableInCEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+	return builder.EndObject()
+}
diff --git a/tests/namespace_test/NamespaceC/TableInC.java b/tests/namespace_test/NamespaceC/TableInC.java
new file mode 100644
index 0000000..2d9e4bf
--- /dev/null
+++ b/tests/namespace_test/NamespaceC/TableInC.java
@@ -0,0 +1,40 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceC;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class TableInC extends Table {
+  public static void ValidateVersion() { Constants.FLATBUFFERS_1_11_1(); }
+  public static TableInC getRootAsTableInC(ByteBuffer _bb) { return getRootAsTableInC(_bb, new TableInC()); }
+  public static TableInC getRootAsTableInC(ByteBuffer _bb, TableInC obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public TableInC __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public NamespaceA.TableInFirstNS referToA1() { return referToA1(new NamespaceA.TableInFirstNS()); }
+  public NamespaceA.TableInFirstNS referToA1(NamespaceA.TableInFirstNS obj) { int o = __offset(4); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; }
+  public NamespaceA.SecondTableInA referToA2() { return referToA2(new NamespaceA.SecondTableInA()); }
+  public NamespaceA.SecondTableInA referToA2(NamespaceA.SecondTableInA obj) { int o = __offset(6); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; }
+
+  public static int createTableInC(FlatBufferBuilder builder,
+      int refer_to_a1Offset,
+      int refer_to_a2Offset) {
+    builder.startTable(2);
+    TableInC.addReferToA2(builder, refer_to_a2Offset);
+    TableInC.addReferToA1(builder, refer_to_a1Offset);
+    return TableInC.endTableInC(builder);
+  }
+
+  public static void startTableInC(FlatBufferBuilder builder) { builder.startTable(2); }
+  public static void addReferToA1(FlatBufferBuilder builder, int referToA1Offset) { builder.addOffset(0, referToA1Offset, 0); }
+  public static void addReferToA2(FlatBufferBuilder builder, int referToA2Offset) { builder.addOffset(1, referToA2Offset, 0); }
+  public static int endTableInC(FlatBufferBuilder builder) {
+    int o = builder.endTable();
+    return o;
+  }
+}
+
diff --git a/tests/namespace_test/NamespaceC/TableInC.kt b/tests/namespace_test/NamespaceC/TableInC.kt
new file mode 100644
index 0000000..e468642
--- /dev/null
+++ b/tests/namespace_test/NamespaceC/TableInC.kt
@@ -0,0 +1,59 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceC
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class TableInC : Table() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : TableInC {
+        __init(_i, _bb)
+        return this
+    }
+    val referToA1 : NamespaceA.TableInFirstNS? get() = referToA1(NamespaceA.TableInFirstNS())
+    fun referToA1(obj: NamespaceA.TableInFirstNS) : NamespaceA.TableInFirstNS? {
+        val o = __offset(4)
+        return if (o != 0) {
+            obj.__assign(__indirect(o + bb_pos), bb)
+        } else {
+            null
+        }
+    }
+    val referToA2 : NamespaceA.SecondTableInA? get() = referToA2(NamespaceA.SecondTableInA())
+    fun referToA2(obj: NamespaceA.SecondTableInA) : NamespaceA.SecondTableInA? {
+        val o = __offset(6)
+        return if (o != 0) {
+            obj.__assign(__indirect(o + bb_pos), bb)
+        } else {
+            null
+        }
+    }
+    companion object {
+        fun validateVersion() = Constants.FLATBUFFERS_1_11_1()
+        fun getRootAsTableInC(_bb: ByteBuffer): TableInC = getRootAsTableInC(_bb, TableInC())
+        fun getRootAsTableInC(_bb: ByteBuffer, obj: TableInC): TableInC {
+            _bb.order(ByteOrder.LITTLE_ENDIAN)
+            return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+        }
+        fun createTableInC(builder: FlatBufferBuilder, referToA1Offset: Int, referToA2Offset: Int) : Int {
+            builder.startTable(2)
+            addReferToA2(builder, referToA2Offset)
+            addReferToA1(builder, referToA1Offset)
+            return endTableInC(builder)
+        }
+        fun startTableInC(builder: FlatBufferBuilder) = builder.startTable(2)
+        fun addReferToA1(builder: FlatBufferBuilder, referToA1: Int) = builder.addOffset(0, referToA1, 0)
+        fun addReferToA2(builder: FlatBufferBuilder, referToA2: Int) = builder.addOffset(1, referToA2, 0)
+        fun endTableInC(builder: FlatBufferBuilder) : Int {
+            val o = builder.endTable()
+            return o
+        }
+    }
+}
diff --git a/tests/namespace_test/NamespaceC/TableInC.lua b/tests/namespace_test/NamespaceC/TableInC.lua
new file mode 100644
index 0000000..bb4fef0
--- /dev/null
+++ b/tests/namespace_test/NamespaceC/TableInC.lua
@@ -0,0 +1,47 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: NamespaceC
+
+local flatbuffers = require('flatbuffers')
+
+local TableInC = {} -- the module
+local TableInC_mt = {} -- the class metatable
+
+function TableInC.New()
+    local o = {}
+    setmetatable(o, {__index = TableInC_mt})
+    return o
+end
+function TableInC.GetRootAsTableInC(buf, offset)
+    local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)
+    local o = TableInC.New()
+    o:Init(buf, n + offset)
+    return o
+end
+function TableInC_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function TableInC_mt:ReferToA1()
+    local o = self.view:Offset(4)
+    if o ~= 0 then
+        local x = self.view:Indirect(o + self.view.pos)
+        local obj = require('NamespaceA.TableInFirstNS').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function TableInC_mt:ReferToA2()
+    local o = self.view:Offset(6)
+    if o ~= 0 then
+        local x = self.view:Indirect(o + self.view.pos)
+        local obj = require('NamespaceA.SecondTableInA').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function TableInC.Start(builder) builder:StartObject(2) end
+function TableInC.AddReferToA1(builder, referToA1) builder:PrependUOffsetTRelativeSlot(0, referToA1, 0) end
+function TableInC.AddReferToA2(builder, referToA2) builder:PrependUOffsetTRelativeSlot(1, referToA2, 0) end
+function TableInC.End(builder) return builder:EndObject() end
+
+return TableInC -- return the module
\ No newline at end of file
diff --git a/tests/namespace_test/NamespaceC/TableInC.php b/tests/namespace_test/NamespaceC/TableInC.php
new file mode 100644
index 0000000..116aea1
--- /dev/null
+++ b/tests/namespace_test/NamespaceC/TableInC.php
@@ -0,0 +1,100 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace NamespaceC;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class TableInC extends Table
+{
+    /**
+     * @param ByteBuffer $bb
+     * @return TableInC
+     */
+    public static function getRootAsTableInC(ByteBuffer $bb)
+    {
+        $obj = new TableInC();
+        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
+    }
+
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return TableInC
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    public function getReferToA1()
+    {
+        $obj = new TableInFirstNS();
+        $o = $this->__offset(4);
+        return $o != 0 ? $obj->init($this->__indirect($o + $this->bb_pos), $this->bb) : 0;
+    }
+
+    public function getReferToA2()
+    {
+        $obj = new SecondTableInA();
+        $o = $this->__offset(6);
+        return $o != 0 ? $obj->init($this->__indirect($o + $this->bb_pos), $this->bb) : 0;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return void
+     */
+    public static function startTableInC(FlatBufferBuilder $builder)
+    {
+        $builder->StartObject(2);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return TableInC
+     */
+    public static function createTableInC(FlatBufferBuilder $builder, $refer_to_a1, $refer_to_a2)
+    {
+        $builder->startObject(2);
+        self::addReferToA1($builder, $refer_to_a1);
+        self::addReferToA2($builder, $refer_to_a2);
+        $o = $builder->endObject();
+        return $o;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addReferToA1(FlatBufferBuilder $builder, $referToA1)
+    {
+        $builder->addOffsetX(0, $referToA1, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addReferToA2(FlatBufferBuilder $builder, $referToA2)
+    {
+        $builder->addOffsetX(1, $referToA2, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return int table offset
+     */
+    public static function endTableInC(FlatBufferBuilder $builder)
+    {
+        $o = $builder->endObject();
+        return $o;
+    }
+}
diff --git a/tests/namespace_test/NamespaceC/TableInC.py b/tests/namespace_test/NamespaceC/TableInC.py
new file mode 100644
index 0000000..90b8736
--- /dev/null
+++ b/tests/namespace_test/NamespaceC/TableInC.py
@@ -0,0 +1,46 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: NamespaceC
+
+import flatbuffers
+
+class TableInC(object):
+    __slots__ = ['_tab']
+
+    @classmethod
+    def GetRootAsTableInC(cls, buf, offset):
+        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
+        x = TableInC()
+        x.Init(buf, n + offset)
+        return x
+
+    # TableInC
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # TableInC
+    def ReferToA1(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+        if o != 0:
+            x = self._tab.Indirect(o + self._tab.Pos)
+            from .TableInFirstNS import TableInFirstNS
+            obj = TableInFirstNS()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+    # TableInC
+    def ReferToA2(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
+        if o != 0:
+            x = self._tab.Indirect(o + self._tab.Pos)
+            from .SecondTableInA import SecondTableInA
+            obj = SecondTableInA()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+def TableInCStart(builder): builder.StartObject(2)
+def TableInCAddReferToA1(builder, referToA1): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(referToA1), 0)
+def TableInCAddReferToA2(builder, referToA2): builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(referToA2), 0)
+def TableInCEnd(builder): return builder.EndObject()
diff --git a/tests/namespace_test/NamespaceC/__init__.py b/tests/namespace_test/NamespaceC/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/namespace_test/NamespaceC/__init__.py
diff --git a/tests/namespace_test/namespace_test1.fbs b/tests/namespace_test/namespace_test1.fbs
new file mode 100644
index 0000000..49449bf
--- /dev/null
+++ b/tests/namespace_test/namespace_test1.fbs
@@ -0,0 +1,17 @@
+namespace NamespaceA.NamespaceB;
+
+table TableInNestedNS
+{
+    foo:int;
+}
+
+enum EnumInNestedNS:byte
+{
+	A, B, C
+}
+
+struct StructInNestedNS
+{
+    a:int;
+	b:int;
+}
\ No newline at end of file
diff --git a/tests/namespace_test/namespace_test1_generated.h b/tests/namespace_test/namespace_test1_generated.h
new file mode 100644
index 0000000..daaf7ae
--- /dev/null
+++ b/tests/namespace_test/namespace_test1_generated.h
@@ -0,0 +1,182 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+#ifndef FLATBUFFERS_GENERATED_NAMESPACETEST1_NAMESPACEA_NAMESPACEB_H_
+#define FLATBUFFERS_GENERATED_NAMESPACETEST1_NAMESPACEA_NAMESPACEB_H_
+
+#include "flatbuffers/flatbuffers.h"
+
+namespace NamespaceA {
+namespace NamespaceB {
+
+struct TableInNestedNS;
+
+struct StructInNestedNS;
+
+inline const flatbuffers::TypeTable *TableInNestedNSTypeTable();
+
+inline const flatbuffers::TypeTable *StructInNestedNSTypeTable();
+
+enum EnumInNestedNS {
+  EnumInNestedNS_A = 0,
+  EnumInNestedNS_B = 1,
+  EnumInNestedNS_C = 2,
+  EnumInNestedNS_MIN = EnumInNestedNS_A,
+  EnumInNestedNS_MAX = EnumInNestedNS_C
+};
+
+inline const EnumInNestedNS (&EnumValuesEnumInNestedNS())[3] {
+  static const EnumInNestedNS values[] = {
+    EnumInNestedNS_A,
+    EnumInNestedNS_B,
+    EnumInNestedNS_C
+  };
+  return values;
+}
+
+inline const char * const *EnumNamesEnumInNestedNS() {
+  static const char * const names[4] = {
+    "A",
+    "B",
+    "C",
+    nullptr
+  };
+  return names;
+}
+
+inline const char *EnumNameEnumInNestedNS(EnumInNestedNS e) {
+  if (e < EnumInNestedNS_A || e > EnumInNestedNS_C) return "";
+  const size_t index = static_cast<size_t>(e);
+  return EnumNamesEnumInNestedNS()[index];
+}
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) StructInNestedNS FLATBUFFERS_FINAL_CLASS {
+ private:
+  int32_t a_;
+  int32_t b_;
+
+ public:
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return StructInNestedNSTypeTable();
+  }
+  StructInNestedNS() {
+    memset(static_cast<void *>(this), 0, sizeof(StructInNestedNS));
+  }
+  StructInNestedNS(int32_t _a, int32_t _b)
+      : a_(flatbuffers::EndianScalar(_a)),
+        b_(flatbuffers::EndianScalar(_b)) {
+  }
+  int32_t a() const {
+    return flatbuffers::EndianScalar(a_);
+  }
+  void mutate_a(int32_t _a) {
+    flatbuffers::WriteScalar(&a_, _a);
+  }
+  int32_t b() const {
+    return flatbuffers::EndianScalar(b_);
+  }
+  void mutate_b(int32_t _b) {
+    flatbuffers::WriteScalar(&b_, _b);
+  }
+};
+FLATBUFFERS_STRUCT_END(StructInNestedNS, 8);
+
+struct TableInNestedNS FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return TableInNestedNSTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_FOO = 4
+  };
+  int32_t foo() const {
+    return GetField<int32_t>(VT_FOO, 0);
+  }
+  bool mutate_foo(int32_t _foo) {
+    return SetField<int32_t>(VT_FOO, _foo, 0);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<int32_t>(verifier, VT_FOO) &&
+           verifier.EndTable();
+  }
+};
+
+struct TableInNestedNSBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_foo(int32_t foo) {
+    fbb_.AddElement<int32_t>(TableInNestedNS::VT_FOO, foo, 0);
+  }
+  explicit TableInNestedNSBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  TableInNestedNSBuilder &operator=(const TableInNestedNSBuilder &);
+  flatbuffers::Offset<TableInNestedNS> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<TableInNestedNS>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<TableInNestedNS> CreateTableInNestedNS(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    int32_t foo = 0) {
+  TableInNestedNSBuilder builder_(_fbb);
+  builder_.add_foo(foo);
+  return builder_.Finish();
+}
+
+inline const flatbuffers::TypeTable *EnumInNestedNSTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_CHAR, 0, 0 },
+    { flatbuffers::ET_CHAR, 0, 0 },
+    { flatbuffers::ET_CHAR, 0, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    NamespaceA::NamespaceB::EnumInNestedNSTypeTable
+  };
+  static const char * const names[] = {
+    "A",
+    "B",
+    "C"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_ENUM, 3, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *TableInNestedNSTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_INT, 0, -1 }
+  };
+  static const char * const names[] = {
+    "foo"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 1, type_codes, nullptr, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *StructInNestedNSTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_INT, 0, -1 },
+    { flatbuffers::ET_INT, 0, -1 }
+  };
+  static const int64_t values[] = { 0, 4, 8 };
+  static const char * const names[] = {
+    "a",
+    "b"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_STRUCT, 2, type_codes, nullptr, values, names
+  };
+  return &tt;
+}
+
+}  // namespace NamespaceB
+}  // namespace NamespaceA
+
+#endif  // FLATBUFFERS_GENERATED_NAMESPACETEST1_NAMESPACEA_NAMESPACEB_H_
diff --git a/tests/namespace_test/namespace_test1_generated.js b/tests/namespace_test/namespace_test1_generated.js
new file mode 100644
index 0000000..bd018d6
--- /dev/null
+++ b/tests/namespace_test/namespace_test1_generated.js
@@ -0,0 +1,219 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+/**
+ * @const
+ * @namespace
+ */
+var NamespaceA = NamespaceA || {};
+
+/**
+ * @const
+ * @namespace
+ */
+NamespaceA.NamespaceB = NamespaceA.NamespaceB || {};
+
+/**
+ * @enum {number}
+ */
+NamespaceA.NamespaceB.EnumInNestedNS = {
+  A: 0,
+  B: 1,
+  C: 2
+};
+
+/**
+ * @enum {string}
+ */
+NamespaceA.NamespaceB.EnumInNestedNSName = {
+  0: 'A',
+  1: 'B',
+  2: 'C'
+};
+
+/**
+ * @constructor
+ */
+NamespaceA.NamespaceB.TableInNestedNS = function() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+};
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {NamespaceA.NamespaceB.TableInNestedNS}
+ */
+NamespaceA.NamespaceB.TableInNestedNS.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {NamespaceA.NamespaceB.TableInNestedNS=} obj
+ * @returns {NamespaceA.NamespaceB.TableInNestedNS}
+ */
+NamespaceA.NamespaceB.TableInNestedNS.getRootAsTableInNestedNS = function(bb, obj) {
+  return (obj || new NamespaceA.NamespaceB.TableInNestedNS).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {NamespaceA.NamespaceB.TableInNestedNS=} obj
+ * @returns {NamespaceA.NamespaceB.TableInNestedNS}
+ */
+NamespaceA.NamespaceB.TableInNestedNS.getSizePrefixedRootAsTableInNestedNS = function(bb, obj) {
+  return (obj || new NamespaceA.NamespaceB.TableInNestedNS).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @returns {number}
+ */
+NamespaceA.NamespaceB.TableInNestedNS.prototype.foo = function() {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+  return offset ? this.bb.readInt32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+NamespaceA.NamespaceB.TableInNestedNS.prototype.mutate_foo = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ */
+NamespaceA.NamespaceB.TableInNestedNS.startTableInNestedNS = function(builder) {
+  builder.startObject(1);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} foo
+ */
+NamespaceA.NamespaceB.TableInNestedNS.addFoo = function(builder, foo) {
+  builder.addFieldInt32(0, foo, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @returns {flatbuffers.Offset}
+ */
+NamespaceA.NamespaceB.TableInNestedNS.endTableInNestedNS = function(builder) {
+  var offset = builder.endObject();
+  return offset;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} foo
+ * @returns {flatbuffers.Offset}
+ */
+NamespaceA.NamespaceB.TableInNestedNS.createTableInNestedNS = function(builder, foo) {
+  NamespaceA.NamespaceB.TableInNestedNS.startTableInNestedNS(builder);
+  NamespaceA.NamespaceB.TableInNestedNS.addFoo(builder, foo);
+  return NamespaceA.NamespaceB.TableInNestedNS.endTableInNestedNS(builder);
+}
+
+/**
+ * @constructor
+ */
+NamespaceA.NamespaceB.StructInNestedNS = function() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+};
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {NamespaceA.NamespaceB.StructInNestedNS}
+ */
+NamespaceA.NamespaceB.StructInNestedNS.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @returns {number}
+ */
+NamespaceA.NamespaceB.StructInNestedNS.prototype.a = function() {
+  return this.bb.readInt32(this.bb_pos);
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+NamespaceA.NamespaceB.StructInNestedNS.prototype.mutate_a = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 0);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+NamespaceA.NamespaceB.StructInNestedNS.prototype.b = function() {
+  return this.bb.readInt32(this.bb_pos + 4);
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+NamespaceA.NamespaceB.StructInNestedNS.prototype.mutate_b = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} a
+ * @param {number} b
+ * @returns {flatbuffers.Offset}
+ */
+NamespaceA.NamespaceB.StructInNestedNS.createStructInNestedNS = function(builder, a, b) {
+  builder.prep(4, 8);
+  builder.writeInt32(b);
+  builder.writeInt32(a);
+  return builder.offset();
+};
+
+// Exports for Node.js and RequireJS
+this.NamespaceA = NamespaceA;
diff --git a/tests/namespace_test/namespace_test1_generated.lobster b/tests/namespace_test/namespace_test1_generated.lobster
new file mode 100644
index 0000000..6503005
--- /dev/null
+++ b/tests/namespace_test/namespace_test1_generated.lobster
@@ -0,0 +1,43 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+import flatbuffers
+
+namespace NamespaceA_NamespaceB
+
+enum EnumInNestedNS:
+    EnumInNestedNS_A = 0
+    EnumInNestedNS_B = 1
+    EnumInNestedNS_C = 2
+
+class TableInNestedNS
+
+class StructInNestedNS
+
+class TableInNestedNS : flatbuffers_handle
+    def foo():
+        return buf_.flatbuffers_field_int32(pos_, 4, 0)
+
+def GetRootAsTableInNestedNS(buf:string): return TableInNestedNS { buf, buf.flatbuffers_indirect(0) }
+
+struct TableInNestedNSBuilder:
+    b_:flatbuffers_builder
+    def start():
+        b_.StartObject(1)
+        return this
+    def add_foo(foo:int):
+        b_.PrependInt32Slot(0, foo, 0)
+        return this
+    def end():
+        return b_.EndObject()
+
+class StructInNestedNS : flatbuffers_handle
+    def a():
+        return buf_.read_int32_le(pos_ + 0)
+    def b():
+        return buf_.read_int32_le(pos_ + 4)
+
+def CreateStructInNestedNS(b_:flatbuffers_builder, a:int, b:int):
+    b_.Prep(4, 8)
+    b_.PrependInt32(b)
+    b_.PrependInt32(a)
+    return b_.Offset()
+
diff --git a/tests/namespace_test/namespace_test1_generated.rs b/tests/namespace_test/namespace_test1_generated.rs
new file mode 100644
index 0000000..ab30299
--- /dev/null
+++ b/tests/namespace_test/namespace_test1_generated.rs
@@ -0,0 +1,230 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+
+use std::mem;
+use std::cmp::Ordering;
+
+extern crate flatbuffers;
+use self::flatbuffers::EndianScalar;
+
+#[allow(unused_imports, dead_code)]
+pub mod namespace_a {
+
+  use std::mem;
+  use std::cmp::Ordering;
+
+  extern crate flatbuffers;
+  use self::flatbuffers::EndianScalar;
+#[allow(unused_imports, dead_code)]
+pub mod namespace_b {
+
+  use std::mem;
+  use std::cmp::Ordering;
+
+  extern crate flatbuffers;
+  use self::flatbuffers::EndianScalar;
+
+#[allow(non_camel_case_types)]
+#[repr(i8)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+pub enum EnumInNestedNS {
+  A = 0,
+  B = 1,
+  C = 2,
+
+}
+
+const ENUM_MIN_ENUM_IN_NESTED_NS: i8 = 0;
+const ENUM_MAX_ENUM_IN_NESTED_NS: i8 = 2;
+
+impl<'a> flatbuffers::Follow<'a> for EnumInNestedNS {
+  type Inner = Self;
+  #[inline]
+  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    flatbuffers::read_scalar_at::<Self>(buf, loc)
+  }
+}
+
+impl flatbuffers::EndianScalar for EnumInNestedNS {
+  #[inline]
+  fn to_little_endian(self) -> Self {
+    let n = i8::to_le(self as i8);
+    let p = &n as *const i8 as *const EnumInNestedNS;
+    unsafe { *p }
+  }
+  #[inline]
+  fn from_little_endian(self) -> Self {
+    let n = i8::from_le(self as i8);
+    let p = &n as *const i8 as *const EnumInNestedNS;
+    unsafe { *p }
+  }
+}
+
+impl flatbuffers::Push for EnumInNestedNS {
+    type Output = EnumInNestedNS;
+    #[inline]
+    fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+        flatbuffers::emplace_scalar::<EnumInNestedNS>(dst, *self);
+    }
+}
+
+#[allow(non_camel_case_types)]
+const ENUM_VALUES_ENUM_IN_NESTED_NS:[EnumInNestedNS; 3] = [
+  EnumInNestedNS::A,
+  EnumInNestedNS::B,
+  EnumInNestedNS::C
+];
+
+#[allow(non_camel_case_types)]
+const ENUM_NAMES_ENUM_IN_NESTED_NS:[&'static str; 3] = [
+    "A",
+    "B",
+    "C"
+];
+
+pub fn enum_name_enum_in_nested_ns(e: EnumInNestedNS) -> &'static str {
+  let index = e as i8;
+  ENUM_NAMES_ENUM_IN_NESTED_NS[index as usize]
+}
+
+// struct StructInNestedNS, aligned to 4
+#[repr(C, align(4))]
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub struct StructInNestedNS {
+  a_: i32,
+  b_: i32,
+} // pub struct StructInNestedNS
+impl flatbuffers::SafeSliceAccess for StructInNestedNS {}
+impl<'a> flatbuffers::Follow<'a> for StructInNestedNS {
+  type Inner = &'a StructInNestedNS;
+  #[inline]
+  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    <&'a StructInNestedNS>::follow(buf, loc)
+  }
+}
+impl<'a> flatbuffers::Follow<'a> for &'a StructInNestedNS {
+  type Inner = &'a StructInNestedNS;
+  #[inline]
+  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    flatbuffers::follow_cast_ref::<StructInNestedNS>(buf, loc)
+  }
+}
+impl<'b> flatbuffers::Push for StructInNestedNS {
+    type Output = StructInNestedNS;
+    #[inline]
+    fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+        let src = unsafe {
+            ::std::slice::from_raw_parts(self as *const StructInNestedNS as *const u8, Self::size())
+        };
+        dst.copy_from_slice(src);
+    }
+}
+impl<'b> flatbuffers::Push for &'b StructInNestedNS {
+    type Output = StructInNestedNS;
+
+    #[inline]
+    fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+        let src = unsafe {
+            ::std::slice::from_raw_parts(*self as *const StructInNestedNS as *const u8, Self::size())
+        };
+        dst.copy_from_slice(src);
+    }
+}
+
+
+impl StructInNestedNS {
+  pub fn new<'a>(_a: i32, _b: i32) -> Self {
+    StructInNestedNS {
+      a_: _a.to_little_endian(),
+      b_: _b.to_little_endian(),
+
+    }
+  }
+  pub fn a<'a>(&'a self) -> i32 {
+    self.a_.from_little_endian()
+  }
+  pub fn b<'a>(&'a self) -> i32 {
+    self.b_.from_little_endian()
+  }
+}
+
+pub enum TableInNestedNSOffset {}
+#[derive(Copy, Clone, Debug, PartialEq)]
+
+pub struct TableInNestedNS<'a> {
+  pub _tab: flatbuffers::Table<'a>,
+}
+
+impl<'a> flatbuffers::Follow<'a> for TableInNestedNS<'a> {
+    type Inner = TableInNestedNS<'a>;
+    #[inline]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        Self {
+            _tab: flatbuffers::Table { buf: buf, loc: loc },
+        }
+    }
+}
+
+impl<'a> TableInNestedNS<'a> {
+    #[inline]
+    pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
+        TableInNestedNS {
+            _tab: table,
+        }
+    }
+    #[allow(unused_mut)]
+    pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
+        _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
+        args: &'args TableInNestedNSArgs) -> flatbuffers::WIPOffset<TableInNestedNS<'bldr>> {
+      let mut builder = TableInNestedNSBuilder::new(_fbb);
+      builder.add_foo(args.foo);
+      builder.finish()
+    }
+
+    pub const VT_FOO: flatbuffers::VOffsetT = 4;
+
+  #[inline]
+  pub fn foo(&self) -> i32 {
+    self._tab.get::<i32>(TableInNestedNS::VT_FOO, Some(0)).unwrap()
+  }
+}
+
+pub struct TableInNestedNSArgs {
+    pub foo: i32,
+}
+impl<'a> Default for TableInNestedNSArgs {
+    #[inline]
+    fn default() -> Self {
+        TableInNestedNSArgs {
+            foo: 0,
+        }
+    }
+}
+pub struct TableInNestedNSBuilder<'a: 'b, 'b> {
+  fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
+  start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
+}
+impl<'a: 'b, 'b> TableInNestedNSBuilder<'a, 'b> {
+  #[inline]
+  pub fn add_foo(&mut self, foo: i32) {
+    self.fbb_.push_slot::<i32>(TableInNestedNS::VT_FOO, foo, 0);
+  }
+  #[inline]
+  pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> TableInNestedNSBuilder<'a, 'b> {
+    let start = _fbb.start_table();
+    TableInNestedNSBuilder {
+      fbb_: _fbb,
+      start_: start,
+    }
+  }
+  #[inline]
+  pub fn finish(self) -> flatbuffers::WIPOffset<TableInNestedNS<'a>> {
+    let o = self.fbb_.end_table(self.start_);
+    flatbuffers::WIPOffset::new(o.value())
+  }
+}
+
+}  // pub mod NamespaceB
+}  // pub mod NamespaceA
+
diff --git a/tests/namespace_test/namespace_test1_generated.ts b/tests/namespace_test/namespace_test1_generated.ts
new file mode 100644
index 0000000..615c7ce
--- /dev/null
+++ b/tests/namespace_test/namespace_test1_generated.ts
@@ -0,0 +1,181 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+/**
+ * @enum {number}
+ */
+export namespace NamespaceA.NamespaceB{
+export enum EnumInNestedNS{
+  A= 0,
+  B= 1,
+  C= 2
+}};
+
+/**
+ * @constructor
+ */
+export namespace NamespaceA.NamespaceB{
+export class TableInNestedNS {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns TableInNestedNS
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):TableInNestedNS {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param TableInNestedNS= obj
+ * @returns TableInNestedNS
+ */
+static getRootAsTableInNestedNS(bb:flatbuffers.ByteBuffer, obj?:TableInNestedNS):TableInNestedNS {
+  return (obj || new TableInNestedNS).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param TableInNestedNS= obj
+ * @returns TableInNestedNS
+ */
+static getSizePrefixedRootAsTableInNestedNS(bb:flatbuffers.ByteBuffer, obj?:TableInNestedNS):TableInNestedNS {
+  return (obj || new TableInNestedNS).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @returns number
+ */
+foo():number {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+  return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_foo(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ */
+static startTableInNestedNS(builder:flatbuffers.Builder) {
+  builder.startObject(1);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number foo
+ */
+static addFoo(builder:flatbuffers.Builder, foo:number) {
+  builder.addFieldInt32(0, foo, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @returns flatbuffers.Offset
+ */
+static endTableInNestedNS(builder:flatbuffers.Builder):flatbuffers.Offset {
+  var offset = builder.endObject();
+  return offset;
+};
+
+static createTableInNestedNS(builder:flatbuffers.Builder, foo:number):flatbuffers.Offset {
+  TableInNestedNS.startTableInNestedNS(builder);
+  TableInNestedNS.addFoo(builder, foo);
+  return TableInNestedNS.endTableInNestedNS(builder);
+}
+}
+}
+/**
+ * @constructor
+ */
+export namespace NamespaceA.NamespaceB{
+export class StructInNestedNS {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns StructInNestedNS
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):StructInNestedNS {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @returns number
+ */
+a():number {
+  return this.bb!.readInt32(this.bb_pos);
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_a(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 0);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+b():number {
+  return this.bb!.readInt32(this.bb_pos + 4);
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_b(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number a
+ * @param number b
+ * @returns flatbuffers.Offset
+ */
+static createStructInNestedNS(builder:flatbuffers.Builder, a: number, b: number):flatbuffers.Offset {
+  builder.prep(4, 8);
+  builder.writeInt32(b);
+  builder.writeInt32(a);
+  return builder.offset();
+};
+
+}
+}
diff --git a/tests/namespace_test/namespace_test1_namespace_a.namespace_b_generated.dart b/tests/namespace_test/namespace_test1_namespace_a.namespace_b_generated.dart
new file mode 100644
index 0000000..f999e44
--- /dev/null
+++ b/tests/namespace_test/namespace_test1_namespace_a.namespace_b_generated.dart
@@ -0,0 +1,198 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+// ignore_for_file: unused_import, unused_field, unused_local_variable
+
+library namespace_a.namespace_b;
+
+import 'dart:typed_data' show Uint8List;
+import 'package:flat_buffers/flat_buffers.dart' as fb;
+
+
+class EnumInNestedNS {
+  final int value;
+  const EnumInNestedNS._(this.value);
+
+  factory EnumInNestedNS.fromValue(int value) {
+    if (value == null) value = 0;
+    if (!values.containsKey(value)) {
+      throw new StateError('Invalid value $value for bit flag enum EnumInNestedNS');
+    }
+    return values[value];
+  }
+
+  static const int minValue = 0;
+  static const int maxValue = 2;
+  static bool containsValue(int value) => values.containsKey(value);
+
+  static const EnumInNestedNS A = const EnumInNestedNS._(0);
+  static const EnumInNestedNS B = const EnumInNestedNS._(1);
+  static const EnumInNestedNS C = const EnumInNestedNS._(2);
+  static get values => {0: A,1: B,2: C,};
+
+  static const fb.Reader<EnumInNestedNS> reader = const _EnumInNestedNSReader();
+
+  @override
+  String toString() {
+    return 'EnumInNestedNS{value: $value}';
+  }
+}
+
+class _EnumInNestedNSReader extends fb.Reader<EnumInNestedNS> {
+  const _EnumInNestedNSReader();
+
+  @override
+  int get size => 1;
+
+  @override
+  EnumInNestedNS read(fb.BufferContext bc, int offset) =>
+      new EnumInNestedNS.fromValue(const fb.Int8Reader().read(bc, offset));
+}
+
+class TableInNestedNS {
+  TableInNestedNS._(this._bc, this._bcOffset);
+  factory TableInNestedNS(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<TableInNestedNS> reader = const _TableInNestedNSReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  int get foo => const fb.Int32Reader().vTableGet(_bc, _bcOffset, 4, 0);
+
+  @override
+  String toString() {
+    return 'TableInNestedNS{foo: $foo}';
+  }
+}
+
+class _TableInNestedNSReader extends fb.TableReader<TableInNestedNS> {
+  const _TableInNestedNSReader();
+
+  @override
+  TableInNestedNS createObject(fb.BufferContext bc, int offset) => 
+    new TableInNestedNS._(bc, offset);
+}
+
+class TableInNestedNSBuilder {
+  TableInNestedNSBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  void begin() {
+    fbBuilder.startTable();
+  }
+
+  int addFoo(int foo) {
+    fbBuilder.addInt32(0, foo);
+    return fbBuilder.offset;
+  }
+
+  int finish() {
+    return fbBuilder.endTable();
+  }
+}
+
+class TableInNestedNSObjectBuilder extends fb.ObjectBuilder {
+  final int _foo;
+
+  TableInNestedNSObjectBuilder({
+    int foo,
+  })
+      : _foo = foo;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+
+    fbBuilder.startTable();
+    fbBuilder.addInt32(0, _foo);
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
+class StructInNestedNS {
+  StructInNestedNS._(this._bc, this._bcOffset);
+
+  static const fb.Reader<StructInNestedNS> reader = const _StructInNestedNSReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  int get a => const fb.Int32Reader().read(_bc, _bcOffset + 0);
+  int get b => const fb.Int32Reader().read(_bc, _bcOffset + 4);
+
+  @override
+  String toString() {
+    return 'StructInNestedNS{a: $a, b: $b}';
+  }
+}
+
+class _StructInNestedNSReader extends fb.StructReader<StructInNestedNS> {
+  const _StructInNestedNSReader();
+
+  @override
+  int get size => 8;
+
+  @override
+  StructInNestedNS createObject(fb.BufferContext bc, int offset) => 
+    new StructInNestedNS._(bc, offset);
+}
+
+class StructInNestedNSBuilder {
+  StructInNestedNSBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  int finish(int a, int b) {
+    fbBuilder.putInt32(b);
+    fbBuilder.putInt32(a);
+    return fbBuilder.offset;
+  }
+
+}
+
+class StructInNestedNSObjectBuilder extends fb.ObjectBuilder {
+  final int _a;
+  final int _b;
+
+  StructInNestedNSObjectBuilder({
+    int a,
+    int b,
+  })
+      : _a = a,
+        _b = b;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+
+    fbBuilder.putInt32(_b);
+    fbBuilder.putInt32(_a);
+    return fbBuilder.offset;
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
diff --git a/tests/namespace_test/namespace_test2.fbs b/tests/namespace_test/namespace_test2.fbs
new file mode 100644
index 0000000..11d7dea
--- /dev/null
+++ b/tests/namespace_test/namespace_test2.fbs
@@ -0,0 +1,24 @@
+include "namespace_test1.fbs";
+
+namespace NamespaceA;
+
+table TableInFirstNS
+{
+    foo_table:NamespaceB.TableInNestedNS;
+	foo_enum:NamespaceB.EnumInNestedNS;
+	foo_struct:NamespaceB.StructInNestedNS;
+}
+
+// Test switching namespaces inside a file.
+namespace NamespaceC;
+
+table TableInC {
+    refer_to_a1:NamespaceA.TableInFirstNS;
+    refer_to_a2:NamespaceA.SecondTableInA;
+}
+
+namespace NamespaceA;
+
+table SecondTableInA {
+    refer_to_c:NamespaceC.TableInC;
+}
diff --git a/tests/namespace_test/namespace_test2_generated.h b/tests/namespace_test/namespace_test2_generated.h
new file mode 100644
index 0000000..135100a
--- /dev/null
+++ b/tests/namespace_test/namespace_test2_generated.h
@@ -0,0 +1,305 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+#ifndef FLATBUFFERS_GENERATED_NAMESPACETEST2_NAMESPACEA_H_
+#define FLATBUFFERS_GENERATED_NAMESPACETEST2_NAMESPACEA_H_
+
+#include "flatbuffers/flatbuffers.h"
+
+#include "namespace_test1_generated.h"
+
+namespace NamespaceA {
+
+struct TableInFirstNS;
+
+}  // namespace NamespaceA
+
+namespace NamespaceC {
+
+struct TableInC;
+
+}  // namespace NamespaceC
+
+namespace NamespaceA {
+
+struct SecondTableInA;
+
+inline const flatbuffers::TypeTable *TableInFirstNSTypeTable();
+
+}  // namespace NamespaceA
+
+namespace NamespaceC {
+
+inline const flatbuffers::TypeTable *TableInCTypeTable();
+
+}  // namespace NamespaceC
+
+namespace NamespaceA {
+
+inline const flatbuffers::TypeTable *SecondTableInATypeTable();
+
+struct TableInFirstNS FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return TableInFirstNSTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_FOO_TABLE = 4,
+    VT_FOO_ENUM = 6,
+    VT_FOO_STRUCT = 8
+  };
+  const NamespaceA::NamespaceB::TableInNestedNS *foo_table() const {
+    return GetPointer<const NamespaceA::NamespaceB::TableInNestedNS *>(VT_FOO_TABLE);
+  }
+  NamespaceA::NamespaceB::TableInNestedNS *mutable_foo_table() {
+    return GetPointer<NamespaceA::NamespaceB::TableInNestedNS *>(VT_FOO_TABLE);
+  }
+  NamespaceA::NamespaceB::EnumInNestedNS foo_enum() const {
+    return static_cast<NamespaceA::NamespaceB::EnumInNestedNS>(GetField<int8_t>(VT_FOO_ENUM, 0));
+  }
+  bool mutate_foo_enum(NamespaceA::NamespaceB::EnumInNestedNS _foo_enum) {
+    return SetField<int8_t>(VT_FOO_ENUM, static_cast<int8_t>(_foo_enum), 0);
+  }
+  const NamespaceA::NamespaceB::StructInNestedNS *foo_struct() const {
+    return GetStruct<const NamespaceA::NamespaceB::StructInNestedNS *>(VT_FOO_STRUCT);
+  }
+  NamespaceA::NamespaceB::StructInNestedNS *mutable_foo_struct() {
+    return GetStruct<NamespaceA::NamespaceB::StructInNestedNS *>(VT_FOO_STRUCT);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyOffset(verifier, VT_FOO_TABLE) &&
+           verifier.VerifyTable(foo_table()) &&
+           VerifyField<int8_t>(verifier, VT_FOO_ENUM) &&
+           VerifyField<NamespaceA::NamespaceB::StructInNestedNS>(verifier, VT_FOO_STRUCT) &&
+           verifier.EndTable();
+  }
+};
+
+struct TableInFirstNSBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_foo_table(flatbuffers::Offset<NamespaceA::NamespaceB::TableInNestedNS> foo_table) {
+    fbb_.AddOffset(TableInFirstNS::VT_FOO_TABLE, foo_table);
+  }
+  void add_foo_enum(NamespaceA::NamespaceB::EnumInNestedNS foo_enum) {
+    fbb_.AddElement<int8_t>(TableInFirstNS::VT_FOO_ENUM, static_cast<int8_t>(foo_enum), 0);
+  }
+  void add_foo_struct(const NamespaceA::NamespaceB::StructInNestedNS *foo_struct) {
+    fbb_.AddStruct(TableInFirstNS::VT_FOO_STRUCT, foo_struct);
+  }
+  explicit TableInFirstNSBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  TableInFirstNSBuilder &operator=(const TableInFirstNSBuilder &);
+  flatbuffers::Offset<TableInFirstNS> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<TableInFirstNS>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<TableInFirstNS> CreateTableInFirstNS(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<NamespaceA::NamespaceB::TableInNestedNS> foo_table = 0,
+    NamespaceA::NamespaceB::EnumInNestedNS foo_enum = NamespaceA::NamespaceB::EnumInNestedNS_A,
+    const NamespaceA::NamespaceB::StructInNestedNS *foo_struct = 0) {
+  TableInFirstNSBuilder builder_(_fbb);
+  builder_.add_foo_struct(foo_struct);
+  builder_.add_foo_table(foo_table);
+  builder_.add_foo_enum(foo_enum);
+  return builder_.Finish();
+}
+
+}  // namespace NamespaceA
+
+namespace NamespaceC {
+
+struct TableInC FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return TableInCTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_REFER_TO_A1 = 4,
+    VT_REFER_TO_A2 = 6
+  };
+  const NamespaceA::TableInFirstNS *refer_to_a1() const {
+    return GetPointer<const NamespaceA::TableInFirstNS *>(VT_REFER_TO_A1);
+  }
+  NamespaceA::TableInFirstNS *mutable_refer_to_a1() {
+    return GetPointer<NamespaceA::TableInFirstNS *>(VT_REFER_TO_A1);
+  }
+  const NamespaceA::SecondTableInA *refer_to_a2() const {
+    return GetPointer<const NamespaceA::SecondTableInA *>(VT_REFER_TO_A2);
+  }
+  NamespaceA::SecondTableInA *mutable_refer_to_a2() {
+    return GetPointer<NamespaceA::SecondTableInA *>(VT_REFER_TO_A2);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyOffset(verifier, VT_REFER_TO_A1) &&
+           verifier.VerifyTable(refer_to_a1()) &&
+           VerifyOffset(verifier, VT_REFER_TO_A2) &&
+           verifier.VerifyTable(refer_to_a2()) &&
+           verifier.EndTable();
+  }
+};
+
+struct TableInCBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_refer_to_a1(flatbuffers::Offset<NamespaceA::TableInFirstNS> refer_to_a1) {
+    fbb_.AddOffset(TableInC::VT_REFER_TO_A1, refer_to_a1);
+  }
+  void add_refer_to_a2(flatbuffers::Offset<NamespaceA::SecondTableInA> refer_to_a2) {
+    fbb_.AddOffset(TableInC::VT_REFER_TO_A2, refer_to_a2);
+  }
+  explicit TableInCBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  TableInCBuilder &operator=(const TableInCBuilder &);
+  flatbuffers::Offset<TableInC> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<TableInC>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<TableInC> CreateTableInC(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<NamespaceA::TableInFirstNS> refer_to_a1 = 0,
+    flatbuffers::Offset<NamespaceA::SecondTableInA> refer_to_a2 = 0) {
+  TableInCBuilder builder_(_fbb);
+  builder_.add_refer_to_a2(refer_to_a2);
+  builder_.add_refer_to_a1(refer_to_a1);
+  return builder_.Finish();
+}
+
+}  // namespace NamespaceC
+
+namespace NamespaceA {
+
+struct SecondTableInA FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return SecondTableInATypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_REFER_TO_C = 4
+  };
+  const NamespaceC::TableInC *refer_to_c() const {
+    return GetPointer<const NamespaceC::TableInC *>(VT_REFER_TO_C);
+  }
+  NamespaceC::TableInC *mutable_refer_to_c() {
+    return GetPointer<NamespaceC::TableInC *>(VT_REFER_TO_C);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyOffset(verifier, VT_REFER_TO_C) &&
+           verifier.VerifyTable(refer_to_c()) &&
+           verifier.EndTable();
+  }
+};
+
+struct SecondTableInABuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_refer_to_c(flatbuffers::Offset<NamespaceC::TableInC> refer_to_c) {
+    fbb_.AddOffset(SecondTableInA::VT_REFER_TO_C, refer_to_c);
+  }
+  explicit SecondTableInABuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  SecondTableInABuilder &operator=(const SecondTableInABuilder &);
+  flatbuffers::Offset<SecondTableInA> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<SecondTableInA>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<SecondTableInA> CreateSecondTableInA(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<NamespaceC::TableInC> refer_to_c = 0) {
+  SecondTableInABuilder builder_(_fbb);
+  builder_.add_refer_to_c(refer_to_c);
+  return builder_.Finish();
+}
+
+}  // namespace NamespaceA
+
+namespace NamespaceC {
+
+}  // namespace NamespaceC
+
+namespace NamespaceA {
+
+inline const flatbuffers::TypeTable *TableInFirstNSTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SEQUENCE, 0, 0 },
+    { flatbuffers::ET_CHAR, 0, 1 },
+    { flatbuffers::ET_SEQUENCE, 0, 2 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    NamespaceA::NamespaceB::TableInNestedNSTypeTable,
+    NamespaceA::NamespaceB::EnumInNestedNSTypeTable,
+    NamespaceA::NamespaceB::StructInNestedNSTypeTable
+  };
+  static const char * const names[] = {
+    "foo_table",
+    "foo_enum",
+    "foo_struct"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 3, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+}  // namespace NamespaceA
+
+namespace NamespaceC {
+
+inline const flatbuffers::TypeTable *TableInCTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SEQUENCE, 0, 0 },
+    { flatbuffers::ET_SEQUENCE, 0, 1 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    NamespaceA::TableInFirstNSTypeTable,
+    NamespaceA::SecondTableInATypeTable
+  };
+  static const char * const names[] = {
+    "refer_to_a1",
+    "refer_to_a2"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 2, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+}  // namespace NamespaceC
+
+namespace NamespaceA {
+
+inline const flatbuffers::TypeTable *SecondTableInATypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SEQUENCE, 0, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    NamespaceC::TableInCTypeTable
+  };
+  static const char * const names[] = {
+    "refer_to_c"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 1, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+}  // namespace NamespaceA
+
+#endif  // FLATBUFFERS_GENERATED_NAMESPACETEST2_NAMESPACEA_H_
diff --git a/tests/namespace_test/namespace_test2_generated.js b/tests/namespace_test/namespace_test2_generated.js
new file mode 100644
index 0000000..f54cda7
--- /dev/null
+++ b/tests/namespace_test/namespace_test2_generated.js
@@ -0,0 +1,358 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+/**
+ * @const
+ * @namespace
+ */
+var NamespaceA = NamespaceA || {};
+
+/**
+ * @const
+ * @namespace
+ */
+NamespaceA.NamespaceB = NamespaceA.NamespaceB || {};
+
+/**
+ * @const
+ * @namespace
+ */
+var NamespaceC = NamespaceC || {};
+
+/**
+ * @constructor
+ */
+NamespaceA.TableInFirstNS = function() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+};
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {NamespaceA.TableInFirstNS}
+ */
+NamespaceA.TableInFirstNS.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {NamespaceA.TableInFirstNS=} obj
+ * @returns {NamespaceA.TableInFirstNS}
+ */
+NamespaceA.TableInFirstNS.getRootAsTableInFirstNS = function(bb, obj) {
+  return (obj || new NamespaceA.TableInFirstNS).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {NamespaceA.TableInFirstNS=} obj
+ * @returns {NamespaceA.TableInFirstNS}
+ */
+NamespaceA.TableInFirstNS.getSizePrefixedRootAsTableInFirstNS = function(bb, obj) {
+  return (obj || new NamespaceA.TableInFirstNS).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {NamespaceA.NamespaceB.TableInNestedNS=} obj
+ * @returns {NamespaceA.NamespaceB.TableInNestedNS|null}
+ */
+NamespaceA.TableInFirstNS.prototype.fooTable = function(obj) {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+  return offset ? (obj || new NamespaceA.NamespaceB.TableInNestedNS).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null;
+};
+
+/**
+ * @returns {NamespaceA.NamespaceB.EnumInNestedNS}
+ */
+NamespaceA.TableInFirstNS.prototype.fooEnum = function() {
+  var offset = this.bb.__offset(this.bb_pos, 6);
+  return offset ? /** @type {NamespaceA.NamespaceB.EnumInNestedNS} */ (this.bb.readInt8(this.bb_pos + offset)) : NamespaceA.NamespaceB.EnumInNestedNS.A;
+};
+
+/**
+ * @param {NamespaceA.NamespaceB.EnumInNestedNS} value
+ * @returns {boolean}
+ */
+NamespaceA.TableInFirstNS.prototype.mutate_foo_enum = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 6);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {NamespaceA.NamespaceB.StructInNestedNS=} obj
+ * @returns {NamespaceA.NamespaceB.StructInNestedNS|null}
+ */
+NamespaceA.TableInFirstNS.prototype.fooStruct = function(obj) {
+  var offset = this.bb.__offset(this.bb_pos, 8);
+  return offset ? (obj || new NamespaceA.NamespaceB.StructInNestedNS).__init(this.bb_pos + offset, this.bb) : null;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ */
+NamespaceA.TableInFirstNS.startTableInFirstNS = function(builder) {
+  builder.startObject(3);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} fooTableOffset
+ */
+NamespaceA.TableInFirstNS.addFooTable = function(builder, fooTableOffset) {
+  builder.addFieldOffset(0, fooTableOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {NamespaceA.NamespaceB.EnumInNestedNS} fooEnum
+ */
+NamespaceA.TableInFirstNS.addFooEnum = function(builder, fooEnum) {
+  builder.addFieldInt8(1, fooEnum, NamespaceA.NamespaceB.EnumInNestedNS.A);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} fooStructOffset
+ */
+NamespaceA.TableInFirstNS.addFooStruct = function(builder, fooStructOffset) {
+  builder.addFieldStruct(2, fooStructOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @returns {flatbuffers.Offset}
+ */
+NamespaceA.TableInFirstNS.endTableInFirstNS = function(builder) {
+  var offset = builder.endObject();
+  return offset;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} fooTableOffset
+ * @param {NS8755221360535654258.NamespaceA.NamespaceB.EnumInNestedNS} fooEnum
+ * @param {flatbuffers.Offset} fooStructOffset
+ * @returns {flatbuffers.Offset}
+ */
+NamespaceA.TableInFirstNS.createTableInFirstNS = function(builder, fooTableOffset, fooEnum, fooStructOffset) {
+  NamespaceA.TableInFirstNS.startTableInFirstNS(builder);
+  NamespaceA.TableInFirstNS.addFooTable(builder, fooTableOffset);
+  NamespaceA.TableInFirstNS.addFooEnum(builder, fooEnum);
+  NamespaceA.TableInFirstNS.addFooStruct(builder, fooStructOffset);
+  return NamespaceA.TableInFirstNS.endTableInFirstNS(builder);
+}
+
+/**
+ * @constructor
+ */
+NamespaceC.TableInC = function() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+};
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {NamespaceC.TableInC}
+ */
+NamespaceC.TableInC.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {NamespaceC.TableInC=} obj
+ * @returns {NamespaceC.TableInC}
+ */
+NamespaceC.TableInC.getRootAsTableInC = function(bb, obj) {
+  return (obj || new NamespaceC.TableInC).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {NamespaceC.TableInC=} obj
+ * @returns {NamespaceC.TableInC}
+ */
+NamespaceC.TableInC.getSizePrefixedRootAsTableInC = function(bb, obj) {
+  return (obj || new NamespaceC.TableInC).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {NamespaceA.TableInFirstNS=} obj
+ * @returns {NamespaceA.TableInFirstNS|null}
+ */
+NamespaceC.TableInC.prototype.referToA1 = function(obj) {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+  return offset ? (obj || new NamespaceA.TableInFirstNS).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null;
+};
+
+/**
+ * @param {NamespaceA.SecondTableInA=} obj
+ * @returns {NamespaceA.SecondTableInA|null}
+ */
+NamespaceC.TableInC.prototype.referToA2 = function(obj) {
+  var offset = this.bb.__offset(this.bb_pos, 6);
+  return offset ? (obj || new NamespaceA.SecondTableInA).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ */
+NamespaceC.TableInC.startTableInC = function(builder) {
+  builder.startObject(2);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} referToA1Offset
+ */
+NamespaceC.TableInC.addReferToA1 = function(builder, referToA1Offset) {
+  builder.addFieldOffset(0, referToA1Offset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} referToA2Offset
+ */
+NamespaceC.TableInC.addReferToA2 = function(builder, referToA2Offset) {
+  builder.addFieldOffset(1, referToA2Offset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @returns {flatbuffers.Offset}
+ */
+NamespaceC.TableInC.endTableInC = function(builder) {
+  var offset = builder.endObject();
+  return offset;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} referToA1Offset
+ * @param {flatbuffers.Offset} referToA2Offset
+ * @returns {flatbuffers.Offset}
+ */
+NamespaceC.TableInC.createTableInC = function(builder, referToA1Offset, referToA2Offset) {
+  NamespaceC.TableInC.startTableInC(builder);
+  NamespaceC.TableInC.addReferToA1(builder, referToA1Offset);
+  NamespaceC.TableInC.addReferToA2(builder, referToA2Offset);
+  return NamespaceC.TableInC.endTableInC(builder);
+}
+
+/**
+ * @constructor
+ */
+NamespaceA.SecondTableInA = function() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+};
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {NamespaceA.SecondTableInA}
+ */
+NamespaceA.SecondTableInA.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {NamespaceA.SecondTableInA=} obj
+ * @returns {NamespaceA.SecondTableInA}
+ */
+NamespaceA.SecondTableInA.getRootAsSecondTableInA = function(bb, obj) {
+  return (obj || new NamespaceA.SecondTableInA).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {NamespaceA.SecondTableInA=} obj
+ * @returns {NamespaceA.SecondTableInA}
+ */
+NamespaceA.SecondTableInA.getSizePrefixedRootAsSecondTableInA = function(bb, obj) {
+  return (obj || new NamespaceA.SecondTableInA).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {NamespaceC.TableInC=} obj
+ * @returns {NamespaceC.TableInC|null}
+ */
+NamespaceA.SecondTableInA.prototype.referToC = function(obj) {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+  return offset ? (obj || new NamespaceC.TableInC).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ */
+NamespaceA.SecondTableInA.startSecondTableInA = function(builder) {
+  builder.startObject(1);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} referToCOffset
+ */
+NamespaceA.SecondTableInA.addReferToC = function(builder, referToCOffset) {
+  builder.addFieldOffset(0, referToCOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @returns {flatbuffers.Offset}
+ */
+NamespaceA.SecondTableInA.endSecondTableInA = function(builder) {
+  var offset = builder.endObject();
+  return offset;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} referToCOffset
+ * @returns {flatbuffers.Offset}
+ */
+NamespaceA.SecondTableInA.createSecondTableInA = function(builder, referToCOffset) {
+  NamespaceA.SecondTableInA.startSecondTableInA(builder);
+  NamespaceA.SecondTableInA.addReferToC(builder, referToCOffset);
+  return NamespaceA.SecondTableInA.endSecondTableInA(builder);
+}
+
+// Exports for Node.js and RequireJS
+this.NamespaceA = NamespaceA;
+this.NamespaceC = NamespaceC;
diff --git a/tests/namespace_test/namespace_test2_generated.lobster b/tests/namespace_test/namespace_test2_generated.lobster
new file mode 100644
index 0000000..4383e68
--- /dev/null
+++ b/tests/namespace_test/namespace_test2_generated.lobster
@@ -0,0 +1,90 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+import flatbuffers
+
+namespace NamespaceA
+
+class TableInFirstNS
+
+namespace NamespaceC
+
+class TableInC
+
+namespace NamespaceA
+
+class SecondTableInA
+
+class TableInFirstNS : flatbuffers_handle
+    def foo_table():
+        let o = buf_.flatbuffers_field_table(pos_, 4)
+        return if o: NamespaceA_NamespaceB_TableInNestedNS { buf_, o } else: nil
+    def foo_enum():
+        return EnumInNestedNS(buf_.flatbuffers_field_int8(pos_, 6, 0))
+    def foo_struct():
+        let o = buf_.flatbuffers_field_struct(pos_, 8)
+        return if o: NamespaceA_NamespaceB_StructInNestedNS { buf_, o } else: nil
+
+def GetRootAsTableInFirstNS(buf:string): return TableInFirstNS { buf, buf.flatbuffers_indirect(0) }
+
+struct TableInFirstNSBuilder:
+    b_:flatbuffers_builder
+    def start():
+        b_.StartObject(3)
+        return this
+    def add_foo_table(foo_table:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(0, foo_table)
+        return this
+    def add_foo_enum(foo_enum:EnumInNestedNS):
+        b_.PrependInt8Slot(1, foo_enum, 0)
+        return this
+    def add_foo_struct(foo_struct:flatbuffers_offset):
+        b_.PrependStructSlot(2, foo_struct)
+        return this
+    def end():
+        return b_.EndObject()
+
+namespace NamespaceC
+
+class TableInC : flatbuffers_handle
+    def refer_to_a1():
+        let o = buf_.flatbuffers_field_table(pos_, 4)
+        return if o: NamespaceA_TableInFirstNS { buf_, o } else: nil
+    def refer_to_a2():
+        let o = buf_.flatbuffers_field_table(pos_, 6)
+        return if o: NamespaceA_SecondTableInA { buf_, o } else: nil
+
+def GetRootAsTableInC(buf:string): return TableInC { buf, buf.flatbuffers_indirect(0) }
+
+struct TableInCBuilder:
+    b_:flatbuffers_builder
+    def start():
+        b_.StartObject(2)
+        return this
+    def add_refer_to_a1(refer_to_a1:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(0, refer_to_a1)
+        return this
+    def add_refer_to_a2(refer_to_a2:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(1, refer_to_a2)
+        return this
+    def end():
+        return b_.EndObject()
+
+namespace NamespaceA
+
+class SecondTableInA : flatbuffers_handle
+    def refer_to_c():
+        let o = buf_.flatbuffers_field_table(pos_, 4)
+        return if o: NamespaceC_TableInC { buf_, o } else: nil
+
+def GetRootAsSecondTableInA(buf:string): return SecondTableInA { buf, buf.flatbuffers_indirect(0) }
+
+struct SecondTableInABuilder:
+    b_:flatbuffers_builder
+    def start():
+        b_.StartObject(1)
+        return this
+    def add_refer_to_c(refer_to_c:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(0, refer_to_c)
+        return this
+    def end():
+        return b_.EndObject()
+
diff --git a/tests/namespace_test/namespace_test2_generated.rs b/tests/namespace_test/namespace_test2_generated.rs
new file mode 100644
index 0000000..3c04c0f
--- /dev/null
+++ b/tests/namespace_test/namespace_test2_generated.rs
@@ -0,0 +1,296 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+
+use std::mem;
+use std::cmp::Ordering;
+
+extern crate flatbuffers;
+use self::flatbuffers::EndianScalar;
+
+#[allow(unused_imports, dead_code)]
+pub mod namespace_a {
+
+  use std::mem;
+  use std::cmp::Ordering;
+
+  extern crate flatbuffers;
+  use self::flatbuffers::EndianScalar;
+
+pub enum TableInFirstNSOffset {}
+#[derive(Copy, Clone, Debug, PartialEq)]
+
+pub struct TableInFirstNS<'a> {
+  pub _tab: flatbuffers::Table<'a>,
+}
+
+impl<'a> flatbuffers::Follow<'a> for TableInFirstNS<'a> {
+    type Inner = TableInFirstNS<'a>;
+    #[inline]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        Self {
+            _tab: flatbuffers::Table { buf: buf, loc: loc },
+        }
+    }
+}
+
+impl<'a> TableInFirstNS<'a> {
+    #[inline]
+    pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
+        TableInFirstNS {
+            _tab: table,
+        }
+    }
+    #[allow(unused_mut)]
+    pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
+        _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
+        args: &'args TableInFirstNSArgs<'args>) -> flatbuffers::WIPOffset<TableInFirstNS<'bldr>> {
+      let mut builder = TableInFirstNSBuilder::new(_fbb);
+      if let Some(x) = args.foo_struct { builder.add_foo_struct(x); }
+      if let Some(x) = args.foo_table { builder.add_foo_table(x); }
+      builder.add_foo_enum(args.foo_enum);
+      builder.finish()
+    }
+
+    pub const VT_FOO_TABLE: flatbuffers::VOffsetT = 4;
+    pub const VT_FOO_ENUM: flatbuffers::VOffsetT = 6;
+    pub const VT_FOO_STRUCT: flatbuffers::VOffsetT = 8;
+
+  #[inline]
+  pub fn foo_table(&self) -> Option<namespace_b::TableInNestedNS<'a>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<namespace_b::TableInNestedNS<'a>>>(TableInFirstNS::VT_FOO_TABLE, None)
+  }
+  #[inline]
+  pub fn foo_enum(&self) -> namespace_b::EnumInNestedNS {
+    self._tab.get::<namespace_b::EnumInNestedNS>(TableInFirstNS::VT_FOO_ENUM, Some(namespace_b::EnumInNestedNS::A)).unwrap()
+  }
+  #[inline]
+  pub fn foo_struct(&self) -> Option<&'a namespace_b::StructInNestedNS> {
+    self._tab.get::<namespace_b::StructInNestedNS>(TableInFirstNS::VT_FOO_STRUCT, None)
+  }
+}
+
+pub struct TableInFirstNSArgs<'a> {
+    pub foo_table: Option<flatbuffers::WIPOffset<namespace_b::TableInNestedNS<'a >>>,
+    pub foo_enum: namespace_b::EnumInNestedNS,
+    pub foo_struct: Option<&'a  namespace_b::StructInNestedNS>,
+}
+impl<'a> Default for TableInFirstNSArgs<'a> {
+    #[inline]
+    fn default() -> Self {
+        TableInFirstNSArgs {
+            foo_table: None,
+            foo_enum: namespace_b::EnumInNestedNS::A,
+            foo_struct: None,
+        }
+    }
+}
+pub struct TableInFirstNSBuilder<'a: 'b, 'b> {
+  fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
+  start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
+}
+impl<'a: 'b, 'b> TableInFirstNSBuilder<'a, 'b> {
+  #[inline]
+  pub fn add_foo_table(&mut self, foo_table: flatbuffers::WIPOffset<namespace_b::TableInNestedNS<'b >>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<namespace_b::TableInNestedNS>>(TableInFirstNS::VT_FOO_TABLE, foo_table);
+  }
+  #[inline]
+  pub fn add_foo_enum(&mut self, foo_enum: namespace_b::EnumInNestedNS) {
+    self.fbb_.push_slot::<namespace_b::EnumInNestedNS>(TableInFirstNS::VT_FOO_ENUM, foo_enum, namespace_b::EnumInNestedNS::A);
+  }
+  #[inline]
+  pub fn add_foo_struct(&mut self, foo_struct: &'b  namespace_b::StructInNestedNS) {
+    self.fbb_.push_slot_always::<&namespace_b::StructInNestedNS>(TableInFirstNS::VT_FOO_STRUCT, foo_struct);
+  }
+  #[inline]
+  pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> TableInFirstNSBuilder<'a, 'b> {
+    let start = _fbb.start_table();
+    TableInFirstNSBuilder {
+      fbb_: _fbb,
+      start_: start,
+    }
+  }
+  #[inline]
+  pub fn finish(self) -> flatbuffers::WIPOffset<TableInFirstNS<'a>> {
+    let o = self.fbb_.end_table(self.start_);
+    flatbuffers::WIPOffset::new(o.value())
+  }
+}
+
+pub enum SecondTableInAOffset {}
+#[derive(Copy, Clone, Debug, PartialEq)]
+
+pub struct SecondTableInA<'a> {
+  pub _tab: flatbuffers::Table<'a>,
+}
+
+impl<'a> flatbuffers::Follow<'a> for SecondTableInA<'a> {
+    type Inner = SecondTableInA<'a>;
+    #[inline]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        Self {
+            _tab: flatbuffers::Table { buf: buf, loc: loc },
+        }
+    }
+}
+
+impl<'a> SecondTableInA<'a> {
+    #[inline]
+    pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
+        SecondTableInA {
+            _tab: table,
+        }
+    }
+    #[allow(unused_mut)]
+    pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
+        _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
+        args: &'args SecondTableInAArgs<'args>) -> flatbuffers::WIPOffset<SecondTableInA<'bldr>> {
+      let mut builder = SecondTableInABuilder::new(_fbb);
+      if let Some(x) = args.refer_to_c { builder.add_refer_to_c(x); }
+      builder.finish()
+    }
+
+    pub const VT_REFER_TO_C: flatbuffers::VOffsetT = 4;
+
+  #[inline]
+  pub fn refer_to_c(&self) -> Option<super::namespace_c::TableInC<'a>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<super::namespace_c::TableInC<'a>>>(SecondTableInA::VT_REFER_TO_C, None)
+  }
+}
+
+pub struct SecondTableInAArgs<'a> {
+    pub refer_to_c: Option<flatbuffers::WIPOffset<super::namespace_c::TableInC<'a >>>,
+}
+impl<'a> Default for SecondTableInAArgs<'a> {
+    #[inline]
+    fn default() -> Self {
+        SecondTableInAArgs {
+            refer_to_c: None,
+        }
+    }
+}
+pub struct SecondTableInABuilder<'a: 'b, 'b> {
+  fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
+  start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
+}
+impl<'a: 'b, 'b> SecondTableInABuilder<'a, 'b> {
+  #[inline]
+  pub fn add_refer_to_c(&mut self, refer_to_c: flatbuffers::WIPOffset<super::namespace_c::TableInC<'b >>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<super::namespace_c::TableInC>>(SecondTableInA::VT_REFER_TO_C, refer_to_c);
+  }
+  #[inline]
+  pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> SecondTableInABuilder<'a, 'b> {
+    let start = _fbb.start_table();
+    SecondTableInABuilder {
+      fbb_: _fbb,
+      start_: start,
+    }
+  }
+  #[inline]
+  pub fn finish(self) -> flatbuffers::WIPOffset<SecondTableInA<'a>> {
+    let o = self.fbb_.end_table(self.start_);
+    flatbuffers::WIPOffset::new(o.value())
+  }
+}
+
+}  // pub mod NamespaceA
+
+#[allow(unused_imports, dead_code)]
+pub mod namespace_c {
+
+  use std::mem;
+  use std::cmp::Ordering;
+
+  extern crate flatbuffers;
+  use self::flatbuffers::EndianScalar;
+
+pub enum TableInCOffset {}
+#[derive(Copy, Clone, Debug, PartialEq)]
+
+pub struct TableInC<'a> {
+  pub _tab: flatbuffers::Table<'a>,
+}
+
+impl<'a> flatbuffers::Follow<'a> for TableInC<'a> {
+    type Inner = TableInC<'a>;
+    #[inline]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        Self {
+            _tab: flatbuffers::Table { buf: buf, loc: loc },
+        }
+    }
+}
+
+impl<'a> TableInC<'a> {
+    #[inline]
+    pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
+        TableInC {
+            _tab: table,
+        }
+    }
+    #[allow(unused_mut)]
+    pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
+        _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
+        args: &'args TableInCArgs<'args>) -> flatbuffers::WIPOffset<TableInC<'bldr>> {
+      let mut builder = TableInCBuilder::new(_fbb);
+      if let Some(x) = args.refer_to_a2 { builder.add_refer_to_a2(x); }
+      if let Some(x) = args.refer_to_a1 { builder.add_refer_to_a1(x); }
+      builder.finish()
+    }
+
+    pub const VT_REFER_TO_A1: flatbuffers::VOffsetT = 4;
+    pub const VT_REFER_TO_A2: flatbuffers::VOffsetT = 6;
+
+  #[inline]
+  pub fn refer_to_a1(&self) -> Option<super::namespace_a::TableInFirstNS<'a>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<super::namespace_a::TableInFirstNS<'a>>>(TableInC::VT_REFER_TO_A1, None)
+  }
+  #[inline]
+  pub fn refer_to_a2(&self) -> Option<super::namespace_a::SecondTableInA<'a>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<super::namespace_a::SecondTableInA<'a>>>(TableInC::VT_REFER_TO_A2, None)
+  }
+}
+
+pub struct TableInCArgs<'a> {
+    pub refer_to_a1: Option<flatbuffers::WIPOffset<super::namespace_a::TableInFirstNS<'a >>>,
+    pub refer_to_a2: Option<flatbuffers::WIPOffset<super::namespace_a::SecondTableInA<'a >>>,
+}
+impl<'a> Default for TableInCArgs<'a> {
+    #[inline]
+    fn default() -> Self {
+        TableInCArgs {
+            refer_to_a1: None,
+            refer_to_a2: None,
+        }
+    }
+}
+pub struct TableInCBuilder<'a: 'b, 'b> {
+  fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
+  start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
+}
+impl<'a: 'b, 'b> TableInCBuilder<'a, 'b> {
+  #[inline]
+  pub fn add_refer_to_a1(&mut self, refer_to_a1: flatbuffers::WIPOffset<super::namespace_a::TableInFirstNS<'b >>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<super::namespace_a::TableInFirstNS>>(TableInC::VT_REFER_TO_A1, refer_to_a1);
+  }
+  #[inline]
+  pub fn add_refer_to_a2(&mut self, refer_to_a2: flatbuffers::WIPOffset<super::namespace_a::SecondTableInA<'b >>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<super::namespace_a::SecondTableInA>>(TableInC::VT_REFER_TO_A2, refer_to_a2);
+  }
+  #[inline]
+  pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> TableInCBuilder<'a, 'b> {
+    let start = _fbb.start_table();
+    TableInCBuilder {
+      fbb_: _fbb,
+      start_: start,
+    }
+  }
+  #[inline]
+  pub fn finish(self) -> flatbuffers::WIPOffset<TableInC<'a>> {
+    let o = self.fbb_.end_table(self.start_);
+    flatbuffers::WIPOffset::new(o.value())
+  }
+}
+
+}  // pub mod NamespaceC
+
diff --git a/tests/namespace_test/namespace_test2_generated.ts b/tests/namespace_test/namespace_test2_generated.ts
new file mode 100644
index 0000000..7bd0543
--- /dev/null
+++ b/tests/namespace_test/namespace_test2_generated.ts
@@ -0,0 +1,302 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+import * as NS8755221360535654258 from "./namespace_test1_generated";
+/**
+ * @constructor
+ */
+export namespace NamespaceA{
+export class TableInFirstNS {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns TableInFirstNS
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):TableInFirstNS {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param TableInFirstNS= obj
+ * @returns TableInFirstNS
+ */
+static getRootAsTableInFirstNS(bb:flatbuffers.ByteBuffer, obj?:TableInFirstNS):TableInFirstNS {
+  return (obj || new TableInFirstNS).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param TableInFirstNS= obj
+ * @returns TableInFirstNS
+ */
+static getSizePrefixedRootAsTableInFirstNS(bb:flatbuffers.ByteBuffer, obj?:TableInFirstNS):TableInFirstNS {
+  return (obj || new TableInFirstNS).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param NamespaceA.NamespaceB.TableInNestedNS= obj
+ * @returns NamespaceA.NamespaceB.TableInNestedNS|null
+ */
+fooTable(obj?:NS8755221360535654258.NamespaceA.NamespaceB.TableInNestedNS):NS8755221360535654258.NamespaceA.NamespaceB.TableInNestedNS|null {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+  return offset ? (obj || new NS8755221360535654258.NamespaceA.NamespaceB.TableInNestedNS).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
+};
+
+/**
+ * @returns NamespaceA.NamespaceB.EnumInNestedNS
+ */
+fooEnum():NS8755221360535654258.NamespaceA.NamespaceB.EnumInNestedNS {
+  var offset = this.bb!.__offset(this.bb_pos, 6);
+  return offset ? /**  */ (this.bb!.readInt8(this.bb_pos + offset)) : NS8755221360535654258.NamespaceA.NamespaceB.EnumInNestedNS.A;
+};
+
+/**
+ * @param NamespaceA.NamespaceB.EnumInNestedNS value
+ * @returns boolean
+ */
+mutate_foo_enum(value:NS8755221360535654258.NamespaceA.NamespaceB.EnumInNestedNS):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 6);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param NamespaceA.NamespaceB.StructInNestedNS= obj
+ * @returns NamespaceA.NamespaceB.StructInNestedNS|null
+ */
+fooStruct(obj?:NS8755221360535654258.NamespaceA.NamespaceB.StructInNestedNS):NS8755221360535654258.NamespaceA.NamespaceB.StructInNestedNS|null {
+  var offset = this.bb!.__offset(this.bb_pos, 8);
+  return offset ? (obj || new NS8755221360535654258.NamespaceA.NamespaceB.StructInNestedNS).__init(this.bb_pos + offset, this.bb!) : null;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ */
+static startTableInFirstNS(builder:flatbuffers.Builder) {
+  builder.startObject(3);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset fooTableOffset
+ */
+static addFooTable(builder:flatbuffers.Builder, fooTableOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(0, fooTableOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param NamespaceA.NamespaceB.EnumInNestedNS fooEnum
+ */
+static addFooEnum(builder:flatbuffers.Builder, fooEnum:NS8755221360535654258.NamespaceA.NamespaceB.EnumInNestedNS) {
+  builder.addFieldInt8(1, fooEnum, NS8755221360535654258.NamespaceA.NamespaceB.EnumInNestedNS.A);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset fooStructOffset
+ */
+static addFooStruct(builder:flatbuffers.Builder, fooStructOffset:flatbuffers.Offset) {
+  builder.addFieldStruct(2, fooStructOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @returns flatbuffers.Offset
+ */
+static endTableInFirstNS(builder:flatbuffers.Builder):flatbuffers.Offset {
+  var offset = builder.endObject();
+  return offset;
+};
+
+static createTableInFirstNS(builder:flatbuffers.Builder, fooTableOffset:flatbuffers.Offset, fooEnum:NS8755221360535654258.NamespaceA.NamespaceB.EnumInNestedNS, fooStructOffset:flatbuffers.Offset):flatbuffers.Offset {
+  TableInFirstNS.startTableInFirstNS(builder);
+  TableInFirstNS.addFooTable(builder, fooTableOffset);
+  TableInFirstNS.addFooEnum(builder, fooEnum);
+  TableInFirstNS.addFooStruct(builder, fooStructOffset);
+  return TableInFirstNS.endTableInFirstNS(builder);
+}
+}
+}
+/**
+ * @constructor
+ */
+export namespace NamespaceC{
+export class TableInC {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns TableInC
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):TableInC {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param TableInC= obj
+ * @returns TableInC
+ */
+static getRootAsTableInC(bb:flatbuffers.ByteBuffer, obj?:TableInC):TableInC {
+  return (obj || new TableInC).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param TableInC= obj
+ * @returns TableInC
+ */
+static getSizePrefixedRootAsTableInC(bb:flatbuffers.ByteBuffer, obj?:TableInC):TableInC {
+  return (obj || new TableInC).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param NamespaceA.TableInFirstNS= obj
+ * @returns NamespaceA.TableInFirstNS|null
+ */
+referToA1(obj?:NamespaceA.TableInFirstNS):NamespaceA.TableInFirstNS|null {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+  return offset ? (obj || new NamespaceA.TableInFirstNS).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
+};
+
+/**
+ * @param NamespaceA.SecondTableInA= obj
+ * @returns NamespaceA.SecondTableInA|null
+ */
+referToA2(obj?:NamespaceA.SecondTableInA):NamespaceA.SecondTableInA|null {
+  var offset = this.bb!.__offset(this.bb_pos, 6);
+  return offset ? (obj || new NamespaceA.SecondTableInA).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ */
+static startTableInC(builder:flatbuffers.Builder) {
+  builder.startObject(2);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset referToA1Offset
+ */
+static addReferToA1(builder:flatbuffers.Builder, referToA1Offset:flatbuffers.Offset) {
+  builder.addFieldOffset(0, referToA1Offset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset referToA2Offset
+ */
+static addReferToA2(builder:flatbuffers.Builder, referToA2Offset:flatbuffers.Offset) {
+  builder.addFieldOffset(1, referToA2Offset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @returns flatbuffers.Offset
+ */
+static endTableInC(builder:flatbuffers.Builder):flatbuffers.Offset {
+  var offset = builder.endObject();
+  return offset;
+};
+
+static createTableInC(builder:flatbuffers.Builder, referToA1Offset:flatbuffers.Offset, referToA2Offset:flatbuffers.Offset):flatbuffers.Offset {
+  TableInC.startTableInC(builder);
+  TableInC.addReferToA1(builder, referToA1Offset);
+  TableInC.addReferToA2(builder, referToA2Offset);
+  return TableInC.endTableInC(builder);
+}
+}
+}
+/**
+ * @constructor
+ */
+export namespace NamespaceA{
+export class SecondTableInA {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns SecondTableInA
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):SecondTableInA {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param SecondTableInA= obj
+ * @returns SecondTableInA
+ */
+static getRootAsSecondTableInA(bb:flatbuffers.ByteBuffer, obj?:SecondTableInA):SecondTableInA {
+  return (obj || new SecondTableInA).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param SecondTableInA= obj
+ * @returns SecondTableInA
+ */
+static getSizePrefixedRootAsSecondTableInA(bb:flatbuffers.ByteBuffer, obj?:SecondTableInA):SecondTableInA {
+  return (obj || new SecondTableInA).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param NamespaceC.TableInC= obj
+ * @returns NamespaceC.TableInC|null
+ */
+referToC(obj?:NamespaceC.TableInC):NamespaceC.TableInC|null {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+  return offset ? (obj || new NamespaceC.TableInC).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ */
+static startSecondTableInA(builder:flatbuffers.Builder) {
+  builder.startObject(1);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset referToCOffset
+ */
+static addReferToC(builder:flatbuffers.Builder, referToCOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(0, referToCOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @returns flatbuffers.Offset
+ */
+static endSecondTableInA(builder:flatbuffers.Builder):flatbuffers.Offset {
+  var offset = builder.endObject();
+  return offset;
+};
+
+static createSecondTableInA(builder:flatbuffers.Builder, referToCOffset:flatbuffers.Offset):flatbuffers.Offset {
+  SecondTableInA.startSecondTableInA(builder);
+  SecondTableInA.addReferToC(builder, referToCOffset);
+  return SecondTableInA.endSecondTableInA(builder);
+}
+}
+}
diff --git a/tests/namespace_test/namespace_test2_namespace_a_generated.dart b/tests/namespace_test/namespace_test2_namespace_a_generated.dart
new file mode 100644
index 0000000..d5108eb
--- /dev/null
+++ b/tests/namespace_test/namespace_test2_namespace_a_generated.dart
@@ -0,0 +1,189 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+// ignore_for_file: unused_import, unused_field, unused_local_variable
+
+library namespace_a;
+
+import 'dart:typed_data' show Uint8List;
+import 'package:flat_buffers/flat_buffers.dart' as fb;
+
+import 'namespace_test1_namespace_a_generated.dart';
+import './namespace_test2_namespace_c_generated.dart' as namespace_c;
+
+class TableInFirstNS {
+  TableInFirstNS._(this._bc, this._bcOffset);
+  factory TableInFirstNS(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<TableInFirstNS> reader = const _TableInFirstNSReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  namespace_a_namespace_b.TableInNestedNS get fooTable => namespace_a_namespace_b.TableInNestedNS.reader.vTableGet(_bc, _bcOffset, 4, null);
+  EnumInNestedNS get fooEnum => new EnumInNestedNS.fromValue(const fb.Int8Reader().vTableGet(_bc, _bcOffset, 6, 0));
+  namespace_a_namespace_b.StructInNestedNS get fooStruct => namespace_a_namespace_b.StructInNestedNS.reader.vTableGet(_bc, _bcOffset, 8, null);
+
+  @override
+  String toString() {
+    return 'TableInFirstNS{fooTable: $fooTable, fooEnum: $fooEnum, fooStruct: $fooStruct}';
+  }
+}
+
+class _TableInFirstNSReader extends fb.TableReader<TableInFirstNS> {
+  const _TableInFirstNSReader();
+
+  @override
+  TableInFirstNS createObject(fb.BufferContext bc, int offset) => 
+    new TableInFirstNS._(bc, offset);
+}
+
+class TableInFirstNSBuilder {
+  TableInFirstNSBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  void begin() {
+    fbBuilder.startTable();
+  }
+
+  int addFooTableOffset(int offset) {
+    fbBuilder.addOffset(0, offset);
+    return fbBuilder.offset;
+  }
+  int addFooEnum(EnumInNestedNS fooEnum) {
+    fbBuilder.addInt8(1, fooEnum?.value);
+    return fbBuilder.offset;
+  }
+  int addFooStruct(int offset) {
+    fbBuilder.addStruct(2, offset);
+    return fbBuilder.offset;
+  }
+
+  int finish() {
+    return fbBuilder.endTable();
+  }
+}
+
+class TableInFirstNSObjectBuilder extends fb.ObjectBuilder {
+  final namespace_a_namespace_b.TableInNestedNSObjectBuilder _fooTable;
+  final EnumInNestedNS _fooEnum;
+  final namespace_a_namespace_b.StructInNestedNSObjectBuilder _fooStruct;
+
+  TableInFirstNSObjectBuilder({
+    namespace_a_namespace_b.TableInNestedNSObjectBuilder fooTable,
+    EnumInNestedNS fooEnum,
+    namespace_a_namespace_b.StructInNestedNSObjectBuilder fooStruct,
+  })
+      : _fooTable = fooTable,
+        _fooEnum = fooEnum,
+        _fooStruct = fooStruct;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+    final int fooTableOffset = _fooTable?.getOrCreateOffset(fbBuilder);
+
+    fbBuilder.startTable();
+    if (fooTableOffset != null) {
+      fbBuilder.addOffset(0, fooTableOffset);
+    }
+    fbBuilder.addInt8(1, _fooEnum?.value);
+    if (_fooStruct != null) {
+      fbBuilder.addStruct(2, _fooStruct.finish(fbBuilder));
+    }
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
+class SecondTableInA {
+  SecondTableInA._(this._bc, this._bcOffset);
+  factory SecondTableInA(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<SecondTableInA> reader = const _SecondTableInAReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  namespace_c.TableInC get referToC => namespace_c.TableInC.reader.vTableGet(_bc, _bcOffset, 4, null);
+
+  @override
+  String toString() {
+    return 'SecondTableInA{referToC: $referToC}';
+  }
+}
+
+class _SecondTableInAReader extends fb.TableReader<SecondTableInA> {
+  const _SecondTableInAReader();
+
+  @override
+  SecondTableInA createObject(fb.BufferContext bc, int offset) => 
+    new SecondTableInA._(bc, offset);
+}
+
+class SecondTableInABuilder {
+  SecondTableInABuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  void begin() {
+    fbBuilder.startTable();
+  }
+
+  int addReferToCOffset(int offset) {
+    fbBuilder.addOffset(0, offset);
+    return fbBuilder.offset;
+  }
+
+  int finish() {
+    return fbBuilder.endTable();
+  }
+}
+
+class SecondTableInAObjectBuilder extends fb.ObjectBuilder {
+  final namespace_c.TableInCObjectBuilder _referToC;
+
+  SecondTableInAObjectBuilder({
+    namespace_c.TableInCObjectBuilder referToC,
+  })
+      : _referToC = referToC;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+    final int referToCOffset = _referToC?.getOrCreateOffset(fbBuilder);
+
+    fbBuilder.startTable();
+    if (referToCOffset != null) {
+      fbBuilder.addOffset(0, referToCOffset);
+    }
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
diff --git a/tests/namespace_test/namespace_test2_namespace_c_generated.dart b/tests/namespace_test/namespace_test2_namespace_c_generated.dart
new file mode 100644
index 0000000..7214feb
--- /dev/null
+++ b/tests/namespace_test/namespace_test2_namespace_c_generated.dart
@@ -0,0 +1,102 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+// ignore_for_file: unused_import, unused_field, unused_local_variable
+
+library namespace_c;
+
+import 'dart:typed_data' show Uint8List;
+import 'package:flat_buffers/flat_buffers.dart' as fb;
+
+import 'namespace_test1_namespace_c_generated.dart';
+import './namespace_test2_namespace_a_generated.dart' as namespace_a;
+
+class TableInC {
+  TableInC._(this._bc, this._bcOffset);
+  factory TableInC(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<TableInC> reader = const _TableInCReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  namespace_a.TableInFirstNS get referToA1 => namespace_a.TableInFirstNS.reader.vTableGet(_bc, _bcOffset, 4, null);
+  namespace_a.SecondTableInA get referToA2 => namespace_a.SecondTableInA.reader.vTableGet(_bc, _bcOffset, 6, null);
+
+  @override
+  String toString() {
+    return 'TableInC{referToA1: $referToA1, referToA2: $referToA2}';
+  }
+}
+
+class _TableInCReader extends fb.TableReader<TableInC> {
+  const _TableInCReader();
+
+  @override
+  TableInC createObject(fb.BufferContext bc, int offset) => 
+    new TableInC._(bc, offset);
+}
+
+class TableInCBuilder {
+  TableInCBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  void begin() {
+    fbBuilder.startTable();
+  }
+
+  int addReferToA1Offset(int offset) {
+    fbBuilder.addOffset(0, offset);
+    return fbBuilder.offset;
+  }
+  int addReferToA2Offset(int offset) {
+    fbBuilder.addOffset(1, offset);
+    return fbBuilder.offset;
+  }
+
+  int finish() {
+    return fbBuilder.endTable();
+  }
+}
+
+class TableInCObjectBuilder extends fb.ObjectBuilder {
+  final namespace_a.TableInFirstNSObjectBuilder _referToA1;
+  final namespace_a.SecondTableInAObjectBuilder _referToA2;
+
+  TableInCObjectBuilder({
+    namespace_a.TableInFirstNSObjectBuilder referToA1,
+    namespace_a.SecondTableInAObjectBuilder referToA2,
+  })
+      : _referToA1 = referToA1,
+        _referToA2 = referToA2;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+    final int referToA1Offset = _referToA1?.getOrCreateOffset(fbBuilder);
+    final int referToA2Offset = _referToA2?.getOrCreateOffset(fbBuilder);
+
+    fbBuilder.startTable();
+    if (referToA1Offset != null) {
+      fbBuilder.addOffset(0, referToA1Offset);
+    }
+    if (referToA2Offset != null) {
+      fbBuilder.addOffset(1, referToA2Offset);
+    }
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
diff --git a/tests/native_type_test.fbs b/tests/native_type_test.fbs
new file mode 100644
index 0000000..de80bdf
--- /dev/null
+++ b/tests/native_type_test.fbs
@@ -0,0 +1,15 @@
+native_include "native_type_test_impl.h";
+
+namespace Geometry;
+
+struct Vector3D (native_type:"Native::Vector3D") {
+  x:float;
+  y:float;
+  z:float;
+}
+
+table ApplicationData {
+  vectors:[Vector3D];
+}
+
+root_type ApplicationData;
diff --git a/tests/native_type_test_generated.h b/tests/native_type_test_generated.h
new file mode 100644
index 0000000..9ba7c61
--- /dev/null
+++ b/tests/native_type_test_generated.h
@@ -0,0 +1,238 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+#ifndef FLATBUFFERS_GENERATED_NATIVETYPETEST_GEOMETRY_H_
+#define FLATBUFFERS_GENERATED_NATIVETYPETEST_GEOMETRY_H_
+
+#include "flatbuffers/flatbuffers.h"
+
+#include "native_type_test_impl.h"
+
+namespace Geometry {
+
+struct Vector3D;
+
+struct ApplicationData;
+struct ApplicationDataT;
+
+inline const flatbuffers::TypeTable *Vector3DTypeTable();
+
+inline const flatbuffers::TypeTable *ApplicationDataTypeTable();
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Vector3D FLATBUFFERS_FINAL_CLASS {
+ private:
+  float x_;
+  float y_;
+  float z_;
+
+ public:
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return Vector3DTypeTable();
+  }
+  Vector3D() {
+    memset(static_cast<void *>(this), 0, sizeof(Vector3D));
+  }
+  Vector3D(float _x, float _y, float _z)
+      : x_(flatbuffers::EndianScalar(_x)),
+        y_(flatbuffers::EndianScalar(_y)),
+        z_(flatbuffers::EndianScalar(_z)) {
+  }
+  float x() const {
+    return flatbuffers::EndianScalar(x_);
+  }
+  void mutate_x(float _x) {
+    flatbuffers::WriteScalar(&x_, _x);
+  }
+  float y() const {
+    return flatbuffers::EndianScalar(y_);
+  }
+  void mutate_y(float _y) {
+    flatbuffers::WriteScalar(&y_, _y);
+  }
+  float z() const {
+    return flatbuffers::EndianScalar(z_);
+  }
+  void mutate_z(float _z) {
+    flatbuffers::WriteScalar(&z_, _z);
+  }
+};
+FLATBUFFERS_STRUCT_END(Vector3D, 12);
+
+struct ApplicationDataT : public flatbuffers::NativeTable {
+  typedef ApplicationData TableType;
+  std::vector<Native::Vector3D> vectors;
+  ApplicationDataT() {
+  }
+};
+
+struct ApplicationData FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef ApplicationDataT NativeTableType;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return ApplicationDataTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_VECTORS = 4
+  };
+  const flatbuffers::Vector<const Geometry::Vector3D *> *vectors() const {
+    return GetPointer<const flatbuffers::Vector<const Geometry::Vector3D *> *>(VT_VECTORS);
+  }
+  flatbuffers::Vector<const Geometry::Vector3D *> *mutable_vectors() {
+    return GetPointer<flatbuffers::Vector<const Geometry::Vector3D *> *>(VT_VECTORS);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyOffset(verifier, VT_VECTORS) &&
+           verifier.VerifyVector(vectors()) &&
+           verifier.EndTable();
+  }
+  ApplicationDataT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(ApplicationDataT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<ApplicationData> Pack(flatbuffers::FlatBufferBuilder &_fbb, const ApplicationDataT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct ApplicationDataBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_vectors(flatbuffers::Offset<flatbuffers::Vector<const Geometry::Vector3D *>> vectors) {
+    fbb_.AddOffset(ApplicationData::VT_VECTORS, vectors);
+  }
+  explicit ApplicationDataBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  ApplicationDataBuilder &operator=(const ApplicationDataBuilder &);
+  flatbuffers::Offset<ApplicationData> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<ApplicationData>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<ApplicationData> CreateApplicationData(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<flatbuffers::Vector<const Geometry::Vector3D *>> vectors = 0) {
+  ApplicationDataBuilder builder_(_fbb);
+  builder_.add_vectors(vectors);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<ApplicationData> CreateApplicationDataDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const std::vector<Geometry::Vector3D> *vectors = nullptr) {
+  auto vectors__ = vectors ? _fbb.CreateVectorOfStructs<Geometry::Vector3D>(*vectors) : 0;
+  return Geometry::CreateApplicationData(
+      _fbb,
+      vectors__);
+}
+
+flatbuffers::Offset<ApplicationData> CreateApplicationData(flatbuffers::FlatBufferBuilder &_fbb, const ApplicationDataT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+inline ApplicationDataT *ApplicationData::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = new ApplicationDataT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+inline void ApplicationData::UnPackTo(ApplicationDataT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+  { auto _e = vectors(); if (_e) { _o->vectors.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vectors[_i] = flatbuffers::UnPack(*_e->Get(_i)); } } };
+}
+
+inline flatbuffers::Offset<ApplicationData> ApplicationData::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ApplicationDataT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateApplicationData(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<ApplicationData> CreateApplicationData(flatbuffers::FlatBufferBuilder &_fbb, const ApplicationDataT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ApplicationDataT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  auto _vectors = _o->vectors.size() ? _fbb.CreateVectorOfNativeStructs<Geometry::Vector3D>(_o->vectors) : 0;
+  return Geometry::CreateApplicationData(
+      _fbb,
+      _vectors);
+}
+
+inline const flatbuffers::TypeTable *Vector3DTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 }
+  };
+  static const int64_t values[] = { 0, 4, 8, 12 };
+  static const char * const names[] = {
+    "x",
+    "y",
+    "z"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_STRUCT, 3, type_codes, nullptr, values, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *ApplicationDataTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SEQUENCE, 1, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    Geometry::Vector3DTypeTable
+  };
+  static const char * const names[] = {
+    "vectors"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 1, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+inline const Geometry::ApplicationData *GetApplicationData(const void *buf) {
+  return flatbuffers::GetRoot<Geometry::ApplicationData>(buf);
+}
+
+inline const Geometry::ApplicationData *GetSizePrefixedApplicationData(const void *buf) {
+  return flatbuffers::GetSizePrefixedRoot<Geometry::ApplicationData>(buf);
+}
+
+inline ApplicationData *GetMutableApplicationData(void *buf) {
+  return flatbuffers::GetMutableRoot<ApplicationData>(buf);
+}
+
+inline bool VerifyApplicationDataBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifyBuffer<Geometry::ApplicationData>(nullptr);
+}
+
+inline bool VerifySizePrefixedApplicationDataBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifySizePrefixedBuffer<Geometry::ApplicationData>(nullptr);
+}
+
+inline void FinishApplicationDataBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<Geometry::ApplicationData> root) {
+  fbb.Finish(root);
+}
+
+inline void FinishSizePrefixedApplicationDataBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<Geometry::ApplicationData> root) {
+  fbb.FinishSizePrefixed(root);
+}
+
+inline flatbuffers::unique_ptr<Geometry::ApplicationDataT> UnPackApplicationData(
+    const void *buf,
+    const flatbuffers::resolver_function_t *res = nullptr) {
+  return flatbuffers::unique_ptr<Geometry::ApplicationDataT>(GetApplicationData(buf)->UnPack(res));
+}
+
+inline flatbuffers::unique_ptr<Geometry::ApplicationDataT> UnPackSizePrefixedApplicationData(
+    const void *buf,
+    const flatbuffers::resolver_function_t *res = nullptr) {
+  return flatbuffers::unique_ptr<Geometry::ApplicationDataT>(GetSizePrefixedApplicationData(buf)->UnPack(res));
+}
+
+}  // namespace Geometry
+
+#endif  // FLATBUFFERS_GENERATED_NATIVETYPETEST_GEOMETRY_H_
diff --git a/tests/native_type_test_impl.cpp b/tests/native_type_test_impl.cpp
new file mode 100644
index 0000000..04ddb96
--- /dev/null
+++ b/tests/native_type_test_impl.cpp
@@ -0,0 +1,13 @@
+#include "native_type_test_impl.h"
+#include "native_type_test_generated.h"
+
+namespace flatbuffers {
+  Geometry::Vector3D Pack(const Native::Vector3D &obj) {
+    return Geometry::Vector3D(obj.x, obj.y, obj.z);
+  }
+
+  const Native::Vector3D UnPack(const Geometry::Vector3D &obj) {
+    return Native::Vector3D(obj.x(), obj.y(), obj.z());
+  }
+}
+
diff --git a/tests/native_type_test_impl.h b/tests/native_type_test_impl.h
new file mode 100644
index 0000000..2473ad3
--- /dev/null
+++ b/tests/native_type_test_impl.h
@@ -0,0 +1,24 @@
+#ifndef NATIVE_TYPE_TEST_IMPL_H
+#define NATIVE_TYPE_TEST_IMPL_H
+
+namespace Native {
+  struct Vector3D {
+    float x;
+    float y;
+    float z;
+
+    Vector3D() { x = 0; y = 0; z = 0; };
+    Vector3D(float _x, float _y, float _z) { this->x = _x; this->y = _y; this->z = _z; }
+  };
+}
+
+namespace Geometry { 
+  struct Vector3D;
+}
+
+namespace flatbuffers {
+  Geometry::Vector3D Pack(const Native::Vector3D &obj);
+  const Native::Vector3D UnPack(const Geometry::Vector3D &obj);
+}
+
+#endif // VECTOR3D_PACK_H
diff --git a/tests/phpTest.php b/tests/phpTest.php
new file mode 100644
index 0000000..c1447c2
--- /dev/null
+++ b/tests/phpTest.php
@@ -0,0 +1,632 @@
+<?php
+// manual load for testing. please use PSR style autoloader when you use flatbuffers.
+require join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)), "php", "Constants.php"));
+require join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)), "php", "ByteBuffer.php"));
+require join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)), "php", "FlatbufferBuilder.php"));
+require join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)), "php", "Table.php"));
+require join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)), "php", "Struct.php"));
+foreach (glob(join(DIRECTORY_SEPARATOR, array(dirname(__FILE__), "MyGame", "Example", "*.php"))) as $file) {
+    require $file;
+}
+
+function main()
+{
+    /// Begin Test
+    $assert = new Assert();
+
+    // First, let's test reading a FlatBuffer generated by C++ code:
+    // This file was generated from monsterdata_test.json
+
+    // Now test it:
+    $data = file_get_contents('monsterdata_test.mon');
+    $bb = Google\FlatBuffers\ByteBuffer::wrap($data);
+    test_buffer($assert, $bb);
+
+    // Second, let's create a FlatBuffer from scratch in JavaScript, and test it also.
+    // We use an initial size of 1 to exercise the reallocation algorithm,
+    // normally a size larger than the typical FlatBuffer you generate would be
+    // better for performance.
+    $fbb = new Google\FlatBuffers\FlatBufferBuilder(1);
+
+    // We set up the same values as monsterdata.json:
+    $str = $fbb->createString("MyMonster");
+    $name = $fbb->createString('Fred');
+    \MyGame\Example\Monster::startMonster($fbb);
+    \MyGame\Example\Monster::addName($fbb, $name);
+    $enemy = \MyGame\Example\Monster::endMonster($fbb);
+
+    $inv = \MyGame\Example\Monster::CreateInventoryVector($fbb, array(0, 1, 2, 3, 4));
+
+    $fred = $fbb->createString('Fred');
+    \MyGame\Example\Monster::StartMonster($fbb);
+    \MyGame\Example\Monster::AddName($fbb, $fred);
+    $mon2 = \MyGame\Example\Monster::EndMonster($fbb);
+
+    \MyGame\Example\Monster::StartTest4Vector($fbb, 2);
+    \MyGame\Example\Test::CreateTest($fbb, 10, 20);
+    \MyGame\Example\Test::CreateTest($fbb, 30, 40);
+    $test4 = $fbb->endVector();
+
+    $testArrayOfString = \MyGame\Example\Monster::CreateTestarrayofstringVector($fbb, array(
+        $fbb->createString('test1'),
+        $fbb->createString('test2')
+    ));
+
+    \MyGame\Example\Monster::StartMonster($fbb);
+    \MyGame\Example\Monster::AddPos($fbb, \MyGame\Example\Vec3::CreateVec3($fbb,
+        1.0, 2.0, 3.0, //float
+        3.0, // double
+        \MyGame\Example\Color::Green,
+        5, //short
+        6));
+    \MyGame\Example\Monster::AddHp($fbb, 80);
+    \MyGame\Example\Monster::AddName($fbb, $str);
+    \MyGame\Example\Monster::AddInventory($fbb, $inv);
+    \MyGame\Example\Monster::AddTestType($fbb, \MyGame\Example\Any::Monster);
+    \MyGame\Example\Monster::AddTest($fbb, $mon2);
+    \MyGame\Example\Monster::AddTest4($fbb, $test4);
+    \MyGame\Example\Monster::AddTestarrayofstring($fbb, $testArrayOfString);
+    \MyGame\Example\Monster::AddEnemy($fbb, $enemy);
+    \MyGame\Example\Monster::AddTestbool($fbb, true);
+    $mon = \MyGame\Example\Monster::EndMonster($fbb);
+
+    \MyGame\Example\Monster::FinishMonsterBuffer($fbb, $mon);
+
+    // Test it:
+    test_buffer($assert, $fbb->dataBuffer());
+
+    testByteBuffer($assert);
+    fuzzTest1($assert);
+//    testUnicode($assert);
+
+    echo 'FlatBuffers php test: completed successfully' . PHP_EOL;
+}
+
+try {
+    main();
+    exit(0);
+} catch(Exception $e) {
+    printf("Fatal error: Uncaught exception '%s' with message '%s. in %s:%d\n", get_class($e), $e->getMessage(), $e->getFile(), $e->getLine());
+    printf("Stack trace:\n");
+    echo $e->getTraceAsString() . PHP_EOL;
+    printf("  thrown in in %s:%d\n", $e->getFile(), $e->getLine());
+
+    die(-1);
+}
+
+function test_buffer(Assert $assert, Google\FlatBuffers\ByteBuffer $bb) {
+
+    $assert->ok(MyGame\Example\Monster::MonsterBufferHasIdentifier($bb));
+    $monster = \MyGame\Example\Monster::GetRootAsMonster($bb);
+
+    $assert->strictEqual($monster->GetHp(), 80);
+    $assert->strictEqual($monster->GetMana(), 150); // default
+
+    $assert->strictEqual($monster->GetName(), 'MyMonster');
+
+    $pos = $monster->GetPos();
+    $assert->strictEqual($pos->GetX(), 1.0);
+    $assert->strictEqual($pos->GetY(), 2.0);
+    $assert->strictEqual($pos->GetZ(), 3.0);
+
+    $assert->Equal($pos->GetTest1(), 3.0);
+    $assert->strictEqual($pos->GetTest2(), \MyGame\Example\Color::Green);
+
+    $t = $pos->GetTest3();
+    $assert->strictEqual($t->GetA(), 5);
+    $assert->strictEqual($t->GetB(), 6);
+    $assert->strictEqual($monster->GetTestType(), \MyGame\Example\Any::Monster);
+
+    $monster2 = new \MyGame\Example\Monster();
+    $assert->strictEqual($monster->GetTest($monster2) != null, true);
+    $assert->strictEqual($monster2->GetName(), 'Fred');
+
+    $assert->strictEqual($monster->GetInventoryLength(), 5);
+    $invsum = 0;
+    for ($i = 0; $i < $monster->GetInventoryLength(); $i++) {
+        $invsum += $monster->GetInventory($i);
+    }
+    $assert->strictEqual($invsum, 10);
+
+    $assert->strictEqual(bin2hex($monster->GetInventoryBytes()), "0001020304");
+
+    $test_0 = $monster->GetTest4(0);
+    $test_1 = $monster->GetTest4(1);
+    $assert->strictEqual($monster->GetTest4Length(), 2);
+    $assert->strictEqual($test_0->GetA() + $test_0->GetB() + $test_1->GetA() + $test_1->GetB(), 100);
+
+    $assert->strictEqual($monster->GetTestarrayofstringLength(), 2);
+    $assert->strictEqual($monster->GetTestarrayofstring(0), 'test1');
+    $assert->strictEqual($monster->GetTestarrayofstring(1), 'test2');
+
+    $fred = $monster->getEnemy();
+    $assert->Equal('Fred', $fred->getName());
+
+    $assert->strictEqual($monster->GetTestbool(), true);
+}
+
+//function testUnicode(Assert $assert) {
+//    // missing unicode_test.mon, implemented later
+//    $correct = file_get_contents('unicode_test.mon');
+//    $json = json_decode(file_get_contents('unicode_test.json'));
+//
+//    // Test reading
+//    $bb = flatbuffers\ByteBuffer::Wrap($correct);
+//    $monster = \MyGame\Example\Monster::GetRootAsMonster($bb);
+//    $assert->strictEqual($monster->GetName(), $json["name"]);
+//
+//    //$assert->deepEqual(new Buffer(monster.name(flatbuffers.Encoding.UTF8_BYTES)), new Buffer(json.name));
+//    //assert.strictEqual(monster.testarrayoftablesLength(), json.testarrayoftables.length);
+//    foreach ($json["testarrayoftables"]as $i => $table) {
+//        $value = $monster->GetTestArrayOfTables($i);
+//        $assert->strictEqual($value->GetName(), $table["name"]);
+//        //assert.deepEqual(new Buffer(value.name(flatbuffers.Encoding.UTF8_BYTES)), new Buffer(table.name));
+//    }
+//    $assert->strictEqual($monster->GetTestarrayofstringLength(), $json["testarrayofstring"]["length"]);
+//    foreach ($json["testarrayofstring"] as $i => $string) {
+//        $assert->strictEqual($monster->GetTestarrayofstring($i), $string);
+//        //assert.deepEqual(new Buffer(monster.testarrayofstring(i, flatbuffers.Encoding.UTF8_BYTES)), new Buffer(string));
+//    }
+//
+//    // Test writing
+//    $fbb = new FlatBuffers\FlatBufferBuilder(1);
+//    $name = $fbb->CreateString($json["name"]);
+//    $testarrayoftablesOffsets = array_map(function($table) use($fbb) {
+//        $name = $fbb->CreateString($table["name"]);
+//        \MyGame\Example\Monster::StartMonster($fbb);
+//        \MyGame\Example\Monster::AddName($fbb, $name);
+//        return \MyGame\Example\Monster::EndMonster($fbb);
+//    }, $json["testarrayoftables"]);
+//    $testarrayoftablesOffset = \MyGame\Example\Monster::CreateTestarrayoftablesVector($fbb,
+//            $testarrayoftablesOffsets);
+////    $testarrayofstringOffset = \MyGame\Example\Monster::CreateTestarrayofstringVector($fbb,
+////            $json["testarrayofstring"].map(function(string) { return fbb.createString(string); }));
+//
+//    \MyGame\Example\Monster::startMonster($fbb);
+//    \MyGame\Example\Monster::addTestarrayofstring($fbb, $testarrayoftablesOffset);
+//    \MyGame\Example\Monster::addTestarrayoftables($fbb, $testarrayoftablesOffset);
+//    \MyGame\Example\Monster::addName($fbb, $name);
+//    \MyGame\Example\Monster::finishMonsterBuffer($fbb, \MyGame\Example\Monster::endMonster($fbb));
+//    //;assert.deepEqual(new Buffer(fbb.asUint8Array()), correct);
+//}
+
+// Low level stress/fuzz test: serialize/deserialize a variety of
+// different kinds of data in different combinations
+function fuzzTest1(Assert $assert)
+{
+
+    // Values we're testing against: chosen to ensure no bits get chopped
+    // off anywhere, and also be different from eachother.
+    $bool_val = true;
+    $char_val = -127; // 0x81
+    $uchar_val = 0xFF;
+    $short_val = -32222; // 0x8222;
+    $ushort_val = 0xFEEE;
+    $int_val = 0x7fffffff | 0;
+    // for now
+    $uint_val = 1;
+    $long_val = 2;
+    $ulong_val = 3;
+
+//    var uint_val   = 0xFDDDDDDD;
+//    var long_val   = new flatbuffers.Long(0x44444444, 0x84444444);
+//    var ulong_val  = new flatbuffers.Long(0xCCCCCCCC, 0xFCCCCCCC);
+
+    $float_val = 3.14159;
+    $double_val = 3.14159265359;
+
+    $test_values_max = 11;
+    $fields_per_object = 4;
+    // current implementation is not good at encoding.
+    $num_fuzz_objects = 1000;
+    $builder = new Google\FlatBuffers\FlatBufferBuilder(1);
+
+    // can't use same implementation due to PHP_INTMAX overflow issue.
+    // we use mt_rand function to reproduce fuzzy test.
+    mt_srand(48271);
+    $objects = array();
+    // Generate num_fuzz_objects random objects each consisting of
+    // fields_per_object fields, each of a random type.
+    for ($i = 0; $i < $num_fuzz_objects; $i++) {
+        $builder->startObject($fields_per_object);
+        for ($f = 0; $f < $fields_per_object; $f++) {
+            $choice = mt_rand() % $test_values_max;
+            switch ($choice) {
+                case 0:
+                    $builder->addBoolX($f, $bool_val, 0);
+                    break;
+                case 1:
+                    $builder->addByteX($f, $char_val, 0);
+                    break;
+                case 2:
+                    $builder->addSbyteX($f, $uchar_val, 0);
+                    break;
+                case 3:
+                    $builder->addShortX($f, $short_val, 0);
+                    break;
+                case 4:
+                    $builder->addUshortX($f, $ushort_val, 0);
+                    break;
+                case 5:
+                    $builder->addIntX($f, $int_val, 0);
+                    break;
+                case 6:
+                    $builder->addUintX($f, $uint_val, 0);
+                    break;
+                case 7:
+                    $builder->addLongX($f, $long_val, 0);
+                    break;
+                case 8:
+                    $builder->addUlongX($f, $ulong_val, 0);
+                    break;
+                case 9:
+                    $builder->addFloatX($f, $float_val, 0);
+                    break;
+                case 10:
+                    $builder->addDoubleX($f, $double_val, 0);
+                    break;
+            }
+        }
+        $objects[] = $builder->endObject();
+    }
+    $builder->prep(8, 0); // Align whole buffer.
+
+    mt_srand(48271); // Reset
+    $builder->finish($objects[count($objects) - 1]);
+
+    $view = Google\FlatBuffers\ByteBuffer::wrap($builder->sizedByteArray());
+    for ($i = 0; $i < $num_fuzz_objects; $i++) {
+        $offset = $view->capacity() - $objects[$i];
+        for ($f = 0; $f < $fields_per_object; $f++) {
+            $choice = mt_rand() % $test_values_max;
+            $vtable_offset = fieldIndexToOffset($f);
+            $vtable = $offset - $view->getInt($offset);
+            $assert->ok($vtable_offset < $view->getShort($vtable));
+            $field_offset = $offset + $view->getShort($vtable + $vtable_offset);
+            switch ($choice) {
+                case 0:
+                    $assert->strictEqual(!!$view->getBool($field_offset), $bool_val);
+                    break;
+                case 1:
+                    $assert->strictEqual($view->getSbyte($field_offset), $char_val);
+                    break;
+                case 2:
+                    $assert->strictEqual($view->getByte($field_offset), $uchar_val);
+                    break;
+                case 3:
+                    $assert->strictEqual($view->getShort($field_offset), $short_val);
+                    break;
+                case 4:
+                    $assert->strictEqual($view->getUShort($field_offset), $ushort_val);
+                    break;
+                case 5:
+                    $assert->strictEqual($view->getInt($field_offset), $int_val);
+                    break;
+                case 6:
+                    $assert->strictEqual($view->getUint($field_offset), $uint_val);
+                    break;
+                case 7:
+                    if (PHP_INT_SIZE <= 4) break;
+                    $assert->strictEqual($view->getLong($field_offset), $long_val);
+                    break;
+                case 8:
+                    if (PHP_INT_SIZE <= 4) break;
+                    $assert->strictEqual($view->getUlong($field_offset), $ulong_val);
+                    break;
+                case 9:
+                    $assert->strictEqual(floor($view->getFloat($field_offset)), floor($float_val));
+                    break;
+                case 10:
+                    $assert->strictEqual($view->getDouble($field_offset), $double_val);
+                    break;
+            }
+        }
+    }
+}
+
+function fieldIndexToOffset($field_id) {
+    // Should correspond to what EndTable() below builds up.
+    $fixed_fields = 2;  // Vtable size and Object Size.
+    return ($field_id + $fixed_fields) * 2;
+}
+
+function testByteBuffer(Assert $assert) {
+
+    //Test: ByteBuffer_Length_MatchesBufferLength
+    $buffer = str_repeat("\0", 100);
+    $uut  = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Equal($uut->capacity(), strlen($buffer));
+
+    //Test: ByteBuffer_PutBytePopulatesBufferAtZeroOffset
+    $buffer = "\0";
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $uut->putByte(0, "\x63"); // 99
+    $assert->Equal("\x63", $uut->_buffer[0]); // don't share buffer as php user might confuse reference.
+
+    //Test: ByteBuffer_PutByteCannotPutAtOffsetPastLength
+    $buffer = "\0";
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+        $uut->putByte(1, "\x63"); // 99
+    });
+
+    //Test: ByteBuffer_PutShortPopulatesBufferCorrectly
+    $buffer = str_repeat("\0", 2);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $uut->putShort(0, 1);
+
+    // Ensure Endiannes was written correctly
+    $assert->Equal(chr(0x01), $uut->_buffer[0]);
+    $assert->Equal(chr(0x00), $uut->_buffer[1]);
+
+    $buffer = str_repeat("\0", 2);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $uut->putShort(0, -32768);
+
+    // Ensure Endiannes was written correctly
+    $assert->Equal(chr(0x00), $uut->_buffer[0]);
+    $assert->Equal(chr(0x80), $uut->_buffer[1]);
+
+    //Test: ByteBuffer_PutShortCannotPutAtOffsetPastLength
+    $buffer = "\0";
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+        $uut->putShort(2, "\x63"); // 99
+    });
+
+    //Test: ByteBuffer_PutShortChecksLength
+    $buffer = "\0";
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+        $uut->putShort(0, "\x63"); // 99
+    });
+
+    //Test: ByteBuffer_PutShortChecksLengthAndOffset
+    $buffer = str_repeat("\0", 2);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+        $uut->putShort(1, "\x63"); // 99
+    });
+
+    //Test: ByteBuffer_PutIntPopulatesBufferCorrectly
+    $buffer = str_repeat("\0", 4);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $uut->putInt(0, 0x0A0B0C0D);
+    $assert->Equal(chr(0x0D), $uut->_buffer[0]);
+    $assert->Equal(chr(0x0C), $uut->_buffer[1]);
+    $assert->Equal(chr(0x0B), $uut->_buffer[2]);
+    $assert->Equal(chr(0x0A), $uut->_buffer[3]);
+
+    $buffer = str_repeat("\0", 4);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $uut->putInt(0, -2147483648);
+    $assert->Equal(chr(0x00), $uut->_buffer[0]);
+    $assert->Equal(chr(0x00), $uut->_buffer[1]);
+    $assert->Equal(chr(0x00), $uut->_buffer[2]);
+    $assert->Equal(chr(0x80), $uut->_buffer[3]);
+
+    //Test: ByteBuffer_PutIntCannotPutAtOffsetPastLength
+    $buffer = str_repeat("\0", 4);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+        $uut->putInt(2, 0x0A0B0C0D);
+    });
+
+    //Test: ByteBuffer_PutIntChecksLength
+    $buffer = str_repeat("\0", 1);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+        $uut->putInt(0, 0x0A0B0C0D);
+    });
+
+    //Test: ByteBuffer_PutIntChecksLengthAndOffset
+    $buffer = str_repeat("\0", 4);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+        $uut->putInt(2, 0x0A0B0C0D);
+    });
+
+    if (PHP_INT_SIZE > 4) {
+        //Test: ByteBuffer_PutLongPopulatesBufferCorrectly
+        $buffer = str_repeat("\0", 8);
+        $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+        $uut->putLong(0, 0x010203040A0B0C0D);
+        $assert->Equal(chr(0x0D), $uut->_buffer[0]);
+        $assert->Equal(chr(0x0C), $uut->_buffer[1]);
+        $assert->Equal(chr(0x0B), $uut->_buffer[2]);
+        $assert->Equal(chr(0x0A), $uut->_buffer[3]);
+        $assert->Equal(chr(0x04), $uut->_buffer[4]);
+        $assert->Equal(chr(0x03), $uut->_buffer[5]);
+        $assert->Equal(chr(0x02), $uut->_buffer[6]);
+        $assert->Equal(chr(0x01), $uut->_buffer[7]);
+
+        //Test: ByteBuffer_PutLongCannotPutAtOffsetPastLength
+        $buffer = str_repeat("\0", 8);
+        $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+        $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+            $uut->putLong(2, 0x010203040A0B0C0D);
+        });
+
+        //Test: ByteBuffer_PutLongCannotPutAtOffsetPastLength
+        $buffer = str_repeat("\0", 1);
+        $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+        $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+            $uut->putLong(0, 0x010203040A0B0C0D);
+        });
+
+
+        //Test: ByteBuffer_PutLongChecksLengthAndOffset
+        $buffer = str_repeat("\0", 8);
+        $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+        $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+            $uut->putLong(2, 0x010203040A0B0C0D);
+        });
+    }
+
+    //Test: ByteBuffer_GetByteReturnsCorrectData
+    $buffer = str_repeat("\0", 1);
+    $buffer[0] = "\x63";
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Equal("\x63", $uut->get(0));
+
+    //Test: ByteBuffer_GetByteChecksOffset
+    $buffer = str_repeat("\0", 1);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+        $uut->get(1);
+    });
+
+    //Test: ByteBuffer_GetShortReturnsCorrectData
+    $buffer = str_repeat("\0", 2);
+    $buffer[0] = chr(0x01);
+    $buffer[1] = chr(0x00);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Equal(1, $uut->getShort(0));
+
+    //Test: ByteBuffer_GetShortReturnsCorrectData (signed value)
+    $buffer = str_repeat("\0", 2);
+    $buffer[0] = chr(0x00);
+    $buffer[1] = chr(0x80);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Equal(-32768, $uut->getShort(0));
+
+    //Test: ByteBuffer_GetShortChecksOffset
+    $buffer = str_repeat("\0", 2);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+        $uut->getShort(2);
+    });
+
+    //Test: ByteBuffer_GetShortChecksLength
+    $buffer = str_repeat("\0", 2);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+        $uut->getShort(1);
+    });
+
+    //Test: ByteBuffer_GetIntReturnsCorrectData
+    $buffer = str_repeat("\0", 4);
+    $buffer[0] = chr(0x0D);
+    $buffer[1] = chr(0x0C);
+    $buffer[2] = chr(0x0B);
+    $buffer[3] = chr(0x0A);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Equal(0x0A0B0C0D, $uut->getInt(0));
+
+    $buffer = str_repeat("\0", 4);
+    $buffer[0] = chr(0x00);
+    $buffer[1] = chr(0x00);
+    $buffer[2] = chr(0x00);
+    $buffer[3] = chr(0x80);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Equal(-2147483648, $uut->getInt(0));
+
+    //Test: ByteBuffer_GetIntChecksOffset
+    $buffer = str_repeat("\0", 4);
+
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+        $uut->getInt(4);
+    });
+
+    //Test: ByteBuffer_GetIntChecksLength
+    $buffer = str_repeat("\0", 2);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+        $uut->getInt(0);
+    });
+
+    if (PHP_INT_SIZE > 4) {
+        //Test: ByteBuffer_GetLongReturnsCorrectData
+        $buffer = str_repeat("\0", 8);
+        $buffer[0] = chr(0x0D);
+        $buffer[1] = chr(0x0C);
+        $buffer[2] = chr(0x0B);
+        $buffer[3] = chr(0x0A);
+        $buffer[4] = chr(0x04);
+        $buffer[5] = chr(0x03);
+        $buffer[6] = chr(0x02);
+        $buffer[7] = chr(0x01);
+        $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+        $assert->Equal(0x010203040A0B0C0D, $uut->getLong(0));
+
+        //Test: Signed Long
+        $buffer = str_repeat("\0", 8);
+        $buffer[0] = chr(0x00);
+        $buffer[1] = chr(0x00);
+        $buffer[2] = chr(0x00);
+        $buffer[3] = chr(0x00);
+        $buffer[4] = chr(0x00);
+        $buffer[5] = chr(0x00);
+        $buffer[6] = chr(0x00);
+        $buffer[7] = chr(0x80);
+        $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+        $assert->Equal(-1 << 63, $uut->getLong(0));
+    }
+
+    //Test: ByteBuffer_GetLongChecksOffset
+    $buffer = str_repeat("\0", 8);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+        $uut->getLong(8);
+    });
+
+    //Test: ByteBuffer_GetLongChecksLength
+    $buffer = str_repeat("\0", 7);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+        $uut->getLong(0);
+    });
+
+    //Test: big endian
+    $buffer = str_repeat("\0", 2);
+    // 0xFF 0x00
+    // Little Endian: 255
+    // Big Endian: 65280
+    $buffer[0] = chr(0xff);
+    $buffer[1] = chr(0x00);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Equal(65280, $uut->readLittleEndian(0, 2, true));
+
+    $buffer = str_repeat("\0", 4);
+    $buffer[0] = chr(0x0D);
+    $buffer[1] = chr(0x0C);
+    $buffer[2] = chr(0x0B);
+    $buffer[3] = chr(0x0A);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Equal(0x0D0C0B0A, $uut->readLittleEndian(0, 4, true));
+
+}
+
+class Assert {
+    public function ok($result, $message = "") {
+        if (!$result){
+            throw new Exception(!empty($message) ? $message : "{$result} is not true.");
+        }
+    }
+
+    public function Equal($result, $expected, $message = "") {
+        if ($result != $expected) {
+            throw new Exception(!empty($message) ? $message : "given the result {$result} is not equals as {$expected}");
+        }
+    }
+
+
+    public function strictEqual($result, $expected, $message = "") {
+        if ($result !== $expected) {
+            throw new Exception(!empty($message) ? $message : "given the result {$result} is not strict equals as {$expected}");
+        }
+    }
+
+    public function Throws($class, Callable $callback) {
+        try {
+            $callback();
+
+            throw new \Exception("passed statement don't throw an exception.");
+        } catch (\Exception $e) {
+            if (get_class($e) != get_class($class)) {
+                throw new Exception("passed statement doesn't throw " . get_class($class) . ". throwws " . get_class($e));
+            }
+        }
+    }
+}
diff --git a/tests/phpUnionVectorTest.php b/tests/phpUnionVectorTest.php
new file mode 100644
index 0000000..4b5e258
--- /dev/null
+++ b/tests/phpUnionVectorTest.php
@@ -0,0 +1,109 @@
+<?php
+
+require join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)), "php", "Constants.php"));
+require join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)), "php", "ByteBuffer.php"));
+require join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)), "php", "FlatbufferBuilder.php"));
+require join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)), "php", "Table.php"));
+require join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)), "php", "Struct.php"));
+
+require join(DIRECTORY_SEPARATOR, array(dirname(__FILE__), "php", 'Attacker.php'));
+require join(DIRECTORY_SEPARATOR, array(dirname(__FILE__), "php", 'BookReader.php'));
+require join(DIRECTORY_SEPARATOR, array(dirname(__FILE__), "php", 'Character.php'));
+require join(DIRECTORY_SEPARATOR, array(dirname(__FILE__), "php", 'Movie.php'));
+
+class Assert {
+    public function ok($result, $message = "") {
+        if (!$result){
+            throw new Exception(!empty($message) ? $message : "{$result} is not true.");
+        }
+    }
+
+    public function Equal($result, $expected, $message = "") {
+        if ($result != $expected) {
+            throw new Exception(!empty($message) ? $message : "given the result {$result} is not equals as {$expected}");
+        }
+    }
+
+
+    public function strictEqual($result, $expected, $message = "") {
+        if ($result !== $expected) {
+            throw new Exception(!empty($message) ? $message : "given the result {$result} is not strict equals as {$expected}");
+        }
+    }
+
+    public function Throws($class, Callable $callback) {
+        try {
+            $callback();
+
+            throw new \Exception("passed statement don't throw an exception.");
+        } catch (\Exception $e) {
+            if (get_class($e) != get_class($class)) {
+                throw new Exception("passed statement doesn't throw " . get_class($class) . ". throwws " . get_class($e));
+            }
+        }
+    }
+}
+
+function main()
+{
+    $assert = new Assert();
+
+    $fbb = new Google\FlatBuffers\FlatBufferBuilder(1);
+
+    $charTypes = [
+        Character::Belle,
+        Character::MuLan,
+        Character::BookFan,
+    ];
+
+    Attacker::startAttacker($fbb);
+    Attacker::addSwordAttackDamage($fbb, 5);
+    $attackerOffset = Attacker::endAttacker($fbb);
+
+    $charTypesOffset = Movie::createCharactersTypeVector($fbb, $charTypes);
+    $charsOffset = Movie::createCharactersVector(
+        $fbb,
+        [
+            BookReader::createBookReader($fbb, 7),
+            $attackerOffset,
+            BookReader::createBookReader($fbb, 2),
+        ]
+    );
+
+    Movie::startMovie($fbb);
+    Movie::addCharactersType($fbb, $charTypesOffset);
+    Movie::addCharacters($fbb, $charsOffset);
+    Movie::finishMovieBuffer($fbb, Movie::endMovie($fbb));
+
+    $buf = Google\FlatBuffers\ByteBuffer::wrap($fbb->dataBuffer()->data());
+
+    $movie = Movie::getRootAsMovie($buf);
+
+    $assert->strictEqual($movie->getCharactersTypeLength(), count($charTypes));
+    $assert->strictEqual($movie->getCharactersLength(), $movie->getCharactersTypeLength());
+
+    for ($i = 0; $i < count($charTypes); ++$i) {
+        $assert->strictEqual($movie->getCharactersType($i), $charTypes[$i]);
+    }
+
+    $bookReader7 = $movie->getCharacters(0, new BookReader());
+    $assert->strictEqual($bookReader7->getBooksRead(), 7);
+
+    $attacker = $movie->getCharacters(1, new Attacker());
+    $assert->strictEqual($attacker->getSwordAttackDamage(), 5);
+
+    $bookReader2 = $movie->getCharacters(2, new BookReader());
+    $assert->strictEqual($bookReader2->getBooksRead(), 2);
+}
+
+try {
+    main();
+    exit(0);
+} catch(Exception $e) {
+    printf("Fatal error: Uncaught exception '%s' with message '%s. in %s:%d\n", get_class($e), $e->getMessage(), $e->getFile(), $e->getLine());
+    printf("Stack trace:\n");
+    echo $e->getTraceAsString() . PHP_EOL;
+    printf("  thrown in in %s:%d\n", $e->getFile(), $e->getLine());
+
+    die(-1);
+}
diff --git a/tests/phpUnionVectorTest.sh b/tests/phpUnionVectorTest.sh
new file mode 100755
index 0000000..a6c3f26
--- /dev/null
+++ b/tests/phpUnionVectorTest.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+set -e
+
+../flatc --php -o php union_vector/union_vector.fbs
+php phpUnionVectorTest.php
+
+echo 'PHP union vector test passed'
diff --git a/tests/prototest/imported.proto b/tests/prototest/imported.proto
new file mode 100644
index 0000000..5b43e4b
--- /dev/null
+++ b/tests/prototest/imported.proto
@@ -0,0 +1,5 @@
+package proto.test;
+
+message ImportedMessage {
+    optional int32 a = 26;
+}
diff --git a/tests/prototest/test.golden b/tests/prototest/test.golden
new file mode 100644
index 0000000..cf861b9
--- /dev/null
+++ b/tests/prototest/test.golden
@@ -0,0 +1,59 @@
+// Generated from test.proto
+
+namespace proto.test;
+
+/// Enum doc comment.
+enum ProtoEnum : int {
+  NUL = 0,
+  FOO = 1,
+  /// Enum 2nd value doc comment misaligned.
+  BAR = 5,
+}
+
+table ImportedMessage {
+  a:int;
+}
+
+/// 2nd table doc comment with
+/// many lines.
+table ProtoMessage {
+  c:int = 16;
+  d:long;
+  p:uint;
+  e:ulong;
+  /// doc comment for f.
+  f:int = -1;
+  g:long;
+  h:uint;
+  q:ulong;
+  i:int;
+  j:long;
+  /// doc comment for k.
+  k:bool;
+  /// doc comment for l on 2
+  /// lines
+  l:string (required);
+  m:[ubyte];
+  n:proto.test.ProtoMessage_.OtherMessage;
+  o:[string];
+  z:proto.test.ImportedMessage;
+  /// doc comment for r.
+  r:proto.test.ProtoMessage_.Anonymous0;
+}
+
+namespace proto.test.ProtoMessage_;
+
+table OtherMessage {
+  a:double;
+  /// doc comment for b.
+  b:float = 3.14149;
+}
+
+table Anonymous0 {
+  /// doc comment for s.
+  s:proto.test.ImportedMessage;
+  /// doc comment for t on 2
+  /// lines.
+  t:proto.test.ProtoMessage_.OtherMessage;
+}
+
diff --git a/tests/prototest/test.proto b/tests/prototest/test.proto
new file mode 100644
index 0000000..45ce6c0
--- /dev/null
+++ b/tests/prototest/test.proto
@@ -0,0 +1,59 @@
+// Sample .proto file that we can translate to the corresponding .fbs.
+
+option some_option = is_ignored;
+import "imported.proto";
+
+package proto.test;
+
+/// Enum doc comment.
+enum ProtoEnum {
+  option allow_alias = true;
+  NUL = 0;
+  FOO = 1;
+  /// Enum 2nd value doc comment misaligned.
+  BAR = 5;
+  // Aliases
+  FOO_A1 = 1;
+  BAR_A1 = 5;
+  FOO_A2 = 1;
+}
+
+/// 2nd table doc comment with
+/// many lines.
+message ProtoMessage {
+  // Ignored non-doc comment.
+  // A nested message declaration, will be moved to top level in .fbs
+  message OtherMessage {
+    optional double a = 26;
+    /// doc comment for b.
+    optional float b = 32 [default = 3.14149];
+  }
+  optional int32 c = 12 [default = 16];
+  optional int64 d = 1 [default = 0];
+  optional uint32 p = 1;
+  optional uint64 e = 2;
+  /// doc comment for f.
+  optional sint32 f = 3 [default = -1];
+  optional sint64 g = 4;
+  optional fixed32 h = 5;
+  optional fixed64 q = 6;
+  optional sfixed32 i = 7;
+  optional sfixed64 j = 8;
+  /// doc comment for k.
+  optional bool k = 9;
+  /// doc comment for l on 2
+  /// lines
+  required string l = 10;
+  optional bytes m = 11;
+  optional OtherMessage n = 12;
+  repeated string o = 14;
+  optional ImportedMessage z = 16;
+  /// doc comment for r.
+  oneof r {
+    /// doc comment for s.
+    ImportedMessage s = 17;
+    /// doc comment for t on 2
+    /// lines.
+    OtherMessage t = 18;
+  }
+}
diff --git a/tests/prototest/test_union.golden b/tests/prototest/test_union.golden
new file mode 100644
index 0000000..18270eb
--- /dev/null
+++ b/tests/prototest/test_union.golden
@@ -0,0 +1,63 @@
+// Generated from test.proto
+
+namespace proto.test;
+
+/// Enum doc comment.
+enum ProtoEnum : int {
+  NUL = 0,
+  FOO = 1,
+  /// Enum 2nd value doc comment misaligned.
+  BAR = 5,
+}
+
+namespace proto.test.ProtoMessage_;
+
+union RUnion {
+  /// doc comment for s.
+  proto.test.ImportedMessage,
+  /// doc comment for t on 2
+  /// lines.
+  proto.test.ProtoMessage_.OtherMessage,
+}
+
+namespace proto.test;
+
+table ImportedMessage {
+  a:int;
+}
+
+/// 2nd table doc comment with
+/// many lines.
+table ProtoMessage {
+  c:int = 16;
+  d:long;
+  p:uint;
+  e:ulong;
+  /// doc comment for f.
+  f:int = -1;
+  g:long;
+  h:uint;
+  q:ulong;
+  i:int;
+  j:long;
+  /// doc comment for k.
+  k:bool;
+  /// doc comment for l on 2
+  /// lines
+  l:string (required);
+  m:[ubyte];
+  n:proto.test.ProtoMessage_.OtherMessage;
+  o:[string];
+  z:proto.test.ImportedMessage;
+  /// doc comment for r.
+  r:proto.test.ProtoMessage_.RUnion;
+}
+
+namespace proto.test.ProtoMessage_;
+
+table OtherMessage {
+  a:double;
+  /// doc comment for b.
+  b:float = 3.14149;
+}
+
diff --git a/tests/py_test.py b/tests/py_test.py
new file mode 100644
index 0000000..b152270
--- /dev/null
+++ b/tests/py_test.py
@@ -0,0 +1,1817 @@
+# coding=utf-8
+# 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.
+
+import os.path
+import sys
+import imp
+PY_VERSION = sys.version_info[:2]
+
+import ctypes
+from collections import defaultdict
+import math
+import random
+import timeit
+import unittest
+
+from flatbuffers import compat
+from flatbuffers import util
+from flatbuffers.compat import range_func as compat_range
+from flatbuffers.compat import NumpyRequiredForThisFeature
+
+import flatbuffers
+from flatbuffers import number_types as N
+
+import MyGame  # refers to generated code
+import MyGame.Example  # refers to generated code
+import MyGame.Example.Any  # refers to generated code
+import MyGame.Example.Color  # refers to generated code
+import MyGame.Example.Monster  # refers to generated code
+import MyGame.Example.Test  # refers to generated code
+import MyGame.Example.Stat  # refers to generated code
+import MyGame.Example.Vec3  # refers to generated code
+import MyGame.MonsterExtra  # refers to generated code
+import MyGame.Example.ArrayTable  # refers to generated code
+import MyGame.Example.ArrayStruct  # refers to generated code
+import MyGame.Example.NestedStruct  # refers to generated code
+import MyGame.Example.TestEnum  # refers to generated code
+
+def assertRaises(test_case, fn, exception_class):
+    ''' Backwards-compatible assertion for exceptions raised. '''
+
+    exc = None
+    try:
+        fn()
+    except Exception as e:
+        exc = e
+    test_case.assertTrue(exc is not None)
+    test_case.assertTrue(isinstance(exc, exception_class))
+
+
+class TestWireFormat(unittest.TestCase):
+    def test_wire_format(self):
+        # Verify that using the generated Python code builds a buffer without
+        # returning errors, and is interpreted correctly, for size prefixed
+        # representation and regular:
+        for sizePrefix in [True, False]:
+            for file_identifier in [None, b"MONS"]:
+                gen_buf, gen_off = make_monster_from_generated_code(sizePrefix=sizePrefix, file_identifier=file_identifier)
+                CheckReadBuffer(gen_buf, gen_off, sizePrefix=sizePrefix, file_identifier=file_identifier)
+
+        # Verify that the canonical flatbuffer file is readable by the
+        # generated Python code. Note that context managers are not part of
+        # Python 2.5, so we use the simpler open/close methods here:
+        f = open('monsterdata_test.mon', 'rb')
+        canonicalWireData = f.read()
+        f.close()
+        CheckReadBuffer(bytearray(canonicalWireData), 0, file_identifier=b'MONS')
+
+        # Write the generated buffer out to a file:
+        f = open('monsterdata_python_wire.mon', 'wb')
+        f.write(gen_buf[gen_off:])
+        f.close()
+
+
+def CheckReadBuffer(buf, offset, sizePrefix=False, file_identifier=None):
+    ''' CheckReadBuffer checks that the given buffer is evaluated correctly
+        as the example Monster. '''
+
+    def asserter(stmt):
+        ''' An assertion helper that is separated from TestCase classes. '''
+        if not stmt:
+            raise AssertionError('CheckReadBuffer case failed')
+    if file_identifier:
+        # test prior to removal of size_prefix
+        asserter(util.GetBufferIdentifier(buf, offset, size_prefixed=sizePrefix) == file_identifier)
+        asserter(util.BufferHasIdentifier(buf, offset, file_identifier=file_identifier, size_prefixed=sizePrefix))
+    if sizePrefix:
+        size = util.GetSizePrefix(buf, offset)
+        asserter(size == len(buf[offset:])-4)
+        buf, offset = util.RemoveSizePrefix(buf, offset)
+    if file_identifier:
+        asserter(MyGame.Example.Monster.Monster.MonsterBufferHasIdentifier(buf, offset))
+    else:
+        asserter(not MyGame.Example.Monster.Monster.MonsterBufferHasIdentifier(buf, offset))
+    monster = MyGame.Example.Monster.Monster.GetRootAsMonster(buf, offset)
+
+    asserter(monster.Hp() == 80)
+    asserter(monster.Mana() == 150)
+    asserter(monster.Name() == b'MyMonster')
+
+    # initialize a Vec3 from Pos()
+    vec = monster.Pos()
+    asserter(vec is not None)
+
+    # verify the properties of the Vec3
+    asserter(vec.X() == 1.0)
+    asserter(vec.Y() == 2.0)
+    asserter(vec.Z() == 3.0)
+    asserter(vec.Test1() == 3.0)
+    asserter(vec.Test2() == 2)
+
+    # initialize a Test from Test3(...)
+    t = MyGame.Example.Test.Test()
+    t = vec.Test3(t)
+    asserter(t is not None)
+
+    # verify the properties of the Test
+    asserter(t.A() == 5)
+    asserter(t.B() == 6)
+
+    # verify that the enum code matches the enum declaration:
+    union_type = MyGame.Example.Any.Any
+    asserter(monster.TestType() == union_type.Monster)
+
+    # initialize a Table from a union field Test(...)
+    table2 = monster.Test()
+    asserter(type(table2) is flatbuffers.table.Table)
+
+    # initialize a Monster from the Table from the union
+    monster2 = MyGame.Example.Monster.Monster()
+    monster2.Init(table2.Bytes, table2.Pos)
+
+    asserter(monster2.Name() == b"Fred")
+
+    # iterate through the first monster's inventory:
+    asserter(monster.InventoryLength() == 5)
+
+    invsum = 0
+    for i in compat_range(monster.InventoryLength()):
+        v = monster.Inventory(i)
+        invsum += int(v)
+    asserter(invsum == 10)
+
+    for i in range(5):
+        asserter(monster.VectorOfLongs(i) == 10 ** (i * 2))
+
+    asserter(([-1.7976931348623157e+308, 0, 1.7976931348623157e+308]
+              == [monster.VectorOfDoubles(i)
+                  for i in range(monster.VectorOfDoublesLength())]))
+
+    try:
+        imp.find_module('numpy')
+        # if numpy exists, then we should be able to get the
+        # vector as a numpy array
+        import numpy as np
+
+        asserter(monster.InventoryAsNumpy().sum() == 10)
+        asserter(monster.InventoryAsNumpy().dtype == np.dtype('uint8'))
+
+        VectorOfLongs = monster.VectorOfLongsAsNumpy()
+        asserter(VectorOfLongs.dtype == np.dtype('int64'))
+        for i in range(5):
+            asserter(VectorOfLongs[i] == 10 ** (i * 2))
+
+        VectorOfDoubles = monster.VectorOfDoublesAsNumpy()
+        asserter(VectorOfDoubles.dtype == np.dtype('float64'))
+        asserter(VectorOfDoubles[0] == np.finfo('float64').min)
+        asserter(VectorOfDoubles[1] == 0.0)
+        asserter(VectorOfDoubles[2] == np.finfo('float64').max)
+
+    except ImportError:
+        # If numpy does not exist, trying to get vector as numpy
+        # array should raise NumpyRequiredForThisFeature. The way
+        # assertRaises has been implemented prevents us from
+        # asserting this error is raised outside of a test case.
+        pass
+
+    asserter(monster.Test4Length() == 2)
+
+    # create a 'Test' object and populate it:
+    test0 = monster.Test4(0)
+    asserter(type(test0) is MyGame.Example.Test.Test)
+
+    test1 = monster.Test4(1)
+    asserter(type(test1) is MyGame.Example.Test.Test)
+
+    # the position of test0 and test1 are swapped in monsterdata_java_wire
+    # and monsterdata_test_wire, so ignore ordering
+    v0 = test0.A()
+    v1 = test0.B()
+    v2 = test1.A()
+    v3 = test1.B()
+    sumtest12 = int(v0) + int(v1) + int(v2) + int(v3)
+
+    asserter(sumtest12 == 100)
+
+    asserter(monster.TestarrayofstringLength() == 2)
+    asserter(monster.Testarrayofstring(0) == b"test1")
+    asserter(monster.Testarrayofstring(1) == b"test2")
+
+    asserter(monster.TestarrayoftablesLength() == 0)
+    asserter(monster.TestnestedflatbufferLength() == 0)
+    asserter(monster.Testempty() is None)
+
+
+class TestFuzz(unittest.TestCase):
+    ''' Low level stress/fuzz test: serialize/deserialize a variety of
+        different kinds of data in different combinations '''
+
+    binary_type = compat.binary_types[0] # this will always exist
+    ofInt32Bytes = binary_type([0x83, 0x33, 0x33, 0x33])
+    ofInt64Bytes = binary_type([0x84, 0x44, 0x44, 0x44,
+                                0x44, 0x44, 0x44, 0x44])
+    overflowingInt32Val = flatbuffers.encode.Get(flatbuffers.packer.int32,
+                                                 ofInt32Bytes, 0)
+    overflowingInt64Val = flatbuffers.encode.Get(flatbuffers.packer.int64,
+                                                 ofInt64Bytes, 0)
+
+    # Values we're testing against: chosen to ensure no bits get chopped
+    # off anywhere, and also be different from eachother.
+    boolVal = True
+    int8Val = N.Int8Flags.py_type(-127) # 0x81
+    uint8Val = N.Uint8Flags.py_type(0xFF)
+    int16Val = N.Int16Flags.py_type(-32222) # 0x8222
+    uint16Val = N.Uint16Flags.py_type(0xFEEE)
+    int32Val = N.Int32Flags.py_type(overflowingInt32Val)
+    uint32Val = N.Uint32Flags.py_type(0xFDDDDDDD)
+    int64Val = N.Int64Flags.py_type(overflowingInt64Val)
+    uint64Val = N.Uint64Flags.py_type(0xFCCCCCCCCCCCCCCC)
+    # Python uses doubles, so force it here
+    float32Val = N.Float32Flags.py_type(ctypes.c_float(3.14159).value)
+    float64Val = N.Float64Flags.py_type(3.14159265359)
+
+    def test_fuzz(self):
+        return self.check_once(11, 100)
+
+    def check_once(self, fuzzFields, fuzzObjects):
+        testValuesMax = 11 # hardcoded to the number of scalar types
+
+        builder = flatbuffers.Builder(0)
+        l = LCG()
+
+        objects = [0 for _ in compat_range(fuzzObjects)]
+
+        # Generate fuzzObjects random objects each consisting of
+        # fuzzFields fields, each of a random type.
+        for i in compat_range(fuzzObjects):
+            builder.StartObject(fuzzFields)
+
+            for j in compat_range(fuzzFields):
+                choice = int(l.Next()) % testValuesMax
+                if choice == 0:
+                    builder.PrependBoolSlot(int(j), self.boolVal, False)
+                elif choice == 1:
+                    builder.PrependInt8Slot(int(j), self.int8Val, 0)
+                elif choice == 2:
+                    builder.PrependUint8Slot(int(j), self.uint8Val, 0)
+                elif choice == 3:
+                    builder.PrependInt16Slot(int(j), self.int16Val, 0)
+                elif choice == 4:
+                    builder.PrependUint16Slot(int(j), self.uint16Val, 0)
+                elif choice == 5:
+                    builder.PrependInt32Slot(int(j), self.int32Val, 0)
+                elif choice == 6:
+                    builder.PrependUint32Slot(int(j), self.uint32Val, 0)
+                elif choice == 7:
+                    builder.PrependInt64Slot(int(j), self.int64Val, 0)
+                elif choice == 8:
+                    builder.PrependUint64Slot(int(j), self.uint64Val, 0)
+                elif choice == 9:
+                    builder.PrependFloat32Slot(int(j), self.float32Val, 0)
+                elif choice == 10:
+                    builder.PrependFloat64Slot(int(j), self.float64Val, 0)
+                else:
+                    raise RuntimeError('unreachable')
+
+            off = builder.EndObject()
+
+            # store the offset from the end of the builder buffer,
+            # since it will keep growing:
+            objects[i] = off
+
+        # Do some bookkeeping to generate stats on fuzzes:
+        stats = defaultdict(int)
+        def check(table, desc, want, got):
+            stats[desc] += 1
+            self.assertEqual(want, got, "%s != %s, %s" % (want, got, desc))
+
+        l = LCG()  # Reset.
+
+        # Test that all objects we generated are readable and return the
+        # expected values. We generate random objects in the same order
+        # so this is deterministic.
+        for i in compat_range(fuzzObjects):
+
+            table = flatbuffers.table.Table(builder.Bytes,
+                                            len(builder.Bytes) - objects[i])
+
+            for j in compat_range(fuzzFields):
+                field_count = flatbuffers.builder.VtableMetadataFields + j
+                f = N.VOffsetTFlags.py_type(field_count *
+                                            N.VOffsetTFlags.bytewidth)
+                choice = int(l.Next()) % testValuesMax
+
+                if choice == 0:
+                    check(table, "bool", self.boolVal,
+                          table.GetSlot(f, False, N.BoolFlags))
+                elif choice == 1:
+                    check(table, "int8", self.int8Val,
+                          table.GetSlot(f, 0, N.Int8Flags))
+                elif choice == 2:
+                    check(table, "uint8", self.uint8Val,
+                          table.GetSlot(f, 0, N.Uint8Flags))
+                elif choice == 3:
+                    check(table, "int16", self.int16Val,
+                          table.GetSlot(f, 0, N.Int16Flags))
+                elif choice == 4:
+                    check(table, "uint16", self.uint16Val,
+                          table.GetSlot(f, 0, N.Uint16Flags))
+                elif choice == 5:
+                    check(table, "int32", self.int32Val,
+                          table.GetSlot(f, 0, N.Int32Flags))
+                elif choice == 6:
+                    check(table, "uint32", self.uint32Val,
+                          table.GetSlot(f, 0, N.Uint32Flags))
+                elif choice == 7:
+                    check(table, "int64", self.int64Val,
+                          table.GetSlot(f, 0, N.Int64Flags))
+                elif choice == 8:
+                    check(table, "uint64", self.uint64Val,
+                          table.GetSlot(f, 0, N.Uint64Flags))
+                elif choice == 9:
+                    check(table, "float32", self.float32Val,
+                          table.GetSlot(f, 0, N.Float32Flags))
+                elif choice == 10:
+                    check(table, "float64", self.float64Val,
+                          table.GetSlot(f, 0, N.Float64Flags))
+                else:
+                    raise RuntimeError('unreachable')
+
+        # If enough checks were made, verify that all scalar types were used:
+        self.assertEqual(testValuesMax, len(stats),
+                "fuzzing failed to test all scalar types: %s" % stats)
+
+
+class TestByteLayout(unittest.TestCase):
+    ''' TestByteLayout checks the bytes of a Builder in various scenarios. '''
+
+    def assertBuilderEquals(self, builder, want_chars_or_ints):
+        def integerize(x):
+            if isinstance(x, compat.string_types):
+                return ord(x)
+            return x
+
+        want_ints = list(map(integerize, want_chars_or_ints))
+        want = bytearray(want_ints)
+        got = builder.Bytes[builder.Head():] # use the buffer directly
+        self.assertEqual(want, got)
+
+    def test_numbers(self):
+        b = flatbuffers.Builder(0)
+        self.assertBuilderEquals(b, [])
+        b.PrependBool(True)
+        self.assertBuilderEquals(b, [1])
+        b.PrependInt8(-127)
+        self.assertBuilderEquals(b, [129, 1])
+        b.PrependUint8(255)
+        self.assertBuilderEquals(b, [255, 129, 1])
+        b.PrependInt16(-32222)
+        self.assertBuilderEquals(b, [0x22, 0x82, 0, 255, 129, 1]) # first pad
+        b.PrependUint16(0xFEEE)
+        # no pad this time:
+        self.assertBuilderEquals(b, [0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1])
+        b.PrependInt32(-53687092)
+        self.assertBuilderEquals(b, [204, 204, 204, 252, 0xEE, 0xFE,
+                                     0x22, 0x82, 0, 255, 129, 1])
+        b.PrependUint32(0x98765432)
+        self.assertBuilderEquals(b, [0x32, 0x54, 0x76, 0x98,
+                                     204, 204, 204, 252,
+                                     0xEE, 0xFE, 0x22, 0x82,
+                                     0, 255, 129, 1])
+
+    def test_numbers64(self):
+        b = flatbuffers.Builder(0)
+        b.PrependUint64(0x1122334455667788)
+        self.assertBuilderEquals(b, [0x88, 0x77, 0x66, 0x55,
+                                     0x44, 0x33, 0x22, 0x11])
+
+        b = flatbuffers.Builder(0)
+        b.PrependInt64(0x1122334455667788)
+        self.assertBuilderEquals(b, [0x88, 0x77, 0x66, 0x55,
+                                     0x44, 0x33, 0x22, 0x11])
+
+    def test_1xbyte_vector(self):
+        b = flatbuffers.Builder(0)
+        self.assertBuilderEquals(b, [])
+        b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 1, 1)
+        self.assertBuilderEquals(b, [0, 0, 0]) # align to 4bytes
+        b.PrependByte(1)
+        self.assertBuilderEquals(b, [1, 0, 0, 0])
+        b.EndVector(1)
+        self.assertBuilderEquals(b, [1, 0, 0, 0, 1, 0, 0, 0]) # padding
+
+    def test_2xbyte_vector(self):
+        b = flatbuffers.Builder(0)
+        b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 2, 1)
+        self.assertBuilderEquals(b, [0, 0]) # align to 4bytes
+        b.PrependByte(1)
+        self.assertBuilderEquals(b, [1, 0, 0])
+        b.PrependByte(2)
+        self.assertBuilderEquals(b, [2, 1, 0, 0])
+        b.EndVector(2)
+        self.assertBuilderEquals(b, [2, 0, 0, 0, 2, 1, 0, 0]) # padding
+
+    def test_1xuint16_vector(self):
+        b = flatbuffers.Builder(0)
+        b.StartVector(flatbuffers.number_types.Uint16Flags.bytewidth, 1, 1)
+        self.assertBuilderEquals(b, [0, 0]) # align to 4bytes
+        b.PrependUint16(1)
+        self.assertBuilderEquals(b, [1, 0, 0, 0])
+        b.EndVector(1)
+        self.assertBuilderEquals(b, [1, 0, 0, 0, 1, 0, 0, 0]) # padding
+
+    def test_2xuint16_vector(self):
+        b = flatbuffers.Builder(0)
+        b.StartVector(flatbuffers.number_types.Uint16Flags.bytewidth, 2, 1)
+        self.assertBuilderEquals(b, []) # align to 4bytes
+        b.PrependUint16(0xABCD)
+        self.assertBuilderEquals(b, [0xCD, 0xAB])
+        b.PrependUint16(0xDCBA)
+        self.assertBuilderEquals(b, [0xBA, 0xDC, 0xCD, 0xAB])
+        b.EndVector(2)
+        self.assertBuilderEquals(b, [2, 0, 0, 0, 0xBA, 0xDC, 0xCD, 0xAB])
+
+    def test_create_ascii_string(self):
+        b = flatbuffers.Builder(0)
+        b.CreateString(u"foo", encoding='ascii')
+
+        # 0-terminated, no pad:
+        self.assertBuilderEquals(b, [3, 0, 0, 0, 'f', 'o', 'o', 0])
+        b.CreateString(u"moop", encoding='ascii')
+        # 0-terminated, 3-byte pad:
+        self.assertBuilderEquals(b, [4, 0, 0, 0, 'm', 'o', 'o', 'p',
+                                     0, 0, 0, 0,
+                                     3, 0, 0, 0, 'f', 'o', 'o', 0])
+
+    def test_create_utf8_string(self):
+        b = flatbuffers.Builder(0)
+        b.CreateString(u"Цлїςσδε")
+        self.assertBuilderEquals(b, "\x0e\x00\x00\x00\xd0\xa6\xd0\xbb\xd1\x97" \
+            "\xcf\x82\xcf\x83\xce\xb4\xce\xb5\x00\x00")
+
+        b.CreateString(u"フムアムカモケモ")
+        self.assertBuilderEquals(b, "\x18\x00\x00\x00\xef\xbe\x8c\xef\xbe\x91" \
+            "\xef\xbd\xb1\xef\xbe\x91\xef\xbd\xb6\xef\xbe\x93\xef\xbd\xb9\xef" \
+            "\xbe\x93\x00\x00\x00\x00\x0e\x00\x00\x00\xd0\xa6\xd0\xbb\xd1\x97" \
+            "\xcf\x82\xcf\x83\xce\xb4\xce\xb5\x00\x00")
+
+    def test_create_arbitrary_string(self):
+        b = flatbuffers.Builder(0)
+        s = "\x01\x02\x03"
+        b.CreateString(s) # Default encoding is utf-8.
+        # 0-terminated, no pad:
+        self.assertBuilderEquals(b, [3, 0, 0, 0, 1, 2, 3, 0])
+        s2 = "\x04\x05\x06\x07"
+        b.CreateString(s2) # Default encoding is utf-8.
+        # 0-terminated, 3-byte pad:
+        self.assertBuilderEquals(b, [4, 0, 0, 0, 4, 5, 6, 7, 0, 0, 0, 0,
+                                     3, 0, 0, 0, 1, 2, 3, 0])
+
+    def test_create_byte_vector(self):
+        b = flatbuffers.Builder(0)
+        b.CreateByteVector(b"")
+        # 0-byte pad:
+        self.assertBuilderEquals(b, [0, 0, 0, 0])
+
+        b = flatbuffers.Builder(0)
+        b.CreateByteVector(b"\x01\x02\x03")
+        # 1-byte pad:
+        self.assertBuilderEquals(b, [3, 0, 0, 0, 1, 2, 3, 0])
+
+    def test_create_numpy_vector_int8(self):
+        try:
+            imp.find_module('numpy')
+            # if numpy exists, then we should be able to get the
+            # vector as a numpy array
+            import numpy as np
+
+            # Systems endian:
+            b = flatbuffers.Builder(0)
+            x = np.array([1, 2, -3], dtype=np.int8)
+            b.CreateNumpyVector(x)
+            self.assertBuilderEquals(b, [
+                3, 0, 0, 0,  # vector length
+                1, 2, 256 - 3, 0   # vector value + padding
+            ])
+
+            # Reverse endian:
+            b = flatbuffers.Builder(0)
+            x_other_endian = x.byteswap().newbyteorder()
+            b.CreateNumpyVector(x_other_endian)
+            self.assertBuilderEquals(b, [
+                3, 0, 0, 0,  # vector length
+                1, 2, 256 - 3, 0   # vector value + padding
+            ])
+        except ImportError:
+            b = flatbuffers.Builder(0)
+            x = 0
+            assertRaises(
+                self,
+                lambda: b.CreateNumpyVector(x),
+                NumpyRequiredForThisFeature)
+
+    def test_create_numpy_vector_uint16(self):
+        try:
+            imp.find_module('numpy')
+            # if numpy exists, then we should be able to get the
+            # vector as a numpy array
+            import numpy as np
+
+            # Systems endian:
+            b = flatbuffers.Builder(0)
+            x = np.array([1, 2, 312], dtype=np.uint16)
+            b.CreateNumpyVector(x)
+            self.assertBuilderEquals(b, [
+                3, 0, 0, 0,     # vector length
+                1, 0,           # 1
+                2, 0,           # 2
+                312 - 256, 1,   # 312
+                0, 0            # padding
+            ])
+
+            # Reverse endian:
+            b = flatbuffers.Builder(0)
+            x_other_endian = x.byteswap().newbyteorder()
+            b.CreateNumpyVector(x_other_endian)
+            self.assertBuilderEquals(b, [
+                3, 0, 0, 0,     # vector length
+                1, 0,           # 1
+                2, 0,           # 2
+                312 - 256, 1,   # 312
+                0, 0            # padding
+            ])
+        except ImportError:
+            b = flatbuffers.Builder(0)
+            x = 0
+            assertRaises(
+                self,
+                lambda: b.CreateNumpyVector(x),
+                NumpyRequiredForThisFeature)
+
+    def test_create_numpy_vector_int64(self):
+        try:
+            imp.find_module('numpy')
+            # if numpy exists, then we should be able to get the
+            # vector as a numpy array
+            import numpy as np
+
+            # Systems endian:
+            b = flatbuffers.Builder(0)
+            x = np.array([1, 2, -12], dtype=np.int64)
+            b.CreateNumpyVector(x)
+            self.assertBuilderEquals(b, [
+                3, 0, 0, 0,                     # vector length
+                1, 0, 0, 0, 0, 0, 0, 0,         # 1
+                2, 0, 0, 0, 0, 0, 0, 0,         # 2
+                256 - 12, 255, 255, 255, 255, 255, 255, 255   # -12
+            ])
+
+            # Reverse endian:
+            b = flatbuffers.Builder(0)
+            x_other_endian = x.byteswap().newbyteorder()
+            b.CreateNumpyVector(x_other_endian)
+            self.assertBuilderEquals(b, [
+                3, 0, 0, 0,                     # vector length
+                1, 0, 0, 0, 0, 0, 0, 0,         # 1
+                2, 0, 0, 0, 0, 0, 0, 0,         # 2
+                256 - 12, 255, 255, 255, 255, 255, 255, 255   # -12
+            ])
+
+        except ImportError:
+            b = flatbuffers.Builder(0)
+            x = 0
+            assertRaises(
+                self,
+                lambda: b.CreateNumpyVector(x),
+                NumpyRequiredForThisFeature)
+
+    def test_create_numpy_vector_float32(self):
+        try:
+            imp.find_module('numpy')
+            # if numpy exists, then we should be able to get the
+            # vector as a numpy array
+            import numpy as np
+
+            # Systems endian:
+            b = flatbuffers.Builder(0)
+            x = np.array([1, 2, -12], dtype=np.float32)
+            b.CreateNumpyVector(x)
+            self.assertBuilderEquals(b, [
+                3, 0, 0, 0,                     # vector length
+                0, 0, 128, 63,                  # 1
+                0, 0, 0, 64,                    # 2
+                0, 0, 64, 193                   # -12
+            ])
+
+            # Reverse endian:
+            b = flatbuffers.Builder(0)
+            x_other_endian = x.byteswap().newbyteorder()
+            b.CreateNumpyVector(x_other_endian)
+            self.assertBuilderEquals(b, [
+                3, 0, 0, 0,                     # vector length
+                0, 0, 128, 63,                  # 1
+                0, 0, 0, 64,                    # 2
+                0, 0, 64, 193                   # -12
+            ])
+
+        except ImportError:
+            b = flatbuffers.Builder(0)
+            x = 0
+            assertRaises(
+                self,
+                lambda: b.CreateNumpyVector(x),
+                NumpyRequiredForThisFeature)
+
+    def test_create_numpy_vector_float64(self):
+        try:
+            imp.find_module('numpy')
+            # if numpy exists, then we should be able to get the
+            # vector as a numpy array
+            import numpy as np
+
+            # Systems endian:
+            b = flatbuffers.Builder(0)
+            x = np.array([1, 2, -12], dtype=np.float64)
+            b.CreateNumpyVector(x)
+            self.assertBuilderEquals(b, [
+                3, 0, 0, 0,                     # vector length
+                0, 0, 0, 0, 0, 0, 240, 63,                  # 1
+                0, 0, 0, 0, 0, 0, 0, 64,                    # 2
+                0, 0, 0, 0, 0, 0, 40, 192                   # -12
+            ])
+
+            # Reverse endian:
+            b = flatbuffers.Builder(0)
+            x_other_endian = x.byteswap().newbyteorder()
+            b.CreateNumpyVector(x_other_endian)
+            self.assertBuilderEquals(b, [
+                3, 0, 0, 0,                     # vector length
+                0, 0, 0, 0, 0, 0, 240, 63,                  # 1
+                0, 0, 0, 0, 0, 0, 0, 64,                    # 2
+                0, 0, 0, 0, 0, 0, 40, 192                   # -12
+            ])
+
+        except ImportError:
+            b = flatbuffers.Builder(0)
+            x = 0
+            assertRaises(
+                self,
+                lambda: b.CreateNumpyVector(x),
+                NumpyRequiredForThisFeature)
+
+    def test_create_numpy_vector_bool(self):
+        try:
+            imp.find_module('numpy')
+            # if numpy exists, then we should be able to get the
+            # vector as a numpy array
+            import numpy as np
+
+            # Systems endian:
+            b = flatbuffers.Builder(0)
+            x = np.array([True, False, True], dtype=np.bool)
+            b.CreateNumpyVector(x)
+            self.assertBuilderEquals(b, [
+                3, 0, 0, 0, # vector length
+                1, 0, 1, 0  # vector values + padding
+            ])
+
+            # Reverse endian:
+            b = flatbuffers.Builder(0)
+            x_other_endian = x.byteswap().newbyteorder()
+            b.CreateNumpyVector(x_other_endian)
+            self.assertBuilderEquals(b, [
+                3, 0, 0, 0, # vector length
+                1, 0, 1, 0  # vector values + padding
+            ])
+
+        except ImportError:
+            b = flatbuffers.Builder(0)
+            x = 0
+            assertRaises(
+                self,
+                lambda: b.CreateNumpyVector(x),
+                NumpyRequiredForThisFeature)
+
+    def test_create_numpy_vector_reject_strings(self):
+        try:
+            imp.find_module('numpy')
+            # if numpy exists, then we should be able to get the
+            # vector as a numpy array
+            import numpy as np
+
+            # Create String array
+            b = flatbuffers.Builder(0)
+            x = np.array(["hello", "fb", "testing"])
+            assertRaises(
+                self,
+                lambda: b.CreateNumpyVector(x),
+                TypeError)
+
+        except ImportError:
+            b = flatbuffers.Builder(0)
+            x = 0
+            assertRaises(
+                self,
+                lambda: b.CreateNumpyVector(x),
+                NumpyRequiredForThisFeature)
+
+    def test_create_numpy_vector_reject_object(self):
+        try:
+            imp.find_module('numpy')
+            # if numpy exists, then we should be able to get the
+            # vector as a numpy array
+            import numpy as np
+
+            # Create String array
+            b = flatbuffers.Builder(0)
+            x = np.array([{"m": 0}, {"as": -2.1, 'c': 'c'}])
+            assertRaises(
+                self,
+                lambda: b.CreateNumpyVector(x),
+                TypeError)
+
+        except ImportError:
+            b = flatbuffers.Builder(0)
+            x = 0
+            assertRaises(
+                self,
+                lambda: b.CreateNumpyVector(x),
+                NumpyRequiredForThisFeature)
+
+    def test_empty_vtable(self):
+        b = flatbuffers.Builder(0)
+        b.StartObject(0)
+        self.assertBuilderEquals(b, [])
+        b.EndObject()
+        self.assertBuilderEquals(b, [4, 0, 4, 0, 4, 0, 0, 0])
+
+    def test_vtable_with_one_true_bool(self):
+        b = flatbuffers.Builder(0)
+        self.assertBuilderEquals(b, [])
+        b.StartObject(1)
+        self.assertBuilderEquals(b, [])
+        b.PrependBoolSlot(0, True, False)
+        b.EndObject()
+        self.assertBuilderEquals(b, [
+            6, 0,  # vtable bytes
+            8, 0,  # length of object including vtable offset
+            7, 0,  # start of bool value
+            6, 0, 0, 0,  # offset for start of vtable (int32)
+            0, 0, 0,  # padded to 4 bytes
+            1,  # bool value
+        ])
+
+    def test_vtable_with_one_default_bool(self):
+        b = flatbuffers.Builder(0)
+        self.assertBuilderEquals(b, [])
+        b.StartObject(1)
+        self.assertBuilderEquals(b, [])
+        b.PrependBoolSlot(0, False, False)
+        b.EndObject()
+        self.assertBuilderEquals(b, [
+            4, 0,  # vtable bytes
+            4, 0,  # end of object from here
+            # entry 1 is zero and not stored
+            4, 0, 0, 0,  # offset for start of vtable (int32)
+        ])
+
+    def test_vtable_with_one_int16(self):
+        b = flatbuffers.Builder(0)
+        b.StartObject(1)
+        b.PrependInt16Slot(0, 0x789A, 0)
+        b.EndObject()
+        self.assertBuilderEquals(b, [
+            6, 0,  # vtable bytes
+            8, 0,  # end of object from here
+            6, 0,  # offset to value
+            6, 0, 0, 0,  # offset for start of vtable (int32)
+            0, 0,  # padding to 4 bytes
+            0x9A, 0x78,
+        ])
+
+    def test_vtable_with_two_int16(self):
+        b = flatbuffers.Builder(0)
+        b.StartObject(2)
+        b.PrependInt16Slot(0, 0x3456, 0)
+        b.PrependInt16Slot(1, 0x789A, 0)
+        b.EndObject()
+        self.assertBuilderEquals(b, [
+            8, 0,  # vtable bytes
+            8, 0,  # end of object from here
+            6, 0,  # offset to value 0
+            4, 0,  # offset to value 1
+            8, 0, 0, 0,  # offset for start of vtable (int32)
+            0x9A, 0x78,  # value 1
+            0x56, 0x34,  # value 0
+        ])
+
+    def test_vtable_with_int16_and_bool(self):
+        b = flatbuffers.Builder(0)
+        b.StartObject(2)
+        b.PrependInt16Slot(0, 0x3456, 0)
+        b.PrependBoolSlot(1, True, False)
+        b.EndObject()
+        self.assertBuilderEquals(b, [
+            8, 0,  # vtable bytes
+            8, 0,  # end of object from here
+            6, 0,  # offset to value 0
+            5, 0,  # offset to value 1
+            8, 0, 0, 0,  # offset for start of vtable (int32)
+            0,          # padding
+            1,          # value 1
+            0x56, 0x34,  # value 0
+        ])
+
+    def test_vtable_with_empty_vector(self):
+        b = flatbuffers.Builder(0)
+        b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 0, 1)
+        vecend = b.EndVector(0)
+        b.StartObject(1)
+        b.PrependUOffsetTRelativeSlot(0, vecend, 0)
+        b.EndObject()
+        self.assertBuilderEquals(b, [
+            6, 0,  # vtable bytes
+            8, 0,
+            4, 0,  # offset to vector offset
+            6, 0, 0, 0,  # offset for start of vtable (int32)
+            4, 0, 0, 0,
+            0, 0, 0, 0,  # length of vector (not in struct)
+        ])
+
+    def test_vtable_with_empty_vector_of_byte_and_some_scalars(self):
+        b = flatbuffers.Builder(0)
+        b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 0, 1)
+        vecend = b.EndVector(0)
+        b.StartObject(2)
+        b.PrependInt16Slot(0, 55, 0)
+        b.PrependUOffsetTRelativeSlot(1, vecend, 0)
+        b.EndObject()
+        self.assertBuilderEquals(b, [
+            8, 0,  # vtable bytes
+            12, 0,
+            10, 0,  # offset to value 0
+            4, 0,  # offset to vector offset
+            8, 0, 0, 0,  # vtable loc
+            8, 0, 0, 0,  # value 1
+            0, 0, 55, 0,  # value 0
+
+            0, 0, 0, 0,  # length of vector (not in struct)
+        ])
+
+    def test_vtable_with_1_int16_and_2vector_of_int16(self):
+        b = flatbuffers.Builder(0)
+        b.StartVector(flatbuffers.number_types.Int16Flags.bytewidth, 2, 1)
+        b.PrependInt16(0x1234)
+        b.PrependInt16(0x5678)
+        vecend = b.EndVector(2)
+        b.StartObject(2)
+        b.PrependUOffsetTRelativeSlot(1, vecend, 0)
+        b.PrependInt16Slot(0, 55, 0)
+        b.EndObject()
+        self.assertBuilderEquals(b, [
+            8, 0,  # vtable bytes
+            12, 0,  # length of object
+            6, 0,  # start of value 0 from end of vtable
+            8, 0,  # start of value 1 from end of buffer
+            8, 0, 0, 0,  # offset for start of vtable (int32)
+            0, 0,  # padding
+            55, 0,  # value 0
+            4, 0, 0, 0,  # vector position from here
+            2, 0, 0, 0,  # length of vector (uint32)
+            0x78, 0x56,  # vector value 1
+            0x34, 0x12,  # vector value 0
+        ])
+
+    def test_vtable_with_1_struct_of_1_int8__1_int16__1_int32(self):
+        b = flatbuffers.Builder(0)
+        b.StartObject(1)
+        b.Prep(4+4+4, 0)
+        b.PrependInt8(55)
+        b.Pad(3)
+        b.PrependInt16(0x1234)
+        b.Pad(2)
+        b.PrependInt32(0x12345678)
+        structStart = b.Offset()
+        b.PrependStructSlot(0, structStart, 0)
+        b.EndObject()
+        self.assertBuilderEquals(b, [
+            6, 0,  # vtable bytes
+            16, 0,  # end of object from here
+            4, 0,  # start of struct from here
+            6, 0, 0, 0,  # offset for start of vtable (int32)
+            0x78, 0x56, 0x34, 0x12,  # value 2
+            0, 0,  # padding
+            0x34, 0x12,  # value 1
+            0, 0, 0,  # padding
+            55,  # value 0
+        ])
+
+    def test_vtable_with_1_vector_of_2_struct_of_2_int8(self):
+        b = flatbuffers.Builder(0)
+        b.StartVector(flatbuffers.number_types.Int8Flags.bytewidth*2, 2, 1)
+        b.PrependInt8(33)
+        b.PrependInt8(44)
+        b.PrependInt8(55)
+        b.PrependInt8(66)
+        vecend = b.EndVector(2)
+        b.StartObject(1)
+        b.PrependUOffsetTRelativeSlot(0, vecend, 0)
+        b.EndObject()
+        self.assertBuilderEquals(b, [
+            6, 0,  # vtable bytes
+            8, 0,
+            4, 0,  # offset of vector offset
+            6, 0, 0, 0,  # offset for start of vtable (int32)
+            4, 0, 0, 0,  # vector start offset
+
+            2, 0, 0, 0,  # vector length
+            66,  # vector value 1,1
+            55,  # vector value 1,0
+            44,  # vector value 0,1
+            33,  # vector value 0,0
+        ])
+
+    def test_table_with_some_elements(self):
+        b = flatbuffers.Builder(0)
+        b.StartObject(2)
+        b.PrependInt8Slot(0, 33, 0)
+        b.PrependInt16Slot(1, 66, 0)
+        off = b.EndObject()
+        b.Finish(off)
+
+        self.assertBuilderEquals(b, [
+            12, 0, 0, 0,  # root of table: points to vtable offset
+
+            8, 0,  # vtable bytes
+            8, 0,  # end of object from here
+            7, 0,  # start of value 0
+            4, 0,  # start of value 1
+
+            8, 0, 0, 0,  # offset for start of vtable (int32)
+
+            66, 0,  # value 1
+            0,  # padding
+            33,  # value 0
+        ])
+
+    def test__one_unfinished_table_and_one_finished_table(self):
+        b = flatbuffers.Builder(0)
+        b.StartObject(2)
+        b.PrependInt8Slot(0, 33, 0)
+        b.PrependInt8Slot(1, 44, 0)
+        off = b.EndObject()
+        b.Finish(off)
+
+        b.StartObject(3)
+        b.PrependInt8Slot(0, 55, 0)
+        b.PrependInt8Slot(1, 66, 0)
+        b.PrependInt8Slot(2, 77, 0)
+        off = b.EndObject()
+        b.Finish(off)
+
+        self.assertBuilderEquals(b, [
+            16, 0, 0, 0,  # root of table: points to object
+            0, 0,  # padding
+
+            10, 0,  # vtable bytes
+            8, 0,  # size of object
+            7, 0,  # start of value 0
+            6, 0,  # start of value 1
+            5, 0,  # start of value 2
+            10, 0, 0, 0,  # offset for start of vtable (int32)
+            0,  # padding
+            77,  # value 2
+            66,  # value 1
+            55,  # value 0
+
+            12, 0, 0, 0,  # root of table: points to object
+
+            8, 0,  # vtable bytes
+            8, 0,  # size of object
+            7, 0,  # start of value 0
+            6, 0,  # start of value 1
+            8, 0, 0, 0,  # offset for start of vtable (int32)
+            0, 0,  # padding
+            44,  # value 1
+            33,  # value 0
+        ])
+
+    def test_a_bunch_of_bools(self):
+        b = flatbuffers.Builder(0)
+        b.StartObject(8)
+        b.PrependBoolSlot(0, True, False)
+        b.PrependBoolSlot(1, True, False)
+        b.PrependBoolSlot(2, True, False)
+        b.PrependBoolSlot(3, True, False)
+        b.PrependBoolSlot(4, True, False)
+        b.PrependBoolSlot(5, True, False)
+        b.PrependBoolSlot(6, True, False)
+        b.PrependBoolSlot(7, True, False)
+        off = b.EndObject()
+        b.Finish(off)
+
+        self.assertBuilderEquals(b, [
+            24, 0, 0, 0,  # root of table: points to vtable offset
+
+            20, 0,  # vtable bytes
+            12, 0,  # size of object
+            11, 0,  # start of value 0
+            10, 0,  # start of value 1
+            9, 0,  # start of value 2
+            8, 0,  # start of value 3
+            7, 0,  # start of value 4
+            6, 0,  # start of value 5
+            5, 0,  # start of value 6
+            4, 0,  # start of value 7
+            20, 0, 0, 0,  # vtable offset
+
+            1,  # value 7
+            1,  # value 6
+            1,  # value 5
+            1,  # value 4
+            1,  # value 3
+            1,  # value 2
+            1,  # value 1
+            1,  # value 0
+        ])
+
+    def test_three_bools(self):
+        b = flatbuffers.Builder(0)
+        b.StartObject(3)
+        b.PrependBoolSlot(0, True, False)
+        b.PrependBoolSlot(1, True, False)
+        b.PrependBoolSlot(2, True, False)
+        off = b.EndObject()
+        b.Finish(off)
+
+        self.assertBuilderEquals(b, [
+            16, 0, 0, 0,  # root of table: points to vtable offset
+
+            0, 0,  # padding
+
+            10, 0,  # vtable bytes
+            8, 0,  # size of object
+            7, 0,  # start of value 0
+            6, 0,  # start of value 1
+            5, 0,  # start of value 2
+            10, 0, 0, 0,  # vtable offset from here
+
+            0,  # padding
+            1,  # value 2
+            1,  # value 1
+            1,  # value 0
+        ])
+
+    def test_some_floats(self):
+        b = flatbuffers.Builder(0)
+        b.StartObject(1)
+        b.PrependFloat32Slot(0, 1.0, 0.0)
+        off = b.EndObject()
+
+        self.assertBuilderEquals(b, [
+            6, 0,  # vtable bytes
+            8, 0,  # size of object
+            4, 0,  # start of value 0
+            6, 0, 0, 0,  # vtable offset
+
+            0, 0, 128, 63,  # value 0
+        ])
+
+
+def make_monster_from_generated_code(sizePrefix = False, file_identifier=None):
+    ''' Use generated code to build the example Monster. '''
+
+    b = flatbuffers.Builder(0)
+    string = b.CreateString("MyMonster")
+    test1 = b.CreateString("test1")
+    test2 = b.CreateString("test2")
+    fred = b.CreateString("Fred")
+
+    MyGame.Example.Monster.MonsterStartInventoryVector(b, 5)
+    b.PrependByte(4)
+    b.PrependByte(3)
+    b.PrependByte(2)
+    b.PrependByte(1)
+    b.PrependByte(0)
+    inv = b.EndVector(5)
+
+    MyGame.Example.Monster.MonsterStart(b)
+    MyGame.Example.Monster.MonsterAddName(b, fred)
+    mon2 = MyGame.Example.Monster.MonsterEnd(b)
+
+    MyGame.Example.Monster.MonsterStartTest4Vector(b, 2)
+    MyGame.Example.Test.CreateTest(b, 10, 20)
+    MyGame.Example.Test.CreateTest(b, 30, 40)
+    test4 = b.EndVector(2)
+
+    MyGame.Example.Monster.MonsterStartTestarrayofstringVector(b, 2)
+    b.PrependUOffsetTRelative(test2)
+    b.PrependUOffsetTRelative(test1)
+    testArrayOfString = b.EndVector(2)
+
+    MyGame.Example.Monster.MonsterStartVectorOfLongsVector(b, 5)
+    b.PrependInt64(100000000)
+    b.PrependInt64(1000000)
+    b.PrependInt64(10000)
+    b.PrependInt64(100)
+    b.PrependInt64(1)
+    VectorOfLongs = b.EndVector(5)
+
+    MyGame.Example.Monster.MonsterStartVectorOfDoublesVector(b, 3)
+    b.PrependFloat64(1.7976931348623157e+308)
+    b.PrependFloat64(0)
+    b.PrependFloat64(-1.7976931348623157e+308)
+    VectorOfDoubles = b.EndVector(3)
+
+    MyGame.Example.Monster.MonsterStart(b)
+
+    pos = MyGame.Example.Vec3.CreateVec3(b, 1.0, 2.0, 3.0, 3.0, 2, 5, 6)
+    MyGame.Example.Monster.MonsterAddPos(b, pos)
+
+    MyGame.Example.Monster.MonsterAddHp(b, 80)
+    MyGame.Example.Monster.MonsterAddName(b, string)
+    MyGame.Example.Monster.MonsterAddInventory(b, inv)
+    MyGame.Example.Monster.MonsterAddTestType(b, 1)
+    MyGame.Example.Monster.MonsterAddTest(b, mon2)
+    MyGame.Example.Monster.MonsterAddTest4(b, test4)
+    MyGame.Example.Monster.MonsterAddTestarrayofstring(b, testArrayOfString)
+    MyGame.Example.Monster.MonsterAddVectorOfLongs(b, VectorOfLongs)
+    MyGame.Example.Monster.MonsterAddVectorOfDoubles(b, VectorOfDoubles)
+    mon = MyGame.Example.Monster.MonsterEnd(b)
+
+    if sizePrefix:
+        b.FinishSizePrefixed(mon, file_identifier)
+    else:
+        b.Finish(mon, file_identifier)
+
+    return b.Bytes, b.Head()
+
+
+class TestAllCodePathsOfExampleSchema(unittest.TestCase):
+    def setUp(self, *args, **kwargs):
+        super(TestAllCodePathsOfExampleSchema, self).setUp(*args, **kwargs)
+
+        b = flatbuffers.Builder(0)
+        MyGame.Example.Monster.MonsterStart(b)
+        gen_mon = MyGame.Example.Monster.MonsterEnd(b)
+        b.Finish(gen_mon)
+
+        self.mon = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+                                                                   b.Head())
+
+    def test_default_monster_pos(self):
+        self.assertTrue(self.mon.Pos() is None)
+
+    def test_nondefault_monster_mana(self):
+        b = flatbuffers.Builder(0)
+        MyGame.Example.Monster.MonsterStart(b)
+        MyGame.Example.Monster.MonsterAddMana(b, 50)
+        mon = MyGame.Example.Monster.MonsterEnd(b)
+        b.Finish(mon)
+
+        got_mon = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+                                                                  b.Head())
+        self.assertEqual(50, got_mon.Mana())
+
+    def test_default_monster_hp(self):
+        self.assertEqual(100, self.mon.Hp())
+
+    def test_default_monster_name(self):
+        self.assertEqual(None, self.mon.Name())
+
+    def test_default_monster_inventory_item(self):
+        self.assertEqual(0, self.mon.Inventory(0))
+
+    def test_default_monster_inventory_length(self):
+        self.assertEqual(0, self.mon.InventoryLength())
+
+    def test_default_monster_color(self):
+        self.assertEqual(MyGame.Example.Color.Color.Blue, self.mon.Color())
+
+    def test_nondefault_monster_color(self):
+        b = flatbuffers.Builder(0)
+        color = MyGame.Example.Color.Color.Red
+        MyGame.Example.Monster.MonsterStart(b)
+        MyGame.Example.Monster.MonsterAddColor(b, color)
+        mon = MyGame.Example.Monster.MonsterEnd(b)
+        b.Finish(mon)
+
+        mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+                                                               b.Head())
+        self.assertEqual(MyGame.Example.Color.Color.Red, mon2.Color())
+
+    def test_default_monster_testtype(self):
+        self.assertEqual(0, self.mon.TestType())
+
+    def test_default_monster_test_field(self):
+        self.assertEqual(None, self.mon.Test())
+
+    def test_default_monster_test4_item(self):
+        self.assertEqual(None, self.mon.Test4(0))
+
+    def test_default_monster_test4_length(self):
+        self.assertEqual(0, self.mon.Test4Length())
+
+    def test_default_monster_testarrayofstring(self):
+        self.assertEqual("", self.mon.Testarrayofstring(0))
+
+    def test_default_monster_testarrayofstring_length(self):
+        self.assertEqual(0, self.mon.TestarrayofstringLength())
+
+    def test_default_monster_testarrayoftables(self):
+        self.assertEqual(None, self.mon.Testarrayoftables(0))
+
+    def test_nondefault_monster_testarrayoftables(self):
+        b = flatbuffers.Builder(0)
+
+        # make a child Monster within a vector of Monsters:
+        MyGame.Example.Monster.MonsterStart(b)
+        MyGame.Example.Monster.MonsterAddHp(b, 99)
+        sub_monster = MyGame.Example.Monster.MonsterEnd(b)
+
+        # build the vector:
+        MyGame.Example.Monster.MonsterStartTestarrayoftablesVector(b, 1)
+        b.PrependUOffsetTRelative(sub_monster)
+        vec = b.EndVector(1)
+
+        # make the parent monster and include the vector of Monster:
+        MyGame.Example.Monster.MonsterStart(b)
+        MyGame.Example.Monster.MonsterAddTestarrayoftables(b, vec)
+        mon = MyGame.Example.Monster.MonsterEnd(b)
+        b.Finish(mon)
+
+        # inspect the resulting data:
+        mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Output(), 0)
+        self.assertEqual(99, mon2.Testarrayoftables(0).Hp())
+        self.assertEqual(1, mon2.TestarrayoftablesLength())
+
+    def test_default_monster_testarrayoftables_length(self):
+        self.assertEqual(0, self.mon.TestarrayoftablesLength())
+
+    def test_nondefault_monster_enemy(self):
+        b = flatbuffers.Builder(0)
+
+        # make an Enemy object:
+        MyGame.Example.Monster.MonsterStart(b)
+        MyGame.Example.Monster.MonsterAddHp(b, 88)
+        enemy = MyGame.Example.Monster.MonsterEnd(b)
+        b.Finish(enemy)
+
+        # make the parent monster and include the vector of Monster:
+        MyGame.Example.Monster.MonsterStart(b)
+        MyGame.Example.Monster.MonsterAddEnemy(b, enemy)
+        mon = MyGame.Example.Monster.MonsterEnd(b)
+        b.Finish(mon)
+
+        # inspect the resulting data:
+        mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+                                                               b.Head())
+        self.assertEqual(88, mon2.Enemy().Hp())
+
+    def test_default_monster_testnestedflatbuffer(self):
+        self.assertEqual(0, self.mon.Testnestedflatbuffer(0))
+
+    def test_default_monster_testnestedflatbuffer_length(self):
+        self.assertEqual(0, self.mon.TestnestedflatbufferLength())
+
+    def test_nondefault_monster_testnestedflatbuffer(self):
+        b = flatbuffers.Builder(0)
+
+        MyGame.Example.Monster.MonsterStartTestnestedflatbufferVector(b, 3)
+        b.PrependByte(4)
+        b.PrependByte(2)
+        b.PrependByte(0)
+        sub_buf = b.EndVector(3)
+
+        # make the parent monster and include the vector of Monster:
+        MyGame.Example.Monster.MonsterStart(b)
+        MyGame.Example.Monster.MonsterAddTestnestedflatbuffer(b, sub_buf)
+        mon = MyGame.Example.Monster.MonsterEnd(b)
+        b.Finish(mon)
+
+        # inspect the resulting data:
+        mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+                                                               b.Head())
+        self.assertEqual(3, mon2.TestnestedflatbufferLength())
+        self.assertEqual(0, mon2.Testnestedflatbuffer(0))
+        self.assertEqual(2, mon2.Testnestedflatbuffer(1))
+        self.assertEqual(4, mon2.Testnestedflatbuffer(2))
+        try:
+            imp.find_module('numpy')
+            # if numpy exists, then we should be able to get the
+            # vector as a numpy array
+            self.assertEqual([0, 2, 4], mon2.TestnestedflatbufferAsNumpy().tolist())
+        except ImportError:
+            assertRaises(self,
+                         lambda: mon2.TestnestedflatbufferAsNumpy(),
+                         NumpyRequiredForThisFeature)
+
+    def test_nondefault_monster_testempty(self):
+        b = flatbuffers.Builder(0)
+
+        # make a Stat object:
+        MyGame.Example.Stat.StatStart(b)
+        MyGame.Example.Stat.StatAddVal(b, 123)
+        my_stat = MyGame.Example.Stat.StatEnd(b)
+        b.Finish(my_stat)
+
+        # include the stat object in a monster:
+        MyGame.Example.Monster.MonsterStart(b)
+        MyGame.Example.Monster.MonsterAddTestempty(b, my_stat)
+        mon = MyGame.Example.Monster.MonsterEnd(b)
+        b.Finish(mon)
+
+        # inspect the resulting data:
+        mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+                                                               b.Head())
+        self.assertEqual(123, mon2.Testempty().Val())
+
+    def test_default_monster_testbool(self):
+        self.assertFalse(self.mon.Testbool())
+
+    def test_nondefault_monster_testbool(self):
+        b = flatbuffers.Builder(0)
+        MyGame.Example.Monster.MonsterStart(b)
+        MyGame.Example.Monster.MonsterAddTestbool(b, True)
+        mon = MyGame.Example.Monster.MonsterEnd(b)
+        b.Finish(mon)
+
+        # inspect the resulting data:
+        mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+                                                               b.Head())
+        self.assertTrue(mon2.Testbool())
+
+    def test_default_monster_testhashes(self):
+        self.assertEqual(0, self.mon.Testhashs32Fnv1())
+        self.assertEqual(0, self.mon.Testhashu32Fnv1())
+        self.assertEqual(0, self.mon.Testhashs64Fnv1())
+        self.assertEqual(0, self.mon.Testhashu64Fnv1())
+        self.assertEqual(0, self.mon.Testhashs32Fnv1a())
+        self.assertEqual(0, self.mon.Testhashu32Fnv1a())
+        self.assertEqual(0, self.mon.Testhashs64Fnv1a())
+        self.assertEqual(0, self.mon.Testhashu64Fnv1a())
+
+    def test_nondefault_monster_testhashes(self):
+        b = flatbuffers.Builder(0)
+        MyGame.Example.Monster.MonsterStart(b)
+        MyGame.Example.Monster.MonsterAddTesthashs32Fnv1(b, 1)
+        MyGame.Example.Monster.MonsterAddTesthashu32Fnv1(b, 2)
+        MyGame.Example.Monster.MonsterAddTesthashs64Fnv1(b, 3)
+        MyGame.Example.Monster.MonsterAddTesthashu64Fnv1(b, 4)
+        MyGame.Example.Monster.MonsterAddTesthashs32Fnv1a(b, 5)
+        MyGame.Example.Monster.MonsterAddTesthashu32Fnv1a(b, 6)
+        MyGame.Example.Monster.MonsterAddTesthashs64Fnv1a(b, 7)
+        MyGame.Example.Monster.MonsterAddTesthashu64Fnv1a(b, 8)
+        mon = MyGame.Example.Monster.MonsterEnd(b)
+        b.Finish(mon)
+
+        # inspect the resulting data:
+        mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+                                                               b.Head())
+        self.assertEqual(1, mon2.Testhashs32Fnv1())
+        self.assertEqual(2, mon2.Testhashu32Fnv1())
+        self.assertEqual(3, mon2.Testhashs64Fnv1())
+        self.assertEqual(4, mon2.Testhashu64Fnv1())
+        self.assertEqual(5, mon2.Testhashs32Fnv1a())
+        self.assertEqual(6, mon2.Testhashu32Fnv1a())
+        self.assertEqual(7, mon2.Testhashs64Fnv1a())
+        self.assertEqual(8, mon2.Testhashu64Fnv1a())
+
+    def test_getrootas_for_nonroot_table(self):
+        b = flatbuffers.Builder(0)
+        string = b.CreateString("MyStat")
+
+        MyGame.Example.Stat.StatStart(b)
+        MyGame.Example.Stat.StatAddId(b, string)
+        MyGame.Example.Stat.StatAddVal(b, 12345678)
+        MyGame.Example.Stat.StatAddCount(b, 12345)
+        stat = MyGame.Example.Stat.StatEnd(b)
+        b.Finish(stat)
+
+        stat2 = MyGame.Example.Stat.Stat.GetRootAsStat(b.Bytes, b.Head())
+
+        self.assertEqual(b"MyStat", stat2.Id())
+        self.assertEqual(12345678, stat2.Val())
+        self.assertEqual(12345, stat2.Count())
+
+
+class TestAllCodePathsOfMonsterExtraSchema(unittest.TestCase):
+    def setUp(self, *args, **kwargs):
+        super(TestAllCodePathsOfMonsterExtraSchema, self).setUp(*args, **kwargs)
+
+        b = flatbuffers.Builder(0)
+        MyGame.MonsterExtra.MonsterExtraStart(b)
+        gen_mon = MyGame.MonsterExtra.MonsterExtraEnd(b)
+        b.Finish(gen_mon)
+
+        self.mon = MyGame.MonsterExtra.MonsterExtra.GetRootAsMonsterExtra(b.Bytes, b.Head())
+
+    def test_default_nan_inf(self):
+        self.assertTrue(math.isnan(self.mon.F1()))
+        self.assertEqual(self.mon.F2(), float("inf"))
+        self.assertEqual(self.mon.F3(), float("-inf"))
+
+        self.assertTrue(math.isnan(self.mon.D1()))
+        self.assertEqual(self.mon.D2(), float("inf"))
+        self.assertEqual(self.mon.D3(), float("-inf"))
+
+
+class TestVtableDeduplication(unittest.TestCase):
+    ''' TestVtableDeduplication verifies that vtables are deduplicated. '''
+
+    def test_vtable_deduplication(self):
+        b = flatbuffers.Builder(0)
+
+        b.StartObject(4)
+        b.PrependByteSlot(0, 0, 0)
+        b.PrependByteSlot(1, 11, 0)
+        b.PrependByteSlot(2, 22, 0)
+        b.PrependInt16Slot(3, 33, 0)
+        obj0 = b.EndObject()
+
+        b.StartObject(4)
+        b.PrependByteSlot(0, 0, 0)
+        b.PrependByteSlot(1, 44, 0)
+        b.PrependByteSlot(2, 55, 0)
+        b.PrependInt16Slot(3, 66, 0)
+        obj1 = b.EndObject()
+
+        b.StartObject(4)
+        b.PrependByteSlot(0, 0, 0)
+        b.PrependByteSlot(1, 77, 0)
+        b.PrependByteSlot(2, 88, 0)
+        b.PrependInt16Slot(3, 99, 0)
+        obj2 = b.EndObject()
+
+        got = b.Bytes[b.Head():]
+
+        want = bytearray([
+            240, 255, 255, 255,  # == -12. offset to dedupped vtable.
+            99, 0,
+            88,
+            77,
+            248, 255, 255, 255,  # == -8. offset to dedupped vtable.
+            66, 0,
+            55,
+            44,
+            12, 0,
+            8, 0,
+            0, 0,
+            7, 0,
+            6, 0,
+            4, 0,
+            12, 0, 0, 0,
+            33, 0,
+            22,
+            11,
+        ])
+
+        self.assertEqual((len(want), want), (len(got), got))
+
+        table0 = flatbuffers.table.Table(b.Bytes, len(b.Bytes) - obj0)
+        table1 = flatbuffers.table.Table(b.Bytes, len(b.Bytes) - obj1)
+        table2 = flatbuffers.table.Table(b.Bytes, len(b.Bytes) - obj2)
+
+        def _checkTable(tab, voffsett_value, b, c, d):
+            # vtable size
+            got = tab.GetVOffsetTSlot(0, 0)
+            self.assertEqual(12, got, 'case 0, 0')
+
+            # object size
+            got = tab.GetVOffsetTSlot(2, 0)
+            self.assertEqual(8, got, 'case 2, 0')
+
+            # default value
+            got = tab.GetVOffsetTSlot(4, 0)
+            self.assertEqual(voffsett_value, got, 'case 4, 0')
+
+            got = tab.GetSlot(6, 0, N.Uint8Flags)
+            self.assertEqual(b, got, 'case 6, 0')
+
+            val = tab.GetSlot(8, 0, N.Uint8Flags)
+            self.assertEqual(c, val, 'failed 8, 0')
+
+            got = tab.GetSlot(10, 0, N.Uint8Flags)
+            self.assertEqual(d, got, 'failed 10, 0')
+
+        _checkTable(table0, 0, 11, 22, 33)
+        _checkTable(table1, 0, 44, 55, 66)
+        _checkTable(table2, 0, 77, 88, 99)
+
+
+class TestExceptions(unittest.TestCase):
+    def test_object_is_nested_error(self):
+        b = flatbuffers.Builder(0)
+        b.StartObject(0)
+        assertRaises(self, lambda: b.StartObject(0),
+                     flatbuffers.builder.IsNestedError)
+
+    def test_object_is_not_nested_error(self):
+        b = flatbuffers.Builder(0)
+        assertRaises(self, lambda: b.EndObject(),
+                     flatbuffers.builder.IsNotNestedError)
+
+    def test_struct_is_not_inline_error(self):
+        b = flatbuffers.Builder(0)
+        b.StartObject(0)
+        assertRaises(self, lambda: b.PrependStructSlot(0, 1, 0),
+                     flatbuffers.builder.StructIsNotInlineError)
+
+    def test_unreachable_error(self):
+        b = flatbuffers.Builder(0)
+        assertRaises(self, lambda: b.PrependUOffsetTRelative(1),
+                     flatbuffers.builder.OffsetArithmeticError)
+
+    def test_create_string_is_nested_error(self):
+        b = flatbuffers.Builder(0)
+        b.StartObject(0)
+        s = 'test1'
+        assertRaises(self, lambda: b.CreateString(s),
+                     flatbuffers.builder.IsNestedError)
+
+    def test_create_byte_vector_is_nested_error(self):
+        b = flatbuffers.Builder(0)
+        b.StartObject(0)
+        s = b'test1'
+        assertRaises(self, lambda: b.CreateByteVector(s),
+                     flatbuffers.builder.IsNestedError)
+
+    def test_finished_bytes_error(self):
+        b = flatbuffers.Builder(0)
+        assertRaises(self, lambda: b.Output(),
+                     flatbuffers.builder.BuilderNotFinishedError)
+
+
+class TestFixedLengthArrays(unittest.TestCase):
+    def test_fixed_length_array(self):
+        builder = flatbuffers.Builder(0)
+
+        a = 0.5
+        b = range(0, 15)
+        c = 1
+        d_a = [[1, 2], [3, 4]]
+        d_b = [MyGame.Example.TestEnum.TestEnum.B, \
+                MyGame.Example.TestEnum.TestEnum.C]
+        d_c = [[MyGame.Example.TestEnum.TestEnum.A, \
+                MyGame.Example.TestEnum.TestEnum.B], \
+                [MyGame.Example.TestEnum.TestEnum.C, \
+                 MyGame.Example.TestEnum.TestEnum.B]]
+
+        arrayOffset = MyGame.Example.ArrayStruct.CreateArrayStruct(builder, \
+            a, b, c, d_a, d_b, d_c)
+
+        # Create a table with the ArrayStruct.
+        MyGame.Example.ArrayTable.ArrayTableStart(builder)
+        MyGame.Example.ArrayTable.ArrayTableAddA(builder, arrayOffset)
+        tableOffset = MyGame.Example.ArrayTable.ArrayTableEnd(builder)
+
+        builder.Finish(tableOffset)
+
+        buf = builder.Output()
+
+        table = MyGame.Example.ArrayTable.ArrayTable.GetRootAsArrayTable(buf, 0)
+
+        # Verify structure.
+        nested = MyGame.Example.NestedStruct.NestedStruct()
+        self.assertEqual(table.A().A(), 0.5)
+        self.assertEqual(table.A().B(), \
+            [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
+        self.assertEqual(table.A().C(), 1)
+        self.assertEqual(table.A().D(nested, 0).A(), [1, 2])
+        self.assertEqual(table.A().D(nested, 1).A(), [3, 4])
+        self.assertEqual(table.A().D(nested, 0).B(), \
+            MyGame.Example.TestEnum.TestEnum.B)
+        self.assertEqual(table.A().D(nested, 1).B(), \
+            MyGame.Example.TestEnum.TestEnum.C)
+        self.assertEqual(table.A().D(nested, 0).C(), \
+            [MyGame.Example.TestEnum.TestEnum.A, \
+             MyGame.Example.TestEnum.TestEnum.B])
+        self.assertEqual(table.A().D(nested, 1).C(), \
+            [MyGame.Example.TestEnum.TestEnum.C, \
+             MyGame.Example.TestEnum.TestEnum.B])
+
+
+def CheckAgainstGoldDataGo():
+    try:
+        gen_buf, gen_off = make_monster_from_generated_code()
+        fn = 'monsterdata_go_wire.mon'
+        if not os.path.exists(fn):
+            print('Go-generated data does not exist, failed.')
+            return False
+
+        # would like to use a context manager here, but it's less
+        # backwards-compatible:
+        f = open(fn, 'rb')
+        go_wire_data = f.read()
+        f.close()
+
+        CheckReadBuffer(bytearray(go_wire_data), 0)
+        if not bytearray(gen_buf[gen_off:]) == bytearray(go_wire_data):
+            raise AssertionError('CheckAgainstGoldDataGo failed')
+    except:
+        print('Failed to test against Go-generated test data.')
+        return False
+
+    print('Can read Go-generated test data, and Python generates bytewise identical data.')
+    return True
+
+
+def CheckAgainstGoldDataJava():
+    try:
+        gen_buf, gen_off = make_monster_from_generated_code()
+        fn = 'monsterdata_java_wire.mon'
+        if not os.path.exists(fn):
+            print('Java-generated data does not exist, failed.')
+            return False
+        f = open(fn, 'rb')
+        java_wire_data = f.read()
+        f.close()
+
+        CheckReadBuffer(bytearray(java_wire_data), 0)
+    except:
+        print('Failed to read Java-generated test data.')
+        return False
+
+    print('Can read Java-generated test data.')
+    return True
+
+
+class LCG(object):
+    ''' Include simple random number generator to ensure results will be the
+        same cross platform.
+        http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator '''
+
+    __slots__ = ['n']
+
+    InitialLCGSeed = 48271
+
+    def __init__(self):
+        self.n = self.InitialLCGSeed
+
+    def Reset(self):
+        self.n = self.InitialLCGSeed
+
+    def Next(self):
+        self.n = ((self.n * 279470273) % 4294967291) & 0xFFFFFFFF
+        return self.n
+
+
+def BenchmarkVtableDeduplication(count):
+    '''
+    BenchmarkVtableDeduplication measures the speed of vtable deduplication
+    by creating `prePop` vtables, then populating `count` objects with a
+    different single vtable.
+
+    When count is large (as in long benchmarks), memory usage may be high.
+    '''
+
+    for prePop in (1, 10, 100, 1000):
+        builder = flatbuffers.Builder(0)
+        n = 1 + int(math.log(prePop, 1.5))
+
+        # generate some layouts:
+        layouts = set()
+        r = list(compat_range(n))
+        while len(layouts) < prePop:
+            layouts.add(tuple(sorted(random.sample(r, int(max(1, n / 2))))))
+
+        layouts = list(layouts)
+
+        # pre-populate vtables:
+        for layout in layouts:
+            builder.StartObject(n)
+            for j in layout:
+                builder.PrependInt16Slot(j, j, 0)
+            builder.EndObject()
+
+        # benchmark deduplication of a new vtable:
+        def f():
+            layout = random.choice(layouts)
+            builder.StartObject(n)
+            for j in layout:
+                builder.PrependInt16Slot(j, j, 0)
+            builder.EndObject()
+
+        duration = timeit.timeit(stmt=f, number=count)
+        rate = float(count) / duration
+        print(('vtable deduplication rate (n=%d, vtables=%d): %.2f sec' % (
+            prePop,
+            len(builder.vtables),
+            rate))
+        )
+
+
+def BenchmarkCheckReadBuffer(count, buf, off):
+    '''
+    BenchmarkCheckReadBuffer measures the speed of flatbuffer reading
+    by re-using the CheckReadBuffer function with the gold data.
+    '''
+
+    def f():
+        CheckReadBuffer(buf, off)
+
+    duration = timeit.timeit(stmt=f, number=count)
+    rate = float(count) / duration
+    data = float(len(buf) * count) / float(1024 * 1024)
+    data_rate = data / float(duration)
+
+    print(('traversed %d %d-byte flatbuffers in %.2fsec: %.2f/sec, %.2fMB/sec')
+          % (count, len(buf), duration, rate, data_rate))
+
+
+def BenchmarkMakeMonsterFromGeneratedCode(count, length):
+    '''
+    BenchmarkMakeMonsterFromGeneratedCode measures the speed of flatbuffer
+    creation by re-using the make_monster_from_generated_code function for
+    generating gold data examples.
+    '''
+
+    duration = timeit.timeit(stmt=make_monster_from_generated_code,
+                             number=count)
+    rate = float(count) / duration
+    data = float(length * count) / float(1024 * 1024)
+    data_rate = data / float(duration)
+
+    print(('built %d %d-byte flatbuffers in %.2fsec: %.2f/sec, %.2fMB/sec' % \
+           (count, length, duration, rate, data_rate)))
+
+
+def backward_compatible_run_tests(**kwargs):
+    if PY_VERSION < (2, 6):
+        sys.stderr.write("Python version less than 2.6 are not supported")
+        sys.stderr.flush()
+        return False
+
+    # python2.6 has a reduced-functionality unittest.main function:
+    if PY_VERSION == (2, 6):
+        try:
+            unittest.main(**kwargs)
+        except SystemExit as e:
+            if not e.code == 0:
+                return False
+        return True
+
+    # python2.7 and above let us not exit once unittest.main is run:
+    kwargs['exit'] = False
+    kwargs['verbosity'] = 0
+    ret = unittest.main(**kwargs)
+    if ret.result.errors or ret.result.failures:
+        return False
+
+    return True
+
+def main():
+    import os
+    import sys
+    if not len(sys.argv) == 4:
+       sys.stderr.write('Usage: %s <benchmark vtable count>'
+                        '<benchmark read count> <benchmark build count>\n'
+                        % sys.argv[0])
+       sys.stderr.write('       Provide COMPARE_GENERATED_TO_GO=1   to check'
+                        'for bytewise comparison to Go data.\n')
+       sys.stderr.write('       Provide COMPARE_GENERATED_TO_JAVA=1 to check'
+                        'for bytewise comparison to Java data.\n')
+       sys.stderr.flush()
+       sys.exit(1)
+
+    kwargs = dict(argv=sys.argv[:-3])
+
+    # run tests, and run some language comparison checks if needed:
+    success = backward_compatible_run_tests(**kwargs)
+    if success and os.environ.get('COMPARE_GENERATED_TO_GO', 0) == "1":
+        success = success and CheckAgainstGoldDataGo()
+    if success and os.environ.get('COMPARE_GENERATED_TO_JAVA', 0) == "1":
+        success = success and CheckAgainstGoldDataJava()
+
+    if not success:
+        sys.stderr.write('Tests failed, skipping benchmarks.\n')
+        sys.stderr.flush()
+        sys.exit(1)
+
+    # run benchmarks (if 0, they will be a noop):
+    bench_vtable = int(sys.argv[1])
+    bench_traverse = int(sys.argv[2])
+    bench_build = int(sys.argv[3])
+    if bench_vtable:
+        BenchmarkVtableDeduplication(bench_vtable)
+    if bench_traverse:
+        buf, off = make_monster_from_generated_code()
+        BenchmarkCheckReadBuffer(bench_traverse, buf, off)
+    if bench_build:
+        buf, off = make_monster_from_generated_code()
+        BenchmarkMakeMonsterFromGeneratedCode(bench_build, len(buf))
+
+if __name__ == '__main__':
+    main()
diff --git a/tests/rust_usage_test/Cargo.toml b/tests/rust_usage_test/Cargo.toml
new file mode 100644
index 0000000..490d6d2
--- /dev/null
+++ b/tests/rust_usage_test/Cargo.toml
@@ -0,0 +1,26 @@
+[package]
+name = "rust_usage_test"
+version = "0.1.0"
+authors = ["Robert Winslow <hello@rwinslow.com>", "FlatBuffers Maintainers"]
+
+[dependencies]
+flatbuffers = { path = "../../rust/flatbuffers" }
+
+[[bin]]
+name = "monster_example"
+path = "bin/monster_example.rs"
+
+[[bin]]
+name = "alloc_check"
+path = "bin/alloc_check.rs"
+
+
+[dev-dependencies]
+quickcheck = "0.6"
+# TODO(rw): look into moving to criterion.rs
+bencher = "0.1.5"
+
+[[bench]]
+# setup for bencher
+name = "flatbuffers_benchmarks"
+harness = false
diff --git a/tests/rust_usage_test/benches/flatbuffers_benchmarks.rs b/tests/rust_usage_test/benches/flatbuffers_benchmarks.rs
new file mode 100644
index 0000000..2c6be1f
--- /dev/null
+++ b/tests/rust_usage_test/benches/flatbuffers_benchmarks.rs
@@ -0,0 +1,219 @@
+/*
+ * Copyright 2018 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.
+ */
+
+#[macro_use]
+extern crate bencher;
+use bencher::Bencher;
+
+extern crate flatbuffers;
+
+#[allow(dead_code, unused_imports)]
+#[path = "../../monster_test_generated.rs"]
+mod monster_test_generated;
+pub use monster_test_generated::my_game;
+
+fn traverse_canonical_buffer(bench: &mut Bencher) {
+    let owned_data = {
+        let mut builder = &mut flatbuffers::FlatBufferBuilder::new();
+        create_serialized_example_with_generated_code(&mut builder, true);
+        builder.finished_data().to_vec()
+    };
+    let data = &owned_data[..];
+    let n = data.len() as u64;
+    bench.iter(|| {
+        traverse_serialized_example_with_generated_code(data);
+    });
+    bench.bytes = n;
+}
+
+fn create_canonical_buffer_then_reset(bench: &mut Bencher) {
+    let mut builder = &mut flatbuffers::FlatBufferBuilder::new();
+    // warmup
+    create_serialized_example_with_generated_code(&mut builder, true);
+    let n = builder.finished_data().len() as u64;
+    builder.reset();
+
+    bench.iter(|| {
+        let _ = create_serialized_example_with_generated_code(&mut builder, true);
+        builder.reset();
+    });
+
+    bench.bytes = n;
+}
+
+#[inline(always)]
+fn create_serialized_example_with_generated_code(builder: &mut flatbuffers::FlatBufferBuilder, finish: bool) -> usize{
+    let s0 = builder.create_string("test1");
+    let s1 = builder.create_string("test2");
+    let t0_name = builder.create_string("Barney");
+    let t1_name = builder.create_string("Fred");
+    let t2_name = builder.create_string("Wilma");
+    let t0 = my_game::example::Monster::create(builder, &my_game::example::MonsterArgs{
+        hp: 1000,
+        name: Some(t0_name),
+        ..Default::default()
+    });
+    let t1 = my_game::example::Monster::create(builder, &my_game::example::MonsterArgs{
+        name: Some(t1_name),
+        ..Default::default()
+    });
+    let t2 = my_game::example::Monster::create(builder, &my_game::example::MonsterArgs{
+        name: Some(t2_name),
+        ..Default::default()
+    });
+    let mon = {
+        let name = builder.create_string("MyMonster");
+        let fred_name = builder.create_string("Fred");
+        let inventory = builder.create_vector_direct(&[0u8, 1, 2, 3, 4]);
+        let test4 = builder.create_vector_direct(&[my_game::example::Test::new(10, 20),
+                                                   my_game::example::Test::new(30, 40)]);
+        let pos = my_game::example::Vec3::new(1.0, 2.0, 3.0, 3.0, my_game::example::Color::Green, &my_game::example::Test::new(5i16, 6i8));
+        let args = my_game::example::MonsterArgs{
+            hp: 80,
+            mana: 150,
+            name: Some(name),
+            pos: Some(&pos),
+            test_type: my_game::example::Any::Monster,
+            test: Some(my_game::example::Monster::create(builder, &my_game::example::MonsterArgs{
+                name: Some(fred_name),
+                ..Default::default()
+            }).as_union_value()),
+            inventory: Some(inventory),
+            test4: Some(test4),
+            testarrayofstring: Some(builder.create_vector(&[s0, s1])),
+            testarrayoftables: Some(builder.create_vector(&[t0, t1, t2])),
+            ..Default::default()
+        };
+        my_game::example::Monster::create(builder, &args)
+    };
+    if finish {
+        my_game::example::finish_monster_buffer(builder, mon);
+    }
+
+    builder.finished_data().len()
+
+    // make it do some work
+    // if builder.finished_data().len() == 0 { panic!("bad benchmark"); }
+}
+
+#[inline(always)]
+fn blackbox<T>(t: T) -> T {
+    // encapsulate this in case we need to turn it into a noop
+    bencher::black_box(t)
+}
+
+#[inline(always)]
+fn traverse_serialized_example_with_generated_code(bytes: &[u8]) {
+    let m = my_game::example::get_root_as_monster(bytes);
+    blackbox(m.hp());
+    blackbox(m.mana());
+    blackbox(m.name());
+    let pos = m.pos().unwrap();
+    blackbox(pos.x());
+    blackbox(pos.y());
+    blackbox(pos.z());
+    blackbox(pos.test1());
+    blackbox(pos.test2());
+    let pos_test3 = pos.test3();
+    blackbox(pos_test3.a());
+    blackbox(pos_test3.b());
+    blackbox(m.test_type());
+    let table2 = m.test().unwrap();
+    let monster2 = my_game::example::Monster::init_from_table(table2);
+    blackbox(monster2.name());
+    blackbox(m.inventory());
+    blackbox(m.test4());
+    let testarrayoftables = m.testarrayoftables().unwrap();
+    blackbox(testarrayoftables.get(0).hp());
+    blackbox(testarrayoftables.get(0).name());
+    blackbox(testarrayoftables.get(1).name());
+    blackbox(testarrayoftables.get(2).name());
+    let testarrayofstring = m.testarrayofstring().unwrap();
+    blackbox(testarrayofstring.get(0));
+    blackbox(testarrayofstring.get(1));
+}
+
+fn create_string_10(bench: &mut Bencher) {
+    let builder = &mut flatbuffers::FlatBufferBuilder::new_with_capacity(1<<20);
+    let mut i = 0;
+    bench.iter(|| {
+        builder.create_string("foobarbaz"); // zero-terminated -> 10 bytes
+        i += 1;
+        if i == 10000 {
+            builder.reset();
+            i = 0;
+        }
+    });
+
+    bench.bytes = 10;
+}
+
+fn create_string_100(bench: &mut Bencher) {
+    let builder = &mut flatbuffers::FlatBufferBuilder::new_with_capacity(1<<20);
+    let s_owned = (0..99).map(|_| "x").collect::<String>();
+    let s: &str = &s_owned;
+
+    let mut i = 0;
+    bench.iter(|| {
+        builder.create_string(s); // zero-terminated -> 100 bytes
+        i += 1;
+        if i == 1000 {
+            builder.reset();
+            i = 0;
+        }
+    });
+
+    bench.bytes = s.len() as u64;
+}
+
+fn create_byte_vector_100_naive(bench: &mut Bencher) {
+    let builder = &mut flatbuffers::FlatBufferBuilder::new_with_capacity(1<<20);
+    let v_owned = (0u8..100).map(|i| i).collect::<Vec<u8>>();
+    let v: &[u8] = &v_owned;
+
+    let mut i = 0;
+    bench.iter(|| {
+        builder.create_vector(v); // zero-terminated -> 100 bytes
+        i += 1;
+        if i == 10000 {
+            builder.reset();
+            i = 0;
+        }
+    });
+
+    bench.bytes = v.len() as u64;
+}
+
+fn create_byte_vector_100_optimal(bench: &mut Bencher) {
+    let builder = &mut flatbuffers::FlatBufferBuilder::new_with_capacity(1<<20);
+    let v_owned = (0u8..100).map(|i| i).collect::<Vec<u8>>();
+    let v: &[u8] = &v_owned;
+
+    let mut i = 0;
+    bench.iter(|| {
+        builder.create_vector_direct(v);
+        i += 1;
+        if i == 10000 {
+            builder.reset();
+            i = 0;
+        }
+    });
+
+    bench.bytes = v.len() as u64;
+}
+
+benchmark_group!(benches, create_byte_vector_100_naive, create_byte_vector_100_optimal, traverse_canonical_buffer, create_canonical_buffer_then_reset, create_string_10, create_string_100);
+benchmark_main!(benches);
diff --git a/tests/rust_usage_test/bin/alloc_check.rs b/tests/rust_usage_test/bin/alloc_check.rs
new file mode 100644
index 0000000..ae1039c
--- /dev/null
+++ b/tests/rust_usage_test/bin/alloc_check.rs
@@ -0,0 +1,143 @@
+// define a passthrough allocator that tracks alloc calls.
+// (note that we can't drop this in to the usual test suite, because it's a big
+// global variable).
+use std::alloc::{GlobalAlloc, Layout, System};
+
+static mut N_ALLOCS: usize = 0;
+
+struct TrackingAllocator;
+
+impl TrackingAllocator {
+    fn n_allocs(&self) -> usize {
+        unsafe { N_ALLOCS }
+    }
+}
+unsafe impl GlobalAlloc for TrackingAllocator {
+    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
+        N_ALLOCS += 1;
+        System.alloc(layout)
+    }
+    unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
+        System.dealloc(ptr, layout)
+    }
+}
+
+// use the tracking allocator:
+#[global_allocator]
+static A: TrackingAllocator = TrackingAllocator;
+
+// import the flatbuffers generated code:
+extern crate flatbuffers;
+#[allow(dead_code, unused_imports)]
+#[path = "../../monster_test_generated.rs"]
+mod monster_test_generated;
+pub use monster_test_generated::my_game;
+
+// verbatim from the test suite:
+fn create_serialized_example_with_generated_code(builder: &mut flatbuffers::FlatBufferBuilder) {
+    let mon = {
+        let _ = builder.create_vector_of_strings(&["these", "unused", "strings", "check", "the", "create_vector_of_strings", "function"]);
+
+        let s0 = builder.create_string("test1");
+        let s1 = builder.create_string("test2");
+        let fred_name = builder.create_string("Fred");
+
+        // can't inline creation of this Vec3 because we refer to it by reference, so it must live
+        // long enough to be used by MonsterArgs.
+        let pos = my_game::example::Vec3::new(1.0, 2.0, 3.0, 3.0, my_game::example::Color::Green, &my_game::example::Test::new(5i16, 6i8));
+
+        let args = my_game::example::MonsterArgs{
+            hp: 80,
+            mana: 150,
+            name: Some(builder.create_string("MyMonster")),
+            pos: Some(&pos),
+            test_type: my_game::example::Any::Monster,
+            test: Some(my_game::example::Monster::create(builder, &my_game::example::MonsterArgs{
+                name: Some(fred_name),
+                ..Default::default()
+            }).as_union_value()),
+            inventory: Some(builder.create_vector_direct(&[0u8, 1, 2, 3, 4][..])),
+            test4: Some(builder.create_vector_direct(&[my_game::example::Test::new(10, 20),
+            my_game::example::Test::new(30, 40)])),
+            testarrayofstring: Some(builder.create_vector(&[s0, s1])),
+            ..Default::default()
+        };
+        my_game::example::Monster::create(builder, &args)
+    };
+    my_game::example::finish_monster_buffer(builder, mon);
+}
+
+fn main() {
+    // test the allocation tracking:
+    {
+        let before = A.n_allocs();
+        let _x: Vec<u8> = vec![0u8; 1];
+        let after = A.n_allocs();
+        assert_eq!(before + 1, after);
+    }
+
+    let builder = &mut flatbuffers::FlatBufferBuilder::new();
+    {
+        // warm up the builder (it can make small allocs internally, such as for storing vtables):
+        create_serialized_example_with_generated_code(builder);
+    }
+
+    // reset the builder, clearing its heap-allocated memory:
+    builder.reset();
+
+    {
+        let before = A.n_allocs();
+        create_serialized_example_with_generated_code(builder);
+        let after = A.n_allocs();
+        assert_eq!(before, after, "KO: Heap allocs occurred in Rust write path");
+    }
+
+    let buf = builder.finished_data();
+
+    // use the allocation tracking on the read path:
+    {
+        let before = A.n_allocs();
+
+        // do many reads, forcing them to execute by using assert_eq:
+        {
+            let m = my_game::example::get_root_as_monster(buf);
+            assert_eq!(80, m.hp());
+            assert_eq!(150, m.mana());
+            assert_eq!("MyMonster", m.name());
+
+            let pos = m.pos().unwrap();
+            assert_eq!(pos.x(), 1.0f32);
+            assert_eq!(pos.y(), 2.0f32);
+            assert_eq!(pos.z(), 3.0f32);
+            assert_eq!(pos.test1(), 3.0f64);
+            assert_eq!(pos.test2(), my_game::example::Color::Green);
+            let pos_test3 = pos.test3();
+            assert_eq!(pos_test3.a(), 5i16);
+            assert_eq!(pos_test3.b(), 6i8);
+            assert_eq!(m.test_type(), my_game::example::Any::Monster);
+            let table2 = m.test().unwrap();
+            let m2 = my_game::example::Monster::init_from_table(table2);
+
+            assert_eq!(m2.name(), "Fred");
+
+            let inv = m.inventory().unwrap();
+            assert_eq!(inv.len(), 5);
+            assert_eq!(inv.iter().sum::<u8>(), 10u8);
+
+            let test4 = m.test4().unwrap();
+            assert_eq!(test4.len(), 2);
+            assert_eq!(test4[0].a() as i32 + test4[0].b() as i32 +
+                       test4[1].a() as i32 + test4[1].b() as i32, 100);
+
+            let testarrayofstring = m.testarrayofstring().unwrap();
+            assert_eq!(testarrayofstring.len(), 2);
+            assert_eq!(testarrayofstring.get(0), "test1");
+            assert_eq!(testarrayofstring.get(1), "test2");
+        }
+
+        // assert that no allocs occurred:
+        let after = A.n_allocs();
+        assert_eq!(before, after, "KO: Heap allocs occurred in Rust read path");
+    }
+    println!("Rust: Heap alloc checks completed successfully");
+}
diff --git a/tests/rust_usage_test/bin/monster_example.rs b/tests/rust_usage_test/bin/monster_example.rs
new file mode 100644
index 0000000..3c9a0a0
--- /dev/null
+++ b/tests/rust_usage_test/bin/monster_example.rs
@@ -0,0 +1,19 @@
+extern crate flatbuffers;
+
+#[allow(dead_code, unused_imports)]
+#[path = "../../monster_test_generated.rs"]
+mod monster_test_generated;
+pub use monster_test_generated::my_game;
+
+use std::io::Read;
+
+fn main() {
+    let mut f = std::fs::File::open("../monsterdata_test.mon").unwrap();
+    let mut buf = Vec::new();
+    f.read_to_end(&mut buf).expect("file reading failed");
+
+    let monster = my_game::example::get_root_as_monster(&buf[..]);
+    println!("{}", monster.hp());     // `80`
+    println!("{}", monster.mana());   // default value of `150`
+    println!("{:?}", monster.name()); // Some("MyMonster")
+}
diff --git a/tests/rust_usage_test/tests/integration_test.rs b/tests/rust_usage_test/tests/integration_test.rs
new file mode 100644
index 0000000..0dace96
--- /dev/null
+++ b/tests/rust_usage_test/tests/integration_test.rs
@@ -0,0 +1,2716 @@
+/*
+ *
+ * Copyright 2018 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.
+ */
+
+extern crate quickcheck;
+
+extern crate flatbuffers;
+
+#[allow(dead_code, unused_imports)]
+#[path = "../../monster_test_generated.rs"]
+mod monster_test_generated;
+pub use monster_test_generated::my_game;
+
+// Include simple random number generator to ensure results will be the
+// same across platforms.
+// http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator
+struct LCG(u64);
+impl LCG {
+    fn new() -> Self {
+        LCG { 0: 48271 }
+    }
+    fn next(&mut self) -> u64 {
+        let old = self.0;
+        self.0 = (self.0 * 279470273u64) % 4294967291u64;
+        old
+    }
+    fn reset(&mut self) {
+        self.0 = 48271
+    }
+}
+
+// test helper macro to return an error if two expressions are not equal
+macro_rules! check_eq {
+    ($field_call:expr, $want:expr) => (
+        if $field_call == $want {
+            Ok(())
+        } else {
+            Err(stringify!($field_call))
+        }
+    )
+}
+
+#[test]
+fn macro_check_eq() {
+    assert!(check_eq!(1, 1).is_ok());
+    assert!(check_eq!(1, 2).is_err());
+}
+
+// test helper macro to return an error if two expressions are equal
+macro_rules! check_is_some {
+    ($field_call:expr) => (
+        if $field_call.is_some() {
+            Ok(())
+        } else {
+            Err(stringify!($field_call))
+        }
+    )
+}
+
+#[test]
+fn macro_check_is_some() {
+    let some: Option<usize> = Some(0);
+    let none: Option<usize> = None;
+    assert!(check_is_some!(some).is_ok());
+    assert!(check_is_some!(none).is_err());
+}
+
+
+fn create_serialized_example_with_generated_code(builder: &mut flatbuffers::FlatBufferBuilder) {
+    let mon = {
+        let s0 = builder.create_string("test1");
+        let s1 = builder.create_string("test2");
+        let fred_name = builder.create_string("Fred");
+
+        // can't inline creation of this Vec3 because we refer to it by reference, so it must live
+        // long enough to be used by MonsterArgs.
+        let pos = my_game::example::Vec3::new(1.0, 2.0, 3.0, 3.0, my_game::example::Color::Green, &my_game::example::Test::new(5i16, 6i8));
+
+        let args = my_game::example::MonsterArgs{
+            hp: 80,
+            mana: 150,
+            name: Some(builder.create_string("MyMonster")),
+            pos: Some(&pos),
+            test_type: my_game::example::Any::Monster,
+            test: Some(my_game::example::Monster::create(builder, &my_game::example::MonsterArgs{
+                name: Some(fred_name),
+                ..Default::default()
+            }).as_union_value()),
+            inventory: Some(builder.create_vector_direct(&[0u8, 1, 2, 3, 4][..])),
+            test4: Some(builder.create_vector_direct(&[my_game::example::Test::new(10, 20),
+                                                       my_game::example::Test::new(30, 40)])),
+            testarrayofstring: Some(builder.create_vector(&[s0, s1])),
+            ..Default::default()
+        };
+        my_game::example::Monster::create(builder, &args)
+    };
+    my_game::example::finish_monster_buffer(builder, mon);
+}
+
+fn create_serialized_example_with_library_code(builder: &mut flatbuffers::FlatBufferBuilder) {
+    let nested_union_mon = {
+        let name = builder.create_string("Fred");
+        let table_start = builder.start_table();
+        builder.push_slot_always(my_game::example::Monster::VT_NAME, name);
+        builder.end_table(table_start)
+    };
+    let pos = my_game::example::Vec3::new(1.0, 2.0, 3.0, 3.0, my_game::example::Color::Green, &my_game::example::Test::new(5i16, 6i8));
+    let inv = builder.create_vector(&[0u8, 1, 2, 3, 4]);
+
+    let test4 = builder.create_vector(&[my_game::example::Test::new(10, 20),
+                                        my_game::example::Test::new(30, 40)][..]);
+
+    let name = builder.create_string("MyMonster");
+    let testarrayofstring = builder.create_vector_of_strings(&["test1", "test2"][..]);
+
+    // begin building
+
+    let table_start = builder.start_table();
+    builder.push_slot(my_game::example::Monster::VT_HP, 80i16, 100);
+    builder.push_slot_always(my_game::example::Monster::VT_NAME, name);
+    builder.push_slot_always(my_game::example::Monster::VT_POS, &pos);
+    builder.push_slot(my_game::example::Monster::VT_TEST_TYPE, my_game::example::Any::Monster, my_game::example::Any::NONE);
+    builder.push_slot_always(my_game::example::Monster::VT_TEST, nested_union_mon);
+    builder.push_slot_always(my_game::example::Monster::VT_INVENTORY, inv);
+    builder.push_slot_always(my_game::example::Monster::VT_TEST4, test4);
+    builder.push_slot_always(my_game::example::Monster::VT_TESTARRAYOFSTRING, testarrayofstring);
+    let root = builder.end_table(table_start);
+    builder.finish(root, Some(my_game::example::MONSTER_IDENTIFIER));
+}
+
+fn serialized_example_is_accessible_and_correct(bytes: &[u8], identifier_required: bool, size_prefixed: bool) -> Result<(), &'static str> {
+
+    if identifier_required {
+        let correct = if size_prefixed {
+            my_game::example::monster_size_prefixed_buffer_has_identifier(bytes)
+        } else {
+            my_game::example::monster_buffer_has_identifier(bytes)
+        };
+        check_eq!(correct, true)?;
+    }
+
+    let m = if size_prefixed {
+        my_game::example::get_size_prefixed_root_as_monster(bytes)
+    } else {
+        my_game::example::get_root_as_monster(bytes)
+    };
+
+    check_eq!(m.hp(), 80)?;
+    check_eq!(m.mana(), 150)?;
+    check_eq!(m.name(), "MyMonster")?;
+
+    let pos = m.pos().unwrap();
+    check_eq!(pos.x(), 1.0f32)?;
+    check_eq!(pos.y(), 2.0f32)?;
+    check_eq!(pos.z(), 3.0f32)?;
+    check_eq!(pos.test1(), 3.0f64)?;
+    check_eq!(pos.test2(), my_game::example::Color::Green)?;
+
+    let pos_test3 = pos.test3();
+    check_eq!(pos_test3.a(), 5i16)?;
+    check_eq!(pos_test3.b(), 6i8)?;
+
+    check_eq!(m.test_type(), my_game::example::Any::Monster)?;
+    check_is_some!(m.test())?;
+    let table2 = m.test().unwrap();
+    let monster2 = my_game::example::Monster::init_from_table(table2);
+
+    check_eq!(monster2.name(), "Fred")?;
+
+    check_is_some!(m.inventory())?;
+    let inv = m.inventory().unwrap();
+    check_eq!(inv.len(), 5)?;
+    check_eq!(inv.iter().sum::<u8>(), 10u8)?;
+
+    check_is_some!(m.test4())?;
+    let test4 = m.test4().unwrap();
+    check_eq!(test4.len(), 2)?;
+    check_eq!(test4[0].a() as i32 + test4[0].b() as i32 +
+              test4[1].a() as i32 + test4[1].b() as i32, 100)?;
+
+    check_is_some!(m.testarrayofstring())?;
+    let testarrayofstring = m.testarrayofstring().unwrap();
+    check_eq!(testarrayofstring.len(), 2)?;
+    check_eq!(testarrayofstring.get(0), "test1")?;
+    check_eq!(testarrayofstring.get(1), "test2")?;
+
+    Ok(())
+}
+
+// Disabled due to Windows CI limitations.
+// #[test]
+// fn builder_initializes_with_maximum_buffer_size() {
+//     flatbuffers::FlatBufferBuilder::new_with_capacity(flatbuffers::FLATBUFFERS_MAX_BUFFER_SIZE);
+// }
+
+#[should_panic]
+#[test]
+fn builder_abort_with_greater_than_maximum_buffer_size() {
+    flatbuffers::FlatBufferBuilder::new_with_capacity(flatbuffers::FLATBUFFERS_MAX_BUFFER_SIZE+1);
+}
+
+#[test]
+fn builder_collapses_into_vec() {
+    let mut b = flatbuffers::FlatBufferBuilder::new();
+    create_serialized_example_with_generated_code(&mut b);
+    let (backing_buf, head) = b.collapse();
+    serialized_example_is_accessible_and_correct(&backing_buf[head..], true, false).unwrap();
+}
+
+#[cfg(test)]
+mod generated_constants {
+    extern crate flatbuffers;
+    use super::my_game;
+
+    #[test]
+    fn monster_identifier() {
+        assert_eq!("MONS", my_game::example::MONSTER_IDENTIFIER);
+    }
+
+    #[test]
+    fn monster_file_extension() {
+        assert_eq!("mon", my_game::example::MONSTER_EXTENSION);
+    }
+}
+
+#[cfg(test)]
+mod lifetime_correctness {
+    extern crate flatbuffers;
+
+    use std::mem;
+
+    use super::my_game;
+    use super::load_file;
+
+    #[test]
+    fn table_get_field_from_static_buffer_1() {
+        let buf = load_file("../monsterdata_test.mon").expect("missing monsterdata_test.mon");
+        // create 'static slice
+        let slice: &[u8] = &buf;
+        let slice: &'static [u8] = unsafe { mem::transmute(slice) };
+        // make sure values retrieved from the 'static buffer are themselves 'static
+        let monster: my_game::example::Monster<'static> = my_game::example::get_root_as_monster(slice);
+        // this line should compile:
+        let name: Option<&'static str> = monster._tab.get::<flatbuffers::ForwardsUOffset<&str>>(my_game::example::Monster::VT_NAME, None);
+        assert_eq!(name, Some("MyMonster"));
+    }
+
+    #[test]
+    fn table_get_field_from_static_buffer_2() {
+        static DATA: [u8; 4] = [0, 0, 0, 0]; // some binary data
+        let table: flatbuffers::Table<'static> = flatbuffers::Table::new(&DATA, 0);
+        // this line should compile:
+        table.get::<&'static str>(0, None);
+    }
+
+    #[test]
+    fn table_object_self_lifetime_in_closure() {
+        // This test is designed to ensure that lifetimes for temporary intermediate tables aren't inflated beyond where the need to be.
+        let buf = load_file("../monsterdata_test.mon").expect("missing monsterdata_test.mon");
+        let monster = my_game::example::get_root_as_monster(&buf);
+        let enemy: Option<my_game::example::Monster> = monster.enemy();
+        // This line won't compile if "self" is required to live for the lifetime of buf above as the borrow disappears at the end of the closure.
+        let enemy_of_my_enemy = enemy.map(|e| {
+            // enemy (the Option) is consumed, and the enum's value is taken as a temporary (e) at the start of the closure
+            let name = e.name();
+            // ... the temporary dies here, so for this to compile name's lifetime must not be tied to the temporary
+            name
+            // If this test fails the error would be "`e` dropped here while still borrowed"
+        });
+        assert_eq!(enemy_of_my_enemy, Some("Fred"));
+    }
+}
+
+#[cfg(test)]
+mod roundtrip_generated_code {
+    extern crate flatbuffers;
+
+    use super::my_game;
+
+    fn build_mon<'a, 'b>(builder: &'a mut flatbuffers::FlatBufferBuilder, args: &'b my_game::example::MonsterArgs) -> my_game::example::Monster<'a> {
+        let mon = my_game::example::Monster::create(builder, &args);
+        my_game::example::finish_monster_buffer(builder, mon);
+        my_game::example::get_root_as_monster(builder.finished_data())
+    }
+
+    #[test]
+    fn scalar_store() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{hp: 123, name: Some(name), ..Default::default()});
+        assert_eq!(m.hp(), 123);
+    }
+    #[test]
+    fn scalar_default() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{name: Some(name), ..Default::default()});
+        assert_eq!(m.hp(), 100);
+    }
+    #[test]
+    fn string_store() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let name = b.create_string("foobar");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{name: Some(name), ..Default::default()});
+        assert_eq!(m.name(), "foobar");
+    }
+    #[test]
+    fn struct_store() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{
+            name: Some(name),
+            pos: Some(&my_game::example::Vec3::new(1.0, 2.0, 3.0, 4.0,
+                                                   my_game::example::Color::Green,
+                                                   &my_game::example::Test::new(98, 99))),
+            ..Default::default()
+        });
+        assert_eq!(m.pos(), Some(&my_game::example::Vec3::new(1.0, 2.0, 3.0, 4.0,
+                                                              my_game::example::Color::Green,
+                                                              &my_game::example::Test::new(98, 99))));
+    }
+    #[test]
+    fn struct_default() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{name: Some(name), ..Default::default()});
+        assert_eq!(m.pos(), None);
+    }
+    #[test]
+    fn enum_store() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{name: Some(name), color: my_game::example::Color::Red, ..Default::default()});
+        assert_eq!(m.color(), my_game::example::Color::Red);
+    }
+    #[test]
+    fn enum_default() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{name: Some(name), ..Default::default()});
+        assert_eq!(m.color(), my_game::example::Color::Blue);
+    }
+    #[test]
+    fn union_store() {
+        let b = &mut flatbuffers::FlatBufferBuilder::new();
+        {
+            let name_inner = b.create_string("foo");
+            let name_outer = b.create_string("bar");
+
+            let inner = my_game::example::Monster::create(b, &my_game::example::MonsterArgs{
+                name: Some(name_inner),
+                ..Default::default()
+            });
+            let outer = my_game::example::Monster::create(b, &my_game::example::MonsterArgs{
+                name: Some(name_outer),
+                test_type: my_game::example::Any::Monster,
+                test: Some(inner.as_union_value()),
+                ..Default::default()
+            });
+            my_game::example::finish_monster_buffer(b, outer);
+        }
+
+        let mon = my_game::example::get_root_as_monster(b.finished_data());
+        assert_eq!(mon.name(), "bar");
+        assert_eq!(mon.test_type(), my_game::example::Any::Monster);
+        assert_eq!(my_game::example::Monster::init_from_table(mon.test().unwrap()).name(),
+                   "foo");
+        assert_eq!(mon.test_as_monster().unwrap().name(), "foo");
+        assert_eq!(mon.test_as_test_simple_table_with_enum(), None);
+        assert_eq!(mon.test_as_my_game_example_2_monster(), None);
+    }
+    #[test]
+    fn union_default() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{name: Some(name), ..Default::default()});
+        assert_eq!(m.test_type(), my_game::example::Any::NONE);
+        assert_eq!(m.test(), None);
+    }
+    #[test]
+    fn table_full_namespace_store() {
+        let b = &mut flatbuffers::FlatBufferBuilder::new();
+        {
+            let name_inner = b.create_string("foo");
+            let name_outer = b.create_string("bar");
+
+            let inner = my_game::example::Monster::create(b, &my_game::example::MonsterArgs{
+                name: Some(name_inner),
+                ..Default::default()
+            });
+            let outer = my_game::example::Monster::create(b, &my_game::example::MonsterArgs{
+                name: Some(name_outer),
+                enemy: Some(inner),
+                ..Default::default()
+            });
+            my_game::example::finish_monster_buffer(b, outer);
+        }
+
+        let mon = my_game::example::get_root_as_monster(b.finished_data());
+        assert_eq!(mon.name(), "bar");
+        assert_eq!(mon.enemy().unwrap().name(), "foo");
+    }
+    #[test]
+    fn table_full_namespace_default() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{name: Some(name), ..Default::default()});
+        assert_eq!(m.enemy(), None);
+    }
+    #[test]
+    fn table_store() {
+        let b = &mut flatbuffers::FlatBufferBuilder::new();
+        {
+            let id_inner = b.create_string("foo");
+            let name_outer = b.create_string("bar");
+
+            let inner = my_game::example::Stat::create(b, &my_game::example::StatArgs{
+                id: Some(id_inner),
+                ..Default::default()
+            });
+            let outer = my_game::example::Monster::create(b, &my_game::example::MonsterArgs{
+                name: Some(name_outer),
+                testempty: Some(inner),
+                ..Default::default()
+            });
+            my_game::example::finish_monster_buffer(b, outer);
+        }
+
+        let mon = my_game::example::get_root_as_monster(b.finished_data());
+        assert_eq!(mon.name(), "bar");
+        assert_eq!(mon.testempty().unwrap().id(), Some("foo"));
+    }
+    #[test]
+    fn table_default() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{name: Some(name), ..Default::default()});
+        assert_eq!(m.testempty(), None);
+    }
+    #[test]
+    fn nested_flatbuffer_store() {
+        let b0 = {
+            let mut b0 = flatbuffers::FlatBufferBuilder::new();
+            let args = my_game::example::MonsterArgs{
+                hp: 123,
+                name: Some(b0.create_string("foobar")),
+                ..Default::default()
+            };
+            let mon = my_game::example::Monster::create(&mut b0, &args);
+            my_game::example::finish_monster_buffer(&mut b0, mon);
+            b0
+        };
+
+        let b1 = {
+            let mut b1 = flatbuffers::FlatBufferBuilder::new();
+            let args = my_game::example::MonsterArgs{
+                testnestedflatbuffer: Some(b1.create_vector(b0.finished_data())),
+                name: Some(b1.create_string("foo")),
+                ..Default::default()
+            };
+            let mon = my_game::example::Monster::create(&mut b1, &args);
+            my_game::example::finish_monster_buffer(&mut b1, mon);
+            b1
+        };
+
+        let m = my_game::example::get_root_as_monster(b1.finished_data());
+
+        assert!(m.testnestedflatbuffer().is_some());
+        assert_eq!(m.testnestedflatbuffer().unwrap(), b0.finished_data());
+
+        let m2_a = my_game::example::get_root_as_monster(m.testnestedflatbuffer().unwrap());
+        assert_eq!(m2_a.hp(), 123);
+        assert_eq!(m2_a.name(), "foobar");
+
+        assert!(m.testnestedflatbuffer_nested_flatbuffer().is_some());
+        let m2_b = m.testnestedflatbuffer_nested_flatbuffer().unwrap();
+
+        assert_eq!(m2_b.hp(), 123);
+        assert_eq!(m2_b.name(), "foobar");
+    }
+    #[test]
+    fn nested_flatbuffer_default() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{name: Some(name), ..Default::default()});
+        assert!(m.testnestedflatbuffer().is_none());
+    }
+    #[test]
+    fn vector_of_string_store_helper_build() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let v = b.create_vector_of_strings(&["foobar", "baz"]);
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{
+            name: Some(name),
+            testarrayofstring: Some(v), ..Default::default()});
+        assert_eq!(m.testarrayofstring().unwrap().len(), 2);
+        assert_eq!(m.testarrayofstring().unwrap().get(0), "foobar");
+        assert_eq!(m.testarrayofstring().unwrap().get(1), "baz");
+    }
+    #[test]
+    fn vector_of_string_store_manual_build() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let s0 = b.create_string("foobar");
+        let s1 = b.create_string("baz");
+        let v = b.create_vector(&[s0, s1]);
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{
+            name: Some(name),
+            testarrayofstring: Some(v), ..Default::default()});
+        assert_eq!(m.testarrayofstring().unwrap().len(), 2);
+        assert_eq!(m.testarrayofstring().unwrap().get(0), "foobar");
+        assert_eq!(m.testarrayofstring().unwrap().get(1), "baz");
+    }
+    #[test]
+    fn vector_of_ubyte_store() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let v = b.create_vector(&[123u8, 234u8][..]);
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{
+            name: Some(name),
+            inventory: Some(v), ..Default::default()});
+        assert_eq!(m.inventory().unwrap(), &[123, 234][..]);
+    }
+    #[test]
+    fn vector_of_bool_store() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let v = b.create_vector(&[false, true, false, true][..]);
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{
+            name: Some(name),
+            testarrayofbools: Some(v), ..Default::default()});
+        assert_eq!(m.testarrayofbools().unwrap(), &[false, true, false, true][..]);
+    }
+    #[test]
+    fn vector_of_f64_store() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let v = b.create_vector(&[3.14159265359f64][..]);
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{
+            name: Some(name),
+            vector_of_doubles: Some(v), ..Default::default()});
+        assert_eq!(m.vector_of_doubles().unwrap().len(), 1);
+        assert_eq!(m.vector_of_doubles().unwrap().get(0), 3.14159265359f64);
+    }
+    #[test]
+    fn vector_of_struct_store() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let v = b.create_vector(&[my_game::example::Test::new(127, -128), my_game::example::Test::new(3, 123)][..]);
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{
+            name: Some(name),
+            test4: Some(v), ..Default::default()});
+        assert_eq!(m.test4().unwrap(), &[my_game::example::Test::new(127, -128), my_game::example::Test::new(3, 123)][..]);
+    }
+    #[test]
+    fn vector_of_struct_store_with_type_inference() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let v = b.create_vector(&[my_game::example::Test::new(127, -128),
+                                  my_game::example::Test::new(3, 123),
+                                  my_game::example::Test::new(100, 101)]);
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{
+            name: Some(name),
+            test4: Some(v), ..Default::default()});
+        assert_eq!(m.test4().unwrap(), &[my_game::example::Test::new(127, -128), my_game::example::Test::new(3, 123), my_game::example::Test::new(100, 101)][..]);
+    }
+    // TODO(rw) this passes, but I don't want to change the monster test schema right now
+    // #[test]
+    // fn vector_of_enum_store() {
+    //     let mut b = flatbuffers::FlatBufferBuilder::new();
+    //     let v = b.create_vector::<my_game::example::Color>(&[my_game::example::Color::Red, my_game::example::Color::Green][..]);
+    //     let name = b.create_string("foo");
+    //     let m = build_mon(&mut b, &my_game::example::MonsterArgs{
+    //         name: Some(name),
+    //         vector_of_enum: Some(v), ..Default::default()});
+    //     assert_eq!(m.vector_of_enum().unwrap().len(), 2);
+    //     assert_eq!(m.vector_of_enum().unwrap().get(0), my_game::example::Color::Red);
+    //     assert_eq!(m.vector_of_enum().unwrap().get(1), my_game::example::Color::Green);
+    // }
+    #[test]
+    fn vector_of_table_store() {
+        let b = &mut flatbuffers::FlatBufferBuilder::new();
+        let t0 = {
+            let name = b.create_string("foo");
+            let args = my_game::example::MonsterArgs{hp: 55, name: Some(name), ..Default::default()};
+            my_game::example::Monster::create(b, &args)
+        };
+        let t1 = {
+            let name = b.create_string("bar");
+            let args = my_game::example::MonsterArgs{name: Some(name), ..Default::default()};
+            my_game::example::Monster::create(b, &args)
+        };
+        let v = b.create_vector(&[t0, t1][..]);
+        let name = b.create_string("foo");
+        let m = build_mon(b, &my_game::example::MonsterArgs{
+            name: Some(name),
+            testarrayoftables: Some(v), ..Default::default()});
+        assert_eq!(m.testarrayoftables().unwrap().len(), 2);
+        assert_eq!(m.testarrayoftables().unwrap().get(0).hp(), 55);
+        assert_eq!(m.testarrayoftables().unwrap().get(0).name(), "foo");
+        assert_eq!(m.testarrayoftables().unwrap().get(1).hp(), 100);
+        assert_eq!(m.testarrayoftables().unwrap().get(1).name(), "bar");
+    }
+}
+
+#[cfg(test)]
+mod generated_code_alignment_and_padding {
+    extern crate flatbuffers;
+    use super::my_game;
+
+    #[test]
+    fn enum_color_is_1_byte() {
+        assert_eq!(1, ::std::mem::size_of::<my_game::example::Color>());
+    }
+
+    #[test]
+    fn enum_color_is_aligned_to_1() {
+        assert_eq!(1, ::std::mem::align_of::<my_game::example::Color>());
+    }
+
+    #[test]
+    fn union_any_is_1_byte() {
+        assert_eq!(1, ::std::mem::size_of::<my_game::example::Any>());
+    }
+
+    #[test]
+    fn union_any_is_aligned_to_1() {
+        assert_eq!(1, ::std::mem::align_of::<my_game::example::Any>());
+    }
+
+    #[test]
+    fn struct_test_is_4_bytes() {
+        assert_eq!(4, ::std::mem::size_of::<my_game::example::Test>());
+    }
+
+    #[test]
+    fn struct_test_is_aligned_to_2() {
+        assert_eq!(2, ::std::mem::align_of::<my_game::example::Test>());
+    }
+
+    #[test]
+    fn struct_vec3_is_32_bytes() {
+        assert_eq!(32, ::std::mem::size_of::<my_game::example::Vec3>());
+    }
+
+    #[test]
+    fn struct_vec3_is_aligned_to_8() {
+        assert_eq!(8, ::std::mem::align_of::<my_game::example::Vec3>());
+    }
+
+    #[test]
+    fn struct_vec3_is_written_with_correct_alignment_in_table() {
+        let b = &mut flatbuffers::FlatBufferBuilder::new();
+        {
+            let name = b.create_string("foo");
+            let mon = my_game::example::Monster::create(b, &my_game::example::MonsterArgs{
+                name: Some(name),
+                pos: Some(&my_game::example::Vec3::new(1.0, 2.0, 3.0, 4.0,
+                                                       my_game::example::Color::Green,
+                                                       &my_game::example::Test::new(98, 99))),
+                                                       ..Default::default()});
+            my_game::example::finish_monster_buffer(b, mon);
+        }
+        let buf = b.finished_data();
+        let mon = my_game::example::get_root_as_monster(buf);
+        let vec3 = mon.pos().unwrap();
+
+        let start_ptr = buf.as_ptr() as usize;
+        let vec3_ptr = vec3 as *const my_game::example::Vec3 as usize;
+
+        assert!(vec3_ptr > start_ptr);
+        let aln = ::std::mem::align_of::<my_game::example::Vec3>();
+        assert_eq!((vec3_ptr - start_ptr) % aln, 0);
+    }
+
+    #[test]
+    fn struct_ability_is_8_bytes() {
+        assert_eq!(8, ::std::mem::size_of::<my_game::example::Ability>());
+    }
+
+    #[test]
+    fn struct_ability_is_aligned_to_4() {
+        assert_eq!(4, ::std::mem::align_of::<my_game::example::Ability>());
+    }
+
+    #[test]
+    fn struct_ability_is_written_with_correct_alignment_in_table_vector() {
+        let b = &mut flatbuffers::FlatBufferBuilder::new();
+        {
+            let name = b.create_string("foo");
+            let v = b.create_vector(&[my_game::example::Ability::new(1, 2),
+                                      my_game::example::Ability::new(3, 4),
+                                      my_game::example::Ability::new(5, 6)]);
+            let mon = my_game::example::Monster::create(b, &my_game::example::MonsterArgs{
+                name: Some(name),
+                testarrayofsortedstruct: Some(v),
+                ..Default::default()});
+            my_game::example::finish_monster_buffer(b, mon);
+        }
+        let buf = b.finished_data();
+        let mon = my_game::example::get_root_as_monster(buf);
+        let abilities = mon.testarrayofsortedstruct().unwrap();
+
+        let start_ptr = buf.as_ptr() as usize;
+        for a in abilities.iter() {
+            let a_ptr = a as *const my_game::example::Ability as usize;
+            assert!(a_ptr > start_ptr);
+            let aln = ::std::mem::align_of::<my_game::example::Ability>();
+            assert_eq!((a_ptr - start_ptr) % aln, 0);
+        }
+    }
+}
+
+#[cfg(test)]
+mod roundtrip_byteswap {
+    extern crate quickcheck;
+    extern crate flatbuffers;
+
+    const N: u64 = 10000;
+
+    fn palindrome_32(x: f32) -> bool {
+        x == f32::from_bits(x.to_bits().swap_bytes())
+    }
+    fn palindrome_64(x: f64) -> bool {
+        x == f64::from_bits(x.to_bits().swap_bytes())
+    }
+
+    fn prop_f32(x: f32) {
+        use flatbuffers::byte_swap_f32;
+
+        let there = byte_swap_f32(x);
+
+        let back_again = byte_swap_f32(there);
+
+        if !palindrome_32(x) {
+            assert!(x != there);
+        }
+
+        assert_eq!(x, back_again);
+    }
+
+    fn prop_f64(x: f64) {
+        use flatbuffers::byte_swap_f64;
+
+        let there = byte_swap_f64(x);
+        let back_again = byte_swap_f64(there);
+
+        if !palindrome_64(x) {
+            assert!(x != there);
+        }
+
+        assert_eq!(x, back_again);
+    }
+
+    #[test]
+    fn fuzz_f32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_f32 as fn(f32)); }
+    #[test]
+    fn fuzz_f64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_f64 as fn(f64)); }
+}
+
+#[cfg(test)]
+mod roundtrip_vectors {
+
+    #[cfg(test)]
+    mod scalar {
+        extern crate quickcheck;
+        extern crate flatbuffers;
+
+        const N: u64 = 20;
+
+        fn prop<T>(xs: Vec<T>)
+        where
+            T: for<'a> flatbuffers::Follow<'a, Inner = T>
+                + flatbuffers::EndianScalar
+                + flatbuffers::Push
+                + ::std::fmt::Debug,
+        {
+            use flatbuffers::Follow;
+
+            let mut b = flatbuffers::FlatBufferBuilder::new();
+            b.start_vector::<T>(xs.len());
+            for i in (0..xs.len()).rev() {
+                b.push::<T>(xs[i]);
+            }
+            let vecend = b.end_vector::<T>(xs.len());
+            b.finish_minimal(vecend);
+
+            let buf = b.finished_data();
+
+            let got = <flatbuffers::ForwardsUOffset<flatbuffers::Vector<T>>>::follow(&buf[..], 0);
+            let mut result_vec: Vec<T> = Vec::with_capacity(got.len());
+            for i in 0..got.len() {
+                result_vec.push(got.get(i));
+            }
+            assert_eq!(result_vec, xs);
+        }
+
+        #[test]
+        fn easy_u8() {
+            prop::<u8>(vec![]);
+            prop::<u8>(vec![1u8]);
+            prop::<u8>(vec![1u8, 2u8]);
+            prop::<u8>(vec![1u8, 2u8, 3u8]);
+            prop::<u8>(vec![1u8, 2u8, 3u8, 4u8]);
+        }
+
+        #[test]
+        fn fuzz_bool() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<bool> as fn(Vec<_>)); }
+        #[test]
+        fn fuzz_u8() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<u8> as fn(Vec<_>)); }
+        #[test]
+        fn fuzz_i8() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<i8> as fn(Vec<_>)); }
+        #[test]
+        fn fuzz_u16() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<u16> as fn(Vec<_>)); }
+        #[test]
+        fn fuzz_i16() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<i16> as fn(Vec<_>)); }
+        #[test]
+        fn fuzz_u32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<u32> as fn(Vec<_>)); }
+        #[test]
+        fn fuzz_i32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<i32> as fn(Vec<_>)); }
+        #[test]
+        fn fuzz_u64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<u64> as fn(Vec<_>)); }
+        #[test]
+        fn fuzz_i64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<i64> as fn(Vec<_>)); }
+        #[test]
+        fn fuzz_f32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<f32> as fn(Vec<_>)); }
+        #[test]
+        fn fuzz_f64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<f64> as fn(Vec<_>)); }
+    }
+
+    #[cfg(test)]
+    mod create_vector_direct {
+        extern crate quickcheck;
+        extern crate flatbuffers;
+
+        const N: u64 = 20;
+
+        // This uses a macro because lifetimes for the trait-bounded function get too
+        // complicated.
+        macro_rules! impl_prop {
+            ($test_name:ident, $fn_name:ident, $ty:ident) => (
+                fn $fn_name(xs: Vec<$ty>) {
+                    use flatbuffers::Follow;
+
+                    let mut b = flatbuffers::FlatBufferBuilder::new();
+                    b.create_vector_direct(&xs[..]);
+                    let buf = b.unfinished_data();
+
+                    let got = <flatbuffers::Vector<$ty>>::follow(&buf[..], 0).safe_slice();
+                    assert_eq!(got, &xs[..]);
+                }
+                #[test]
+                fn $test_name() { quickcheck::QuickCheck::new().max_tests(N).quickcheck($fn_name as fn(Vec<_>)); }
+            )
+        }
+
+        impl_prop!(test_bool, prop_bool, bool);
+        impl_prop!(test_u8, prop_u8, u8);
+        impl_prop!(test_i8, prop_i8, i8);
+
+        #[cfg(test)]
+        #[cfg(target_endian = "little")]
+        mod host_is_le {
+            const N: u64 = 20;
+            use super::flatbuffers;
+            use super::quickcheck;
+            impl_prop!(test_u16, prop_u16, u16);
+            impl_prop!(test_u32, prop_u32, u32);
+            impl_prop!(test_u64, prop_u64, u64);
+            impl_prop!(test_i16, prop_i16, i16);
+            impl_prop!(test_i32, prop_i32, i32);
+            impl_prop!(test_i64, prop_i64, i64);
+            impl_prop!(test_f32, prop_f32, f32);
+            impl_prop!(test_f64, prop_f64, f64);
+        }
+    }
+
+    #[cfg(test)]
+    mod string_manual_build {
+        extern crate quickcheck;
+        extern crate flatbuffers;
+
+        fn prop(xs: Vec<String>) {
+            use flatbuffers::Follow;
+
+            let mut b = flatbuffers::FlatBufferBuilder::new();
+            let mut offsets = Vec::new();
+            for s in xs.iter().rev() {
+                offsets.push(b.create_string(s.as_str()));
+            }
+
+            b.start_vector::<flatbuffers::WIPOffset<&str>>(xs.len());
+            for &i in offsets.iter() {
+                b.push(i);
+            }
+            let vecend = b.end_vector::<flatbuffers::WIPOffset<&str>>(xs.len());
+
+            b.finish_minimal(vecend);
+
+            let buf = b.finished_data();
+            let got = <flatbuffers::ForwardsUOffset<flatbuffers::Vector<flatbuffers::ForwardsUOffset<&str>>>>::follow(buf, 0);
+
+            assert_eq!(got.len(), xs.len());
+            for i in 0..xs.len() {
+                assert_eq!(got.get(i), &xs[i][..]);
+            }
+        }
+
+        #[test]
+        fn fuzz() {
+            quickcheck::QuickCheck::new().max_tests(20).quickcheck(prop as fn(Vec<_>));
+        }
+    }
+
+    #[cfg(test)]
+    mod string_helper_build {
+        extern crate quickcheck;
+        extern crate flatbuffers;
+
+        fn prop(input: Vec<String>) {
+            let xs: Vec<&str> = input.iter().map(|s: &String| &s[..]).collect();
+
+            use flatbuffers::Follow;
+
+            let mut b = flatbuffers::FlatBufferBuilder::new();
+            let vecend = b.create_vector_of_strings(&xs[..]);
+
+            b.finish_minimal(vecend);
+
+            let buf = b.finished_data();
+            let got = <flatbuffers::ForwardsUOffset<flatbuffers::Vector<flatbuffers::ForwardsUOffset<&str>>>>::follow(buf, 0);
+
+            assert_eq!(got.len(), xs.len());
+            for i in 0..xs.len() {
+                assert_eq!(got.get(i), &xs[i][..]);
+            }
+        }
+
+        #[test]
+        fn fuzz() {
+            quickcheck::QuickCheck::new().max_tests(100).quickcheck(prop as fn(Vec<_>));
+        }
+    }
+
+    #[cfg(test)]
+    mod ubyte {
+        extern crate quickcheck;
+        extern crate flatbuffers;
+
+        #[test]
+        fn fuzz_manual_build() {
+            fn prop(vec: Vec<u8>) {
+                let xs = &vec[..];
+
+                let mut b1 = flatbuffers::FlatBufferBuilder::new();
+                b1.start_vector::<u8>(xs.len());
+
+                for i in (0..xs.len()).rev() {
+                    b1.push(xs[i]);
+                }
+                b1.end_vector::<u8>(xs.len());
+
+                let mut b2 = flatbuffers::FlatBufferBuilder::new();
+                b2.create_vector(xs);
+                assert_eq!(b1.unfinished_data(), b2.unfinished_data());
+            }
+            quickcheck::QuickCheck::new().max_tests(100).quickcheck(prop as fn(Vec<_>));
+        }
+    }
+}
+
+#[cfg(test)]
+mod framing_format {
+    extern crate flatbuffers;
+
+    use super::my_game;
+
+    #[test]
+    fn test_size_prefixed_buffer() {
+        // Create size prefixed buffer.
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let args = &my_game::example::MonsterArgs{
+            mana: 200,
+            hp: 300,
+            name: Some(b.create_string("bob")),
+            ..Default::default()
+        };
+        let mon = my_game::example::Monster::create(&mut b, &args);
+        b.finish_size_prefixed(mon, None);
+
+        // Access it.
+        let buf = b.finished_data();
+        let m = flatbuffers::get_size_prefixed_root::<my_game::example::Monster>(buf);
+        assert_eq!(m.mana(), 200);
+        assert_eq!(m.hp(), 300);
+        assert_eq!(m.name(), "bob");
+    }
+}
+
+#[cfg(test)]
+mod roundtrip_table {
+    use std::collections::HashMap;
+
+    extern crate flatbuffers;
+    extern crate quickcheck;
+
+    use super::LCG;
+
+    #[test]
+    fn table_of_mixed_scalars_fuzz() {
+        // Values we're testing against: chosen to ensure no bits get chopped
+        // off anywhere, and also be different from eachother.
+        let bool_val: bool = true;
+        let char_val: i8 = -127;  // 0x81
+        let uchar_val: u8 = 0xFF;
+        let short_val: i16 = -32222;  // 0x8222;
+        let ushort_val: u16 = 0xFEEE;
+        let int_val: i32 = unsafe { ::std::mem::transmute(0x83333333u32) };
+        let uint_val: u32 = 0xFDDDDDDD;
+        let long_val: i64 = unsafe { ::std::mem::transmute(0x8444444444444444u64) }; // TODO: byte literal?
+        let ulong_val: u64 = 0xFCCCCCCCCCCCCCCCu64;
+        let float_val: f32 = 3.14159;
+        let double_val: f64 = 3.14159265359;
+
+        let test_value_types_max: isize = 11;
+        let max_fields_per_object: flatbuffers::VOffsetT = 100;
+        let num_fuzz_objects: isize = 1000;  // The higher, the more thorough :)
+
+        let mut builder = flatbuffers::FlatBufferBuilder::new();
+        let mut lcg = LCG::new();
+
+        let mut objects: Vec<flatbuffers::UOffsetT> = vec![0; num_fuzz_objects as usize];
+
+        // Generate num_fuzz_objects random objects each consisting of
+        // fields_per_object fields, each of a random type.
+        for i in 0..(num_fuzz_objects as usize) {
+            let fields_per_object = (lcg.next() % (max_fields_per_object as u64)) as flatbuffers::VOffsetT;
+            let start = builder.start_table();
+
+            for j in 0..fields_per_object {
+                let choice = lcg.next() % (test_value_types_max as u64);
+
+                let f = flatbuffers::field_index_to_field_offset(j);
+
+                match choice {
+                    0 => {builder.push_slot::<bool>(f, bool_val, false);}
+                    1 => {builder.push_slot::<i8>(f, char_val, 0);}
+                    2 => {builder.push_slot::<u8>(f, uchar_val, 0);}
+                    3 => {builder.push_slot::<i16>(f, short_val, 0);}
+                    4 => {builder.push_slot::<u16>(f, ushort_val, 0);}
+                    5 => {builder.push_slot::<i32>(f, int_val, 0);}
+                    6 => {builder.push_slot::<u32>(f, uint_val, 0);}
+                    7 => {builder.push_slot::<i64>(f, long_val, 0);}
+                    8 => {builder.push_slot::<u64>(f, ulong_val, 0);}
+                    9 => {builder.push_slot::<f32>(f, float_val, 0.0);}
+                    10 => {builder.push_slot::<f64>(f, double_val, 0.0);}
+                    _ => { panic!("unknown choice: {}", choice); }
+                }
+            }
+            objects[i] = builder.end_table(start).value();
+        }
+
+        // Do some bookkeeping to generate stats on fuzzes:
+        let mut stats: HashMap<u64, u64> = HashMap::new();
+        let mut values_generated: u64 = 0;
+
+        // Embrace PRNG determinism:
+        lcg.reset();
+
+        // Test that all objects we generated are readable and return the
+        // expected values. We generate random objects in the same order
+        // so this is deterministic:
+        for i in 0..(num_fuzz_objects as usize) {
+            let table = {
+                let buf = builder.unfinished_data();
+                let loc = buf.len() as flatbuffers::UOffsetT - objects[i];
+                flatbuffers::Table::new(buf, loc as usize)
+            };
+
+            let fields_per_object = (lcg.next() % (max_fields_per_object as u64)) as flatbuffers::VOffsetT;
+            for j in 0..fields_per_object {
+                let choice = lcg.next() % (test_value_types_max as u64);
+
+                *stats.entry(choice).or_insert(0) += 1;
+                values_generated += 1;
+
+                let f = flatbuffers::field_index_to_field_offset(j);
+
+                match choice {
+                    0 => { assert_eq!(bool_val, table.get::<bool>(f, Some(false)).unwrap()); }
+                    1 => { assert_eq!(char_val, table.get::<i8>(f, Some(0)).unwrap()); }
+                    2 => { assert_eq!(uchar_val, table.get::<u8>(f, Some(0)).unwrap()); }
+                    3 => { assert_eq!(short_val, table.get::<i16>(f, Some(0)).unwrap()); }
+                    4 => { assert_eq!(ushort_val, table.get::<u16>(f, Some(0)).unwrap()); }
+                    5 => { assert_eq!(int_val, table.get::<i32>(f, Some(0)).unwrap()); }
+                    6 => { assert_eq!(uint_val, table.get::<u32>(f, Some(0)).unwrap()); }
+                    7 => { assert_eq!(long_val, table.get::<i64>(f, Some(0)).unwrap()); }
+                    8 => { assert_eq!(ulong_val, table.get::<u64>(f, Some(0)).unwrap()); }
+                    9 => { assert_eq!(float_val, table.get::<f32>(f, Some(0.0)).unwrap()); }
+                    10 => { assert_eq!(double_val, table.get::<f64>(f, Some(0.0)).unwrap()); }
+                    _ => { panic!("unknown choice: {}", choice); }
+                }
+            }
+        }
+
+        // Assert that we tested all the fuzz cases enough:
+        let min_tests_per_choice = 1000;
+        assert!(values_generated > 0);
+        assert!(min_tests_per_choice > 0);
+        for i in 0..test_value_types_max as u64 {
+            assert!(stats[&i] >= min_tests_per_choice,
+                    format!("inadequately-tested fuzz case: {}", i));
+        }
+    }
+
+    #[test]
+    fn table_of_byte_strings_fuzz() {
+        fn prop(vec: Vec<Vec<u8>>) {
+            use flatbuffers::field_index_to_field_offset as fi2fo;
+            use flatbuffers::Follow;
+
+            let xs = &vec[..];
+
+            // build
+            let mut b = flatbuffers::FlatBufferBuilder::new();
+            let str_offsets: Vec<flatbuffers::WIPOffset<_>> = xs.iter().map(|s| b.create_byte_string(&s[..])).collect();
+            let table_start = b.start_table();
+
+            for i in 0..xs.len() {
+                b.push_slot_always(fi2fo(i as flatbuffers::VOffsetT), str_offsets[i]);
+            }
+            let root = b.end_table(table_start);
+            b.finish_minimal(root);
+
+            // use
+            let buf = b.finished_data();
+            let tab = <flatbuffers::ForwardsUOffset<flatbuffers::Table>>::follow(buf, 0);
+
+            for i in 0..xs.len() {
+                let v = tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<u8>>>(fi2fo(i as flatbuffers::VOffsetT), None);
+                assert!(v.is_some());
+                let v2 = v.unwrap().safe_slice();
+                assert_eq!(v2, &xs[i][..]);
+            }
+        }
+        prop(vec![vec![1,2,3]]);
+
+        let n = 20;
+        quickcheck::QuickCheck::new().max_tests(n).quickcheck(prop as fn(Vec<_>));
+    }
+
+    #[test]
+    fn fuzz_table_of_strings() {
+        fn prop(vec: Vec<String>) {
+            use flatbuffers::field_index_to_field_offset as fi2fo;
+            use flatbuffers::Follow;
+
+            let xs = &vec[..];
+
+            // build
+            let mut b = flatbuffers::FlatBufferBuilder::new();
+            let str_offsets: Vec<flatbuffers::WIPOffset<_>> = xs.iter().map(|s| b.create_string(&s[..])).collect();
+            let table_start = b.start_table();
+
+            for i in 0..xs.len() {
+                b.push_slot_always(fi2fo(i as flatbuffers::VOffsetT), str_offsets[i]);
+            }
+            let root = b.end_table(table_start);
+            b.finish_minimal(root);
+
+            // use
+            let buf = b.finished_data();
+            let tab = <flatbuffers::ForwardsUOffset<flatbuffers::Table>>::follow(buf, 0);
+
+            for i in 0..xs.len() {
+                let v = tab.get::<flatbuffers::ForwardsUOffset<&str>>(fi2fo(i as flatbuffers::VOffsetT), None);
+                assert_eq!(v, Some(&xs[i][..]));
+            }
+        }
+        let n = 20;
+        quickcheck::QuickCheck::new().max_tests(n).quickcheck(prop as fn(Vec<String>));
+    }
+
+    mod table_of_vectors_of_scalars {
+        extern crate flatbuffers;
+        extern crate quickcheck;
+
+        const N: u64 = 20;
+
+        fn prop<T>(vecs: Vec<Vec<T>>)
+        where
+            T: for<'a> flatbuffers::Follow<'a, Inner = T>
+                + flatbuffers::EndianScalar
+                + flatbuffers::Push
+                + ::std::fmt::Debug,
+        {
+            use flatbuffers::field_index_to_field_offset as fi2fo;
+            use flatbuffers::Follow;
+
+            // build
+            let mut b = flatbuffers::FlatBufferBuilder::new();
+            let mut offs = vec![];
+            for vec in &vecs {
+                b.start_vector::<T>(vec.len());
+
+                let xs = &vec[..];
+                for i in (0..xs.len()).rev() {
+                    b.push::<T>(xs[i]);
+                }
+                let vecend = b.end_vector::<T>(xs.len());
+                offs.push(vecend);
+            }
+
+            let table_start = b.start_table();
+
+            for i in 0..vecs.len() {
+                b.push_slot_always(fi2fo(i as flatbuffers::VOffsetT), offs[i]);
+            }
+            let root = b.end_table(table_start);
+            b.finish_minimal(root);
+
+            // use
+            let buf = b.finished_data();
+            let tab = <flatbuffers::ForwardsUOffset<flatbuffers::Table>>::follow(buf, 0);
+
+            for i in 0..vecs.len() {
+                let got = tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<T>>>(fi2fo(i as flatbuffers::VOffsetT), None);
+                assert!(got.is_some());
+                let got2 = got.unwrap();
+                let mut got3: Vec<T> = Vec::with_capacity(got2.len());
+                for i in 0..got2.len() {
+                    got3.push(got2.get(i));
+                }
+                assert_eq!(vecs[i], got3);
+            }
+        }
+
+        #[test]
+        fn fuzz_bool() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<bool>>)); }
+
+        #[test]
+        fn fuzz_u8() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<u8>>)); }
+        #[test]
+        fn fuzz_u16() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<u16>>)); }
+        #[test]
+        fn fuzz_u32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<u32>>)); }
+        #[test]
+        fn fuzz_u64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<u64>>)); }
+
+        #[test]
+        fn fuzz_i8() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<u8>>)); }
+        #[test]
+        fn fuzz_i16() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<u16>>)); }
+        #[test]
+        fn fuzz_i32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<u32>>)); }
+        #[test]
+        fn fuzz_i64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<u64>>)); }
+
+        #[test]
+        fn fuzz_f32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<f32>>)); }
+        #[test]
+        fn fuzz_f64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<f64>>)); }
+    }
+}
+
+#[cfg(test)]
+mod roundtrip_scalars {
+    extern crate flatbuffers;
+    extern crate quickcheck;
+
+    const N: u64 = 1000;
+
+    fn prop<T: PartialEq + ::std::fmt::Debug + Copy + flatbuffers::EndianScalar>(x: T) {
+        let mut buf = vec![0u8; ::std::mem::size_of::<T>()];
+        flatbuffers::emplace_scalar(&mut buf[..], x);
+        let y = flatbuffers::read_scalar(&buf[..]);
+        assert_eq!(x, y);
+    }
+
+    #[test]
+    fn fuzz_bool() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<bool> as fn(_)); }
+    #[test]
+    fn fuzz_u8() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<u8> as fn(_)); }
+    #[test]
+    fn fuzz_i8() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<i8> as fn(_)); }
+
+    #[test]
+    fn fuzz_u16() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<u16> as fn(_)); }
+    #[test]
+    fn fuzz_i16() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<i16> as fn(_)); }
+
+    #[test]
+    fn fuzz_u32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<u32> as fn(_)); }
+    #[test]
+    fn fuzz_i32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<i32> as fn(_)); }
+
+    #[test]
+    fn fuzz_u64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<u64> as fn(_)); }
+    #[test]
+    fn fuzz_i64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<i64> as fn(_)); }
+
+    #[test]
+    fn fuzz_f32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<f32> as fn(_)); }
+    #[test]
+    fn fuzz_f64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<f64> as fn(_)); }
+}
+
+#[cfg(test)]
+mod roundtrip_push_follow_scalars {
+    extern crate flatbuffers;
+    extern crate quickcheck;
+
+    use flatbuffers::Push;
+
+    const N: u64 = 1000;
+
+    // This uses a macro because lifetimes for a trait-bounded function get too
+    // complicated.
+    macro_rules! impl_prop {
+        ($fn_name:ident, $ty:ident) => (
+            fn $fn_name(x: $ty) {
+                let mut buf = vec![0u8; ::std::mem::size_of::<$ty>()];
+                x.push(&mut buf[..], &[][..]);
+                let fs: flatbuffers::FollowStart<$ty> = flatbuffers::FollowStart::new();
+                assert_eq!(fs.self_follow(&buf[..], 0), x);
+            }
+        )
+    }
+
+    impl_prop!(prop_bool, bool);
+    impl_prop!(prop_u8, u8);
+    impl_prop!(prop_i8, i8);
+    impl_prop!(prop_u16, u16);
+    impl_prop!(prop_i16, i16);
+    impl_prop!(prop_u32, u32);
+    impl_prop!(prop_i32, i32);
+    impl_prop!(prop_u64, u64);
+    impl_prop!(prop_i64, i64);
+    impl_prop!(prop_f32, f32);
+    impl_prop!(prop_f64, f64);
+
+    #[test]
+    fn fuzz_bool() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_bool as fn(bool)); }
+    #[test]
+    fn fuzz_u8() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_u8 as fn(u8)); }
+    #[test]
+    fn fuzz_i8() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_i8 as fn(i8)); }
+    #[test]
+    fn fuzz_u16() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_u16 as fn(u16)); }
+    #[test]
+    fn fuzz_i16() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_i16 as fn(i16)); }
+    #[test]
+    fn fuzz_u32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_u32 as fn(u32)); }
+    #[test]
+    fn fuzz_i32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_i32 as fn(i32)); }
+    #[test]
+    fn fuzz_u64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_u64 as fn(u64)); }
+    #[test]
+    fn fuzz_i64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_i64 as fn(i64)); }
+    #[test]
+    fn fuzz_f32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_f32 as fn(f32)); }
+    #[test]
+    fn fuzz_f64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_f64 as fn(f64)); }
+}
+
+
+#[cfg(test)]
+mod write_and_read_examples {
+    extern crate flatbuffers;
+
+    use super::create_serialized_example_with_library_code;
+    use super::create_serialized_example_with_generated_code;
+    use super::serialized_example_is_accessible_and_correct;
+
+    #[test]
+    fn generated_code_creates_correct_example() {
+        let b = &mut flatbuffers::FlatBufferBuilder::new();
+        create_serialized_example_with_generated_code(b);
+        let buf = b.finished_data();
+        serialized_example_is_accessible_and_correct(&buf[..], true, false).unwrap();
+    }
+
+    #[test]
+    fn generated_code_creates_correct_example_repeatedly_with_reset() {
+        let b = &mut flatbuffers::FlatBufferBuilder::new();
+        for _ in 0..100 {
+            create_serialized_example_with_generated_code(b);
+            {
+                let buf = b.finished_data();
+                serialized_example_is_accessible_and_correct(&buf[..], true, false).unwrap();
+            }
+            b.reset();
+        }
+    }
+
+    #[test]
+    fn library_code_creates_correct_example() {
+        let b = &mut flatbuffers::FlatBufferBuilder::new();
+        create_serialized_example_with_library_code(b);
+        let buf = b.finished_data();
+        serialized_example_is_accessible_and_correct(&buf[..], true, false).unwrap();
+    }
+
+    #[test]
+    fn library_code_creates_correct_example_repeatedly_with_reset() {
+        let b = &mut flatbuffers::FlatBufferBuilder::new();
+        for _ in 0..100 {
+            create_serialized_example_with_library_code(b);
+            {
+                let buf = b.finished_data();
+                serialized_example_is_accessible_and_correct(&buf[..], true, false).unwrap();
+            }
+            b.reset();
+        }
+    }
+}
+
+#[cfg(test)]
+mod read_examples_from_other_language_ports {
+    extern crate flatbuffers;
+
+    use super::load_file;
+    use super::serialized_example_is_accessible_and_correct;
+
+    #[test]
+    fn gold_cpp_example_data_is_accessible_and_correct() {
+        let buf = load_file("../monsterdata_test.mon").expect("missing monsterdata_test.mon");
+        serialized_example_is_accessible_and_correct(&buf[..], true, false).unwrap();
+    }
+    #[test]
+    fn java_wire_example_data_is_accessible_and_correct() {
+        let buf = load_file("../monsterdata_java_wire.mon");
+        if buf.is_err() {
+            println!("skipping java wire test because it is not present");
+            return;
+        }
+        let buf = buf.unwrap();
+        serialized_example_is_accessible_and_correct(&buf[..], true, false).unwrap();
+    }
+    #[test]
+    fn java_wire_size_prefixed_example_data_is_accessible_and_correct() {
+        let buf = load_file("../monsterdata_java_wire_sp.mon");
+        if buf.is_err() {
+            println!("skipping java wire test because it is not present");
+            return;
+        }
+        let buf = buf.unwrap();
+        serialized_example_is_accessible_and_correct(&buf[..], true, true).unwrap();
+    }
+}
+
+#[cfg(test)]
+mod generated_code_asserts {
+    extern crate flatbuffers;
+
+    use super::my_game;
+
+    #[test]
+    #[should_panic]
+    fn monster_builder_fails_when_name_is_missing() {
+        let b = &mut flatbuffers::FlatBufferBuilder::new();
+        my_game::example::Monster::create(b, &my_game::example::MonsterArgs{..Default::default()});
+    }
+}
+
+#[cfg(test)]
+mod generated_key_comparisons {
+    extern crate flatbuffers;
+
+    use super::my_game;
+
+    #[test]
+    fn struct_ability_key_compare_less_than() {
+        let a = my_game::example::Ability::new(1, 2);
+        let b = my_game::example::Ability::new(2, 1);
+        let c = my_game::example::Ability::new(3, 3);
+
+        assert_eq!(a.key_compare_less_than(&a), false);
+        assert_eq!(b.key_compare_less_than(&b), false);
+        assert_eq!(c.key_compare_less_than(&c), false);
+
+        assert_eq!(a.key_compare_less_than(&b), true);
+        assert_eq!(a.key_compare_less_than(&c), true);
+
+        assert_eq!(b.key_compare_less_than(&a), false);
+        assert_eq!(b.key_compare_less_than(&c), true);
+
+        assert_eq!(c.key_compare_less_than(&a), false);
+        assert_eq!(c.key_compare_less_than(&b), false);
+    }
+
+    #[test]
+    fn struct_key_compare_with_value() {
+        let a = my_game::example::Ability::new(1, 2);
+
+        assert_eq!(a.key_compare_with_value(0), ::std::cmp::Ordering::Greater);
+        assert_eq!(a.key_compare_with_value(1), ::std::cmp::Ordering::Equal);
+        assert_eq!(a.key_compare_with_value(2), ::std::cmp::Ordering::Less);
+    }
+
+    #[test]
+    fn struct_key_compare_less_than() {
+        let a = my_game::example::Ability::new(1, 2);
+        let b = my_game::example::Ability::new(2, 1);
+        let c = my_game::example::Ability::new(3, 3);
+
+        assert_eq!(a.key_compare_less_than(&a), false);
+        assert_eq!(b.key_compare_less_than(&b), false);
+        assert_eq!(c.key_compare_less_than(&c), false);
+
+        assert_eq!(a.key_compare_less_than(&b), true);
+        assert_eq!(a.key_compare_less_than(&c), true);
+
+        assert_eq!(b.key_compare_less_than(&a), false);
+        assert_eq!(b.key_compare_less_than(&c), true);
+
+        assert_eq!(c.key_compare_less_than(&a), false);
+        assert_eq!(c.key_compare_less_than(&b), false);
+    }
+
+    #[test]
+    fn table_key_compare_with_value() {
+        // setup
+        let builder = &mut flatbuffers::FlatBufferBuilder::new();
+        super::create_serialized_example_with_library_code(builder);
+        let buf = builder.finished_data();
+        let a = my_game::example::get_root_as_monster(buf);
+
+        // preconditions
+        assert_eq!(a.name(), "MyMonster");
+
+        assert_eq!(a.key_compare_with_value("AAA"), ::std::cmp::Ordering::Greater);
+        assert_eq!(a.key_compare_with_value("MyMonster"), ::std::cmp::Ordering::Equal);
+        assert_eq!(a.key_compare_with_value("ZZZ"), ::std::cmp::Ordering::Less);
+    }
+
+    #[test]
+    fn table_key_compare_less_than() {
+        // setup
+        let builder = &mut flatbuffers::FlatBufferBuilder::new();
+        super::create_serialized_example_with_library_code(builder);
+        let buf = builder.finished_data();
+        let a = my_game::example::get_root_as_monster(buf);
+        let b = a.test_as_monster().unwrap();
+
+        // preconditions
+        assert_eq!(a.name(), "MyMonster");
+        assert_eq!(b.name(), "Fred");
+
+        assert_eq!(a.key_compare_less_than(&a), false);
+        assert_eq!(a.key_compare_less_than(&b), false);
+
+        assert_eq!(b.key_compare_less_than(&a), true);
+        assert_eq!(b.key_compare_less_than(&b), false);
+    }
+}
+
+#[cfg(test)]
+mod included_schema_generated_code {
+    extern crate flatbuffers;
+
+    //extern crate rust_usage_test;
+
+    // TODO(rw): make generated sub-namespace files importable
+    //#[test]
+    //fn namespace_test_mod_is_importable() {
+    //    use rust_usage_test::namespace_test;
+    //}
+    //#[test]
+    //fn namespace_test1_mod_is_importable() {
+    //    use rust_usage_test::namespace_test::namespace_test1_generated;
+    //}
+    //#[test]
+    //fn namespace_test2_mod_is_importable() {
+    //    use rust_usage_test::namespace_test::namespace_test2_generated;
+    //}
+}
+
+#[cfg(test)]
+mod builder_asserts {
+    extern crate flatbuffers;
+
+    #[test]
+    #[should_panic]
+    fn end_table_should_panic_when_not_in_table() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.end_table(flatbuffers::WIPOffset::new(0));
+    }
+
+    #[test]
+    #[should_panic]
+    fn create_string_should_panic_when_in_table() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.start_table();
+        b.create_string("foo");
+    }
+
+    #[test]
+    #[should_panic]
+    fn create_byte_string_should_panic_when_in_table() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.start_table();
+        b.create_byte_string(b"foo");
+    }
+
+    #[test]
+    #[should_panic]
+    fn push_struct_slot_should_panic_when_not_in_table() {
+        #[derive(Copy, Clone, Debug, PartialEq)]
+        #[repr(C, packed)]
+        struct foo { }
+        impl<'b> flatbuffers::Push for &'b foo {
+            type Output = foo;
+            fn push<'a>(&'a self, _dst: &'a mut [u8], _rest: &'a [u8]) { }
+        }
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.push_slot_always(0, &foo{});
+    }
+
+    #[test]
+    #[should_panic]
+    fn finished_bytes_should_panic_when_table_is_not_finished() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.start_table();
+        b.finished_data();
+    }
+
+    #[test]
+    #[should_panic]
+    fn required_panics_when_field_not_set() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let start = b.start_table();
+        let o = b.end_table(start);
+        b.required(o, 4 /* byte offset to first field */, "test field");
+    }
+}
+
+#[cfg(test)]
+mod follow_impls {
+    extern crate flatbuffers;
+    use flatbuffers::Follow;
+    use flatbuffers::field_index_to_field_offset as fi2fo;
+
+    // Define a test struct to use in a few tests. This replicates the work that the code generator
+    // would normally do when defining a FlatBuffer struct. For reference, compare the following
+    // `FooStruct` code with the code generated for the `Vec3` struct in
+    // `../../monster_test_generated.rs`.
+    use flatbuffers::EndianScalar;
+    #[derive(Copy, Clone, Debug, PartialEq)]
+    #[repr(C, packed)]
+    struct FooStruct {
+        a: i8,
+        b: u8,
+        c: i16,
+    }
+    impl FooStruct {
+        fn new(_a: i8, _b: u8, _c: i16) -> Self {
+            FooStruct {
+                a: _a.to_little_endian(),
+                b: _b.to_little_endian(),
+                c: _c.to_little_endian(),
+            }
+        }
+    }
+    impl flatbuffers::SafeSliceAccess for FooStruct {}
+    impl<'a> flatbuffers::Follow<'a> for FooStruct {
+        type Inner = &'a FooStruct;
+        #[inline(always)]
+        fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+            <&'a FooStruct>::follow(buf, loc)
+        }
+    }
+    impl<'a> flatbuffers::Follow<'a> for &'a FooStruct {
+        type Inner = &'a FooStruct;
+        #[inline(always)]
+        fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+            flatbuffers::follow_cast_ref::<FooStruct>(buf, loc)
+        }
+    }
+
+    #[test]
+    fn to_u8() {
+        let vec: Vec<u8> = vec![255, 3];
+        let fs: flatbuffers::FollowStart<u8> = flatbuffers::FollowStart::new();
+        assert_eq!(fs.self_follow(&vec[..], 1), 3);
+    }
+
+    #[test]
+    fn to_u16() {
+        let vec: Vec<u8> = vec![255, 255, 3, 4];
+        let fs: flatbuffers::FollowStart<u16> = flatbuffers::FollowStart::new();
+        assert_eq!(fs.self_follow(&vec[..], 2), 1027);
+    }
+
+    #[test]
+    fn to_f32() {
+        let vec: Vec<u8> = vec![255, 255, 255, 255, /* start of value */ 208, 15, 73, 64];
+        let fs: flatbuffers::FollowStart<f32> = flatbuffers::FollowStart::new();
+        assert_eq!(fs.self_follow(&vec[..], 4), 3.14159);
+    }
+
+    #[test]
+    fn to_string() {
+        let vec: Vec<u8> = vec![255,255,255,255, 3, 0, 0, 0, 'f' as u8, 'o' as u8, 'o' as u8, 0];
+        let off: flatbuffers::FollowStart<&str> = flatbuffers::FollowStart::new();
+        assert_eq!(off.self_follow(&vec[..], 4), "foo");
+    }
+
+    #[test]
+    fn to_byte_slice() {
+        let vec: Vec<u8> = vec![255, 255, 255, 255, 4, 0, 0, 0, 1, 2, 3, 4];
+        let off: flatbuffers::FollowStart<flatbuffers::Vector<u8>> = flatbuffers::FollowStart::new();
+        assert_eq!(off.self_follow(&vec[..], 4).safe_slice(), &[1, 2, 3, 4][..]);
+    }
+
+    #[test]
+    fn to_byte_vector() {
+        let vec: Vec<u8> = vec![255, 255, 255, 255, 4, 0, 0, 0, 1, 2, 3, 4];
+        let off: flatbuffers::FollowStart<flatbuffers::Vector<u8>> = flatbuffers::FollowStart::new();
+        assert_eq!(off.self_follow(&vec[..], 4).safe_slice(), &[1, 2, 3, 4][..]);
+    }
+
+    #[test]
+    fn to_byte_string_zero_teriminated() {
+        let vec: Vec<u8> = vec![255, 255, 255, 255, 3, 0, 0, 0, 1, 2, 3, 0];
+        let off: flatbuffers::FollowStart<flatbuffers::Vector<u8>> = flatbuffers::FollowStart::new();
+        assert_eq!(off.self_follow(&vec[..], 4).safe_slice(), &[1, 2, 3][..]);
+    }
+
+    #[cfg(target_endian = "little")]
+    #[test]
+    fn to_slice_of_u16() {
+        let vec: Vec<u8> = vec![255, 255, 255, 255, 2, 0, 0, 0, 1, 2, 3, 4];
+        let off: flatbuffers::FollowStart<&[u16]> = flatbuffers::FollowStart::new();
+        assert_eq!(off.self_follow(&vec[..], 4), &vec![513, 1027][..]);
+    }
+
+    #[test]
+    fn to_vector_of_u16() {
+        let vec: Vec<u8> = vec![255, 255, 255, 255, 2, 0, 0, 0, 1, 2, 3, 4];
+        let off: flatbuffers::FollowStart<flatbuffers::Vector<u16>> = flatbuffers::FollowStart::new();
+        assert_eq!(off.self_follow(&vec[..], 4).len(), 2);
+        assert_eq!(off.self_follow(&vec[..], 4).get(0), 513);
+        assert_eq!(off.self_follow(&vec[..], 4).get(1), 1027);
+    }
+
+    #[test]
+    fn to_struct() {
+        let vec: Vec<u8> = vec![255, 255, 255, 255, 1, 2, 3, 4];
+        let off: flatbuffers::FollowStart<&FooStruct> = flatbuffers::FollowStart::new();
+        assert_eq!(*off.self_follow(&vec[..], 4), FooStruct::new(1, 2, 1027));
+    }
+
+    #[test]
+    fn to_vector_of_offset_to_string_elements() {
+        let buf: Vec<u8> = vec![/* vec len */ 1, 0, 0, 0, /* offset to string */ 4, 0, 0, 0, /* str length */ 3, 0, 0, 0, 'f' as u8, 'o' as u8, 'o' as u8, 0];
+        let s: flatbuffers::FollowStart<flatbuffers::Vector<flatbuffers::ForwardsUOffset<&str>>> = flatbuffers::FollowStart::new();
+        assert_eq!(s.self_follow(&buf[..], 0).len(), 1);
+        assert_eq!(s.self_follow(&buf[..], 0).get(0), "foo");
+    }
+
+    #[test]
+    fn to_slice_of_struct_elements() {
+        let buf: Vec<u8> = vec![1, 0, 0, 0, /* struct data */ 1, 2, 3, 4];
+        let fs: flatbuffers::FollowStart<flatbuffers::Vector<FooStruct>> = flatbuffers::FollowStart::new();
+        assert_eq!(fs.self_follow(&buf[..], 0).safe_slice(), &vec![FooStruct::new(1, 2, 1027)][..]);
+    }
+
+    #[test]
+    fn to_vector_of_struct_elements() {
+        let buf: Vec<u8> = vec![1, 0, 0, 0, /* struct data */ 1, 2, 3, 4];
+        let fs: flatbuffers::FollowStart<flatbuffers::Vector<FooStruct>> = flatbuffers::FollowStart::new();
+        assert_eq!(fs.self_follow(&buf[..], 0).len(), 1);
+        assert_eq!(fs.self_follow(&buf[..], 0).get(0), &FooStruct::new(1, 2, 1027));
+    }
+
+    #[test]
+    fn to_root_to_empty_table() {
+        let buf: Vec<u8> = vec![
+            12, 0, 0, 0, // offset to root table
+            // enter vtable
+            4, 0, // vtable len
+            0, 0, // inline size
+            255, 255, 255, 255, // canary
+            // enter table
+            8, 0, 0, 0, // vtable location
+        ];
+        let fs: flatbuffers::FollowStart<flatbuffers::ForwardsUOffset<flatbuffers::Table>> = flatbuffers::FollowStart::new();
+        assert_eq!(fs.self_follow(&buf[..], 0), flatbuffers::Table::new(&buf[..], 12));
+    }
+
+    #[test]
+    fn to_root_table_get_slot_scalar_u8() {
+        let buf: Vec<u8> = vec![
+            14, 0, 0, 0, // offset to root table
+            // enter vtable
+            6, 0, // vtable len
+            2, 0, // inline size
+            5, 0, // value loc
+            255, 255, 255, 255, // canary
+            // enter table
+            10, 0, 0, 0, // vtable location
+            0, 99 // value (with padding)
+        ];
+        let fs: flatbuffers::FollowStart<flatbuffers::ForwardsUOffset<flatbuffers::Table>> = flatbuffers::FollowStart::new();
+        let tab = fs.self_follow(&buf[..], 0);
+        assert_eq!(tab.get::<u8>(fi2fo(0), Some(123)), Some(99));
+    }
+
+    #[test]
+    fn to_root_to_table_get_slot_scalar_u8_default_via_vtable_len() {
+        let buf: Vec<u8> = vec![
+            12, 0, 0, 0, // offset to root table
+            // enter vtable
+            4, 0, // vtable len
+            2, 0, // inline size
+            255, 255, 255, 255, // canary
+            // enter table
+            8, 0, 0, 0, // vtable location
+        ];
+        let fs: flatbuffers::FollowStart<flatbuffers::ForwardsUOffset<flatbuffers::Table>> = flatbuffers::FollowStart::new();
+        let tab = fs.self_follow(&buf[..], 0);
+        assert_eq!(tab.get::<u8>(fi2fo(0), Some(123)), Some(123));
+    }
+
+    #[test]
+    fn to_root_to_table_get_slot_scalar_u8_default_via_vtable_zero() {
+        let buf: Vec<u8> = vec![
+            14, 0, 0, 0, // offset to root table
+            // enter vtable
+            6, 0, // vtable len
+            2, 0, // inline size
+            0, 0, // zero means use the default value
+            255, 255, 255, 255, // canary
+            // enter table
+            10, 0, 0, 0, // vtable location
+        ];
+        let fs: flatbuffers::FollowStart<flatbuffers::ForwardsUOffset<flatbuffers::Table>> = flatbuffers::FollowStart::new();
+        let tab = fs.self_follow(&buf[..], 0);
+        assert_eq!(tab.get::<u8>(fi2fo(0), Some(123)), Some(123));
+    }
+
+    #[test]
+    fn to_root_to_table_get_slot_string_multiple_types() {
+        let buf: Vec<u8> = vec![
+            14, 0, 0, 0, // offset to root table
+            // enter vtable
+            6, 0, // vtable len
+            2, 0, // inline size
+            4, 0, // value loc
+            255, 255, 255, 255, // canary
+            // enter table
+            10, 0, 0, 0, // vtable location
+            8, 0, 0, 0, // offset to string
+            // leave table
+            255, 255, 255, 255, // canary
+            // enter string
+            3, 0, 0, 0, 109, 111, 111, 0 // string length and contents
+        ];
+        let tab = <flatbuffers::ForwardsUOffset<flatbuffers::Table>>::follow(&buf[..], 0);
+        assert_eq!(tab.get::<flatbuffers::ForwardsUOffset<&str>>(fi2fo(0), None), Some("moo"));
+        let byte_vec = tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<u8>>>(fi2fo(0), None).unwrap().safe_slice();
+        assert_eq!(byte_vec, &vec![109, 111, 111][..]);
+        let v = tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<u8>>>(fi2fo(0), None).unwrap();
+        assert_eq!(v.len(), 3);
+        assert_eq!(v.get(0), 109);
+        assert_eq!(v.get(1), 111);
+        assert_eq!(v.get(2), 111);
+    }
+
+    #[test]
+    fn to_root_to_table_get_slot_string_multiple_types_default_via_vtable_len() {
+        let buf: Vec<u8> = vec![
+            12, 0, 0, 0, // offset to root table
+            // enter vtable
+            4, 0, // vtable len
+            4, 0, // table inline len
+            255, 255, 255, 255, // canary
+            // enter table
+            8, 0, 0, 0, // vtable location
+        ];
+        let tab = <flatbuffers::ForwardsUOffset<flatbuffers::Table>>::follow(&buf[..], 0);
+        assert_eq!(tab.get::<flatbuffers::ForwardsUOffset<&str>>(fi2fo(0), Some("abc")), Some("abc"));
+        #[cfg(target_endian = "little")]
+        {
+            assert_eq!(tab.get::<flatbuffers::ForwardsUOffset<&[u8]>>(fi2fo(0), Some(&vec![70, 71, 72][..])), Some(&vec![70, 71, 72][..]));
+        }
+
+        let default_vec_buf: Vec<u8> = vec![3, 0, 0, 0, 70, 71, 72, 0];
+        let default_vec = flatbuffers::Vector::new(&default_vec_buf[..], 0);
+        let v = tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<u8>>>(fi2fo(0), Some(default_vec)).unwrap();
+        assert_eq!(v.len(), 3);
+        assert_eq!(v.get(0), 70);
+        assert_eq!(v.get(1), 71);
+        assert_eq!(v.get(2), 72);
+    }
+
+    #[test]
+    fn to_root_to_table_get_slot_string_multiple_types_default_via_vtable_zero() {
+        let buf: Vec<u8> = vec![
+            14, 0, 0, 0, // offset to root table
+            // enter vtable
+            6, 0, // vtable len
+            2, 0, // inline size
+            0, 0, // value loc
+            255, 255, 255, 255, // canary
+            // enter table
+            10, 0, 0, 0, // vtable location
+        ];
+        let tab = <flatbuffers::ForwardsUOffset<flatbuffers::Table>>::follow(&buf[..], 0);
+        assert_eq!(tab.get::<flatbuffers::ForwardsUOffset<&str>>(fi2fo(0), Some("abc")), Some("abc"));
+        #[cfg(target_endian = "little")]
+        {
+            assert_eq!(tab.get::<flatbuffers::ForwardsUOffset<&[u8]>>(fi2fo(0), Some(&vec![70, 71, 72][..])), Some(&vec![70, 71, 72][..]));
+        }
+
+        let default_vec_buf: Vec<u8> = vec![3, 0, 0, 0, 70, 71, 72, 0];
+        let default_vec = flatbuffers::Vector::new(&default_vec_buf[..], 0);
+        let v = tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<u8>>>(fi2fo(0), Some(default_vec)).unwrap();
+        assert_eq!(v.len(), 3);
+        assert_eq!(v.get(0), 70);
+        assert_eq!(v.get(1), 71);
+        assert_eq!(v.get(2), 72);
+    }
+}
+
+#[cfg(test)]
+mod push_impls {
+    extern crate flatbuffers;
+
+    use super::my_game;
+
+    fn check<'a>(b: &'a flatbuffers::FlatBufferBuilder, want: &'a [u8]) {
+        let got = b.unfinished_data();
+        assert_eq!(want, got);
+    }
+
+    #[test]
+    fn push_u8() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.push(123u8);
+        check(&b, &[123]);
+    }
+
+    #[test]
+    fn push_u64() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.push(0x12345678);
+        check(&b, &[0x78, 0x56, 0x34, 0x12]);
+    }
+
+    #[test]
+    fn push_f64() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.push(3.14159265359f64);
+        check(&b, &[234, 46, 68, 84, 251, 33, 9, 64]);
+    }
+
+    #[test]
+    fn push_generated_struct() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.push(my_game::example::Test::new(10, 20));
+        check(&b, &[10, 0, 20, 0]);
+    }
+
+    #[test]
+    fn push_u8_vector_with_offset_with_alignment() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let off = b.create_vector(&[1u8, 2, 3, 4, 5, 6, 7, 8, 9][..]);
+        b.push(off);
+        check(&b, &[/* loc */ 4, 0, 0, 0, /* len */ 9, 0, 0, 0, /* val */ 1, 2, 3, 4, 5, 6, 7, 8, 9, /* padding */ 0, 0, 0]);
+    }
+
+    #[test]
+    fn push_u8_u16_alignment() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.push(1u8);
+        b.push(2u16);
+        check(&b, &[2, 0, 0, 1]);
+    }
+
+    #[test]
+    fn push_u8_u32_alignment() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.push(1u8);
+        b.push(2u32);
+        check(&b, &[2, 0, 0, 0, 0, 0, 0, 1]);
+    }
+
+    #[test]
+    fn push_u8_u64_alignment() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.push(1u8);
+        b.push(2u64);
+        check(&b, &[2, 0, 0, 0,
+                    0, 0, 0, 0,
+                    0, 0, 0, 0,
+                    0, 0, 0, 1]);
+    }
+}
+
+#[cfg(test)]
+mod vtable_deduplication {
+    extern crate flatbuffers;
+    use flatbuffers::field_index_to_field_offset as fi2fo;
+
+    fn check<'a>(b: &'a flatbuffers::FlatBufferBuilder, want: &'a [u8]) {
+        let got = b.unfinished_data();
+        assert_eq!(want, got);
+    }
+
+    #[test]
+    fn one_empty_table() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let start0 = b.start_table();
+        b.end_table(start0);
+        check(&b, &[
+              4, 0, // vtable size in bytes
+              4, 0, // object inline data in bytes
+
+              4, 0, 0, 0, // backwards offset to vtable
+        ]);
+    }
+
+    #[test]
+    fn two_empty_tables_are_deduplicated() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let start0 = b.start_table();
+        b.end_table(start0);
+        let start1 = b.start_table();
+        b.end_table(start1);
+        check(&b, &[
+              252, 255, 255, 255, // forwards offset to vtable
+
+              4, 0, // vtable size in bytes
+              4, 0, // object inline data in bytes
+
+              4, 0, 0, 0, // backwards offset to vtable
+        ]);
+    }
+
+    #[test]
+    fn two_tables_with_two_conveniently_sized_inline_elements_are_deduplicated() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let start0 = b.start_table();
+        b.push_slot::<u64>(fi2fo(0), 100, 0);
+        b.push_slot::<u32>(fi2fo(1), 101, 0);
+        b.end_table(start0);
+        let start1 = b.start_table();
+        b.push_slot::<u64>(fi2fo(0), 200, 0);
+        b.push_slot::<u32>(fi2fo(1), 201, 0);
+        b.end_table(start1);
+        check(&b, &[
+              240, 255, 255, 255, // forwards offset to vtable
+
+              201, 0, 0, 0, // value #1
+              200, 0, 0, 0, 0, 0, 0, 0, // value #0
+
+              8, 0, // vtable size in bytes
+              16, 0, // object inline data in bytes
+              8, 0, // offset in object for value #0
+              4, 0, // offset in object for value #1
+
+              8, 0, 0, 0, // backwards offset to vtable
+              101, 0, 0, 0, // value #1
+              100, 0, 0, 0, 0, 0, 0, 0 // value #0
+        ]);
+    }
+
+    #[test]
+    fn many_identical_tables_use_few_vtables() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        for _ in 0..1000 {
+            let start = b.start_table();
+            b.push_slot::<u8>(fi2fo(0), 100, 0);
+            b.push_slot::<u32>(fi2fo(1), 101, 0);
+            b.end_table(start);
+        }
+        assert!(b.num_written_vtables() <= 10);
+    }
+}
+
+#[cfg(test)]
+mod byte_layouts {
+    extern crate flatbuffers;
+    use flatbuffers::field_index_to_field_offset as fi2fo;
+
+    fn check<'a>(b: &'a flatbuffers::FlatBufferBuilder, want: &'a [u8]) {
+        let got = b.unfinished_data();
+        assert_eq!(want, got);
+    }
+
+    #[test]
+    fn layout_01_basic_numbers() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.push(true);
+        check(&b, &[1]);
+        b.push(-127i8);
+        check(&b, &[129, 1]);
+        b.push(255u8);
+        check(&b, &[255, 129, 1]);
+        b.push(-32222i16);
+        check(&b, &[0x22, 0x82, 0, 255, 129, 1]); // first pad
+        b.push(0xFEEEu16);
+        check(&b, &[0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1]); // no pad this time
+        b.push(-53687092i32);
+        check(&b, &[204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1]);
+        b.push(0x98765432u32);
+        check(&b, &[0x32, 0x54, 0x76, 0x98, 204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1]);
+    }
+
+    #[test]
+    fn layout_01b_bigger_numbers() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.push(0x1122334455667788u64);
+        check(&b, &[0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11]);
+    }
+
+    #[test]
+    fn layout_02_1xbyte_vector() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        check(&b, &[]);
+        b.start_vector::<u8>(1);
+        check(&b, &[0, 0, 0]); // align to 4bytes
+        b.push(1u8);
+        check(&b, &[1, 0, 0, 0]);
+        b.end_vector::<u8>(1);
+        check(&b, &[1, 0, 0, 0, 1, 0, 0, 0]); // padding
+    }
+
+    #[test]
+    fn layout_03_2xbyte_vector() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.start_vector::<u8>(2);
+        check(&b, &[0, 0]); // align to 4bytes
+        b.push(1u8);
+        check(&b, &[1, 0, 0]);
+        b.push(2u8);
+        check(&b, &[2, 1, 0, 0]);
+        b.end_vector::<u8>(2);
+        check(&b, &[2, 0, 0, 0, 2, 1, 0, 0]); // padding
+    }
+
+    #[test]
+    fn layout_03b_11xbyte_vector_matches_builder_size() {
+        let mut b = flatbuffers::FlatBufferBuilder::new_with_capacity(12);
+        b.start_vector::<u8>(8);
+
+        let mut gold = vec![0u8; 0];
+        check(&b, &gold[..]);
+
+        for i in 1u8..=8 {
+            b.push(i);
+            gold.insert(0, i);
+            check(&b, &gold[..]);
+        }
+        b.end_vector::<u8>(8);
+        let want = vec![8u8, 0, 0, 0,  8, 7, 6, 5, 4, 3, 2, 1];
+        check(&b, &want[..]);
+    }
+    #[test]
+    fn layout_04_1xuint16_vector() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.start_vector::<u16>(1);
+        check(&b, &[0, 0]); // align to 4bytes
+        b.push(1u16);
+        check(&b, &[1, 0, 0, 0]);
+        b.end_vector::<u16>(1);
+        check(&b, &[1, 0, 0, 0, 1, 0, 0, 0]); // padding
+    }
+
+    #[test]
+    fn layout_05_2xuint16_vector() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let _off = b.start_vector::<u16>(2);
+        check(&b, &[]); // align to 4bytes
+        b.push(0xABCDu16);
+        check(&b, &[0xCD, 0xAB]);
+        b.push(0xDCBAu16);
+        check(&b, &[0xBA, 0xDC, 0xCD, 0xAB]);
+        b.end_vector::<u16>(2);
+        check(&b, &[2, 0, 0, 0, 0xBA, 0xDC, 0xCD, 0xAB]);
+    }
+
+    #[test]
+    fn layout_06_create_string() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let off0 = b.create_string("foo");
+        assert_eq!(8, off0.value());
+        check(&b, b"\x03\x00\x00\x00foo\x00"); // 0-terminated, no pad
+        let off1 = b.create_string("moop");
+        assert_eq!(20, off1.value());
+        check(&b, b"\x04\x00\x00\x00moop\x00\x00\x00\x00\
+                    \x03\x00\x00\x00foo\x00"); // 0-terminated, 3-byte pad
+    }
+
+    #[test]
+    fn layout_06b_create_string_unicode() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        // These characters are chinese from blog.golang.org/strings
+        // We use escape codes here so that editors without unicode support
+        // aren't bothered:
+        let uni_str = "\u{65e5}\u{672c}\u{8a9e}";
+        let off0 = b.create_string(uni_str);
+        assert_eq!(16, off0.value());
+        check(&b, &[9, 0, 0, 0, 230, 151, 165, 230, 156, 172, 232, 170, 158, 0, //  null-terminated, 2-byte pad
+                    0, 0]);
+    }
+
+    #[test]
+    fn layout_06c_create_byte_string() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let off0 = b.create_byte_string(b"foo");
+        assert_eq!(8, off0.value());
+        check(&b, b"\x03\x00\x00\x00foo\x00"); // 0-terminated, no pad
+        let off1 = b.create_byte_string(b"moop");
+        assert_eq!(20, off1.value());
+        check(&b, b"\x04\x00\x00\x00moop\x00\x00\x00\x00\
+                    \x03\x00\x00\x00foo\x00"); // 0-terminated, 3-byte pad
+    }
+
+    #[test]
+    fn layout_07_empty_vtable() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let off0 = b.start_table();
+        check(&b, &[]);
+        b.end_table(off0);
+        check(&b, &[4, 0, // vtable length
+                    4, 0, // length of table including vtable offset
+                    4, 0, 0, 0]); // offset for start of vtable
+    }
+
+    #[test]
+    fn layout_08_vtable_with_one_true_bool() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        check(&b, &[]);
+        let off0 = b.start_table();
+        assert_eq!(0, off0.value());
+        check(&b, &[]);
+        b.push_slot(fi2fo(0), true, false);
+        check(&b, &[1]);
+        let off1 = b.end_table(off0);
+        assert_eq!(8, off1.value());
+        check(&b, &[
+              6, 0, // vtable bytes
+              8, 0, // length of object including vtable offset
+              7, 0, // start of bool value
+              6, 0, 0, 0, // offset for start of vtable (int32)
+              0, 0, 0, // padded to 4 bytes
+              1, // bool value
+        ]);
+    }
+
+    #[test]
+    fn layout_09_vtable_with_one_default_bool() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        check(&b, &[]);
+        let off = b.start_table();
+        check(&b, &[]);
+        b.push_slot(fi2fo(0), false, false);
+        b.end_table(off);
+        check(&b, &[
+             4, 0, // vtable bytes
+             4, 0, // end of object from here
+             // entry 1 is zero and not stored.
+             4, 0, 0, 0, // offset for start of vtable (int32)
+        ]);
+    }
+
+    #[test]
+    fn layout_10_vtable_with_one_int16() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        check(&b, &[]);
+        let off = b.start_table();
+        b.push_slot(fi2fo(0), 0x789Ai16, 0);
+        b.end_table(off);
+        check(&b, &[
+              6, 0, // vtable bytes
+              8, 0, // end of object from here
+              6, 0, // offset to value
+              6, 0, 0, 0, // offset for start of vtable (int32)
+              0, 0, // padding to 4 bytes
+              0x9A, 0x78,
+        ]);
+    }
+
+    #[test]
+    fn layout_11_vtable_with_two_int16() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let off = b.start_table();
+        b.push_slot(fi2fo(0), 0x3456i16, 0);
+        b.push_slot(fi2fo(1), 0x789Ai16, 0);
+        b.end_table(off);
+        check(&b, &[
+              8, 0, // vtable bytes
+              8, 0, // end of object from here
+              6, 0, // offset to value 0
+              4, 0, // offset to value 1
+              8, 0, 0, 0, // offset for start of vtable (int32)
+              0x9A, 0x78, // value 1
+              0x56, 0x34, // value 0
+        ]);
+    }
+
+    #[test]
+    fn layout_12_vtable_with_int16_and_bool() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let off = b.start_table();
+        b.push_slot(fi2fo(0), 0x3456i16, 0);
+        b.push_slot(fi2fo(1), true, false);
+        b.end_table(off);
+        check(&b, &[
+            8, 0, // vtable bytes
+            8, 0, // end of object from here
+            6, 0, // offset to value 0
+            5, 0, // offset to value 1
+            8, 0, 0, 0, // offset for start of vtable (int32)
+            0,          // padding
+            1,          // value 1
+            0x56, 0x34, // value 0
+        ]);
+    }
+
+    #[test]
+    fn layout_12b_vtable_with_empty_vector() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.start_vector::<u8>(0);
+        let vecend = b.end_vector::<u8>(0);
+        let off = b.start_table();
+        b.push_slot_always(fi2fo(0), vecend);
+        b.end_table(off);
+        check(&b, &[
+              6, 0, // vtable bytes
+              8, 0,
+              4, 0, // offset to vector offset
+              6, 0, 0, 0, // offset for start of vtable (int32)
+              4, 0, 0, 0,
+              0, 0, 0, 0, // length of vector (not in struct)
+        ]);
+    }
+
+    #[test]
+    fn layout_12c_vtable_with_empty_vector_of_byte_and_some_scalars() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.start_vector::<u8>(0);
+        let vecend = b.end_vector::<u8>(0);
+        let off = b.start_table();
+        b.push_slot::<i16>(fi2fo(0), 55i16, 0);
+        b.push_slot_always::<flatbuffers::WIPOffset<_>>(fi2fo(1), vecend);
+        b.end_table(off);
+        check(&b, &[
+              8, 0, // vtable bytes
+              12, 0,
+              10, 0, // offset to value 0
+              4, 0, // offset to vector offset
+              8, 0, 0, 0, // vtable loc
+              8, 0, 0, 0, // value 1
+              0, 0, 55, 0, // value 0
+
+              0, 0, 0, 0, // length of vector (not in struct)
+        ]);
+    }
+    #[test]
+    fn layout_13_vtable_with_1_int16_and_2_vector_of_i16() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.start_vector::<i16>(2);
+        b.push(0x1234i16);
+        b.push(0x5678i16);
+        let vecend = b.end_vector::<i16>(2);
+        let off = b.start_table();
+        b.push_slot_always(fi2fo(1), vecend);
+        b.push_slot(fi2fo(0), 55i16, 0);
+        b.end_table(off);
+        check(&b, &[
+              8, 0, // vtable bytes
+              12, 0, // length of object
+              6, 0, // start of value 0 from end of vtable
+              8, 0, // start of value 1 from end of buffer
+              8, 0, 0, 0, // offset for start of vtable (int32)
+              0, 0, // padding
+              55, 0, // value 0
+              4, 0, 0, 0, // vector position from here
+              2, 0, 0, 0, // length of vector (uint32)
+              0x78, 0x56, // vector value 1
+              0x34, 0x12, // vector value 0
+        ]);
+    }
+    #[test]
+    fn layout_14_vtable_with_1_struct_of_int8_and_int16_and_int32() {
+        #[derive(Copy, Clone, Debug, Eq, PartialEq)]
+        #[repr(C, packed)]
+        struct foo {
+            a: i32,
+            _pad0: [u8; 2],
+            b: i16,
+            _pad1: [u8; 3],
+            c: i8,
+            _pad2: [u8; 4],
+        }
+        assert_eq!(::std::mem::size_of::<foo>(), 16);
+        impl<'b> flatbuffers::Push for &'b foo {
+            type Output = foo;
+            fn push<'a>(&'a self, dst: &'a mut [u8], _rest: &'a [u8]) {
+                let src = unsafe {
+                    ::std::slice::from_raw_parts(*self as *const foo as *const u8, ::std::mem::size_of::<foo>())
+                };
+                dst.copy_from_slice(src);
+            }
+        }
+
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let off = b.start_table();
+        let x = foo{a: 0x12345678i32.to_le(), _pad0: [0,0], b: 0x1234i16.to_le(), _pad1: [0, 0, 0], c: 0x12i8.to_le(), _pad2: [0, 0, 0, 0]};
+        b.push_slot_always(fi2fo(0), &x);
+        b.end_table(off);
+        check(&b, &[
+              6, 0, // vtable bytes
+              20, 0, // end of object from here
+              4, 0, // start of struct from here
+              6, 0, 0, 0, // offset for start of vtable (int32)
+
+              0x78, 0x56, 0x34, 0x12, // value a
+              0, 0, // padding
+              0x34, 0x12, // value b
+              0, 0, 0, // padding
+              0x12, // value c
+              0, 0, 0, 0, // padding
+        ]);
+    }
+    #[test]
+    fn layout_15_vtable_with_1_vector_of_4_int8() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.start_vector::<i8>(4);
+        b.push(33i8);
+        b.push(44i8);
+        b.push(55i8);
+        b.push(66i8);
+        let vecend = b.end_vector::<i8>(4);
+        let off = b.start_table();
+        b.push_slot_always(fi2fo(0), vecend);
+        b.end_table(off);
+        check(&b, &[
+              6, 0, // vtable bytes
+              8, 0,
+              4, 0, // offset of vector offset
+              6, 0, 0, 0, // offset for start of vtable (int32)
+              4, 0, 0, 0, // vector start offset
+
+              4, 0, 0, 0, // vector length
+              66, // vector value 1,1
+              55, // vector value 1,0
+              44, // vector value 0,1
+              33, // vector value 0,0
+        ]);
+    }
+
+    #[test]
+    fn layout_16_table_with_some_elements() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let off = b.start_table();
+        b.push_slot(fi2fo(0), 33i8, 0);
+        b.push_slot(fi2fo(1), 66i16, 0);
+        let off2 = b.end_table(off);
+        b.finish_minimal(off2);
+
+        check(&b, &[
+              12, 0, 0, 0, // root of table: points to vtable offset
+
+              8, 0, // vtable bytes
+              8, 0, // end of object from here
+              7, 0, // start of value 0
+              4, 0, // start of value 1
+
+              8, 0, 0, 0, // offset for start of vtable (int32)
+
+              66, 0, // value 1
+              0,  // padding
+              33, // value 0
+        ]);
+    }
+
+    #[test]
+    fn layout_17_one_unfinished_table_and_one_finished_table() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        {
+            let off = b.start_table();
+            b.push_slot(fi2fo(0), 33i8, 0);
+            b.push_slot(fi2fo(1), 44i8, 0);
+            b.end_table(off);
+        }
+
+        {
+            let off = b.start_table();
+            b.push_slot(fi2fo(0), 55i8, 0);
+            b.push_slot(fi2fo(1), 66i8, 0);
+            b.push_slot(fi2fo(2), 77i8, 0);
+            let off2 = b.end_table(off);
+            b.finish_minimal(off2);
+        }
+
+        check(&b, &[
+              16, 0, 0, 0, // root of table: points to object
+              0, 0, // padding
+
+              10, 0, // vtable bytes
+              8, 0, // size of object
+              7, 0, // start of value 0
+              6, 0, // start of value 1
+              5, 0, // start of value 2
+              10, 0, 0, 0, // offset for start of vtable (int32)
+              0,  // padding
+              77, // value 2
+              66, // value 1
+              55, // value 0
+
+              //12, 0, 0, 0, // root of table: points to object
+
+              8, 0, // vtable bytes
+              8, 0, // size of object
+              7, 0, // start of value 0
+              6, 0, // start of value 1
+              8, 0, 0, 0, // offset for start of vtable (int32)
+              0, 0, // padding
+              44, // value 1
+              33, // value 0
+              ]);
+    }
+
+    #[test]
+    fn layout_18_a_bunch_of_bools() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let off = b.start_table();
+        b.push_slot(fi2fo(0), true, false);
+        b.push_slot(fi2fo(1), true, false);
+        b.push_slot(fi2fo(2), true, false);
+        b.push_slot(fi2fo(3), true, false);
+        b.push_slot(fi2fo(4), true, false);
+        b.push_slot(fi2fo(5), true, false);
+        b.push_slot(fi2fo(6), true, false);
+        b.push_slot(fi2fo(7), true, false);
+        let off2 = b.end_table(off);
+        b.finish_minimal(off2);
+
+        check(&b, &[
+              24, 0, 0, 0, // root of table: points to vtable offset
+
+              20, 0, // vtable bytes
+              12, 0, // size of object
+              11, 0, // start of value 0
+              10, 0, // start of value 1
+              9, 0, // start of value 2
+              8, 0, // start of value 3
+              7, 0, // start of value 4
+              6, 0, // start of value 5
+              5, 0, // start of value 6
+              4, 0, // start of value 7
+              20, 0, 0, 0, // vtable offset
+
+              1, // value 7
+              1, // value 6
+              1, // value 5
+              1, // value 4
+              1, // value 3
+              1, // value 2
+              1, // value 1
+              1, // value 0
+              ]);
+    }
+
+    #[test]
+    fn layout_19_three_bools() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let off = b.start_table();
+        b.push_slot(fi2fo(0), true, false);
+        b.push_slot(fi2fo(1), true, false);
+        b.push_slot(fi2fo(2), true, false);
+        let off2 = b.end_table(off);
+        b.finish_minimal(off2);
+
+        check(&b, &[
+              16, 0, 0, 0, // root of table: points to vtable offset
+
+              0, 0, // padding
+
+              10, 0, // vtable bytes
+              8, 0, // size of object
+              7, 0, // start of value 0
+              6, 0, // start of value 1
+              5, 0, // start of value 2
+              10, 0, 0, 0, // vtable offset from here
+
+              0, // padding
+              1, // value 2
+              1, // value 1
+              1, // value 0
+        ]);
+    }
+
+    #[test]
+    fn layout_20_some_floats() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let off = b.start_table();
+        b.push_slot(fi2fo(0), 1.0f32, 0.0);
+        b.end_table(off);
+
+        check(&b, &[
+              6, 0, // vtable bytes
+              8, 0, // size of object
+              4, 0, // start of value 0
+              6, 0, 0, 0, // vtable offset
+
+              0, 0, 128, 63, // value 0
+        ]);
+    }
+
+    #[test]
+    fn layout_21_vtable_defaults() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let off = b.start_table();
+        b.push_slot::<i8>(fi2fo(0), 1, 1);
+        b.push_slot::<i8>(fi2fo(1), 3, 2);
+        b.push_slot::<i8>(fi2fo(2), 3, 3);
+        b.end_table(off);
+        check(&b, &[
+              8, 0, // vtable size in bytes
+              8, 0, // object inline data in bytes
+              0, 0, // entry 1/3: 0 => default
+              7, 0, // entry 2/3: 7 => table start + 7 bytes
+              // entry 3/3: not present => default
+              8, 0, 0, 0,
+              0, 0, 0,
+              3,
+        ]);
+    }
+
+    #[test]
+    fn layout_22_root() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let off = b.start_table();
+        // skipped: b.push_slot_scalar::<i16>(0, 1, 1);
+        b.push_slot::<i16>(fi2fo(1), 3, 2);
+        b.push_slot::<i16>(fi2fo(2), 3, 3);
+        let table_end = b.end_table(off);
+        b.finish_minimal(table_end);
+        check(&b, &[
+              12, 0, 0, 0, // root
+
+              8, 0, // vtable size in bytes
+              8, 0, // object inline data in bytes
+              0, 0, // entry 1/3: 0 => default
+              6, 0, // entry 2/3: 6 => table start + 6 bytes
+              // entry 3/3: not present => default
+              8, 0, 0, 0, // size of table data in bytes
+              0, 0, // padding
+              3, 0, // value 2/3
+        ]);
+    }
+    #[test]
+    fn layout_23_varied_slots_and_root() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let off = b.start_table();
+        b.push_slot::<i16>(fi2fo(0), 1, 0);
+        b.push_slot::<u8>(fi2fo(1), 2, 0);
+        b.push_slot::<f32>(fi2fo(2), 3.0, 0.0);
+        let table_end = b.end_table(off);
+        b.finish_minimal(table_end);
+        check(&b, &[
+              16, 0, 0, 0, // root
+              0, 0, // padding
+              10, 0, // vtable bytes
+              12, 0, // object inline data size
+              10, 0, // offset to value #1 (i16)
+              9, 0, // offset to value #2 (u8)
+              4, 0, // offset to value #3 (f32)
+              10, 0, // offset to vtable
+              0, 0, // padding
+              0, 0, 64, 64, // value #3 => 3.0 (float32)
+              0, 2, // value #1 => 2 (u8)
+              1, 0, // value #0 => 1 (int16)
+        ]);
+    }
+}
+
+// this is not technically a test, but we want to always keep this generated
+// file up-to-date, and the simplest way to do that is to make sure that when
+// tests are run, the file is generated.
+#[test]
+fn write_example_wire_data_to_file() {
+    let b = &mut flatbuffers::FlatBufferBuilder::new();
+    create_serialized_example_with_generated_code(b);
+
+    use ::std::io::Write;
+    let mut f = std::fs::File::create("../monsterdata_rust_wire.mon").unwrap();
+    f.write_all(b.finished_data()).unwrap();
+}
+
+fn load_file(filename: &str) -> Result<Vec<u8>, std::io::Error> {
+    use std::io::Read;
+    let mut f = std::fs::File::open(filename)?;
+    let mut buf = Vec::new();
+    f.read_to_end(&mut buf)?;
+    Ok(buf)
+}
diff --git a/tests/test.cpp b/tests/test.cpp
new file mode 100644
index 0000000..461840c
--- /dev/null
+++ b/tests/test.cpp
@@ -0,0 +1,3068 @@
+/*
+ * 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.
+ */
+#include <cmath>
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/idl.h"
+#include "flatbuffers/minireflect.h"
+#include "flatbuffers/registry.h"
+#include "flatbuffers/util.h"
+
+// clang-format off
+#ifdef FLATBUFFERS_CPP98_STL
+  #include "flatbuffers/stl_emulation.h"
+  namespace std {
+    using flatbuffers::unique_ptr;
+  }
+#endif
+// clang-format on
+
+#include "monster_test_generated.h"
+#include "namespace_test/namespace_test1_generated.h"
+#include "namespace_test/namespace_test2_generated.h"
+#include "union_vector/union_vector_generated.h"
+#include "monster_extra_generated.h"
+#if !defined(_MSC_VER) || _MSC_VER >= 1700
+#include "arrays_test_generated.h"
+#endif
+
+#include "native_type_test_generated.h"
+#include "test_assert.h"
+
+#include "flatbuffers/flexbuffers.h"
+
+
+// clang-format off
+// Check that char* and uint8_t* are interoperable types.
+// The reinterpret_cast<> between the pointers are used to simplify data loading.
+static_assert(flatbuffers::is_same<uint8_t, char>::value ||
+              flatbuffers::is_same<uint8_t, unsigned char>::value,
+              "unexpected uint8_t type");
+
+#if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
+  // Ensure IEEE-754 support if tests of floats with NaN/Inf will run.
+  static_assert(std::numeric_limits<float>::is_iec559 &&
+                std::numeric_limits<double>::is_iec559,
+                "IEC-559 (IEEE-754) standard required");
+#endif
+// clang-format on
+
+// Shortcuts for the infinity.
+static const auto infinityf = std::numeric_limits<float>::infinity();
+static const auto infinityd = std::numeric_limits<double>::infinity();
+
+using namespace MyGame::Example;
+
+void FlatBufferBuilderTest();
+
+// Include simple random number generator to ensure results will be the
+// same cross platform.
+// http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator
+uint32_t lcg_seed = 48271;
+uint32_t lcg_rand() {
+  return lcg_seed = (static_cast<uint64_t>(lcg_seed) * 279470273UL) % 4294967291UL;
+}
+void lcg_reset() { lcg_seed = 48271; }
+
+std::string test_data_path =
+#ifdef BAZEL_TEST_DATA_PATH
+    "../com_github_google_flatbuffers/tests/";
+#else
+    "tests/";
+#endif
+
+// example of how to build up a serialized buffer algorithmically:
+flatbuffers::DetachedBuffer CreateFlatBufferTest(std::string &buffer) {
+  flatbuffers::FlatBufferBuilder builder;
+
+  auto vec = Vec3(1, 2, 3, 0, Color_Red, Test(10, 20));
+
+  auto name = builder.CreateString("MyMonster");
+
+  unsigned char inv_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+  auto inventory = builder.CreateVector(inv_data, 10);
+
+  // Alternatively, create the vector first, and fill in data later:
+  // unsigned char *inv_buf = nullptr;
+  // auto inventory = builder.CreateUninitializedVector<unsigned char>(
+  //                                                              10, &inv_buf);
+  // memcpy(inv_buf, inv_data, 10);
+
+  Test tests[] = { Test(10, 20), Test(30, 40) };
+  auto testv = builder.CreateVectorOfStructs(tests, 2);
+
+  // clang-format off
+  #ifndef FLATBUFFERS_CPP98_STL
+    // Create a vector of structures from a lambda.
+    auto testv2 = builder.CreateVectorOfStructs<Test>(
+          2, [&](size_t i, Test* s) -> void {
+            *s = tests[i];
+          });
+  #else
+    // Create a vector of structures using a plain old C++ function.
+    auto testv2 = builder.CreateVectorOfStructs<Test>(
+          2, [](size_t i, Test* s, void *state) -> void {
+            *s = (reinterpret_cast<Test*>(state))[i];
+          }, tests);
+  #endif  // FLATBUFFERS_CPP98_STL
+  // clang-format on
+
+  // create monster with very few fields set:
+  // (same functionality as CreateMonster below, but sets fields manually)
+  flatbuffers::Offset<Monster> mlocs[3];
+  auto fred = builder.CreateString("Fred");
+  auto barney = builder.CreateString("Barney");
+  auto wilma = builder.CreateString("Wilma");
+  MonsterBuilder mb1(builder);
+  mb1.add_name(fred);
+  mlocs[0] = mb1.Finish();
+  MonsterBuilder mb2(builder);
+  mb2.add_name(barney);
+  mb2.add_hp(1000);
+  mlocs[1] = mb2.Finish();
+  MonsterBuilder mb3(builder);
+  mb3.add_name(wilma);
+  mlocs[2] = mb3.Finish();
+
+  // Create an array of strings. Also test string pooling, and lambdas.
+  auto vecofstrings =
+      builder.CreateVector<flatbuffers::Offset<flatbuffers::String>>(
+          4,
+          [](size_t i, flatbuffers::FlatBufferBuilder *b)
+              -> flatbuffers::Offset<flatbuffers::String> {
+            static const char *names[] = { "bob", "fred", "bob", "fred" };
+            return b->CreateSharedString(names[i]);
+          },
+          &builder);
+
+  // Creating vectors of strings in one convenient call.
+  std::vector<std::string> names2;
+  names2.push_back("jane");
+  names2.push_back("mary");
+  auto vecofstrings2 = builder.CreateVectorOfStrings(names2);
+
+  // Create an array of sorted tables, can be used with binary search when read:
+  auto vecoftables = builder.CreateVectorOfSortedTables(mlocs, 3);
+
+  // Create an array of sorted structs,
+  // can be used with binary search when read:
+  std::vector<Ability> abilities;
+  abilities.push_back(Ability(4, 40));
+  abilities.push_back(Ability(3, 30));
+  abilities.push_back(Ability(2, 20));
+  abilities.push_back(Ability(1, 10));
+  auto vecofstructs = builder.CreateVectorOfSortedStructs(&abilities);
+
+  // Create a nested FlatBuffer.
+  // Nested FlatBuffers are stored in a ubyte vector, which can be convenient
+  // since they can be memcpy'd around much easier than other FlatBuffer
+  // values. They have little overhead compared to storing the table directly.
+  // As a test, create a mostly empty Monster buffer:
+  flatbuffers::FlatBufferBuilder nested_builder;
+  auto nmloc = CreateMonster(nested_builder, nullptr, 0, 0,
+                             nested_builder.CreateString("NestedMonster"));
+  FinishMonsterBuffer(nested_builder, nmloc);
+  // Now we can store the buffer in the parent. Note that by default, vectors
+  // are only aligned to their elements or size field, so in this case if the
+  // buffer contains 64-bit elements, they may not be correctly aligned. We fix
+  // that with:
+  builder.ForceVectorAlignment(nested_builder.GetSize(), sizeof(uint8_t),
+                               nested_builder.GetBufferMinAlignment());
+  // If for whatever reason you don't have the nested_builder available, you
+  // can substitute flatbuffers::largest_scalar_t (64-bit) for the alignment, or
+  // the largest force_align value in your schema if you're using it.
+  auto nested_flatbuffer_vector = builder.CreateVector(
+      nested_builder.GetBufferPointer(), nested_builder.GetSize());
+
+  // Test a nested FlexBuffer:
+  flexbuffers::Builder flexbuild;
+  flexbuild.Int(1234);
+  flexbuild.Finish();
+  auto flex = builder.CreateVector(flexbuild.GetBuffer());
+
+  // Test vector of enums.
+  Color colors[] = { Color_Blue, Color_Green };
+  // We use this special creation function because we have an array of
+  // pre-C++11 (enum class) enums whose size likely is int, yet its declared
+  // type in the schema is byte.
+  auto vecofcolors = builder.CreateVectorScalarCast<uint8_t, Color>(colors, 2);
+
+  // shortcut for creating monster with all fields set:
+  auto mloc = CreateMonster(builder, &vec, 150, 80, name, inventory, Color_Blue,
+                            Any_Monster, mlocs[1].Union(),  // Store a union.
+                            testv, vecofstrings, vecoftables, 0,
+                            nested_flatbuffer_vector, 0, false, 0, 0, 0, 0, 0,
+                            0, 0, 0, 0, 3.14159f, 3.0f, 0.0f, vecofstrings2,
+                            vecofstructs, flex, testv2, 0, 0, 0, 0, 0, 0, 0, 0,
+                            0, 0, 0, AnyUniqueAliases_NONE, 0,
+                            AnyAmbiguousAliases_NONE, 0, vecofcolors);
+
+  FinishMonsterBuffer(builder, mloc);
+
+  // clang-format off
+  #ifdef FLATBUFFERS_TEST_VERBOSE
+  // print byte data for debugging:
+  auto p = builder.GetBufferPointer();
+  for (flatbuffers::uoffset_t i = 0; i < builder.GetSize(); i++)
+    printf("%d ", p[i]);
+  #endif
+  // clang-format on
+
+  // return the buffer for the caller to use.
+  auto bufferpointer =
+      reinterpret_cast<const char *>(builder.GetBufferPointer());
+  buffer.assign(bufferpointer, bufferpointer + builder.GetSize());
+
+  return builder.Release();
+}
+
+//  example of accessing a buffer loaded in memory:
+void AccessFlatBufferTest(const uint8_t *flatbuf, size_t length,
+                          bool pooled = true) {
+  // First, verify the buffers integrity (optional)
+  flatbuffers::Verifier verifier(flatbuf, length);
+  TEST_EQ(VerifyMonsterBuffer(verifier), true);
+
+  // clang-format off
+  #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
+    std::vector<uint8_t> test_buff;
+    test_buff.resize(length * 2);
+    std::memcpy(&test_buff[0], flatbuf, length);
+    std::memcpy(&test_buff[length], flatbuf, length);
+
+    flatbuffers::Verifier verifier1(&test_buff[0], length);
+    TEST_EQ(VerifyMonsterBuffer(verifier1), true);
+    TEST_EQ(verifier1.GetComputedSize(), length);
+
+    flatbuffers::Verifier verifier2(&test_buff[length], length);
+    TEST_EQ(VerifyMonsterBuffer(verifier2), true);
+    TEST_EQ(verifier2.GetComputedSize(), length);
+  #endif
+  // clang-format on
+
+  TEST_EQ(strcmp(MonsterIdentifier(), "MONS"), 0);
+  TEST_EQ(MonsterBufferHasIdentifier(flatbuf), true);
+  TEST_EQ(strcmp(MonsterExtension(), "mon"), 0);
+
+  // Access the buffer from the root.
+  auto monster = GetMonster(flatbuf);
+
+  TEST_EQ(monster->hp(), 80);
+  TEST_EQ(monster->mana(), 150);  // default
+  TEST_EQ_STR(monster->name()->c_str(), "MyMonster");
+  // Can't access the following field, it is deprecated in the schema,
+  // which means accessors are not generated:
+  // monster.friendly()
+
+  auto pos = monster->pos();
+  TEST_NOTNULL(pos);
+  TEST_EQ(pos->z(), 3);
+  TEST_EQ(pos->test3().a(), 10);
+  TEST_EQ(pos->test3().b(), 20);
+
+  auto inventory = monster->inventory();
+  TEST_EQ(VectorLength(inventory), 10UL);  // Works even if inventory is null.
+  TEST_NOTNULL(inventory);
+  unsigned char inv_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+  // Check compatibilty of iterators with STL.
+  std::vector<unsigned char> inv_vec(inventory->begin(), inventory->end());
+  int n = 0;
+  for (auto it = inventory->begin(); it != inventory->end(); ++it, ++n) {
+    auto indx = it - inventory->begin();
+    TEST_EQ(*it, inv_vec.at(indx));  // Use bounds-check.
+    TEST_EQ(*it, inv_data[indx]);
+  }
+  TEST_EQ(n, inv_vec.size());
+
+  n = 0;
+  for (auto it = inventory->cbegin(); it != inventory->cend(); ++it, ++n) {
+    auto indx = it - inventory->cbegin();
+    TEST_EQ(*it, inv_vec.at(indx));  // Use bounds-check.
+    TEST_EQ(*it, inv_data[indx]);
+  }
+  TEST_EQ(n, inv_vec.size());
+
+  n = 0;
+  for (auto it = inventory->rbegin(); it != inventory->rend(); ++it, ++n) {
+    auto indx = inventory->rend() - it - 1;
+    TEST_EQ(*it, inv_vec.at(indx));  // Use bounds-check.
+    TEST_EQ(*it, inv_data[indx]);
+  }
+  TEST_EQ(n, inv_vec.size());
+
+  n = 0;
+  for (auto it = inventory->crbegin(); it != inventory->crend(); ++it, ++n) {
+    auto indx = inventory->crend() - it - 1;
+    TEST_EQ(*it, inv_vec.at(indx));  // Use bounds-check.
+    TEST_EQ(*it, inv_data[indx]);
+  }
+  TEST_EQ(n, inv_vec.size());
+
+  TEST_EQ(monster->color(), Color_Blue);
+
+  // Example of accessing a union:
+  TEST_EQ(monster->test_type(), Any_Monster);  // First make sure which it is.
+  auto monster2 = reinterpret_cast<const Monster *>(monster->test());
+  TEST_NOTNULL(monster2);
+  TEST_EQ_STR(monster2->name()->c_str(), "Fred");
+
+  // Example of accessing a vector of strings:
+  auto vecofstrings = monster->testarrayofstring();
+  TEST_EQ(vecofstrings->size(), 4U);
+  TEST_EQ_STR(vecofstrings->Get(0)->c_str(), "bob");
+  TEST_EQ_STR(vecofstrings->Get(1)->c_str(), "fred");
+  if (pooled) {
+    // These should have pointer equality because of string pooling.
+    TEST_EQ(vecofstrings->Get(0)->c_str(), vecofstrings->Get(2)->c_str());
+    TEST_EQ(vecofstrings->Get(1)->c_str(), vecofstrings->Get(3)->c_str());
+  }
+
+  auto vecofstrings2 = monster->testarrayofstring2();
+  if (vecofstrings2) {
+    TEST_EQ(vecofstrings2->size(), 2U);
+    TEST_EQ_STR(vecofstrings2->Get(0)->c_str(), "jane");
+    TEST_EQ_STR(vecofstrings2->Get(1)->c_str(), "mary");
+  }
+
+  // Example of accessing a vector of tables:
+  auto vecoftables = monster->testarrayoftables();
+  TEST_EQ(vecoftables->size(), 3U);
+  for (auto it = vecoftables->begin(); it != vecoftables->end(); ++it)
+    TEST_EQ(strlen(it->name()->c_str()) >= 4, true);
+  TEST_EQ_STR(vecoftables->Get(0)->name()->c_str(), "Barney");
+  TEST_EQ(vecoftables->Get(0)->hp(), 1000);
+  TEST_EQ_STR(vecoftables->Get(1)->name()->c_str(), "Fred");
+  TEST_EQ_STR(vecoftables->Get(2)->name()->c_str(), "Wilma");
+  TEST_NOTNULL(vecoftables->LookupByKey("Barney"));
+  TEST_NOTNULL(vecoftables->LookupByKey("Fred"));
+  TEST_NOTNULL(vecoftables->LookupByKey("Wilma"));
+
+  // Test accessing a vector of sorted structs
+  auto vecofstructs = monster->testarrayofsortedstruct();
+  if (vecofstructs) {  // not filled in monster_test.bfbs
+    for (flatbuffers::uoffset_t i = 0; i < vecofstructs->size() - 1; i++) {
+      auto left = vecofstructs->Get(i);
+      auto right = vecofstructs->Get(i + 1);
+      TEST_EQ(true, (left->KeyCompareLessThan(right)));
+    }
+    TEST_NOTNULL(vecofstructs->LookupByKey(3));
+    TEST_EQ(static_cast<const Ability *>(nullptr),
+            vecofstructs->LookupByKey(5));
+  }
+
+  // Test nested FlatBuffers if available:
+  auto nested_buffer = monster->testnestedflatbuffer();
+  if (nested_buffer) {
+    // nested_buffer is a vector of bytes you can memcpy. However, if you
+    // actually want to access the nested data, this is a convenient
+    // accessor that directly gives you the root table:
+    auto nested_monster = monster->testnestedflatbuffer_nested_root();
+    TEST_EQ_STR(nested_monster->name()->c_str(), "NestedMonster");
+  }
+
+  // Test flexbuffer if available:
+  auto flex = monster->flex();
+  // flex is a vector of bytes you can memcpy etc.
+  TEST_EQ(flex->size(), 4);  // Encoded FlexBuffer bytes.
+  // However, if you actually want to access the nested data, this is a
+  // convenient accessor that directly gives you the root value:
+  TEST_EQ(monster->flex_flexbuffer_root().AsInt16(), 1234);
+
+  // Test vector of enums:
+  auto colors = monster->vector_of_enums();
+  if (colors) {
+    TEST_EQ(colors->size(), 2);
+    TEST_EQ(colors->Get(0), Color_Blue);
+    TEST_EQ(colors->Get(1), Color_Green);
+  }
+
+  // Since Flatbuffers uses explicit mechanisms to override the default
+  // compiler alignment, double check that the compiler indeed obeys them:
+  // (Test consists of a short and byte):
+  TEST_EQ(flatbuffers::AlignOf<Test>(), 2UL);
+  TEST_EQ(sizeof(Test), 4UL);
+
+  const flatbuffers::Vector<const Test *> *tests_array[] = {
+    monster->test4(),
+    monster->test5(),
+  };
+  for (size_t i = 0; i < sizeof(tests_array) / sizeof(tests_array[0]); ++i) {
+    auto tests = tests_array[i];
+    TEST_NOTNULL(tests);
+    auto test_0 = tests->Get(0);
+    auto test_1 = tests->Get(1);
+    TEST_EQ(test_0->a(), 10);
+    TEST_EQ(test_0->b(), 20);
+    TEST_EQ(test_1->a(), 30);
+    TEST_EQ(test_1->b(), 40);
+    for (auto it = tests->begin(); it != tests->end(); ++it) {
+      TEST_EQ(it->a() == 10 || it->a() == 30, true);  // Just testing iterators.
+    }
+  }
+
+  // Checking for presence of fields:
+  TEST_EQ(flatbuffers::IsFieldPresent(monster, Monster::VT_HP), true);
+  TEST_EQ(flatbuffers::IsFieldPresent(monster, Monster::VT_MANA), false);
+
+  // Obtaining a buffer from a root:
+  TEST_EQ(GetBufferStartFromRootPointer(monster), flatbuf);
+}
+
+// Change a FlatBuffer in-place, after it has been constructed.
+void MutateFlatBuffersTest(uint8_t *flatbuf, std::size_t length) {
+  // Get non-const pointer to root.
+  auto monster = GetMutableMonster(flatbuf);
+
+  // Each of these tests mutates, then tests, then set back to the original,
+  // so we can test that the buffer in the end still passes our original test.
+  auto hp_ok = monster->mutate_hp(10);
+  TEST_EQ(hp_ok, true);  // Field was present.
+  TEST_EQ(monster->hp(), 10);
+  // Mutate to default value
+  auto hp_ok_default = monster->mutate_hp(100);
+  TEST_EQ(hp_ok_default, true);  // Field was present.
+  TEST_EQ(monster->hp(), 100);
+  // Test that mutate to default above keeps field valid for further mutations
+  auto hp_ok_2 = monster->mutate_hp(20);
+  TEST_EQ(hp_ok_2, true);
+  TEST_EQ(monster->hp(), 20);
+  monster->mutate_hp(80);
+
+  // Monster originally at 150 mana (default value)
+  auto mana_default_ok = monster->mutate_mana(150);  // Mutate to default value.
+  TEST_EQ(mana_default_ok,
+          true);  // Mutation should succeed, because default value.
+  TEST_EQ(monster->mana(), 150);
+  auto mana_ok = monster->mutate_mana(10);
+  TEST_EQ(mana_ok, false);  // Field was NOT present, because default value.
+  TEST_EQ(monster->mana(), 150);
+
+  // Mutate structs.
+  auto pos = monster->mutable_pos();
+  auto test3 = pos->mutable_test3();  // Struct inside a struct.
+  test3.mutate_a(50);                 // Struct fields never fail.
+  TEST_EQ(test3.a(), 50);
+  test3.mutate_a(10);
+
+  // Mutate vectors.
+  auto inventory = monster->mutable_inventory();
+  inventory->Mutate(9, 100);
+  TEST_EQ(inventory->Get(9), 100);
+  inventory->Mutate(9, 9);
+
+  auto tables = monster->mutable_testarrayoftables();
+  auto first = tables->GetMutableObject(0);
+  TEST_EQ(first->hp(), 1000);
+  first->mutate_hp(0);
+  TEST_EQ(first->hp(), 0);
+  first->mutate_hp(1000);
+
+  // Run the verifier and the regular test to make sure we didn't trample on
+  // anything.
+  AccessFlatBufferTest(flatbuf, length);
+}
+
+// Unpack a FlatBuffer into objects.
+void ObjectFlatBuffersTest(uint8_t *flatbuf) {
+  // Optional: we can specify resolver and rehasher functions to turn hashed
+  // strings into object pointers and back, to implement remote references
+  // and such.
+  auto resolver = flatbuffers::resolver_function_t(
+      [](void **pointer_adr, flatbuffers::hash_value_t hash) {
+        (void)pointer_adr;
+        (void)hash;
+        // Don't actually do anything, leave variable null.
+      });
+  auto rehasher = flatbuffers::rehasher_function_t(
+      [](void *pointer) -> flatbuffers::hash_value_t {
+        (void)pointer;
+        return 0;
+      });
+
+  // Turn a buffer into C++ objects.
+  auto monster1 = UnPackMonster(flatbuf, &resolver);
+
+  // Re-serialize the data.
+  flatbuffers::FlatBufferBuilder fbb1;
+  fbb1.Finish(CreateMonster(fbb1, monster1.get(), &rehasher),
+              MonsterIdentifier());
+
+  // Unpack again, and re-serialize again.
+  auto monster2 = UnPackMonster(fbb1.GetBufferPointer(), &resolver);
+  flatbuffers::FlatBufferBuilder fbb2;
+  fbb2.Finish(CreateMonster(fbb2, monster2.get(), &rehasher),
+              MonsterIdentifier());
+
+  // Now we've gone full round-trip, the two buffers should match.
+  auto len1 = fbb1.GetSize();
+  auto len2 = fbb2.GetSize();
+  TEST_EQ(len1, len2);
+  TEST_EQ(memcmp(fbb1.GetBufferPointer(), fbb2.GetBufferPointer(), len1), 0);
+
+  // Test it with the original buffer test to make sure all data survived.
+  AccessFlatBufferTest(fbb2.GetBufferPointer(), len2, false);
+
+  // Test accessing fields, similar to AccessFlatBufferTest above.
+  TEST_EQ(monster2->hp, 80);
+  TEST_EQ(monster2->mana, 150);  // default
+  TEST_EQ_STR(monster2->name.c_str(), "MyMonster");
+
+  auto &pos = monster2->pos;
+  TEST_NOTNULL(pos);
+  TEST_EQ(pos->z(), 3);
+  TEST_EQ(pos->test3().a(), 10);
+  TEST_EQ(pos->test3().b(), 20);
+
+  auto &inventory = monster2->inventory;
+  TEST_EQ(inventory.size(), 10UL);
+  unsigned char inv_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+  for (auto it = inventory.begin(); it != inventory.end(); ++it)
+    TEST_EQ(*it, inv_data[it - inventory.begin()]);
+
+  TEST_EQ(monster2->color, Color_Blue);
+
+  auto monster3 = monster2->test.AsMonster();
+  TEST_NOTNULL(monster3);
+  TEST_EQ_STR(monster3->name.c_str(), "Fred");
+
+  auto &vecofstrings = monster2->testarrayofstring;
+  TEST_EQ(vecofstrings.size(), 4U);
+  TEST_EQ_STR(vecofstrings[0].c_str(), "bob");
+  TEST_EQ_STR(vecofstrings[1].c_str(), "fred");
+
+  auto &vecofstrings2 = monster2->testarrayofstring2;
+  TEST_EQ(vecofstrings2.size(), 2U);
+  TEST_EQ_STR(vecofstrings2[0].c_str(), "jane");
+  TEST_EQ_STR(vecofstrings2[1].c_str(), "mary");
+
+  auto &vecoftables = monster2->testarrayoftables;
+  TEST_EQ(vecoftables.size(), 3U);
+  TEST_EQ_STR(vecoftables[0]->name.c_str(), "Barney");
+  TEST_EQ(vecoftables[0]->hp, 1000);
+  TEST_EQ_STR(vecoftables[1]->name.c_str(), "Fred");
+  TEST_EQ_STR(vecoftables[2]->name.c_str(), "Wilma");
+
+  auto &tests = monster2->test4;
+  TEST_EQ(tests[0].a(), 10);
+  TEST_EQ(tests[0].b(), 20);
+  TEST_EQ(tests[1].a(), 30);
+  TEST_EQ(tests[1].b(), 40);
+}
+
+// Prefix a FlatBuffer with a size field.
+void SizePrefixedTest() {
+  // Create size prefixed buffer.
+  flatbuffers::FlatBufferBuilder fbb;
+  FinishSizePrefixedMonsterBuffer(
+      fbb,
+      CreateMonster(fbb, 0, 200, 300, fbb.CreateString("bob")));
+
+  // Verify it.
+  flatbuffers::Verifier verifier(fbb.GetBufferPointer(), fbb.GetSize());
+  TEST_EQ(VerifySizePrefixedMonsterBuffer(verifier), true);
+
+  // Access it.
+  auto m = GetSizePrefixedMonster(fbb.GetBufferPointer());
+  TEST_EQ(m->mana(), 200);
+  TEST_EQ(m->hp(), 300);
+  TEST_EQ_STR(m->name()->c_str(), "bob");
+}
+
+void TriviallyCopyableTest() {
+  // clang-format off
+  #if __GNUG__ && __GNUC__ < 5
+    TEST_EQ(__has_trivial_copy(Vec3), true);
+  #else
+    #if __cplusplus >= 201103L
+      TEST_EQ(std::is_trivially_copyable<Vec3>::value, true);
+    #endif
+  #endif
+  // clang-format on
+}
+
+// Check stringify of an default enum value to json
+void JsonDefaultTest() {
+  // load FlatBuffer schema (.fbs) from disk
+  std::string schemafile;
+  TEST_EQ(flatbuffers::LoadFile((test_data_path + "monster_test.fbs").c_str(),
+                                false, &schemafile), true);
+  // parse schema first, so we can use it to parse the data after
+  flatbuffers::Parser parser;
+  auto include_test_path =
+      flatbuffers::ConCatPathFileName(test_data_path, "include_test");
+  const char *include_directories[] = { test_data_path.c_str(),
+                                        include_test_path.c_str(), nullptr };
+
+  TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
+  // create incomplete monster and store to json
+  parser.opts.output_default_scalars_in_json = true;
+  parser.opts.output_enum_identifiers = true;
+  flatbuffers::FlatBufferBuilder builder;
+  auto name = builder.CreateString("default_enum");
+  MonsterBuilder color_monster(builder);
+  color_monster.add_name(name);
+  FinishMonsterBuffer(builder, color_monster.Finish());
+  std::string jsongen;
+  auto result = GenerateText(parser, builder.GetBufferPointer(), &jsongen);
+  TEST_EQ(result, true);
+  // default value of the "color" field is Blue
+  TEST_EQ(std::string::npos != jsongen.find("color: \"Blue\""), true);
+  // default value of the "testf" field is 3.14159
+  TEST_EQ(std::string::npos != jsongen.find("testf: 3.14159"), true);
+}
+
+void JsonEnumsTest() {
+  // load FlatBuffer schema (.fbs) from disk
+  std::string schemafile;
+  TEST_EQ(flatbuffers::LoadFile((test_data_path + "monster_test.fbs").c_str(),
+                                false, &schemafile),
+          true);
+  // parse schema first, so we can use it to parse the data after
+  flatbuffers::Parser parser;
+  auto include_test_path =
+      flatbuffers::ConCatPathFileName(test_data_path, "include_test");
+  const char *include_directories[] = { test_data_path.c_str(),
+                                        include_test_path.c_str(), nullptr };
+  parser.opts.output_enum_identifiers = true;
+  TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
+  flatbuffers::FlatBufferBuilder builder;
+  auto name = builder.CreateString("bitflag_enum");
+  MonsterBuilder color_monster(builder);
+  color_monster.add_name(name);
+  color_monster.add_color(Color(Color_Blue | Color_Red));
+  FinishMonsterBuffer(builder, color_monster.Finish());
+  std::string jsongen;
+  auto result = GenerateText(parser, builder.GetBufferPointer(), &jsongen);
+  TEST_EQ(result, true);
+  TEST_EQ(std::string::npos != jsongen.find("color: \"Red Blue\""), true);
+}
+
+#if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
+// The IEEE-754 quiet_NaN is not simple binary constant.
+// All binary NaN bit strings have all the bits of the biased exponent field E
+// set to 1. A quiet NaN bit string should be encoded with the first bit d[1]
+// of the trailing significand field T being 1 (d[0] is implicit bit).
+// It is assumed that endianness of floating-point is same as integer.
+template<typename T, typename U, U qnan_base> bool is_quiet_nan_impl(T v) {
+  static_assert(sizeof(T) == sizeof(U), "unexpected");
+  U b = 0;
+  std::memcpy(&b, &v, sizeof(T));
+  return ((b & qnan_base) == qnan_base);
+}
+static bool is_quiet_nan(float v) {
+  return is_quiet_nan_impl<float, uint32_t, 0x7FC00000u>(v);
+}
+static bool is_quiet_nan(double v) {
+  return is_quiet_nan_impl<double, uint64_t, 0x7FF8000000000000ul>(v);
+}
+
+void TestMonsterExtraFloats() {
+  TEST_EQ(is_quiet_nan(1.0), false);
+  TEST_EQ(is_quiet_nan(infinityd), false);
+  TEST_EQ(is_quiet_nan(-infinityf), false);
+  TEST_EQ(is_quiet_nan(std::numeric_limits<float>::quiet_NaN()), true);
+  TEST_EQ(is_quiet_nan(std::numeric_limits<double>::quiet_NaN()), true);
+
+  using namespace flatbuffers;
+  using namespace MyGame;
+  // Load FlatBuffer schema (.fbs) from disk.
+  std::string schemafile;
+  TEST_EQ(LoadFile((test_data_path + "monster_extra.fbs").c_str(), false,
+                   &schemafile),
+          true);
+  // Parse schema first, so we can use it to parse the data after.
+  Parser parser;
+  auto include_test_path = ConCatPathFileName(test_data_path, "include_test");
+  const char *include_directories[] = { test_data_path.c_str(),
+                                        include_test_path.c_str(), nullptr };
+  TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
+  // Create empty extra and store to json.
+  parser.opts.output_default_scalars_in_json = true;
+  parser.opts.output_enum_identifiers = true;
+  FlatBufferBuilder builder;
+  const auto def_root = MonsterExtraBuilder(builder).Finish();
+  FinishMonsterExtraBuffer(builder, def_root);
+  const auto def_obj = builder.GetBufferPointer();
+  const auto def_extra = GetMonsterExtra(def_obj);
+  TEST_NOTNULL(def_extra);
+  TEST_EQ(is_quiet_nan(def_extra->f0()), true);
+  TEST_EQ(is_quiet_nan(def_extra->f1()), true);
+  TEST_EQ(def_extra->f2(), +infinityf);
+  TEST_EQ(def_extra->f3(), -infinityf);
+  TEST_EQ(is_quiet_nan(def_extra->d0()), true);
+  TEST_EQ(is_quiet_nan(def_extra->d1()), true);
+  TEST_EQ(def_extra->d2(), +infinityd);
+  TEST_EQ(def_extra->d3(), -infinityd);
+  std::string jsongen;
+  auto result = GenerateText(parser, def_obj, &jsongen);
+  TEST_EQ(result, true);
+  // Check expected default values.
+  TEST_EQ(std::string::npos != jsongen.find("f0: nan"), true);
+  TEST_EQ(std::string::npos != jsongen.find("f1: nan"), true);
+  TEST_EQ(std::string::npos != jsongen.find("f2: inf"), true);
+  TEST_EQ(std::string::npos != jsongen.find("f3: -inf"), true);
+  TEST_EQ(std::string::npos != jsongen.find("d0: nan"), true);
+  TEST_EQ(std::string::npos != jsongen.find("d1: nan"), true);
+  TEST_EQ(std::string::npos != jsongen.find("d2: inf"), true);
+  TEST_EQ(std::string::npos != jsongen.find("d3: -inf"), true);
+  // Parse 'mosterdata_extra.json'.
+  const auto extra_base = test_data_path + "monsterdata_extra";
+  jsongen = "";
+  TEST_EQ(LoadFile((extra_base + ".json").c_str(), false, &jsongen), true);
+  TEST_EQ(parser.Parse(jsongen.c_str()), true);
+  const auto test_file = parser.builder_.GetBufferPointer();
+  const auto test_size = parser.builder_.GetSize();
+  Verifier verifier(test_file, test_size);
+  TEST_ASSERT(VerifyMonsterExtraBuffer(verifier));
+  const auto extra = GetMonsterExtra(test_file);
+  TEST_NOTNULL(extra);
+  TEST_EQ(is_quiet_nan(extra->f0()), true);
+  TEST_EQ(is_quiet_nan(extra->f1()), true);
+  TEST_EQ(extra->f2(), +infinityf);
+  TEST_EQ(extra->f3(), -infinityf);
+  TEST_EQ(is_quiet_nan(extra->d0()), true);
+  TEST_EQ(extra->d1(), +infinityd);
+  TEST_EQ(extra->d2(), -infinityd);
+  TEST_EQ(is_quiet_nan(extra->d3()), true);
+  TEST_NOTNULL(extra->fvec());
+  TEST_EQ(extra->fvec()->size(), 4);
+  TEST_EQ(extra->fvec()->Get(0), 1.0f);
+  TEST_EQ(extra->fvec()->Get(1), -infinityf);
+  TEST_EQ(extra->fvec()->Get(2), +infinityf);
+  TEST_EQ(is_quiet_nan(extra->fvec()->Get(3)), true);
+  TEST_NOTNULL(extra->dvec());
+  TEST_EQ(extra->dvec()->size(), 4);
+  TEST_EQ(extra->dvec()->Get(0), 2.0);
+  TEST_EQ(extra->dvec()->Get(1), +infinityd);
+  TEST_EQ(extra->dvec()->Get(2), -infinityd);
+  TEST_EQ(is_quiet_nan(extra->dvec()->Get(3)), true);
+}
+#else
+void TestMonsterExtraFloats() {}
+#endif
+
+// example of parsing text straight into a buffer, and generating
+// text back from it:
+void ParseAndGenerateTextTest(bool binary) {
+  // load FlatBuffer schema (.fbs) and JSON from disk
+  std::string schemafile;
+  std::string jsonfile;
+  TEST_EQ(flatbuffers::LoadFile(
+              (test_data_path + "monster_test." + (binary ? "bfbs" : "fbs"))
+                  .c_str(),
+              binary, &schemafile),
+          true);
+  TEST_EQ(flatbuffers::LoadFile(
+              (test_data_path + "monsterdata_test.golden").c_str(), false,
+              &jsonfile),
+          true);
+
+  auto include_test_path =
+    flatbuffers::ConCatPathFileName(test_data_path, "include_test");
+  const char *include_directories[] = { test_data_path.c_str(),
+                                        include_test_path.c_str(), nullptr };
+
+  // parse schema first, so we can use it to parse the data after
+  flatbuffers::Parser parser;
+  if (binary) {
+    flatbuffers::Verifier verifier(
+        reinterpret_cast<const uint8_t *>(schemafile.c_str()),
+        schemafile.size());
+    TEST_EQ(reflection::VerifySchemaBuffer(verifier), true);
+    //auto schema = reflection::GetSchema(schemafile.c_str());
+    TEST_EQ(parser.Deserialize((const uint8_t *)schemafile.c_str(), schemafile.size()), true);
+  } else {
+    TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
+  }
+  TEST_EQ(parser.Parse(jsonfile.c_str(), include_directories), true);
+
+  // here, parser.builder_ contains a binary buffer that is the parsed data.
+
+  // First, verify it, just in case:
+  flatbuffers::Verifier verifier(parser.builder_.GetBufferPointer(),
+                                 parser.builder_.GetSize());
+  TEST_EQ(VerifyMonsterBuffer(verifier), true);
+
+  AccessFlatBufferTest(parser.builder_.GetBufferPointer(),
+                       parser.builder_.GetSize(), false);
+
+  // to ensure it is correct, we now generate text back from the binary,
+  // and compare the two:
+  std::string jsongen;
+  auto result =
+      GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
+  TEST_EQ(result, true);
+  TEST_EQ_STR(jsongen.c_str(), jsonfile.c_str());
+
+  // We can also do the above using the convenient Registry that knows about
+  // a set of file_identifiers mapped to schemas.
+  flatbuffers::Registry registry;
+  // Make sure schemas can find their includes.
+  registry.AddIncludeDirectory(test_data_path.c_str());
+  registry.AddIncludeDirectory(include_test_path.c_str());
+  // Call this with many schemas if possible.
+  registry.Register(MonsterIdentifier(),
+                    (test_data_path + "monster_test.fbs").c_str());
+  // Now we got this set up, we can parse by just specifying the identifier,
+  // the correct schema will be loaded on the fly:
+  auto buf = registry.TextToFlatBuffer(jsonfile.c_str(), MonsterIdentifier());
+  // If this fails, check registry.lasterror_.
+  TEST_NOTNULL(buf.data());
+  // Test the buffer, to be sure:
+  AccessFlatBufferTest(buf.data(), buf.size(), false);
+  // We can use the registry to turn this back into text, in this case it
+  // will get the file_identifier from the binary:
+  std::string text;
+  auto ok = registry.FlatBufferToText(buf.data(), buf.size(), &text);
+  // If this fails, check registry.lasterror_.
+  TEST_EQ(ok, true);
+  TEST_EQ_STR(text.c_str(), jsonfile.c_str());
+
+  // Generate text for UTF-8 strings without escapes.
+  std::string jsonfile_utf8;
+  TEST_EQ(flatbuffers::LoadFile((test_data_path + "unicode_test.json").c_str(),
+                                false, &jsonfile_utf8),
+          true);
+  TEST_EQ(parser.Parse(jsonfile_utf8.c_str(), include_directories), true);
+  // To ensure it is correct, generate utf-8 text back from the binary.
+  std::string jsongen_utf8;
+  // request natural printing for utf-8 strings
+  parser.opts.natural_utf8 = true;
+  parser.opts.strict_json = true;
+  TEST_EQ(
+      GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen_utf8),
+      true);
+  TEST_EQ_STR(jsongen_utf8.c_str(), jsonfile_utf8.c_str());
+}
+
+void ReflectionTest(uint8_t *flatbuf, size_t length) {
+  // Load a binary schema.
+  std::string bfbsfile;
+  TEST_EQ(flatbuffers::LoadFile((test_data_path + "monster_test.bfbs").c_str(),
+                                true, &bfbsfile),
+          true);
+
+  // Verify it, just in case:
+  flatbuffers::Verifier verifier(
+      reinterpret_cast<const uint8_t *>(bfbsfile.c_str()), bfbsfile.length());
+  TEST_EQ(reflection::VerifySchemaBuffer(verifier), true);
+
+  // Make sure the schema is what we expect it to be.
+  auto &schema = *reflection::GetSchema(bfbsfile.c_str());
+  auto root_table = schema.root_table();
+  TEST_EQ_STR(root_table->name()->c_str(), "MyGame.Example.Monster");
+  auto fields = root_table->fields();
+  auto hp_field_ptr = fields->LookupByKey("hp");
+  TEST_NOTNULL(hp_field_ptr);
+  auto &hp_field = *hp_field_ptr;
+  TEST_EQ_STR(hp_field.name()->c_str(), "hp");
+  TEST_EQ(hp_field.id(), 2);
+  TEST_EQ(hp_field.type()->base_type(), reflection::Short);
+  auto friendly_field_ptr = fields->LookupByKey("friendly");
+  TEST_NOTNULL(friendly_field_ptr);
+  TEST_NOTNULL(friendly_field_ptr->attributes());
+  TEST_NOTNULL(friendly_field_ptr->attributes()->LookupByKey("priority"));
+
+  // Make sure the table index is what we expect it to be.
+  auto pos_field_ptr = fields->LookupByKey("pos");
+  TEST_NOTNULL(pos_field_ptr);
+  TEST_EQ(pos_field_ptr->type()->base_type(), reflection::Obj);
+  auto pos_table_ptr = schema.objects()->Get(pos_field_ptr->type()->index());
+  TEST_NOTNULL(pos_table_ptr);
+  TEST_EQ_STR(pos_table_ptr->name()->c_str(), "MyGame.Example.Vec3");
+
+  // Now use it to dynamically access a buffer.
+  auto &root = *flatbuffers::GetAnyRoot(flatbuf);
+
+  // Verify the buffer first using reflection based verification
+  TEST_EQ(flatbuffers::Verify(schema, *schema.root_table(), flatbuf, length),
+          true);
+
+  auto hp = flatbuffers::GetFieldI<uint16_t>(root, hp_field);
+  TEST_EQ(hp, 80);
+
+  // Rather than needing to know the type, we can also get the value of
+  // any field as an int64_t/double/string, regardless of what it actually is.
+  auto hp_int64 = flatbuffers::GetAnyFieldI(root, hp_field);
+  TEST_EQ(hp_int64, 80);
+  auto hp_double = flatbuffers::GetAnyFieldF(root, hp_field);
+  TEST_EQ(hp_double, 80.0);
+  auto hp_string = flatbuffers::GetAnyFieldS(root, hp_field, &schema);
+  TEST_EQ_STR(hp_string.c_str(), "80");
+
+  // Get struct field through reflection
+  auto pos_struct = flatbuffers::GetFieldStruct(root, *pos_field_ptr);
+  TEST_NOTNULL(pos_struct);
+  TEST_EQ(flatbuffers::GetAnyFieldF(*pos_struct,
+                                    *pos_table_ptr->fields()->LookupByKey("z")),
+          3.0f);
+
+  auto test3_field = pos_table_ptr->fields()->LookupByKey("test3");
+  auto test3_struct = flatbuffers::GetFieldStruct(*pos_struct, *test3_field);
+  TEST_NOTNULL(test3_struct);
+  auto test3_object = schema.objects()->Get(test3_field->type()->index());
+
+  TEST_EQ(flatbuffers::GetAnyFieldF(*test3_struct,
+                                    *test3_object->fields()->LookupByKey("a")),
+          10);
+
+  // We can also modify it.
+  flatbuffers::SetField<uint16_t>(&root, hp_field, 200);
+  hp = flatbuffers::GetFieldI<uint16_t>(root, hp_field);
+  TEST_EQ(hp, 200);
+
+  // We can also set fields generically:
+  flatbuffers::SetAnyFieldI(&root, hp_field, 300);
+  hp_int64 = flatbuffers::GetAnyFieldI(root, hp_field);
+  TEST_EQ(hp_int64, 300);
+  flatbuffers::SetAnyFieldF(&root, hp_field, 300.5);
+  hp_int64 = flatbuffers::GetAnyFieldI(root, hp_field);
+  TEST_EQ(hp_int64, 300);
+  flatbuffers::SetAnyFieldS(&root, hp_field, "300");
+  hp_int64 = flatbuffers::GetAnyFieldI(root, hp_field);
+  TEST_EQ(hp_int64, 300);
+
+  // Test buffer is valid after the modifications
+  TEST_EQ(flatbuffers::Verify(schema, *schema.root_table(), flatbuf, length),
+          true);
+
+  // Reset it, for further tests.
+  flatbuffers::SetField<uint16_t>(&root, hp_field, 80);
+
+  // More advanced functionality: changing the size of items in-line!
+  // First we put the FlatBuffer inside an std::vector.
+  std::vector<uint8_t> resizingbuf(flatbuf, flatbuf + length);
+  // Find the field we want to modify.
+  auto &name_field = *fields->LookupByKey("name");
+  // Get the root.
+  // This time we wrap the result from GetAnyRoot in a smartpointer that
+  // will keep rroot valid as resizingbuf resizes.
+  auto rroot = flatbuffers::piv(
+      flatbuffers::GetAnyRoot(flatbuffers::vector_data(resizingbuf)),
+      resizingbuf);
+  SetString(schema, "totally new string", GetFieldS(**rroot, name_field),
+            &resizingbuf);
+  // Here resizingbuf has changed, but rroot is still valid.
+  TEST_EQ_STR(GetFieldS(**rroot, name_field)->c_str(), "totally new string");
+  // Now lets extend a vector by 100 elements (10 -> 110).
+  auto &inventory_field = *fields->LookupByKey("inventory");
+  auto rinventory = flatbuffers::piv(
+      flatbuffers::GetFieldV<uint8_t>(**rroot, inventory_field), resizingbuf);
+  flatbuffers::ResizeVector<uint8_t>(schema, 110, 50, *rinventory,
+                                     &resizingbuf);
+  // rinventory still valid, so lets read from it.
+  TEST_EQ(rinventory->Get(10), 50);
+
+  // For reflection uses not covered already, there is a more powerful way:
+  // we can simply generate whatever object we want to add/modify in a
+  // FlatBuffer of its own, then add that to an existing FlatBuffer:
+  // As an example, let's add a string to an array of strings.
+  // First, find our field:
+  auto &testarrayofstring_field = *fields->LookupByKey("testarrayofstring");
+  // Find the vector value:
+  auto rtestarrayofstring = flatbuffers::piv(
+      flatbuffers::GetFieldV<flatbuffers::Offset<flatbuffers::String>>(
+          **rroot, testarrayofstring_field),
+      resizingbuf);
+  // It's a vector of 2 strings, to which we add one more, initialized to
+  // offset 0.
+  flatbuffers::ResizeVector<flatbuffers::Offset<flatbuffers::String>>(
+      schema, 3, 0, *rtestarrayofstring, &resizingbuf);
+  // Here we just create a buffer that contans a single string, but this
+  // could also be any complex set of tables and other values.
+  flatbuffers::FlatBufferBuilder stringfbb;
+  stringfbb.Finish(stringfbb.CreateString("hank"));
+  // Add the contents of it to our existing FlatBuffer.
+  // We do this last, so the pointer doesn't get invalidated (since it is
+  // at the end of the buffer):
+  auto string_ptr = flatbuffers::AddFlatBuffer(
+      resizingbuf, stringfbb.GetBufferPointer(), stringfbb.GetSize());
+  // Finally, set the new value in the vector.
+  rtestarrayofstring->MutateOffset(2, string_ptr);
+  TEST_EQ_STR(rtestarrayofstring->Get(0)->c_str(), "bob");
+  TEST_EQ_STR(rtestarrayofstring->Get(2)->c_str(), "hank");
+  // Test integrity of all resize operations above.
+  flatbuffers::Verifier resize_verifier(
+      reinterpret_cast<const uint8_t *>(flatbuffers::vector_data(resizingbuf)),
+      resizingbuf.size());
+  TEST_EQ(VerifyMonsterBuffer(resize_verifier), true);
+
+  // Test buffer is valid using reflection as well
+  TEST_EQ(flatbuffers::Verify(schema, *schema.root_table(),
+                              flatbuffers::vector_data(resizingbuf),
+                              resizingbuf.size()),
+          true);
+
+  // As an additional test, also set it on the name field.
+  // Note: unlike the name change above, this just overwrites the offset,
+  // rather than changing the string in-place.
+  SetFieldT(*rroot, name_field, string_ptr);
+  TEST_EQ_STR(GetFieldS(**rroot, name_field)->c_str(), "hank");
+
+  // Using reflection, rather than mutating binary FlatBuffers, we can also copy
+  // tables and other things out of other FlatBuffers into a FlatBufferBuilder,
+  // either part or whole.
+  flatbuffers::FlatBufferBuilder fbb;
+  auto root_offset = flatbuffers::CopyTable(
+      fbb, schema, *root_table, *flatbuffers::GetAnyRoot(flatbuf), true);
+  fbb.Finish(root_offset, MonsterIdentifier());
+  // Test that it was copied correctly:
+  AccessFlatBufferTest(fbb.GetBufferPointer(), fbb.GetSize());
+
+  // Test buffer is valid using reflection as well
+  TEST_EQ(flatbuffers::Verify(schema, *schema.root_table(),
+                              fbb.GetBufferPointer(), fbb.GetSize()),
+          true);
+}
+
+void MiniReflectFlatBuffersTest(uint8_t *flatbuf) {
+  auto s = flatbuffers::FlatBufferToString(flatbuf, Monster::MiniReflectTypeTable());
+  TEST_EQ_STR(
+      s.c_str(),
+      "{ "
+      "pos: { x: 1.0, y: 2.0, z: 3.0, test1: 0.0, test2: Red, test3: "
+      "{ a: 10, b: 20 } }, "
+      "hp: 80, "
+      "name: \"MyMonster\", "
+      "inventory: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ], "
+      "test_type: Monster, "
+      "test: { name: \"Fred\" }, "
+      "test4: [ { a: 10, b: 20 }, { a: 30, b: 40 } ], "
+      "testarrayofstring: [ \"bob\", \"fred\", \"bob\", \"fred\" ], "
+      "testarrayoftables: [ { hp: 1000, name: \"Barney\" }, { name: \"Fred\" "
+      "}, "
+      "{ name: \"Wilma\" } ], "
+      // TODO(wvo): should really print this nested buffer correctly.
+      "testnestedflatbuffer: [ 20, 0, 0, 0, 77, 79, 78, 83, 12, 0, 12, 0, 0, "
+      "0, "
+      "4, 0, 6, 0, 8, 0, 12, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 13, 0, 0, 0, 78, "
+      "101, 115, 116, 101, 100, 77, 111, 110, 115, 116, 101, 114, 0, 0, 0 ], "
+      "testarrayofstring2: [ \"jane\", \"mary\" ], "
+      "testarrayofsortedstruct: [ { id: 1, distance: 10 }, "
+      "{ id: 2, distance: 20 }, { id: 3, distance: 30 }, "
+      "{ id: 4, distance: 40 } ], "
+      "flex: [ 210, 4, 5, 2 ], "
+      "test5: [ { a: 10, b: 20 }, { a: 30, b: 40 } ], "
+      "vector_of_enums: [ Blue, Green ] "
+      "}");
+
+  Test test(16, 32);
+  Vec3 vec(1,2,3, 1.5, Color_Red, test);
+  flatbuffers::FlatBufferBuilder vec_builder;
+  vec_builder.Finish(vec_builder.CreateStruct(vec));
+  auto vec_buffer = vec_builder.Release();
+  auto vec_str = flatbuffers::FlatBufferToString(vec_buffer.data(),
+                                                 Vec3::MiniReflectTypeTable());
+  TEST_EQ_STR(
+      vec_str.c_str(),
+      "{ x: 1.0, y: 2.0, z: 3.0, test1: 1.5, test2: Red, test3: { a: 16, b: 32 } }");
+}
+
+// Parse a .proto schema, output as .fbs
+void ParseProtoTest() {
+  // load the .proto and the golden file from disk
+  std::string protofile;
+  std::string goldenfile;
+  std::string goldenunionfile;
+  TEST_EQ(
+      flatbuffers::LoadFile((test_data_path + "prototest/test.proto").c_str(),
+                            false, &protofile),
+      true);
+  TEST_EQ(
+      flatbuffers::LoadFile((test_data_path + "prototest/test.golden").c_str(),
+                            false, &goldenfile),
+      true);
+  TEST_EQ(
+      flatbuffers::LoadFile((test_data_path +
+                            "prototest/test_union.golden").c_str(),
+                            false, &goldenunionfile),
+      true);
+
+  flatbuffers::IDLOptions opts;
+  opts.include_dependence_headers = false;
+  opts.proto_mode = true;
+
+  // Parse proto.
+  flatbuffers::Parser parser(opts);
+  auto protopath = test_data_path + "prototest/";
+  const char *include_directories[] = { protopath.c_str(), nullptr };
+  TEST_EQ(parser.Parse(protofile.c_str(), include_directories), true);
+
+  // Generate fbs.
+  auto fbs = flatbuffers::GenerateFBS(parser, "test");
+
+  // Ensure generated file is parsable.
+  flatbuffers::Parser parser2;
+  TEST_EQ(parser2.Parse(fbs.c_str(), nullptr), true);
+  TEST_EQ_STR(fbs.c_str(), goldenfile.c_str());
+
+  // Parse proto with --oneof-union option.
+  opts.proto_oneof_union = true;
+  flatbuffers::Parser parser3(opts);
+  TEST_EQ(parser3.Parse(protofile.c_str(), include_directories), true);
+
+  // Generate fbs.
+  auto fbs_union = flatbuffers::GenerateFBS(parser3, "test");
+
+  // Ensure generated file is parsable.
+  flatbuffers::Parser parser4;
+  TEST_EQ(parser4.Parse(fbs_union.c_str(), nullptr), true);
+  TEST_EQ_STR(fbs_union.c_str(), goldenunionfile.c_str());
+}
+
+template<typename T>
+void CompareTableFieldValue(flatbuffers::Table *table,
+                            flatbuffers::voffset_t voffset, T val) {
+  T read = table->GetField(voffset, static_cast<T>(0));
+  TEST_EQ(read, val);
+}
+
+// Low level stress/fuzz test: serialize/deserialize a variety of
+// different kinds of data in different combinations
+void FuzzTest1() {
+  // Values we're testing against: chosen to ensure no bits get chopped
+  // off anywhere, and also be different from eachother.
+  const uint8_t bool_val = true;
+  const int8_t char_val = -127;  // 0x81
+  const uint8_t uchar_val = 0xFF;
+  const int16_t short_val = -32222;  // 0x8222;
+  const uint16_t ushort_val = 0xFEEE;
+  const int32_t int_val = 0x83333333;
+  const uint32_t uint_val = 0xFDDDDDDD;
+  const int64_t long_val = 0x8444444444444444LL;
+  const uint64_t ulong_val = 0xFCCCCCCCCCCCCCCCULL;
+  const float float_val = 3.14159f;
+  const double double_val = 3.14159265359;
+
+  const int test_values_max = 11;
+  const flatbuffers::voffset_t fields_per_object = 4;
+  const int num_fuzz_objects = 10000;  // The higher, the more thorough :)
+
+  flatbuffers::FlatBufferBuilder builder;
+
+  lcg_reset();  // Keep it deterministic.
+
+  flatbuffers::uoffset_t objects[num_fuzz_objects];
+
+  // Generate num_fuzz_objects random objects each consisting of
+  // fields_per_object fields, each of a random type.
+  for (int i = 0; i < num_fuzz_objects; i++) {
+    auto start = builder.StartTable();
+    for (flatbuffers::voffset_t f = 0; f < fields_per_object; f++) {
+      int choice = lcg_rand() % test_values_max;
+      auto off = flatbuffers::FieldIndexToOffset(f);
+      switch (choice) {
+        case 0: builder.AddElement<uint8_t>(off, bool_val, 0); break;
+        case 1: builder.AddElement<int8_t>(off, char_val, 0); break;
+        case 2: builder.AddElement<uint8_t>(off, uchar_val, 0); break;
+        case 3: builder.AddElement<int16_t>(off, short_val, 0); break;
+        case 4: builder.AddElement<uint16_t>(off, ushort_val, 0); break;
+        case 5: builder.AddElement<int32_t>(off, int_val, 0); break;
+        case 6: builder.AddElement<uint32_t>(off, uint_val, 0); break;
+        case 7: builder.AddElement<int64_t>(off, long_val, 0); break;
+        case 8: builder.AddElement<uint64_t>(off, ulong_val, 0); break;
+        case 9: builder.AddElement<float>(off, float_val, 0); break;
+        case 10: builder.AddElement<double>(off, double_val, 0); break;
+      }
+    }
+    objects[i] = builder.EndTable(start);
+  }
+  builder.PreAlign<flatbuffers::largest_scalar_t>(0);  // Align whole buffer.
+
+  lcg_reset();  // Reset.
+
+  uint8_t *eob = builder.GetCurrentBufferPointer() + builder.GetSize();
+
+  // Test that all objects we generated are readable and return the
+  // expected values. We generate random objects in the same order
+  // so this is deterministic.
+  for (int i = 0; i < num_fuzz_objects; i++) {
+    auto table = reinterpret_cast<flatbuffers::Table *>(eob - objects[i]);
+    for (flatbuffers::voffset_t f = 0; f < fields_per_object; f++) {
+      int choice = lcg_rand() % test_values_max;
+      flatbuffers::voffset_t off = flatbuffers::FieldIndexToOffset(f);
+      switch (choice) {
+        case 0: CompareTableFieldValue(table, off, bool_val); break;
+        case 1: CompareTableFieldValue(table, off, char_val); break;
+        case 2: CompareTableFieldValue(table, off, uchar_val); break;
+        case 3: CompareTableFieldValue(table, off, short_val); break;
+        case 4: CompareTableFieldValue(table, off, ushort_val); break;
+        case 5: CompareTableFieldValue(table, off, int_val); break;
+        case 6: CompareTableFieldValue(table, off, uint_val); break;
+        case 7: CompareTableFieldValue(table, off, long_val); break;
+        case 8: CompareTableFieldValue(table, off, ulong_val); break;
+        case 9: CompareTableFieldValue(table, off, float_val); break;
+        case 10: CompareTableFieldValue(table, off, double_val); break;
+      }
+    }
+  }
+}
+
+// High level stress/fuzz test: generate a big schema and
+// matching json data in random combinations, then parse both,
+// generate json back from the binary, and compare with the original.
+void FuzzTest2() {
+  lcg_reset();  // Keep it deterministic.
+
+  const int num_definitions = 30;
+  const int num_struct_definitions = 5;  // Subset of num_definitions.
+  const int fields_per_definition = 15;
+  const int instances_per_definition = 5;
+  const int deprecation_rate = 10;  // 1 in deprecation_rate fields will
+                                    // be deprecated.
+
+  std::string schema = "namespace test;\n\n";
+
+  struct RndDef {
+    std::string instances[instances_per_definition];
+
+    // Since we're generating schema and corresponding data in tandem,
+    // this convenience function adds strings to both at once.
+    static void Add(RndDef (&definitions_l)[num_definitions],
+                    std::string &schema_l, const int instances_per_definition_l,
+                    const char *schema_add, const char *instance_add,
+                    int definition) {
+      schema_l += schema_add;
+      for (int i = 0; i < instances_per_definition_l; i++)
+        definitions_l[definition].instances[i] += instance_add;
+    }
+  };
+
+  // clang-format off
+  #define AddToSchemaAndInstances(schema_add, instance_add) \
+    RndDef::Add(definitions, schema, instances_per_definition, \
+                schema_add, instance_add, definition)
+
+  #define Dummy() \
+    RndDef::Add(definitions, schema, instances_per_definition, \
+                "byte", "1", definition)
+  // clang-format on
+
+  RndDef definitions[num_definitions];
+
+  // We are going to generate num_definitions, the first
+  // num_struct_definitions will be structs, the rest tables. For each
+  // generate random fields, some of which may be struct/table types
+  // referring to previously generated structs/tables.
+  // Simultanenously, we generate instances_per_definition JSON data
+  // definitions, which will have identical structure to the schema
+  // being generated. We generate multiple instances such that when creating
+  // hierarchy, we get some variety by picking one randomly.
+  for (int definition = 0; definition < num_definitions; definition++) {
+    std::string definition_name = "D" + flatbuffers::NumToString(definition);
+
+    bool is_struct = definition < num_struct_definitions;
+
+    AddToSchemaAndInstances(
+        ((is_struct ? "struct " : "table ") + definition_name + " {\n").c_str(),
+        "{\n");
+
+    for (int field = 0; field < fields_per_definition; field++) {
+      const bool is_last_field = field == fields_per_definition - 1;
+
+      // Deprecate 1 in deprecation_rate fields. Only table fields can be
+      // deprecated.
+      // Don't deprecate the last field to avoid dangling commas in JSON.
+      const bool deprecated =
+          !is_struct && !is_last_field && (lcg_rand() % deprecation_rate == 0);
+
+      std::string field_name = "f" + flatbuffers::NumToString(field);
+      AddToSchemaAndInstances(("  " + field_name + ":").c_str(),
+                              deprecated ? "" : (field_name + ": ").c_str());
+      // Pick random type:
+      auto base_type = static_cast<flatbuffers::BaseType>(
+          lcg_rand() % (flatbuffers::BASE_TYPE_UNION + 1));
+      switch (base_type) {
+        case flatbuffers::BASE_TYPE_STRING:
+          if (is_struct) {
+            Dummy();  // No strings in structs.
+          } else {
+            AddToSchemaAndInstances("string", deprecated ? "" : "\"hi\"");
+          }
+          break;
+        case flatbuffers::BASE_TYPE_VECTOR:
+          if (is_struct) {
+            Dummy();  // No vectors in structs.
+          } else {
+            AddToSchemaAndInstances("[ubyte]",
+                                    deprecated ? "" : "[\n0,\n1,\n255\n]");
+          }
+          break;
+        case flatbuffers::BASE_TYPE_NONE:
+        case flatbuffers::BASE_TYPE_UTYPE:
+        case flatbuffers::BASE_TYPE_STRUCT:
+        case flatbuffers::BASE_TYPE_UNION:
+          if (definition) {
+            // Pick a random previous definition and random data instance of
+            // that definition.
+            int defref = lcg_rand() % definition;
+            int instance = lcg_rand() % instances_per_definition;
+            AddToSchemaAndInstances(
+                ("D" + flatbuffers::NumToString(defref)).c_str(),
+                deprecated ? ""
+                           : definitions[defref].instances[instance].c_str());
+          } else {
+            // If this is the first definition, we have no definition we can
+            // refer to.
+            Dummy();
+          }
+          break;
+        case flatbuffers::BASE_TYPE_BOOL:
+          AddToSchemaAndInstances(
+              "bool", deprecated ? "" : (lcg_rand() % 2 ? "true" : "false"));
+          break;
+        case flatbuffers::BASE_TYPE_ARRAY:
+          if (!is_struct) {
+            AddToSchemaAndInstances(
+                "ubyte",
+                deprecated ? "" : "255");  // No fixed-length arrays in tables.
+          } else {
+            AddToSchemaAndInstances("[int:3]", deprecated ? "" : "[\n,\n,\n]");
+          }
+          break;
+        default:
+          // All the scalar types.
+          schema += flatbuffers::kTypeNames[base_type];
+
+          if (!deprecated) {
+            // We want each instance to use its own random value.
+            for (int inst = 0; inst < instances_per_definition; inst++)
+              definitions[definition].instances[inst] +=
+                  flatbuffers::IsFloat(base_type)
+                      ? flatbuffers::NumToString<double>(lcg_rand() % 128)
+                            .c_str()
+                      : flatbuffers::NumToString<int>(lcg_rand() % 128).c_str();
+          }
+      }
+      AddToSchemaAndInstances(deprecated ? "(deprecated);\n" : ";\n",
+                              deprecated ? "" : is_last_field ? "\n" : ",\n");
+    }
+    AddToSchemaAndInstances("}\n\n", "}");
+  }
+
+  schema += "root_type D" + flatbuffers::NumToString(num_definitions - 1);
+  schema += ";\n";
+
+  flatbuffers::Parser parser;
+
+  // Will not compare against the original if we don't write defaults
+  parser.builder_.ForceDefaults(true);
+
+  // Parse the schema, parse the generated data, then generate text back
+  // from the binary and compare against the original.
+  TEST_EQ(parser.Parse(schema.c_str()), true);
+
+  const std::string &json =
+      definitions[num_definitions - 1].instances[0] + "\n";
+
+  TEST_EQ(parser.Parse(json.c_str()), true);
+
+  std::string jsongen;
+  parser.opts.indent_step = 0;
+  auto result =
+      GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
+  TEST_EQ(result, true);
+
+  if (jsongen != json) {
+    // These strings are larger than a megabyte, so we show the bytes around
+    // the first bytes that are different rather than the whole string.
+    size_t len = std::min(json.length(), jsongen.length());
+    for (size_t i = 0; i < len; i++) {
+      if (json[i] != jsongen[i]) {
+        i -= std::min(static_cast<size_t>(10), i);  // show some context;
+        size_t end = std::min(len, i + 20);
+        for (; i < end; i++)
+          TEST_OUTPUT_LINE("at %d: found \"%c\", expected \"%c\"\n",
+                           static_cast<int>(i), jsongen[i], json[i]);
+        break;
+      }
+    }
+    TEST_NOTNULL(NULL);
+  }
+
+  // clang-format off
+  #ifdef FLATBUFFERS_TEST_VERBOSE
+    TEST_OUTPUT_LINE("%dk schema tested with %dk of json\n",
+                     static_cast<int>(schema.length() / 1024),
+                     static_cast<int>(json.length() / 1024));
+  #endif
+  // clang-format on
+}
+
+// Test that parser errors are actually generated.
+void TestError_(const char *src, const char *error_substr, bool strict_json,
+                const char *file, int line, const char *func) {
+  flatbuffers::IDLOptions opts;
+  opts.strict_json = strict_json;
+  flatbuffers::Parser parser(opts);
+  if (parser.Parse(src)) {
+    TestFail("true", "false",
+             ("parser.Parse(\"" + std::string(src) + "\")").c_str(), file, line,
+             func);
+  } else if (!strstr(parser.error_.c_str(), error_substr)) {
+    TestFail(parser.error_.c_str(), error_substr,
+             ("parser.Parse(\"" + std::string(src) + "\")").c_str(), file, line,
+             func);
+  }
+}
+
+void TestError_(const char *src, const char *error_substr, const char *file,
+                int line, const char *func) {
+  TestError_(src, error_substr, false, file, line, func);
+}
+
+#ifdef _WIN32
+#  define TestError(src, ...) \
+    TestError_(src, __VA_ARGS__, __FILE__, __LINE__, __FUNCTION__)
+#else
+#  define TestError(src, ...) \
+    TestError_(src, __VA_ARGS__, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#endif
+
+// Test that parsing errors occur as we'd expect.
+// Also useful for coverage, making sure these paths are run.
+void ErrorTest() {
+  // In order they appear in idl_parser.cpp
+  TestError("table X { Y:byte; } root_type X; { Y: 999 }", "does not fit");
+  TestError("\"\0", "illegal");
+  TestError("\"\\q", "escape code");
+  TestError("table ///", "documentation");
+  TestError("@", "illegal");
+  TestError("table 1", "expecting");
+  TestError("table X { Y:[[int]]; }", "nested vector");
+  TestError("table X { Y:1; }", "illegal type");
+  TestError("table X { Y:int; Y:int; }", "field already");
+  TestError("table Y {} table X { Y:int; }", "same as table");
+  TestError("struct X { Y:string; }", "only scalar");
+  TestError("table X { Y:string = \"\"; }", "default values");
+  TestError("struct X { a:uint = 42; }", "default values");
+  TestError("enum Y:byte { Z = 1 } table X { y:Y; }", "not part of enum");
+  TestError("struct X { Y:int (deprecated); }", "deprecate");
+  TestError("union Z { X } table X { Y:Z; } root_type X; { Y: {}, A:1 }",
+            "missing type field");
+  TestError("union Z { X } table X { Y:Z; } root_type X; { Y_type: 99, Y: {",
+            "type id");
+  TestError("table X { Y:int; } root_type X; { Z:", "unknown field");
+  TestError("table X { Y:int; } root_type X; { Y:", "string constant", true);
+  TestError("table X { Y:int; } root_type X; { \"Y\":1, }", "string constant",
+            true);
+  TestError(
+      "struct X { Y:int; Z:int; } table W { V:X; } root_type W; "
+      "{ V:{ Y:1 } }",
+      "wrong number");
+  TestError("enum E:byte { A } table X { Y:E; } root_type X; { Y:U }",
+            "unknown enum value");
+  TestError("table X { Y:byte; } root_type X; { Y:; }", "starting");
+  TestError("enum X:byte { Y } enum X {", "enum already");
+  TestError("enum X:float {}", "underlying");
+  TestError("enum X:byte { Y, Y }", "value already");
+  TestError("enum X:byte { Y=2, Z=1 }", "ascending");
+  TestError("table X { Y:int; } table X {", "datatype already");
+  TestError("struct X (force_align: 7) { Y:int; }", "force_align");
+  TestError("struct X {}", "size 0");
+  TestError("{}", "no root");
+  TestError("table X { Y:byte; } root_type X; { Y:1 } { Y:1 }", "end of file");
+  TestError("table X { Y:byte; } root_type X; { Y:1 } table Y{ Z:int }",
+            "end of file");
+  TestError("root_type X;", "unknown root");
+  TestError("struct X { Y:int; } root_type X;", "a table");
+  TestError("union X { Y }", "referenced");
+  TestError("union Z { X } struct X { Y:int; }", "only tables");
+  TestError("table X { Y:[int]; YLength:int; }", "clash");
+  TestError("table X { Y:byte; } root_type X; { Y:1, Y:2 }", "more than once");
+  // float to integer conversion is forbidden
+  TestError("table X { Y:int; } root_type X; { Y:1.0 }", "float");
+  TestError("table X { Y:bool; } root_type X; { Y:1.0 }", "float");
+  TestError("enum X:bool { Y = true }", "must be integral");
+}
+
+template<typename T>
+T TestValue(const char *json, const char *type_name,
+            const char *decls = nullptr) {
+  flatbuffers::Parser parser;
+  parser.builder_.ForceDefaults(true);  // return defaults
+  auto check_default = json ? false : true;
+  if (check_default) { parser.opts.output_default_scalars_in_json = true; }
+  // Simple schema.
+  std::string schema = std::string(decls ? decls : "") + "\n" +
+                       "table X { Y:" + std::string(type_name) +
+                       "; } root_type X;";
+  auto schema_done = parser.Parse(schema.c_str());
+  TEST_EQ_STR(parser.error_.c_str(), "");
+  TEST_EQ(schema_done, true);
+
+  auto done = parser.Parse(check_default ? "{}" : json);
+  TEST_EQ_STR(parser.error_.c_str(), "");
+  TEST_EQ(done, true);
+
+  // Check with print.
+  std::string print_back;
+  parser.opts.indent_step = -1;
+  TEST_EQ(GenerateText(parser, parser.builder_.GetBufferPointer(), &print_back),
+          true);
+  // restore value from its default
+  if (check_default) { TEST_EQ(parser.Parse(print_back.c_str()), true); }
+
+  auto root = flatbuffers::GetRoot<flatbuffers::Table>(
+      parser.builder_.GetBufferPointer());
+  return root->GetField<T>(flatbuffers::FieldIndexToOffset(0), 0);
+}
+
+bool FloatCompare(float a, float b) { return fabs(a - b) < 0.001; }
+
+// Additional parser testing not covered elsewhere.
+void ValueTest() {
+  // Test scientific notation numbers.
+  TEST_EQ(FloatCompare(TestValue<float>("{ Y:0.0314159e+2 }", "float"),
+                       3.14159f),
+          true);
+  // number in string
+  TEST_EQ(FloatCompare(TestValue<float>("{ Y:\"0.0314159e+2\" }", "float"),
+                       3.14159f),
+          true);
+
+  // Test conversion functions.
+  TEST_EQ(FloatCompare(TestValue<float>("{ Y:cos(rad(180)) }", "float"), -1),
+          true);
+
+  // int embedded to string
+  TEST_EQ(TestValue<int>("{ Y:\"-876\" }", "int=-123"), -876);
+  TEST_EQ(TestValue<int>("{ Y:\"876\" }", "int=-123"), 876);
+
+  // Test negative hex constant.
+  TEST_EQ(TestValue<int>("{ Y:-0x8ea0 }", "int=-0x8ea0"), -36512);
+  TEST_EQ(TestValue<int>(nullptr, "int=-0x8ea0"), -36512);
+
+  // positive hex constant
+  TEST_EQ(TestValue<int>("{ Y:0x1abcdef }", "int=0x1"), 0x1abcdef);
+  // with optional '+' sign
+  TEST_EQ(TestValue<int>("{ Y:+0x1abcdef }", "int=+0x1"), 0x1abcdef);
+  // hex in string
+  TEST_EQ(TestValue<int>("{ Y:\"0x1abcdef\" }", "int=+0x1"), 0x1abcdef);
+
+  // Make sure we do unsigned 64bit correctly.
+  TEST_EQ(TestValue<uint64_t>("{ Y:12335089644688340133 }", "ulong"),
+          12335089644688340133ULL);
+
+  // bool in string
+  TEST_EQ(TestValue<bool>("{ Y:\"false\" }", "bool=true"), false);
+  TEST_EQ(TestValue<bool>("{ Y:\"true\" }", "bool=\"true\""), true);
+  TEST_EQ(TestValue<bool>("{ Y:'false' }", "bool=true"), false);
+  TEST_EQ(TestValue<bool>("{ Y:'true' }", "bool=\"true\""), true);
+
+  // check comments before and after json object
+  TEST_EQ(TestValue<int>("/*before*/ { Y:1 } /*after*/", "int"), 1);
+  TEST_EQ(TestValue<int>("//before \n { Y:1 } //after", "int"), 1);
+
+}
+
+void NestedListTest() {
+  flatbuffers::Parser parser1;
+  TEST_EQ(parser1.Parse("struct Test { a:short; b:byte; } table T { F:[Test]; }"
+                        "root_type T;"
+                        "{ F:[ [10,20], [30,40]] }"),
+          true);
+}
+
+void EnumStringsTest() {
+  flatbuffers::Parser parser1;
+  TEST_EQ(parser1.Parse("enum E:byte { A, B, C } table T { F:[E]; }"
+                        "root_type T;"
+                        "{ F:[ A, B, \"C\", \"A B C\" ] }"),
+          true);
+  flatbuffers::Parser parser2;
+  TEST_EQ(parser2.Parse("enum E:byte { A, B, C } table T { F:[int]; }"
+                        "root_type T;"
+                        "{ F:[ \"E.C\", \"E.A E.B E.C\" ] }"),
+          true);
+  // unsigned bit_flags
+  flatbuffers::Parser parser3;
+  TEST_EQ(
+      parser3.Parse("enum E:uint16 (bit_flags) { F0, F07=7, F08, F14=14, F15 }"
+                    " table T { F: E = \"F15 F08\"; }"
+                    "root_type T;"),
+      true);
+}
+
+void EnumNamesTest() {
+  TEST_EQ_STR("Red", EnumNameColor(Color_Red));
+  TEST_EQ_STR("Green", EnumNameColor(Color_Green));
+  TEST_EQ_STR("Blue", EnumNameColor(Color_Blue));
+  // Check that Color to string don't crash while decode a mixture of Colors.
+  // 1) Example::Color enum is enum with unfixed underlying type.
+  // 2) Valid enum range: [0; 2^(ceil(log2(Color_ANY))) - 1].
+  // Consequence: A value is out of this range will lead to UB (since C++17).
+  // For details see C++17 standard or explanation on the SO:
+  // stackoverflow.com/questions/18195312/what-happens-if-you-static-cast-invalid-value-to-enum-class
+  TEST_EQ_STR("", EnumNameColor(static_cast<Color>(0)));
+  TEST_EQ_STR("", EnumNameColor(static_cast<Color>(Color_ANY-1)));
+  TEST_EQ_STR("", EnumNameColor(static_cast<Color>(Color_ANY+1)));
+}
+
+void EnumOutOfRangeTest() {
+  TestError("enum X:byte { Y = 128 }", "enum value does not fit");
+  TestError("enum X:byte { Y = -129 }", "enum value does not fit");
+  TestError("enum X:byte { Y = 126, Z0, Z1 }", "enum value does not fit");
+  TestError("enum X:ubyte { Y = -1 }", "enum value does not fit");
+  TestError("enum X:ubyte { Y = 256 }", "enum value does not fit");
+  TestError("enum X:ubyte { Y = 255, Z }", "enum value does not fit");
+  // Unions begin with an implicit "NONE = 0".
+  TestError("table Y{} union X { Y = -1 }",
+            "enum values must be specified in ascending order");
+  TestError("table Y{} union X { Y = 256 }", "enum value does not fit");
+  TestError("table Y{} union X { Y = 255, Z:Y }", "enum value does not fit");
+  TestError("enum X:int { Y = -2147483649 }", "enum value does not fit");
+  TestError("enum X:int { Y = 2147483648 }", "enum value does not fit");
+  TestError("enum X:uint { Y = -1 }", "enum value does not fit");
+  TestError("enum X:uint { Y = 4294967297 }", "enum value does not fit");
+  TestError("enum X:long { Y = 9223372036854775808 }", "does not fit");
+  TestError("enum X:long { Y = 9223372036854775807, Z }", "enum value does not fit");
+  TestError("enum X:ulong { Y = -1 }", "does not fit");
+  TestError("enum X:ubyte (bit_flags) { Y=8 }", "bit flag out");
+  TestError("enum X:byte (bit_flags) { Y=7 }", "must be unsigned"); // -128
+  // bit_flgs out of range
+  TestError("enum X:ubyte (bit_flags) { Y0,Y1,Y2,Y3,Y4,Y5,Y6,Y7,Y8 }", "out of range");
+}
+
+void EnumValueTest() {
+  // json: "{ Y:0 }", schema: table X { Y : "E"}
+  // 0 in enum (V=0) E then Y=0 is valid.
+  TEST_EQ(TestValue<int>("{ Y:0 }", "E", "enum E:int { V }"), 0);
+  TEST_EQ(TestValue<int>("{ Y:V }", "E", "enum E:int { V }"), 0);
+  // A default value of Y is 0.
+  TEST_EQ(TestValue<int>("{ }", "E", "enum E:int { V }"), 0);
+  TEST_EQ(TestValue<int>("{ Y:5 }", "E=V", "enum E:int { V=5 }"), 5);
+  // Generate json with defaults and check.
+  TEST_EQ(TestValue<int>(nullptr, "E=V", "enum E:int { V=5 }"), 5);
+  // 5 in enum
+  TEST_EQ(TestValue<int>("{ Y:5 }", "E", "enum E:int { Z, V=5 }"), 5);
+  TEST_EQ(TestValue<int>("{ Y:5 }", "E=V", "enum E:int { Z, V=5 }"), 5);
+  // Generate json with defaults and check.
+  TEST_EQ(TestValue<int>(nullptr, "E", "enum E:int { Z, V=5 }"), 0);
+  TEST_EQ(TestValue<int>(nullptr, "E=V", "enum E:int { Z, V=5 }"), 5);
+  // u84 test
+  TEST_EQ(TestValue<uint64_t>(nullptr, "E=V",
+                              "enum E:ulong { V = 13835058055282163712 }"),
+          13835058055282163712ULL);
+  TEST_EQ(TestValue<uint64_t>(nullptr, "E=V",
+                              "enum E:ulong { V = 18446744073709551615 }"),
+          18446744073709551615ULL);
+  // Assign non-enum value to enum field. Is it right?
+  TEST_EQ(TestValue<int>("{ Y:7 }", "E", "enum E:int { V = 0 }"), 7);
+}
+
+void IntegerOutOfRangeTest() {
+  TestError("table T { F:byte; } root_type T; { F:128 }",
+            "constant does not fit");
+  TestError("table T { F:byte; } root_type T; { F:-129 }",
+            "constant does not fit");
+  TestError("table T { F:ubyte; } root_type T; { F:256 }",
+            "constant does not fit");
+  TestError("table T { F:ubyte; } root_type T; { F:-1 }",
+            "constant does not fit");
+  TestError("table T { F:short; } root_type T; { F:32768 }",
+            "constant does not fit");
+  TestError("table T { F:short; } root_type T; { F:-32769 }",
+            "constant does not fit");
+  TestError("table T { F:ushort; } root_type T; { F:65536 }",
+            "constant does not fit");
+  TestError("table T { F:ushort; } root_type T; { F:-1 }",
+            "constant does not fit");
+  TestError("table T { F:int; } root_type T; { F:2147483648 }",
+            "constant does not fit");
+  TestError("table T { F:int; } root_type T; { F:-2147483649 }",
+            "constant does not fit");
+  TestError("table T { F:uint; } root_type T; { F:4294967296 }",
+            "constant does not fit");
+  TestError("table T { F:uint; } root_type T; { F:-1 }",
+            "constant does not fit");
+  // Check fixed width aliases
+  TestError("table X { Y:uint8; } root_type X; { Y: -1 }", "does not fit");
+  TestError("table X { Y:uint8; } root_type X; { Y: 256 }", "does not fit");
+  TestError("table X { Y:uint16; } root_type X; { Y: -1 }", "does not fit");
+  TestError("table X { Y:uint16; } root_type X; { Y: 65536 }", "does not fit");
+  TestError("table X { Y:uint32; } root_type X; { Y: -1 }", "");
+  TestError("table X { Y:uint32; } root_type X; { Y: 4294967296 }",
+            "does not fit");
+  TestError("table X { Y:uint64; } root_type X; { Y: -1 }", "");
+  TestError("table X { Y:uint64; } root_type X; { Y: -9223372036854775809 }",
+            "does not fit");
+  TestError("table X { Y:uint64; } root_type X; { Y: 18446744073709551616 }",
+            "does not fit");
+
+  TestError("table X { Y:int8; } root_type X; { Y: -129 }", "does not fit");
+  TestError("table X { Y:int8; } root_type X; { Y: 128 }", "does not fit");
+  TestError("table X { Y:int16; } root_type X; { Y: -32769 }", "does not fit");
+  TestError("table X { Y:int16; } root_type X; { Y: 32768 }", "does not fit");
+  TestError("table X { Y:int32; } root_type X; { Y: -2147483649 }", "");
+  TestError("table X { Y:int32; } root_type X; { Y: 2147483648 }",
+            "does not fit");
+  TestError("table X { Y:int64; } root_type X; { Y: -9223372036854775809 }",
+            "does not fit");
+  TestError("table X { Y:int64; } root_type X; { Y: 9223372036854775808 }",
+            "does not fit");
+  // check out-of-int64 as int8
+  TestError("table X { Y:int8; } root_type X; { Y: -9223372036854775809 }",
+            "does not fit");
+  TestError("table X { Y:int8; } root_type X; { Y: 9223372036854775808 }",
+            "does not fit");
+
+  // Check default values
+  TestError("table X { Y:int64=-9223372036854775809; } root_type X; {}",
+            "does not fit");
+  TestError("table X { Y:int64= 9223372036854775808; } root_type X; {}",
+            "does not fit");
+  TestError("table X { Y:uint64; } root_type X; { Y: -1 }", "");
+  TestError("table X { Y:uint64=-9223372036854775809; } root_type X; {}",
+            "does not fit");
+  TestError("table X { Y:uint64= 18446744073709551616; } root_type X; {}",
+            "does not fit");
+}
+
+void IntegerBoundaryTest() {
+  // Check numerical compatibility with non-C++ languages.
+  // By the C++ standard, std::numerical_limits<int64_t>::min() == -9223372036854775807 (-2^63+1) or less*
+  // The Flatbuffers grammar and most of the languages (C#, Java, Rust) expect
+  // that minimum values are: -128, -32768,.., -9223372036854775808.
+  // Since C++20, static_cast<int64>(0x8000000000000000ULL) is well-defined two's complement cast.
+  // Therefore -9223372036854775808 should be valid negative value.
+  TEST_EQ(flatbuffers::numeric_limits<int8_t>::min(), -128);
+  TEST_EQ(flatbuffers::numeric_limits<int8_t>::max(), 127);
+  TEST_EQ(flatbuffers::numeric_limits<int16_t>::min(), -32768);
+  TEST_EQ(flatbuffers::numeric_limits<int16_t>::max(), 32767);
+  TEST_EQ(flatbuffers::numeric_limits<int32_t>::min() + 1, -2147483647);
+  TEST_EQ(flatbuffers::numeric_limits<int32_t>::max(), 2147483647ULL);
+  TEST_EQ(flatbuffers::numeric_limits<int64_t>::min() + 1LL,
+          -9223372036854775807LL);
+  TEST_EQ(flatbuffers::numeric_limits<int64_t>::max(), 9223372036854775807ULL);
+  TEST_EQ(flatbuffers::numeric_limits<uint8_t>::max(), 255);
+  TEST_EQ(flatbuffers::numeric_limits<uint16_t>::max(), 65535);
+  TEST_EQ(flatbuffers::numeric_limits<uint32_t>::max(), 4294967295ULL);
+  TEST_EQ(flatbuffers::numeric_limits<uint64_t>::max(),
+          18446744073709551615ULL);
+
+  TEST_EQ(TestValue<int8_t>("{ Y:127 }", "byte"), 127);
+  TEST_EQ(TestValue<int8_t>("{ Y:-128 }", "byte"), -128);
+  TEST_EQ(TestValue<uint8_t>("{ Y:255 }", "ubyte"), 255);
+  TEST_EQ(TestValue<uint8_t>("{ Y:0 }", "ubyte"), 0);
+  TEST_EQ(TestValue<int16_t>("{ Y:32767 }", "short"), 32767);
+  TEST_EQ(TestValue<int16_t>("{ Y:-32768 }", "short"), -32768);
+  TEST_EQ(TestValue<uint16_t>("{ Y:65535 }", "ushort"), 65535);
+  TEST_EQ(TestValue<uint16_t>("{ Y:0 }", "ushort"), 0);
+  TEST_EQ(TestValue<int32_t>("{ Y:2147483647 }", "int"), 2147483647);
+  TEST_EQ(TestValue<int32_t>("{ Y:-2147483648 }", "int") + 1, -2147483647);
+  TEST_EQ(TestValue<uint32_t>("{ Y:4294967295 }", "uint"), 4294967295);
+  TEST_EQ(TestValue<uint32_t>("{ Y:0 }", "uint"), 0);
+  TEST_EQ(TestValue<int64_t>("{ Y:9223372036854775807 }", "long"),
+          9223372036854775807LL);
+  TEST_EQ(TestValue<int64_t>("{ Y:-9223372036854775808 }", "long") + 1LL,
+          -9223372036854775807LL);
+  TEST_EQ(TestValue<uint64_t>("{ Y:18446744073709551615 }", "ulong"),
+          18446744073709551615ULL);
+  TEST_EQ(TestValue<uint64_t>("{ Y:0 }", "ulong"), 0);
+  TEST_EQ(TestValue<uint64_t>("{ Y: 18446744073709551615 }", "uint64"),
+          18446744073709551615ULL);
+  // check that the default works
+  TEST_EQ(TestValue<uint64_t>(nullptr, "uint64 = 18446744073709551615"),
+          18446744073709551615ULL);
+}
+
+void ValidFloatTest() {
+  // check rounding to infinity
+  TEST_EQ(TestValue<float>("{ Y:+3.4029e+38 }", "float"), +infinityf);
+  TEST_EQ(TestValue<float>("{ Y:-3.4029e+38 }", "float"), -infinityf);
+  TEST_EQ(TestValue<double>("{ Y:+1.7977e+308 }", "double"), +infinityd);
+  TEST_EQ(TestValue<double>("{ Y:-1.7977e+308 }", "double"), -infinityd);
+
+  TEST_EQ(
+      FloatCompare(TestValue<float>("{ Y:0.0314159e+2 }", "float"), 3.14159f),
+      true);
+  // float in string
+  TEST_EQ(FloatCompare(TestValue<float>("{ Y:\" 0.0314159e+2  \" }", "float"),
+                       3.14159f),
+          true);
+
+  TEST_EQ(TestValue<float>("{ Y:1 }", "float"), 1.0f);
+  TEST_EQ(TestValue<float>("{ Y:1.0 }", "float"), 1.0f);
+  TEST_EQ(TestValue<float>("{ Y:1. }", "float"), 1.0f);
+  TEST_EQ(TestValue<float>("{ Y:+1. }", "float"), 1.0f);
+  TEST_EQ(TestValue<float>("{ Y:-1. }", "float"), -1.0f);
+  TEST_EQ(TestValue<float>("{ Y:1.e0 }", "float"), 1.0f);
+  TEST_EQ(TestValue<float>("{ Y:1.e+0 }", "float"), 1.0f);
+  TEST_EQ(TestValue<float>("{ Y:1.e-0 }", "float"), 1.0f);
+  TEST_EQ(TestValue<float>("{ Y:0.125 }", "float"), 0.125f);
+  TEST_EQ(TestValue<float>("{ Y:.125 }", "float"), 0.125f);
+  TEST_EQ(TestValue<float>("{ Y:-.125 }", "float"), -0.125f);
+  TEST_EQ(TestValue<float>("{ Y:+.125 }", "float"), +0.125f);
+  TEST_EQ(TestValue<float>("{ Y:5 }", "float"), 5.0f);
+  TEST_EQ(TestValue<float>("{ Y:\"5\" }", "float"), 5.0f);
+
+  #if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
+  // Old MSVC versions may have problem with this check.
+  // https://www.exploringbinary.com/visual-c-plus-plus-strtod-still-broken/
+  TEST_EQ(TestValue<double>("{ Y:6.9294956446009195e15 }", "double"),
+    6929495644600920.0);
+  // check nan's
+  TEST_EQ(std::isnan(TestValue<double>("{ Y:nan }", "double")), true);
+  TEST_EQ(std::isnan(TestValue<float>("{ Y:nan }", "float")), true);
+  TEST_EQ(std::isnan(TestValue<float>("{ Y:\"nan\" }", "float")), true);
+  TEST_EQ(std::isnan(TestValue<float>("{ Y:+nan }", "float")), true);
+  TEST_EQ(std::isnan(TestValue<float>("{ Y:-nan }", "float")), true);
+  TEST_EQ(std::isnan(TestValue<float>(nullptr, "float=nan")), true);
+  TEST_EQ(std::isnan(TestValue<float>(nullptr, "float=-nan")), true);
+  // check inf
+  TEST_EQ(TestValue<float>("{ Y:inf }", "float"), infinityf);
+  TEST_EQ(TestValue<float>("{ Y:\"inf\" }", "float"), infinityf);
+  TEST_EQ(TestValue<float>("{ Y:+inf }", "float"), infinityf);
+  TEST_EQ(TestValue<float>("{ Y:-inf }", "float"), -infinityf);
+  TEST_EQ(TestValue<float>(nullptr, "float=inf"), infinityf);
+  TEST_EQ(TestValue<float>(nullptr, "float=-inf"), -infinityf);
+  TestValue<double>(
+      "{ Y : [0.2, .2, 1.0, -1.0, -2., 2., 1e0, -1e0, 1.0e0, -1.0e0, -3.e2, "
+      "3.0e2] }",
+      "[double]");
+  TestValue<float>(
+      "{ Y : [0.2, .2, 1.0, -1.0, -2., 2., 1e0, -1e0, 1.0e0, -1.0e0, -3.e2, "
+      "3.0e2] }",
+      "[float]");
+
+  // Test binary format of float point.
+  // https://en.cppreference.com/w/cpp/language/floating_literal
+  // 0x11.12p-1 = (1*16^1 + 2*16^0 + 3*16^-1 + 4*16^-2) * 2^-1 =
+  TEST_EQ(TestValue<double>("{ Y:0x12.34p-1 }", "double"), 9.1015625);
+  // hex fraction 1.2 (decimal 1.125) scaled by 2^3, that is 9.0
+  TEST_EQ(TestValue<float>("{ Y:-0x0.2p0 }", "float"), -0.125f);
+  TEST_EQ(TestValue<float>("{ Y:-0x.2p1 }", "float"), -0.25f);
+  TEST_EQ(TestValue<float>("{ Y:0x1.2p3 }", "float"), 9.0f);
+  TEST_EQ(TestValue<float>("{ Y:0x10.1p0 }", "float"), 16.0625f);
+  TEST_EQ(TestValue<double>("{ Y:0x1.2p3 }", "double"), 9.0);
+  TEST_EQ(TestValue<double>("{ Y:0x10.1p0 }", "double"), 16.0625);
+  TEST_EQ(TestValue<double>("{ Y:0xC.68p+2 }", "double"), 49.625);
+  TestValue<double>("{ Y : [0x20.4ep1, +0x20.4ep1, -0x20.4ep1] }", "[double]");
+  TestValue<float>("{ Y : [0x20.4ep1, +0x20.4ep1, -0x20.4ep1] }", "[float]");
+
+#else   // FLATBUFFERS_HAS_NEW_STRTOD
+  TEST_OUTPUT_LINE("FLATBUFFERS_HAS_NEW_STRTOD tests skipped");
+#endif  // !FLATBUFFERS_HAS_NEW_STRTOD
+}
+
+void InvalidFloatTest() {
+  auto invalid_msg = "invalid number";
+  auto comma_msg = "expecting: ,";
+  TestError("table T { F:float; } root_type T; { F:1,0 }", "");
+  TestError("table T { F:float; } root_type T; { F:. }", "");
+  TestError("table T { F:float; } root_type T; { F:- }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:+ }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:-. }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:+. }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:.e }", "");
+  TestError("table T { F:float; } root_type T; { F:-e }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:+e }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:-.e }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:+.e }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:-e1 }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:+e1 }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:1.0e+ }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:1.0e- }", invalid_msg);
+  // exponent pP is mandatory for hex-float
+  TestError("table T { F:float; } root_type T; { F:0x0 }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:-0x. }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:0x. }", invalid_msg);
+  // eE not exponent in hex-float!
+  TestError("table T { F:float; } root_type T; { F:0x0.0e+ }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:0x0.0e- }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:0x0.0p }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:0x0.0p+ }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:0x0.0p- }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:0x0.0pa1 }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:0x0.0e+ }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:0x0.0e- }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:0x0.0e+0 }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:0x0.0e-0 }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:0x0.0ep+ }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:0x0.0ep- }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:1.2.3 }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:1.2.e3 }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:1.2e.3 }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:1.2e0.3 }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:1.2e3. }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:1.2e3.0 }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:+-1.0 }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:1.0e+-1 }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:\"1.0e+-1\" }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:1.e0e }", comma_msg);
+  TestError("table T { F:float; } root_type T; { F:0x1.p0e }", comma_msg);
+  TestError("table T { F:float; } root_type T; { F:\" 0x10 \" }", invalid_msg);
+  // floats in string
+  TestError("table T { F:float; } root_type T; { F:\"1,2.\" }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:\"1.2e3.\" }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:\"0x1.p0e\" }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:\"0x1.0\" }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:\" 0x1.0\" }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:\"+ 0\" }", invalid_msg);
+  // disable escapes for "number-in-string"
+  TestError("table T { F:float; } root_type T; { F:\"\\f1.2e3.\" }", "invalid");
+  TestError("table T { F:float; } root_type T; { F:\"\\t1.2e3.\" }", "invalid");
+  TestError("table T { F:float; } root_type T; { F:\"\\n1.2e3.\" }", "invalid");
+  TestError("table T { F:float; } root_type T; { F:\"\\r1.2e3.\" }", "invalid");
+  TestError("table T { F:float; } root_type T; { F:\"4\\x005\" }", "invalid");
+  TestError("table T { F:float; } root_type T; { F:\"\'12\'\" }", invalid_msg);
+  // null is not a number constant!
+  TestError("table T { F:float; } root_type T; { F:\"null\" }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:null }", invalid_msg);
+}
+
+void GenerateTableTextTest() {
+  std::string schemafile;
+  std::string jsonfile;
+  bool ok =
+      flatbuffers::LoadFile((test_data_path + "monster_test.fbs").c_str(),
+                            false, &schemafile) &&
+      flatbuffers::LoadFile((test_data_path + "monsterdata_test.json").c_str(),
+                            false, &jsonfile);
+  TEST_EQ(ok, true);
+  auto include_test_path =
+      flatbuffers::ConCatPathFileName(test_data_path, "include_test");
+  const char *include_directories[] = {test_data_path.c_str(),
+                                       include_test_path.c_str(), nullptr};
+  flatbuffers::IDLOptions opt;
+  opt.indent_step = -1;
+  flatbuffers::Parser parser(opt);
+  ok = parser.Parse(schemafile.c_str(), include_directories) &&
+       parser.Parse(jsonfile.c_str(), include_directories);
+  TEST_EQ(ok, true);
+  // Test root table
+  const Monster *monster = GetMonster(parser.builder_.GetBufferPointer());
+  std::string jsongen;
+  auto result = GenerateTextFromTable(parser, monster, "MyGame.Example.Monster",
+                                      &jsongen);
+  TEST_EQ(result, true);
+  // Test sub table
+  const Vec3 *pos = monster->pos();
+  jsongen.clear();
+  result = GenerateTextFromTable(parser, pos, "MyGame.Example.Vec3", &jsongen);
+  TEST_EQ(result, true);
+  TEST_EQ_STR(
+      jsongen.c_str(),
+      "{x: 1.0,y: 2.0,z: 3.0,test1: 3.0,test2: \"Green\",test3: {a: 5,b: 6}}");
+  const Test &test3 = pos->test3();
+  jsongen.clear();
+  result =
+      GenerateTextFromTable(parser, &test3, "MyGame.Example.Test", &jsongen);
+  TEST_EQ(result, true);
+  TEST_EQ_STR(jsongen.c_str(), "{a: 5,b: 6}");
+  const Test *test4 = monster->test4()->Get(0);
+  jsongen.clear();
+  result =
+      GenerateTextFromTable(parser, test4, "MyGame.Example.Test", &jsongen);
+  TEST_EQ(result, true);
+  TEST_EQ_STR(jsongen.c_str(), "{a: 10,b: 20}");
+}
+
+template<typename T>
+void NumericUtilsTestInteger(const char *lower, const char *upper) {
+  T x;
+  TEST_EQ(flatbuffers::StringToNumber("1q", &x), false);
+  TEST_EQ(x, 0);
+  TEST_EQ(flatbuffers::StringToNumber(upper, &x), false);
+  TEST_EQ(x, flatbuffers::numeric_limits<T>::max());
+  TEST_EQ(flatbuffers::StringToNumber(lower, &x), false);
+  auto expval = flatbuffers::is_unsigned<T>::value
+                    ? flatbuffers::numeric_limits<T>::max()
+                    : flatbuffers::numeric_limits<T>::lowest();
+  TEST_EQ(x, expval);
+}
+
+template<typename T>
+void NumericUtilsTestFloat(const char *lower, const char *upper) {
+  T f;
+  TEST_EQ(flatbuffers::StringToNumber("", &f), false);
+  TEST_EQ(flatbuffers::StringToNumber("1q", &f), false);
+  TEST_EQ(f, 0);
+  TEST_EQ(flatbuffers::StringToNumber(upper, &f), true);
+  TEST_EQ(f, +flatbuffers::numeric_limits<T>::infinity());
+  TEST_EQ(flatbuffers::StringToNumber(lower, &f), true);
+  TEST_EQ(f, -flatbuffers::numeric_limits<T>::infinity());
+}
+
+void NumericUtilsTest() {
+  NumericUtilsTestInteger<uint64_t>("-1", "18446744073709551616");
+  NumericUtilsTestInteger<uint8_t>("-1", "256");
+  NumericUtilsTestInteger<int64_t>("-9223372036854775809",
+                                   "9223372036854775808");
+  NumericUtilsTestInteger<int8_t>("-129", "128");
+  NumericUtilsTestFloat<float>("-3.4029e+38", "+3.4029e+38");
+  NumericUtilsTestFloat<float>("-1.7977e+308", "+1.7977e+308");
+}
+
+void IsAsciiUtilsTest() {
+  char c = -128;
+  for (int cnt = 0; cnt < 256; cnt++) {
+    auto alpha = (('a' <= c) && (c <= 'z')) || (('A' <= c) && (c <= 'Z'));
+    auto dec = (('0' <= c) && (c <= '9'));
+    auto hex = (('a' <= c) && (c <= 'f')) || (('A' <= c) && (c <= 'F'));
+    TEST_EQ(flatbuffers::is_alpha(c), alpha);
+    TEST_EQ(flatbuffers::is_alnum(c), alpha || dec);
+    TEST_EQ(flatbuffers::is_digit(c), dec);
+    TEST_EQ(flatbuffers::is_xdigit(c), dec || hex);
+    c += 1;
+  }
+}
+
+void UnicodeTest() {
+  flatbuffers::Parser parser;
+  // Without setting allow_non_utf8 = true, we treat \x sequences as byte
+  // sequences which are then validated as UTF-8.
+  TEST_EQ(parser.Parse("table T { F:string; }"
+                       "root_type T;"
+                       "{ F:\"\\u20AC\\u00A2\\u30E6\\u30FC\\u30B6\\u30FC"
+                       "\\u5225\\u30B5\\u30A4\\u30C8\\xE2\\x82\\xAC\\u0080\\uD8"
+                       "3D\\uDE0E\" }"),
+          true);
+  std::string jsongen;
+  parser.opts.indent_step = -1;
+  auto result =
+      GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
+  TEST_EQ(result, true);
+  TEST_EQ_STR(jsongen.c_str(),
+              "{F: \"\\u20AC\\u00A2\\u30E6\\u30FC\\u30B6\\u30FC"
+              "\\u5225\\u30B5\\u30A4\\u30C8\\u20AC\\u0080\\uD83D\\uDE0E\"}");
+}
+
+void UnicodeTestAllowNonUTF8() {
+  flatbuffers::Parser parser;
+  parser.opts.allow_non_utf8 = true;
+  TEST_EQ(
+      parser.Parse(
+          "table T { F:string; }"
+          "root_type T;"
+          "{ F:\"\\u20AC\\u00A2\\u30E6\\u30FC\\u30B6\\u30FC"
+          "\\u5225\\u30B5\\u30A4\\u30C8\\x01\\x80\\u0080\\uD83D\\uDE0E\" }"),
+      true);
+  std::string jsongen;
+  parser.opts.indent_step = -1;
+  auto result =
+      GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
+  TEST_EQ(result, true);
+  TEST_EQ_STR(
+      jsongen.c_str(),
+      "{F: \"\\u20AC\\u00A2\\u30E6\\u30FC\\u30B6\\u30FC"
+      "\\u5225\\u30B5\\u30A4\\u30C8\\u0001\\x80\\u0080\\uD83D\\uDE0E\"}");
+}
+
+void UnicodeTestGenerateTextFailsOnNonUTF8() {
+  flatbuffers::Parser parser;
+  // Allow non-UTF-8 initially to model what happens when we load a binary
+  // flatbuffer from disk which contains non-UTF-8 strings.
+  parser.opts.allow_non_utf8 = true;
+  TEST_EQ(
+      parser.Parse(
+          "table T { F:string; }"
+          "root_type T;"
+          "{ F:\"\\u20AC\\u00A2\\u30E6\\u30FC\\u30B6\\u30FC"
+          "\\u5225\\u30B5\\u30A4\\u30C8\\x01\\x80\\u0080\\uD83D\\uDE0E\" }"),
+      true);
+  std::string jsongen;
+  parser.opts.indent_step = -1;
+  // Now, disallow non-UTF-8 (the default behavior) so GenerateText indicates
+  // failure.
+  parser.opts.allow_non_utf8 = false;
+  auto result =
+      GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
+  TEST_EQ(result, false);
+}
+
+void UnicodeSurrogatesTest() {
+  flatbuffers::Parser parser;
+
+  TEST_EQ(parser.Parse("table T { F:string (id: 0); }"
+                       "root_type T;"
+                       "{ F:\"\\uD83D\\uDCA9\"}"),
+          true);
+  auto root = flatbuffers::GetRoot<flatbuffers::Table>(
+      parser.builder_.GetBufferPointer());
+  auto string = root->GetPointer<flatbuffers::String *>(
+      flatbuffers::FieldIndexToOffset(0));
+  TEST_EQ_STR(string->c_str(), "\xF0\x9F\x92\xA9");
+}
+
+void UnicodeInvalidSurrogatesTest() {
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\\uD800\"}",
+      "unpaired high surrogate");
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\\uD800abcd\"}",
+      "unpaired high surrogate");
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\\uD800\\n\"}",
+      "unpaired high surrogate");
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\\uD800\\uD800\"}",
+      "multiple high surrogates");
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\\uDC00\"}",
+      "unpaired low surrogate");
+}
+
+void InvalidUTF8Test() {
+  // "1 byte" pattern, under min length of 2 bytes
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\x80\"}",
+      "illegal UTF-8 sequence");
+  // 2 byte pattern, string too short
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\xDF\"}",
+      "illegal UTF-8 sequence");
+  // 3 byte pattern, string too short
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\xEF\xBF\"}",
+      "illegal UTF-8 sequence");
+  // 4 byte pattern, string too short
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\xF7\xBF\xBF\"}",
+      "illegal UTF-8 sequence");
+  // "5 byte" pattern, string too short
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\xFB\xBF\xBF\xBF\"}",
+      "illegal UTF-8 sequence");
+  // "6 byte" pattern, string too short
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\xFD\xBF\xBF\xBF\xBF\"}",
+      "illegal UTF-8 sequence");
+  // "7 byte" pattern, string too short
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\xFE\xBF\xBF\xBF\xBF\xBF\"}",
+      "illegal UTF-8 sequence");
+  // "5 byte" pattern, over max length of 4 bytes
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\xFB\xBF\xBF\xBF\xBF\"}",
+      "illegal UTF-8 sequence");
+  // "6 byte" pattern, over max length of 4 bytes
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\xFD\xBF\xBF\xBF\xBF\xBF\"}",
+      "illegal UTF-8 sequence");
+  // "7 byte" pattern, over max length of 4 bytes
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\xFE\xBF\xBF\xBF\xBF\xBF\xBF\"}",
+      "illegal UTF-8 sequence");
+
+  // Three invalid encodings for U+000A (\n, aka NEWLINE)
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\xC0\x8A\"}",
+      "illegal UTF-8 sequence");
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\xE0\x80\x8A\"}",
+      "illegal UTF-8 sequence");
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\xF0\x80\x80\x8A\"}",
+      "illegal UTF-8 sequence");
+
+  // Two invalid encodings for U+00A9 (COPYRIGHT SYMBOL)
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\xE0\x81\xA9\"}",
+      "illegal UTF-8 sequence");
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\xF0\x80\x81\xA9\"}",
+      "illegal UTF-8 sequence");
+
+  // Invalid encoding for U+20AC (EURO SYMBOL)
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\xF0\x82\x82\xAC\"}",
+      "illegal UTF-8 sequence");
+
+  // UTF-16 surrogate values between U+D800 and U+DFFF cannot be encoded in
+  // UTF-8
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      // U+10400 "encoded" as U+D801 U+DC00
+      "{ F:\"\xED\xA0\x81\xED\xB0\x80\"}",
+      "illegal UTF-8 sequence");
+
+  // Check independence of identifier from locale.
+  std::string locale_ident;
+  locale_ident += "table T { F";
+  locale_ident += static_cast<char>(-32); // unsigned 0xE0
+  locale_ident += " :string; }";
+  locale_ident += "root_type T;";
+  locale_ident += "{}";
+  TestError(locale_ident.c_str(), "");
+}
+
+void UnknownFieldsTest() {
+  flatbuffers::IDLOptions opts;
+  opts.skip_unexpected_fields_in_json = true;
+  flatbuffers::Parser parser(opts);
+
+  TEST_EQ(parser.Parse("table T { str:string; i:int;}"
+                       "root_type T;"
+                       "{ str:\"test\","
+                       "unknown_string:\"test\","
+                       "\"unknown_string\":\"test\","
+                       "unknown_int:10,"
+                       "unknown_float:1.0,"
+                       "unknown_array: [ 1, 2, 3, 4],"
+                       "unknown_object: { i: 10 },"
+                       "\"unknown_object\": { \"i\": 10 },"
+                       "i:10}"),
+          true);
+
+  std::string jsongen;
+  parser.opts.indent_step = -1;
+  auto result =
+      GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
+  TEST_EQ(result, true);
+  TEST_EQ_STR(jsongen.c_str(), "{str: \"test\",i: 10}");
+}
+
+void ParseUnionTest() {
+  // Unions must be parseable with the type field following the object.
+  flatbuffers::Parser parser;
+  TEST_EQ(parser.Parse("table T { A:int; }"
+                       "union U { T }"
+                       "table V { X:U; }"
+                       "root_type V;"
+                       "{ X:{ A:1 }, X_type: T }"),
+          true);
+  // Unions must be parsable with prefixed namespace.
+  flatbuffers::Parser parser2;
+  TEST_EQ(parser2.Parse("namespace N; table A {} namespace; union U { N.A }"
+                        "table B { e:U; } root_type B;"
+                        "{ e_type: N_A, e: {} }"),
+          true);
+}
+
+void InvalidNestedFlatbufferTest() {
+  // First, load and parse FlatBuffer schema (.fbs)
+  std::string schemafile;
+  TEST_EQ(flatbuffers::LoadFile((test_data_path + "monster_test.fbs").c_str(),
+                                false, &schemafile),
+          true);
+  auto include_test_path =
+      flatbuffers::ConCatPathFileName(test_data_path, "include_test");
+  const char *include_directories[] = { test_data_path.c_str(),
+                                        include_test_path.c_str(), nullptr };
+  flatbuffers::Parser parser1;
+  TEST_EQ(parser1.Parse(schemafile.c_str(), include_directories), true);
+
+  // "color" inside nested flatbuffer contains invalid enum value
+  TEST_EQ(parser1.Parse("{ name: \"Bender\", testnestedflatbuffer: { name: "
+                        "\"Leela\", color: \"nonexistent\"}}"),
+          false);
+  // Check that Parser is destroyed correctly after parsing invalid json
+}
+
+void UnionVectorTest() {
+  // load FlatBuffer fbs schema and json.
+  std::string schemafile, jsonfile;
+  TEST_EQ(flatbuffers::LoadFile(
+              (test_data_path + "union_vector/union_vector.fbs").c_str(),
+              false, &schemafile),
+          true);
+  TEST_EQ(flatbuffers::LoadFile(
+              (test_data_path + "union_vector/union_vector.json").c_str(),
+              false, &jsonfile),
+          true);
+
+  // parse schema.
+  flatbuffers::IDLOptions idl_opts;
+  idl_opts.lang_to_generate |= flatbuffers::IDLOptions::kBinary;
+  flatbuffers::Parser parser(idl_opts);
+  TEST_EQ(parser.Parse(schemafile.c_str()), true);
+
+  flatbuffers::FlatBufferBuilder fbb;
+
+  // union types.
+  std::vector<uint8_t> types;
+  types.push_back(static_cast<uint8_t>(Character_Belle));
+  types.push_back(static_cast<uint8_t>(Character_MuLan));
+  types.push_back(static_cast<uint8_t>(Character_BookFan));
+  types.push_back(static_cast<uint8_t>(Character_Other));
+  types.push_back(static_cast<uint8_t>(Character_Unused));
+
+  // union values.
+  std::vector<flatbuffers::Offset<void>> characters;
+  characters.push_back(fbb.CreateStruct(BookReader(/*books_read=*/7)).Union());
+  characters.push_back(CreateAttacker(fbb, /*sword_attack_damage=*/5).Union());
+  characters.push_back(fbb.CreateStruct(BookReader(/*books_read=*/2)).Union());
+  characters.push_back(fbb.CreateString("Other").Union());
+  characters.push_back(fbb.CreateString("Unused").Union());
+
+  // create Movie.
+  const auto movie_offset =
+      CreateMovie(fbb, Character_Rapunzel,
+                  fbb.CreateStruct(Rapunzel(/*hair_length=*/6)).Union(),
+                  fbb.CreateVector(types), fbb.CreateVector(characters));
+  FinishMovieBuffer(fbb, movie_offset);
+  auto buf = fbb.GetBufferPointer();
+
+  flatbuffers::Verifier verifier(buf, fbb.GetSize());
+  TEST_EQ(VerifyMovieBuffer(verifier), true);
+
+  auto flat_movie = GetMovie(buf);
+
+  auto TestMovie = [](const Movie *movie) {
+    TEST_EQ(movie->main_character_type() == Character_Rapunzel, true);
+
+    auto cts = movie->characters_type();
+    TEST_EQ(movie->characters_type()->size(), 5);
+    TEST_EQ(cts->GetEnum<Character>(0) == Character_Belle, true);
+    TEST_EQ(cts->GetEnum<Character>(1) == Character_MuLan, true);
+    TEST_EQ(cts->GetEnum<Character>(2) == Character_BookFan, true);
+    TEST_EQ(cts->GetEnum<Character>(3) == Character_Other, true);
+    TEST_EQ(cts->GetEnum<Character>(4) == Character_Unused, true);
+
+    auto rapunzel = movie->main_character_as_Rapunzel();
+    TEST_NOTNULL(rapunzel);
+    TEST_EQ(rapunzel->hair_length(), 6);
+
+    auto cs = movie->characters();
+    TEST_EQ(cs->size(), 5);
+    auto belle = cs->GetAs<BookReader>(0);
+    TEST_EQ(belle->books_read(), 7);
+    auto mu_lan = cs->GetAs<Attacker>(1);
+    TEST_EQ(mu_lan->sword_attack_damage(), 5);
+    auto book_fan = cs->GetAs<BookReader>(2);
+    TEST_EQ(book_fan->books_read(), 2);
+    auto other = cs->GetAsString(3);
+    TEST_EQ_STR(other->c_str(), "Other");
+    auto unused = cs->GetAsString(4);
+    TEST_EQ_STR(unused->c_str(), "Unused");
+  };
+
+  TestMovie(flat_movie);
+
+  // Also test the JSON we loaded above.
+  TEST_EQ(parser.Parse(jsonfile.c_str()), true);
+  auto jbuf = parser.builder_.GetBufferPointer();
+  flatbuffers::Verifier jverifier(jbuf, parser.builder_.GetSize());
+  TEST_EQ(VerifyMovieBuffer(jverifier), true);
+  TestMovie(GetMovie(jbuf));
+
+  auto movie_object = flat_movie->UnPack();
+  TEST_EQ(movie_object->main_character.AsRapunzel()->hair_length(), 6);
+  TEST_EQ(movie_object->characters[0].AsBelle()->books_read(), 7);
+  TEST_EQ(movie_object->characters[1].AsMuLan()->sword_attack_damage, 5);
+  TEST_EQ(movie_object->characters[2].AsBookFan()->books_read(), 2);
+  TEST_EQ_STR(movie_object->characters[3].AsOther()->c_str(), "Other");
+  TEST_EQ_STR(movie_object->characters[4].AsUnused()->c_str(), "Unused");
+
+  fbb.Clear();
+  fbb.Finish(Movie::Pack(fbb, movie_object));
+
+  delete movie_object;
+
+  auto repacked_movie = GetMovie(fbb.GetBufferPointer());
+
+  TestMovie(repacked_movie);
+
+  auto s =
+      flatbuffers::FlatBufferToString(fbb.GetBufferPointer(), MovieTypeTable());
+  TEST_EQ_STR(
+      s.c_str(),
+      "{ main_character_type: Rapunzel, main_character: { hair_length: 6 }, "
+      "characters_type: [ Belle, MuLan, BookFan, Other, Unused ], "
+      "characters: [ { books_read: 7 }, { sword_attack_damage: 5 }, "
+      "{ books_read: 2 }, \"Other\", \"Unused\" ] }");
+
+
+  flatbuffers::ToStringVisitor visitor("\n", true, "  ");
+  IterateFlatBuffer(fbb.GetBufferPointer(), MovieTypeTable(), &visitor);
+  TEST_EQ_STR(
+      visitor.s.c_str(),
+      "{\n"
+      "  \"main_character_type\": \"Rapunzel\",\n"
+      "  \"main_character\": {\n"
+      "    \"hair_length\": 6\n"
+      "  },\n"
+      "  \"characters_type\": [\n"
+      "    \"Belle\",\n"
+      "    \"MuLan\",\n"
+      "    \"BookFan\",\n"
+      "    \"Other\",\n"
+      "    \"Unused\"\n"
+      "  ],\n"
+      "  \"characters\": [\n"
+      "    {\n"
+      "      \"books_read\": 7\n"
+      "    },\n"
+      "    {\n"
+      "      \"sword_attack_damage\": 5\n"
+      "    },\n"
+      "    {\n"
+      "      \"books_read\": 2\n"
+      "    },\n"
+      "    \"Other\",\n"
+      "    \"Unused\"\n"
+      "  ]\n"
+      "}");
+
+  flatbuffers::Parser parser2(idl_opts);
+  TEST_EQ(parser2.Parse("struct Bool { b:bool; }"
+                        "union Any { Bool }"
+                        "table Root { a:Any; }"
+                        "root_type Root;"), true);
+  TEST_EQ(parser2.Parse("{a_type:Bool,a:{b:true}}"), true);
+}
+
+void ConformTest() {
+  flatbuffers::Parser parser;
+  TEST_EQ(parser.Parse("table T { A:int; } enum E:byte { A }"), true);
+
+  auto test_conform = [](flatbuffers::Parser &parser1, const char *test,
+                         const char *expected_err) {
+    flatbuffers::Parser parser2;
+    TEST_EQ(parser2.Parse(test), true);
+    auto err = parser2.ConformTo(parser1);
+    TEST_NOTNULL(strstr(err.c_str(), expected_err));
+  };
+
+  test_conform(parser, "table T { A:byte; }", "types differ for field");
+  test_conform(parser, "table T { B:int; A:int; }", "offsets differ for field");
+  test_conform(parser, "table T { A:int = 1; }", "defaults differ for field");
+  test_conform(parser, "table T { B:float; }",
+               "field renamed to different type");
+  test_conform(parser, "enum E:byte { B, A }", "values differ for enum");
+}
+
+void ParseProtoBufAsciiTest() {
+  // We can put the parser in a mode where it will accept JSON that looks more
+  // like Protobuf ASCII, for users that have data in that format.
+  // This uses no "" for field names (which we already support by default,
+  // omits `,`, `:` before `{` and a couple of other features.
+  flatbuffers::Parser parser;
+  parser.opts.protobuf_ascii_alike = true;
+  TEST_EQ(
+      parser.Parse("table S { B:int; } table T { A:[int]; C:S; } root_type T;"),
+      true);
+  TEST_EQ(parser.Parse("{ A [1 2] C { B:2 }}"), true);
+  // Similarly, in text output, it should omit these.
+  std::string text;
+  auto ok = flatbuffers::GenerateText(
+      parser, parser.builder_.GetBufferPointer(), &text);
+  TEST_EQ(ok, true);
+  TEST_EQ_STR(text.c_str(),
+              "{\n  A [\n    1\n    2\n  ]\n  C {\n    B: 2\n  }\n}\n");
+}
+
+void FlexBuffersTest() {
+  flexbuffers::Builder slb(512,
+                           flexbuffers::BUILDER_FLAG_SHARE_KEYS_AND_STRINGS);
+
+  // 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" } }
+  // clang-format off
+  #ifndef FLATBUFFERS_CPP98_STL
+    // It's possible to do this without std::function support as well.
+    slb.Map([&]() {
+       slb.Vector("vec", [&]() {
+        slb += -100;  // Equivalent to slb.Add(-100) or slb.Int(-100);
+        slb += "Fred";
+        slb.IndirectFloat(4.0f);
+        uint8_t blob[] = { 77 };
+        slb.Blob(blob, 1);
+        slb += false;
+      });
+      int ints[] = { 1, 2, 3 };
+      slb.Vector("bar", ints, 3);
+      slb.FixedTypedVector("bar3", ints, 3);
+      bool bools[] = {true, false, true, false};
+      slb.Vector("bools", bools, 4);
+      slb.Bool("bool", true);
+      slb.Double("foo", 100);
+      slb.Map("mymap", [&]() {
+        slb.String("foo", "Fred");  // Testing key and string reuse.
+      });
+    });
+    slb.Finish();
+  #else
+    // It's possible to do this without std::function support as well.
+    slb.Map([](flexbuffers::Builder& slb2) {
+       slb2.Vector("vec", [](flexbuffers::Builder& slb3) {
+        slb3 += -100;  // Equivalent to slb.Add(-100) or slb.Int(-100);
+        slb3 += "Fred";
+        slb3.IndirectFloat(4.0f);
+        uint8_t blob[] = { 77 };
+        slb3.Blob(blob, 1);
+        slb3 += false;
+      }, slb2);
+      int ints[] = { 1, 2, 3 };
+      slb2.Vector("bar", ints, 3);
+      slb2.FixedTypedVector("bar3", ints, 3);
+      slb2.Bool("bool", true);
+      slb2.Double("foo", 100);
+      slb2.Map("mymap", [](flexbuffers::Builder& slb3) {
+        slb3.String("foo", "Fred");  // Testing key and string reuse.
+      }, slb2);
+    }, slb);
+    slb.Finish();
+  #endif  // FLATBUFFERS_CPP98_STL
+
+  #ifdef FLATBUFFERS_TEST_VERBOSE
+    for (size_t i = 0; i < slb.GetBuffer().size(); i++)
+      printf("%d ", flatbuffers::vector_data(slb.GetBuffer())[i]);
+    printf("\n");
+  #endif
+  // clang-format on
+
+  auto map = flexbuffers::GetRoot(slb.GetBuffer()).AsMap();
+  TEST_EQ(map.size(), 7);
+  auto vec = map["vec"].AsVector();
+  TEST_EQ(vec.size(), 5);
+  TEST_EQ(vec[0].AsInt64(), -100);
+  TEST_EQ_STR(vec[1].AsString().c_str(), "Fred");
+  TEST_EQ(vec[1].AsInt64(), 0);  // Number parsing failed.
+  TEST_EQ(vec[2].AsDouble(), 4.0);
+  TEST_EQ(vec[2].AsString().IsTheEmptyString(), true);  // Wrong Type.
+  TEST_EQ_STR(vec[2].AsString().c_str(), "");     // This still works though.
+  TEST_EQ_STR(vec[2].ToString().c_str(), "4.0");  // Or have it converted.
+
+  // Few tests for templated version of As.
+  TEST_EQ(vec[0].As<int64_t>(), -100);
+  TEST_EQ_STR(vec[1].As<std::string>().c_str(), "Fred");
+  TEST_EQ(vec[1].As<int64_t>(), 0);  // Number parsing failed.
+  TEST_EQ(vec[2].As<double>(), 4.0);
+
+  // Test that the blob can be accessed.
+  TEST_EQ(vec[3].IsBlob(), true);
+  auto blob = vec[3].AsBlob();
+  TEST_EQ(blob.size(), 1);
+  TEST_EQ(blob.data()[0], 77);
+  TEST_EQ(vec[4].IsBool(), true);   // Check if type is a bool
+  TEST_EQ(vec[4].AsBool(), false);  // Check if value is false
+  auto tvec = map["bar"].AsTypedVector();
+  TEST_EQ(tvec.size(), 3);
+  TEST_EQ(tvec[2].AsInt8(), 3);
+  auto tvec3 = map["bar3"].AsFixedTypedVector();
+  TEST_EQ(tvec3.size(), 3);
+  TEST_EQ(tvec3[2].AsInt8(), 3);
+  TEST_EQ(map["bool"].AsBool(), true);
+  auto tvecb = map["bools"].AsTypedVector();
+  TEST_EQ(tvecb.ElementType(), flexbuffers::FBT_BOOL);
+  TEST_EQ(map["foo"].AsUInt8(), 100);
+  TEST_EQ(map["unknown"].IsNull(), true);
+  auto mymap = map["mymap"].AsMap();
+  // These should be equal by pointer equality, since key and value are shared.
+  TEST_EQ(mymap.Keys()[0].AsKey(), map.Keys()[4].AsKey());
+  TEST_EQ(mymap.Values()[0].AsString().c_str(), vec[1].AsString().c_str());
+  // We can mutate values in the buffer.
+  TEST_EQ(vec[0].MutateInt(-99), true);
+  TEST_EQ(vec[0].AsInt64(), -99);
+  TEST_EQ(vec[1].MutateString("John"), true);  // Size must match.
+  TEST_EQ_STR(vec[1].AsString().c_str(), "John");
+  TEST_EQ(vec[1].MutateString("Alfred"), false);  // Too long.
+  TEST_EQ(vec[2].MutateFloat(2.0f), true);
+  TEST_EQ(vec[2].AsFloat(), 2.0f);
+  TEST_EQ(vec[2].MutateFloat(3.14159), false);  // Double does not fit in float.
+  TEST_EQ(vec[4].AsBool(), false);              // Is false before change
+  TEST_EQ(vec[4].MutateBool(true), true);       // Can change a bool
+  TEST_EQ(vec[4].AsBool(), true);               // Changed bool is now true
+
+  // Parse from JSON:
+  flatbuffers::Parser parser;
+  slb.Clear();
+  auto jsontest = "{ a: [ 123, 456.0 ], b: \"hello\", c: true, d: false }";
+  TEST_EQ(parser.ParseFlexBuffer(jsontest, nullptr, &slb), true);
+  auto jroot = flexbuffers::GetRoot(slb.GetBuffer());
+  auto jmap = jroot.AsMap();
+  auto jvec = jmap["a"].AsVector();
+  TEST_EQ(jvec[0].AsInt64(), 123);
+  TEST_EQ(jvec[1].AsDouble(), 456.0);
+  TEST_EQ_STR(jmap["b"].AsString().c_str(), "hello");
+  TEST_EQ(jmap["c"].IsBool(), true);   // Parsed correctly to a bool
+  TEST_EQ(jmap["c"].AsBool(), true);   // Parsed correctly to true
+  TEST_EQ(jmap["d"].IsBool(), true);   // Parsed correctly to a bool
+  TEST_EQ(jmap["d"].AsBool(), false);  // Parsed correctly to false
+  // And from FlexBuffer back to JSON:
+  auto jsonback = jroot.ToString();
+  TEST_EQ_STR(jsontest, jsonback.c_str());
+}
+
+void TypeAliasesTest() {
+  flatbuffers::FlatBufferBuilder builder;
+
+  builder.Finish(CreateTypeAliases(
+      builder, flatbuffers::numeric_limits<int8_t>::min(),
+      flatbuffers::numeric_limits<uint8_t>::max(),
+      flatbuffers::numeric_limits<int16_t>::min(),
+      flatbuffers::numeric_limits<uint16_t>::max(),
+      flatbuffers::numeric_limits<int32_t>::min(),
+      flatbuffers::numeric_limits<uint32_t>::max(),
+      flatbuffers::numeric_limits<int64_t>::min(),
+      flatbuffers::numeric_limits<uint64_t>::max(), 2.3f, 2.3));
+
+  auto p = builder.GetBufferPointer();
+  auto ta = flatbuffers::GetRoot<TypeAliases>(p);
+
+  TEST_EQ(ta->i8(), flatbuffers::numeric_limits<int8_t>::min());
+  TEST_EQ(ta->u8(), flatbuffers::numeric_limits<uint8_t>::max());
+  TEST_EQ(ta->i16(), flatbuffers::numeric_limits<int16_t>::min());
+  TEST_EQ(ta->u16(), flatbuffers::numeric_limits<uint16_t>::max());
+  TEST_EQ(ta->i32(), flatbuffers::numeric_limits<int32_t>::min());
+  TEST_EQ(ta->u32(), flatbuffers::numeric_limits<uint32_t>::max());
+  TEST_EQ(ta->i64(), flatbuffers::numeric_limits<int64_t>::min());
+  TEST_EQ(ta->u64(), flatbuffers::numeric_limits<uint64_t>::max());
+  TEST_EQ(ta->f32(), 2.3f);
+  TEST_EQ(ta->f64(), 2.3);
+  using namespace flatbuffers; // is_same
+  static_assert(is_same<decltype(ta->i8()), int8_t>::value, "invalid type");
+  static_assert(is_same<decltype(ta->i16()), int16_t>::value, "invalid type");
+  static_assert(is_same<decltype(ta->i32()), int32_t>::value, "invalid type");
+  static_assert(is_same<decltype(ta->i64()), int64_t>::value, "invalid type");
+  static_assert(is_same<decltype(ta->u8()), uint8_t>::value, "invalid type");
+  static_assert(is_same<decltype(ta->u16()), uint16_t>::value, "invalid type");
+  static_assert(is_same<decltype(ta->u32()), uint32_t>::value, "invalid type");
+  static_assert(is_same<decltype(ta->u64()), uint64_t>::value, "invalid type");
+  static_assert(is_same<decltype(ta->f32()), float>::value, "invalid type");
+  static_assert(is_same<decltype(ta->f64()), double>::value, "invalid type");
+}
+
+void EndianSwapTest() {
+  TEST_EQ(flatbuffers::EndianSwap(static_cast<int16_t>(0x1234)), 0x3412);
+  TEST_EQ(flatbuffers::EndianSwap(static_cast<int32_t>(0x12345678)),
+          0x78563412);
+  TEST_EQ(flatbuffers::EndianSwap(static_cast<int64_t>(0x1234567890ABCDEF)),
+          0xEFCDAB9078563412);
+  TEST_EQ(flatbuffers::EndianSwap(flatbuffers::EndianSwap(3.14f)), 3.14f);
+}
+
+void UninitializedVectorTest() {
+  flatbuffers::FlatBufferBuilder builder;
+
+  Test *buf = nullptr;
+  auto vector_offset = builder.CreateUninitializedVectorOfStructs<Test>(2, &buf);
+  TEST_NOTNULL(buf);
+  buf[0] = Test(10, 20);
+  buf[1] = Test(30, 40);
+
+  auto required_name = builder.CreateString("myMonster");
+  auto monster_builder = MonsterBuilder(builder);
+  monster_builder.add_name(required_name); // required field mandated for monster.
+  monster_builder.add_test4(vector_offset);
+  builder.Finish(monster_builder.Finish());
+
+  auto p = builder.GetBufferPointer();
+  auto uvt = flatbuffers::GetRoot<Monster>(p);
+  TEST_NOTNULL(uvt);
+  auto vec = uvt->test4();
+  TEST_NOTNULL(vec);
+  auto test_0 = vec->Get(0);
+  auto test_1 = vec->Get(1);
+  TEST_EQ(test_0->a(), 10);
+  TEST_EQ(test_0->b(), 20);
+  TEST_EQ(test_1->a(), 30);
+  TEST_EQ(test_1->b(), 40);
+}
+
+void EqualOperatorTest() {
+  MonsterT a;
+  MonsterT b;
+  TEST_EQ(b == a, true);
+  TEST_EQ(b != a, false);
+
+  b.mana = 33;
+  TEST_EQ(b == a, false);
+  TEST_EQ(b != a, true);
+  b.mana = 150;
+  TEST_EQ(b == a, true);
+  TEST_EQ(b != a, false);
+
+  b.inventory.push_back(3);
+  TEST_EQ(b == a, false);
+  TEST_EQ(b != a, true);
+  b.inventory.clear();
+  TEST_EQ(b == a, true);
+  TEST_EQ(b != a, false);
+
+  b.test.type = Any_Monster;
+  TEST_EQ(b == a, false);
+  TEST_EQ(b != a, true);
+}
+
+// For testing any binaries, e.g. from fuzzing.
+void LoadVerifyBinaryTest() {
+  std::string binary;
+  if (flatbuffers::LoadFile((test_data_path +
+                             "fuzzer/your-filename-here").c_str(),
+                            true, &binary)) {
+    flatbuffers::Verifier verifier(
+          reinterpret_cast<const uint8_t *>(binary.data()), binary.size());
+    TEST_EQ(VerifyMonsterBuffer(verifier), true);
+  }
+}
+
+void CreateSharedStringTest() {
+  flatbuffers::FlatBufferBuilder builder;
+  const auto one1 = builder.CreateSharedString("one");
+  const auto two = builder.CreateSharedString("two");
+  const auto one2 = builder.CreateSharedString("one");
+  TEST_EQ(one1.o, one2.o);
+  const auto onetwo = builder.CreateSharedString("onetwo");
+  TEST_EQ(onetwo.o != one1.o, true);
+  TEST_EQ(onetwo.o != two.o, true);
+
+  // Support for embedded nulls
+  const char chars_b[] = {'a', '\0', 'b'};
+  const char chars_c[] = {'a', '\0', 'c'};
+  const auto null_b1 = builder.CreateSharedString(chars_b, sizeof(chars_b));
+  const auto null_c = builder.CreateSharedString(chars_c, sizeof(chars_c));
+  const auto null_b2 = builder.CreateSharedString(chars_b, sizeof(chars_b));
+  TEST_EQ(null_b1.o != null_c.o, true); // Issue#5058 repro
+  TEST_EQ(null_b1.o, null_b2.o);
+
+  // Put the strings into an array for round trip verification.
+  const flatbuffers::Offset<flatbuffers::String> array[7] = { one1, two, one2, onetwo, null_b1, null_c, null_b2 };
+  const auto vector_offset = builder.CreateVector(array, flatbuffers::uoffset_t(7));
+  MonsterBuilder monster_builder(builder);
+  monster_builder.add_name(two);
+  monster_builder.add_testarrayofstring(vector_offset);
+  builder.Finish(monster_builder.Finish());
+
+  // Read the Monster back.
+  const auto *monster = flatbuffers::GetRoot<Monster>(builder.GetBufferPointer());
+  TEST_EQ_STR(monster->name()->c_str(), "two");
+  const auto *testarrayofstring = monster->testarrayofstring();
+  TEST_EQ(testarrayofstring->size(), flatbuffers::uoffset_t(7));
+  const auto &a = *testarrayofstring;
+  TEST_EQ_STR(a[0]->c_str(), "one");
+  TEST_EQ_STR(a[1]->c_str(), "two");
+  TEST_EQ_STR(a[2]->c_str(), "one");
+  TEST_EQ_STR(a[3]->c_str(), "onetwo");
+  TEST_EQ(a[4]->str(), (std::string(chars_b, sizeof(chars_b))));
+  TEST_EQ(a[5]->str(), (std::string(chars_c, sizeof(chars_c))));
+  TEST_EQ(a[6]->str(), (std::string(chars_b, sizeof(chars_b))));
+
+  // Make sure String::operator< works, too, since it is related to StringOffsetCompare.
+  TEST_EQ((*a[0]) < (*a[1]), true);
+  TEST_EQ((*a[1]) < (*a[0]), false);
+  TEST_EQ((*a[1]) < (*a[2]), false);
+  TEST_EQ((*a[2]) < (*a[1]), true);
+  TEST_EQ((*a[4]) < (*a[3]), true);
+  TEST_EQ((*a[5]) < (*a[4]), false);
+  TEST_EQ((*a[5]) < (*a[4]), false);
+  TEST_EQ((*a[6]) < (*a[5]), true);
+}
+
+void FixedLengthArrayTest() {
+  // VS10 does not support typed enums, exclude from tests
+#if !defined(_MSC_VER) || _MSC_VER >= 1700
+  // Generate an ArrayTable containing one ArrayStruct.
+  flatbuffers::FlatBufferBuilder fbb;
+  MyGame::Example::NestedStruct nStruct0(MyGame::Example::TestEnum::B);
+  TEST_NOTNULL(nStruct0.mutable_a());
+  nStruct0.mutable_a()->Mutate(0, 1);
+  nStruct0.mutable_a()->Mutate(1, 2);
+  TEST_NOTNULL(nStruct0.mutable_c());
+  nStruct0.mutable_c()->Mutate(0, MyGame::Example::TestEnum::C);
+  nStruct0.mutable_c()->Mutate(1, MyGame::Example::TestEnum::A);
+  MyGame::Example::NestedStruct nStruct1(MyGame::Example::TestEnum::C);
+  TEST_NOTNULL(nStruct1.mutable_a());
+  nStruct1.mutable_a()->Mutate(0, 3);
+  nStruct1.mutable_a()->Mutate(1, 4);
+  TEST_NOTNULL(nStruct1.mutable_c());
+  nStruct1.mutable_c()->Mutate(0, MyGame::Example::TestEnum::C);
+  nStruct1.mutable_c()->Mutate(1, MyGame::Example::TestEnum::A);
+  MyGame::Example::ArrayStruct aStruct(2, 12);
+  TEST_NOTNULL(aStruct.b());
+  TEST_NOTNULL(aStruct.mutable_b());
+  TEST_NOTNULL(aStruct.mutable_d());
+  for (int i = 0; i < aStruct.b()->size(); i++)
+    aStruct.mutable_b()->Mutate(i, i + 1);
+  aStruct.mutable_d()->Mutate(0, nStruct0);
+  aStruct.mutable_d()->Mutate(1, nStruct1);
+  auto aTable = MyGame::Example::CreateArrayTable(fbb, &aStruct);
+  fbb.Finish(aTable);
+
+  // Verify correctness of the ArrayTable.
+  flatbuffers::Verifier verifier(fbb.GetBufferPointer(), fbb.GetSize());
+  MyGame::Example::VerifyArrayTableBuffer(verifier);
+  auto p = MyGame::Example::GetMutableArrayTable(fbb.GetBufferPointer());
+  auto mArStruct = p->mutable_a();
+  TEST_NOTNULL(mArStruct);
+  TEST_NOTNULL(mArStruct->b());
+  TEST_NOTNULL(mArStruct->d());
+  TEST_NOTNULL(mArStruct->mutable_b());
+  TEST_NOTNULL(mArStruct->mutable_d());
+  mArStruct->mutable_b()->Mutate(14, -14);
+  TEST_EQ(mArStruct->a(), 2);
+  TEST_EQ(mArStruct->b()->size(), 15);
+  TEST_EQ(mArStruct->b()->Get(aStruct.b()->size() - 1), -14);
+  TEST_EQ(mArStruct->c(), 12);
+  TEST_NOTNULL(mArStruct->d()->Get(0).a());
+  TEST_EQ(mArStruct->d()->Get(0).a()->Get(0), 1);
+  TEST_EQ(mArStruct->d()->Get(0).a()->Get(1), 2);
+  TEST_NOTNULL(mArStruct->d()->Get(1).a());
+  TEST_EQ(mArStruct->d()->Get(1).a()->Get(0), 3);
+  TEST_EQ(mArStruct->d()->Get(1).a()->Get(1), 4);
+  TEST_NOTNULL(mArStruct->mutable_d()->GetMutablePointer(1));
+  TEST_NOTNULL(mArStruct->mutable_d()->GetMutablePointer(1)->mutable_a());
+  mArStruct->mutable_d()->GetMutablePointer(1)->mutable_a()->Mutate(1, 5);
+  TEST_EQ(mArStruct->d()->Get(1).a()->Get(1), 5);
+  TEST_EQ(mArStruct->d()->Get(0).b() == MyGame::Example::TestEnum::B, true);
+  TEST_NOTNULL(mArStruct->d()->Get(0).c());
+  TEST_EQ(mArStruct->d()->Get(0).c()->Get(0) == MyGame::Example::TestEnum::C,
+          true);
+  TEST_EQ(mArStruct->d()->Get(0).c()->Get(1) == MyGame::Example::TestEnum::A,
+          true);
+  TEST_EQ(mArStruct->d()->Get(1).b() == MyGame::Example::TestEnum::C, true);
+  TEST_NOTNULL(mArStruct->d()->Get(1).c());
+  TEST_EQ(mArStruct->d()->Get(1).c()->Get(0) == MyGame::Example::TestEnum::C,
+          true);
+  TEST_EQ(mArStruct->d()->Get(1).c()->Get(1) == MyGame::Example::TestEnum::A,
+          true);
+  for (int i = 0; i < mArStruct->b()->size() - 1; i++)
+    TEST_EQ(mArStruct->b()->Get(i), i + 1);
+#endif
+}
+
+void NativeTypeTest() {
+  const int N = 3;
+
+  Geometry::ApplicationDataT src_data;
+  src_data.vectors.reserve(N);
+
+  for (int i = 0; i < N; ++i) {
+    src_data.vectors.push_back (Native::Vector3D(10 * i + 0.1f, 10 * i + 0.2f, 10 * i + 0.3f));
+  }
+
+  flatbuffers::FlatBufferBuilder fbb;
+  fbb.Finish(Geometry::ApplicationData::Pack(fbb, &src_data));
+
+  auto dstDataT =  Geometry::UnPackApplicationData(fbb.GetBufferPointer());
+
+  for (int i = 0; i < N; ++i) {
+    Native::Vector3D& v = dstDataT->vectors[i];
+    TEST_EQ(v.x, 10 * i + 0.1f);
+    TEST_EQ(v.y, 10 * i + 0.2f);
+    TEST_EQ(v.z, 10 * i + 0.3f);
+  }
+}
+
+void FixedLengthArrayJsonTest(bool binary) {  
+  // VS10 does not support typed enums, exclude from tests
+#if !defined(_MSC_VER) || _MSC_VER >= 1700
+  // load FlatBuffer schema (.fbs) and JSON from disk
+  std::string schemafile;
+  std::string jsonfile;
+  TEST_EQ(
+      flatbuffers::LoadFile(
+          (test_data_path + "arrays_test." + (binary ? "bfbs" : "fbs")).c_str(),
+          binary, &schemafile),
+      true);
+  TEST_EQ(flatbuffers::LoadFile((test_data_path + "arrays_test.golden").c_str(),
+                                false, &jsonfile),
+          true);
+
+  // parse schema first, so we can use it to parse the data after
+  flatbuffers::Parser parserOrg, parserGen;
+  if (binary) {
+    flatbuffers::Verifier verifier(
+        reinterpret_cast<const uint8_t *>(schemafile.c_str()),
+        schemafile.size());
+    TEST_EQ(reflection::VerifySchemaBuffer(verifier), true);
+    TEST_EQ(parserOrg.Deserialize((const uint8_t *)schemafile.c_str(),
+                                  schemafile.size()),
+            true);
+    TEST_EQ(parserGen.Deserialize((const uint8_t *)schemafile.c_str(),
+                                  schemafile.size()),
+            true);
+  } else {
+    TEST_EQ(parserOrg.Parse(schemafile.c_str()), true);
+    TEST_EQ(parserGen.Parse(schemafile.c_str()), true);
+  }
+  TEST_EQ(parserOrg.Parse(jsonfile.c_str()), true);
+
+  // First, verify it, just in case:
+  flatbuffers::Verifier verifierOrg(parserOrg.builder_.GetBufferPointer(),
+                                    parserOrg.builder_.GetSize());
+  TEST_EQ(VerifyArrayTableBuffer(verifierOrg), true);
+
+  // Export to JSON
+  std::string jsonGen;
+  TEST_EQ(
+      GenerateText(parserOrg, parserOrg.builder_.GetBufferPointer(), &jsonGen),
+      true);
+
+  // Import from JSON
+  TEST_EQ(parserGen.Parse(jsonGen.c_str()), true);
+
+  // Verify buffer from generated JSON
+  flatbuffers::Verifier verifierGen(parserGen.builder_.GetBufferPointer(),
+                                    parserGen.builder_.GetSize());
+  TEST_EQ(VerifyArrayTableBuffer(verifierGen), true);
+
+  // Compare generated buffer to original
+  TEST_EQ(parserOrg.builder_.GetSize(), parserGen.builder_.GetSize());
+  TEST_EQ(std::memcmp(parserOrg.builder_.GetBufferPointer(),
+                      parserGen.builder_.GetBufferPointer(),
+                      parserOrg.builder_.GetSize()),
+          0);
+#else
+  (void)binary;
+#endif
+}
+
+int FlatBufferTests() {
+  // clang-format off
+
+  // Run our various test suites:
+
+  std::string rawbuf;
+  auto flatbuf1 = CreateFlatBufferTest(rawbuf);
+  #if !defined(FLATBUFFERS_CPP98_STL)
+    auto flatbuf = std::move(flatbuf1);  // Test move assignment.
+  #else
+    auto &flatbuf = flatbuf1;
+  #endif // !defined(FLATBUFFERS_CPP98_STL)
+
+  TriviallyCopyableTest();
+
+  AccessFlatBufferTest(reinterpret_cast<const uint8_t *>(rawbuf.c_str()),
+                       rawbuf.length());
+  AccessFlatBufferTest(flatbuf.data(), flatbuf.size());
+
+  MutateFlatBuffersTest(flatbuf.data(), flatbuf.size());
+
+  ObjectFlatBuffersTest(flatbuf.data());
+
+  MiniReflectFlatBuffersTest(flatbuf.data());
+
+  SizePrefixedTest();
+
+  #ifndef FLATBUFFERS_NO_FILE_TESTS
+    #ifdef FLATBUFFERS_TEST_PATH_PREFIX
+      test_data_path = FLATBUFFERS_STRING(FLATBUFFERS_TEST_PATH_PREFIX) +
+                       test_data_path;
+    #endif
+    ParseAndGenerateTextTest(false);
+    ParseAndGenerateTextTest(true);
+    FixedLengthArrayJsonTest(false);
+    FixedLengthArrayJsonTest(true);
+    ReflectionTest(flatbuf.data(), flatbuf.size());
+    ParseProtoTest();
+    UnionVectorTest();
+    LoadVerifyBinaryTest();
+    GenerateTableTextTest();
+  #endif
+  // clang-format on
+
+  FuzzTest1();
+  FuzzTest2();
+
+  ErrorTest();
+  ValueTest();
+  EnumValueTest();
+  EnumStringsTest();
+  EnumNamesTest();
+  EnumOutOfRangeTest();
+  IntegerOutOfRangeTest();
+  IntegerBoundaryTest();
+  UnicodeTest();
+  UnicodeTestAllowNonUTF8();
+  UnicodeTestGenerateTextFailsOnNonUTF8();
+  UnicodeSurrogatesTest();
+  UnicodeInvalidSurrogatesTest();
+  InvalidUTF8Test();
+  UnknownFieldsTest();
+  ParseUnionTest();
+  InvalidNestedFlatbufferTest();
+  ConformTest();
+  ParseProtoBufAsciiTest();
+  TypeAliasesTest();
+  EndianSwapTest();
+  CreateSharedStringTest();
+  JsonDefaultTest();
+  JsonEnumsTest();
+  FlexBuffersTest();
+  UninitializedVectorTest();
+  EqualOperatorTest();
+  NumericUtilsTest();
+  IsAsciiUtilsTest();
+  ValidFloatTest();
+  InvalidFloatTest();
+  TestMonsterExtraFloats();
+  FixedLengthArrayTest();
+  NativeTypeTest();
+  return 0;
+}
+
+int main(int /*argc*/, const char * /*argv*/ []) {
+  InitTestEngine();
+
+  std::string req_locale;
+  if (flatbuffers::ReadEnvironmentVariable("FLATBUFFERS_TEST_LOCALE",
+                                           &req_locale)) {
+    TEST_OUTPUT_LINE("The environment variable FLATBUFFERS_TEST_LOCALE=%s",
+                     req_locale.c_str());
+    req_locale = flatbuffers::RemoveStringQuotes(req_locale);
+    std::string the_locale;
+    TEST_ASSERT_FUNC(
+        flatbuffers::SetGlobalTestLocale(req_locale.c_str(), &the_locale));
+    TEST_OUTPUT_LINE("The global C-locale changed: %s", the_locale.c_str());
+  }
+
+  FlatBufferTests();
+  FlatBufferBuilderTest();
+
+  if (!testing_fails) {
+    TEST_OUTPUT_LINE("ALL TESTS PASSED");
+  } else {
+    TEST_OUTPUT_LINE("%d FAILED TESTS", testing_fails);
+  }
+  return CloseTestEngine();
+}
diff --git a/tests/test_assert.cpp b/tests/test_assert.cpp
new file mode 100644
index 0000000..794ffe7
--- /dev/null
+++ b/tests/test_assert.cpp
@@ -0,0 +1,69 @@
+#include "test_assert.h"
+
+#include <assert.h>
+
+#ifdef _MSC_VER
+#  include <crtdbg.h>
+#  include <windows.h>
+#endif
+
+int testing_fails = 0;
+static TestFailEventListener fail_listener_ = nullptr;
+
+void TestFail(const char *expval, const char *val, const char *exp,
+              const char *file, int line, const char *func) {
+  TEST_OUTPUT_LINE("VALUE: \"%s\"", expval);
+  TEST_OUTPUT_LINE("EXPECTED: \"%s\"", val);
+  TEST_OUTPUT_LINE("TEST FAILED: %s:%d, %s in %s", file, line, exp,
+                   func ? func : "");
+  testing_fails++;
+
+  // Notify, emulate 'gtest::OnTestPartResult' event handler.
+  if (fail_listener_) (*fail_listener_)(expval, val, exp, file, line, func);
+
+  assert(0);  // ignored in Release if NDEBUG defined
+}
+
+void TestEqStr(const char *expval, const char *val, const char *exp,
+               const char *file, int line) {
+  if (strcmp(expval, val) != 0) { TestFail(expval, val, exp, file, line); }
+}
+
+#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && defined(_MSC_VER) && \
+    defined(_DEBUG)
+#define FLATBUFFERS_MEMORY_LEAK_TRACKING_MSVC
+#endif
+
+void InitTestEngine(TestFailEventListener listener) {
+  testing_fails = 0;
+  // Disable stdout buffering to prevent information lost on assertion or core
+  // dump.
+  setvbuf(stdout, NULL, _IONBF, 0);
+  setvbuf(stderr, NULL, _IONBF, 0);
+
+  flatbuffers::SetupDefaultCRTReportMode();
+
+  // clang-format off
+
+  #if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING_MSVC)
+    // For more thorough checking:
+    // _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF
+    auto flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
+    _CrtSetDbgFlag(flags | _CRTDBG_ALLOC_MEM_DF);
+  #endif
+  // clang-format on
+
+  fail_listener_ = listener;
+}
+
+int CloseTestEngine(bool force_report) {
+  if (!testing_fails || force_report) {
+  #if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING_MSVC)
+      auto flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
+      flags &= ~_CRTDBG_DELAY_FREE_MEM_DF;
+      flags |= _CRTDBG_LEAK_CHECK_DF;
+      _CrtSetDbgFlag(flags);
+  #endif
+  }
+  return (0 != testing_fails);
+}
diff --git a/tests/test_assert.h b/tests/test_assert.h
new file mode 100644
index 0000000..883586b
--- /dev/null
+++ b/tests/test_assert.h
@@ -0,0 +1,68 @@
+#ifndef TEST_ASSERT_H
+#define TEST_ASSERT_H
+
+#include "flatbuffers/base.h"
+#include "flatbuffers/util.h"
+
+// clang-format off
+
+#ifdef __ANDROID__
+  #include <android/log.h>
+  #define TEST_OUTPUT_LINE(...) \
+      __android_log_print(ANDROID_LOG_INFO, "FlatBuffers", __VA_ARGS__)
+  #define FLATBUFFERS_NO_FILE_TESTS
+#else
+  #define TEST_OUTPUT_LINE(...) \
+      { printf(__VA_ARGS__); printf("\n"); }
+#endif
+
+#define TEST_EQ(exp, val) TestEq(exp, val, #exp, __FILE__, __LINE__)
+#define TEST_ASSERT(exp) TestEq(exp, true, #exp, __FILE__, __LINE__)
+#define TEST_NOTNULL(exp) TestEq(exp == NULL, false, #exp, __FILE__, __LINE__)
+#define TEST_EQ_STR(exp, val) TestEqStr(exp, val, #exp, __FILE__, __LINE__)
+
+#ifdef _WIN32
+  #define TEST_ASSERT_FUNC(exp) TestEq(exp, true, #exp, __FILE__, __LINE__, __FUNCTION__)
+  #define TEST_EQ_FUNC(exp, val) TestEq(exp, val, #exp, __FILE__, __LINE__, __FUNCTION__)
+#else
+  #define TEST_ASSERT_FUNC(exp) TestEq(exp, true, #exp, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+  #define TEST_EQ_FUNC(exp, val) TestEq(exp, val, #exp, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#endif
+
+// clang-format on
+
+extern int testing_fails;
+
+// Listener of TestFail, like 'gtest::OnTestPartResult' event handler.
+// Called in TestFail after a failed assertion.
+typedef bool (*TestFailEventListener)(const char *expval, const char *val,
+                                      const char *exp, const char *file,
+                                      int line, const char *func);
+
+// Prepare test engine (MSVC assertion setup, etc).
+// listener - this function will be notified on each TestFail call.
+void InitTestEngine(TestFailEventListener listener = nullptr);
+
+// Release all test-engine resources.
+// Prints or schedule a debug report if all test passed.
+// Returns 0 if all tests passed or 1 otherwise.
+// Memory leak report: FLATBUFFERS_MEMORY_LEAK_TRACKING && _MSC_VER && _DEBUG.
+int CloseTestEngine(bool force_report = false);
+
+// Write captured state to a log and terminate test run.
+void TestFail(const char *expval, const char *val, const char *exp,
+              const char *file, int line, const char *func = 0);
+
+void TestEqStr(const char *expval, const char *val, const char *exp,
+               const char *file, int line);
+
+template<typename T, typename U>
+void TestEq(T expval, U val, const char *exp, const char *file, int line,
+            const char *func = 0) {
+  if (U(expval) != val) {
+    TestFail(flatbuffers::NumToString(expval).c_str(),
+             flatbuffers::NumToString(val).c_str(), exp, file, line, func);
+  }
+}
+
+#endif  // !TEST_ASSERT_H
diff --git a/tests/test_builder.cpp b/tests/test_builder.cpp
new file mode 100644
index 0000000..8c070c1
--- /dev/null
+++ b/tests/test_builder.cpp
@@ -0,0 +1,148 @@
+#include "flatbuffers/stl_emulation.h"
+
+#include "monster_test_generated.h"
+#include "test_builder.h"
+
+using namespace MyGame::Example;
+
+const std::string m1_name = "Cyberdemon";
+const Color m1_color = Color_Red;
+const std::string m2_name = "Imp";
+const Color m2_color = Color_Green;
+
+struct OwnedAllocator : public flatbuffers::DefaultAllocator {};
+
+class TestHeapBuilder : public flatbuffers::FlatBufferBuilder {
+private:
+  // clang-format off
+  #if !defined(FLATBUFFERS_CPP98_STL)
+  TestHeapBuilder(const TestHeapBuilder &);
+  TestHeapBuilder &operator=(const TestHeapBuilder &);
+  #endif  // !defined(FLATBUFFERS_CPP98_STL)
+  // clang-format on
+
+public:
+  TestHeapBuilder()
+    : flatbuffers::FlatBufferBuilder(2048, new OwnedAllocator(), true) {}
+
+  // clang-format off
+  #if !defined(FLATBUFFERS_CPP98_STL)
+  // clang-format on
+  TestHeapBuilder(TestHeapBuilder &&other)
+    : FlatBufferBuilder(std::move(other)) { }
+
+  TestHeapBuilder &operator=(TestHeapBuilder &&other) {
+    FlatBufferBuilder::operator=(std::move(other));
+    return *this;
+  }
+  // clang-format off
+  #endif  // !defined(FLATBUFFERS_CPP98_STL)
+  // clang-format on
+};
+
+// This class simulates flatbuffers::grpc::detail::SliceAllocatorMember
+struct AllocatorMember {
+  flatbuffers::DefaultAllocator member_allocator_;
+};
+
+struct GrpcLikeMessageBuilder : private AllocatorMember,
+                                public flatbuffers::FlatBufferBuilder {
+private:
+  GrpcLikeMessageBuilder(const GrpcLikeMessageBuilder &);
+  GrpcLikeMessageBuilder &operator=(const GrpcLikeMessageBuilder &);
+
+public:
+  GrpcLikeMessageBuilder()
+    : flatbuffers::FlatBufferBuilder(1024, &member_allocator_, false) {}
+
+  GrpcLikeMessageBuilder(GrpcLikeMessageBuilder &&other)
+    : FlatBufferBuilder(1024, &member_allocator_, false) {
+    // Default construct and swap idiom.
+    Swap(other);
+  }
+
+  // clang-format off
+  #if !defined(FLATBUFFERS_CPP98_STL)
+  // clang-format on
+  GrpcLikeMessageBuilder &operator=(GrpcLikeMessageBuilder &&other) {
+    // Construct temporary and swap idiom
+    GrpcLikeMessageBuilder temp(std::move(other));
+    Swap(temp);
+    return *this;
+  }
+  // clang-format off
+  #endif  // !defined(FLATBUFFERS_CPP98_STL)
+  // clang-format on
+
+  void Swap(GrpcLikeMessageBuilder &other) {
+    // No need to swap member_allocator_ because it's stateless.
+    FlatBufferBuilder::Swap(other);
+    // After swapping the FlatBufferBuilder, we swap back the allocator, which restores
+    // the original allocator back in place. This is necessary because MessageBuilder's
+    // allocator is its own member (SliceAllocatorMember). The allocator passed to
+    // FlatBufferBuilder::vector_downward must point to this member.
+    buf_.swap_allocator(other.buf_);
+  }
+};
+
+flatbuffers::Offset<Monster> populate1(flatbuffers::FlatBufferBuilder &builder) {
+  auto name_offset = builder.CreateString(m1_name);
+  return CreateMonster(builder, nullptr, 0, 0, name_offset, 0, m1_color);
+}
+
+flatbuffers::Offset<Monster> populate2(flatbuffers::FlatBufferBuilder &builder) {
+  auto name_offset = builder.CreateString(m2_name);
+  return CreateMonster(builder, nullptr, 0, 0, name_offset, 0, m2_color);
+}
+
+uint8_t *release_raw_base(flatbuffers::FlatBufferBuilder &fbb, size_t &size, size_t &offset) {
+  return fbb.ReleaseRaw(size, offset);
+}
+
+void free_raw(flatbuffers::grpc::MessageBuilder &, uint8_t *) {
+  // release_raw_base calls FlatBufferBuilder::ReleaseRaw on the argument MessageBuilder.
+  // It's semantically wrong as MessageBuilder has its own ReleaseRaw member function that
+  // takes three arguments. In such cases though, ~MessageBuilder() invokes
+  // ~SliceAllocator() that takes care of deleting memory as it calls grpc_slice_unref.
+  // Obviously, this behavior is very surprising as the pointer returned by
+  // FlatBufferBuilder::ReleaseRaw is not valid as soon as MessageBuilder goes out of scope.
+  // This problem does not occur with FlatBufferBuilder.
+}
+
+void free_raw(flatbuffers::FlatBufferBuilder &, uint8_t *buf) {
+  flatbuffers::DefaultAllocator().deallocate(buf, 0);
+}
+
+bool verify(const flatbuffers::DetachedBuffer &buf, const std::string &expected_name, Color color) {
+  const Monster *monster = flatbuffers::GetRoot<Monster>(buf.data());
+  return (monster->name()->str() == expected_name) && (monster->color() == color);
+}
+
+bool verify(const uint8_t *buf, size_t offset, const std::string &expected_name, Color color) {
+  const Monster *monster = flatbuffers::GetRoot<Monster>(buf+offset);
+  return (monster->name()->str() == expected_name) && (monster->color() == color);
+}
+
+bool release_n_verify(flatbuffers::FlatBufferBuilder &fbb, const std::string &expected_name, Color color) {
+  flatbuffers::DetachedBuffer buf = fbb.Release();
+  return verify(buf, expected_name, color);
+}
+
+void FlatBufferBuilderTest() {
+  using flatbuffers::FlatBufferBuilder;
+
+  BuilderTests<FlatBufferBuilder>::all_tests();
+  BuilderTests<TestHeapBuilder>::all_tests();
+  BuilderTests<GrpcLikeMessageBuilder>::all_tests();
+
+  BuilderReuseTestSelector tests[4] = {
+    REUSABLE_AFTER_RELEASE,
+    REUSABLE_AFTER_RELEASE_RAW,
+    REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN,
+    REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN
+  };
+
+  BuilderReuseTests<FlatBufferBuilder, FlatBufferBuilder>::run_tests(TestSelector(tests, tests+4));
+  BuilderReuseTests<TestHeapBuilder, TestHeapBuilder>::run_tests(TestSelector(tests, tests+4));
+  BuilderReuseTests<GrpcLikeMessageBuilder, GrpcLikeMessageBuilder>::run_tests(TestSelector(tests, tests+4));
+}
diff --git a/tests/test_builder.h b/tests/test_builder.h
new file mode 100644
index 0000000..1e2fa0a
--- /dev/null
+++ b/tests/test_builder.h
@@ -0,0 +1,326 @@
+#ifndef TEST_BUILDER_H
+#define TEST_BUILDER_H
+
+#include <set>
+#include <type_traits>
+#include "monster_test_generated.h"
+#include "flatbuffers/flatbuffers.h"
+#include "test_assert.h"
+
+using MyGame::Example::Color;
+using MyGame::Example::Monster;
+
+namespace flatbuffers {
+namespace grpc {
+class MessageBuilder;
+}
+}
+
+template <class T, class U>
+struct is_same {
+  static const bool value = false;
+};
+
+template <class T>
+struct is_same<T, T> {
+  static const bool value = true;
+};
+
+extern const std::string m1_name;
+extern const Color m1_color;
+extern const std::string m2_name;
+extern const Color m2_color;
+
+flatbuffers::Offset<Monster> populate1(flatbuffers::FlatBufferBuilder &builder);
+flatbuffers::Offset<Monster> populate2(flatbuffers::FlatBufferBuilder &builder);
+
+uint8_t *release_raw_base(flatbuffers::FlatBufferBuilder &fbb, size_t &size, size_t &offset);
+
+void free_raw(flatbuffers::grpc::MessageBuilder &mbb, uint8_t *buf);
+void free_raw(flatbuffers::FlatBufferBuilder &fbb, uint8_t *buf);
+
+bool verify(const flatbuffers::DetachedBuffer &buf, const std::string &expected_name, Color color);
+bool verify(const uint8_t *buf, size_t offset, const std::string &expected_name, Color color);
+
+bool release_n_verify(flatbuffers::FlatBufferBuilder &fbb, const std::string &expected_name, Color color);
+bool release_n_verify(flatbuffers::grpc::MessageBuilder &mbb, const std::string &expected_name, Color color);
+
+// clang-format off
+#if !defined(FLATBUFFERS_CPP98_STL)
+// clang-format on
+// Invokes this function when testing the following Builder types
+// FlatBufferBuilder, TestHeapBuilder, and GrpcLikeMessageBuilder
+template <class Builder>
+void builder_move_assign_after_releaseraw_test(Builder b1) {
+  auto root_offset1 = populate1(b1);
+  b1.Finish(root_offset1);
+  size_t size, offset;
+  std::shared_ptr<uint8_t> raw(b1.ReleaseRaw(size, offset), [size](uint8_t *ptr) {
+    flatbuffers::DefaultAllocator::dealloc(ptr, size);
+  });
+  Builder src;
+  auto root_offset2 = populate2(src);
+  src.Finish(root_offset2);
+  auto src_size = src.GetSize();
+  // Move into a released builder.
+  b1 = std::move(src);
+  TEST_EQ_FUNC(b1.GetSize(), src_size);
+  TEST_ASSERT_FUNC(release_n_verify(b1, m2_name, m2_color));
+  TEST_EQ_FUNC(src.GetSize(), 0);
+}
+// clang-format off
+#endif  // !defined(FLATBUFFERS_CPP98_STL)
+// clang-format on
+
+void builder_move_assign_after_releaseraw_test(flatbuffers::grpc::MessageBuilder b1);
+
+template <class DestBuilder, class SrcBuilder = DestBuilder>
+struct BuilderTests {
+  // clang-format off
+  #if !defined(FLATBUFFERS_CPP98_STL)
+  // clang-format on
+  static void empty_builder_movector_test() {
+    SrcBuilder src;
+    size_t src_size = src.GetSize();
+    DestBuilder dst(std::move(src));
+    size_t dst_size = dst.GetSize();
+    TEST_EQ_FUNC(src_size, 0);
+    TEST_EQ_FUNC(src_size, dst_size);
+  }
+
+  static void nonempty_builder_movector_test() {
+    SrcBuilder src;
+    populate1(src);
+    size_t src_size = src.GetSize();
+    DestBuilder dst(std::move(src));
+    TEST_EQ_FUNC(src_size, dst.GetSize());
+    TEST_EQ_FUNC(src.GetSize(), 0);
+  }
+
+  static void builder_movector_before_finish_test() {
+    SrcBuilder src;
+    auto root_offset1 = populate1(src);
+    DestBuilder dst(std::move(src));
+    dst.Finish(root_offset1);
+    TEST_ASSERT_FUNC(release_n_verify(dst, m1_name, m1_color));
+    TEST_EQ_FUNC(src.GetSize(), 0);
+  }
+
+  static void builder_movector_after_finish_test() {
+    SrcBuilder src;
+    auto root_offset1 = populate1(src);
+    src.Finish(root_offset1);
+    auto src_size = src.GetSize();
+    DestBuilder dst(std::move(src));
+    TEST_EQ_FUNC(dst.GetSize(), src_size);
+    TEST_ASSERT_FUNC(release_n_verify(dst, m1_name, m1_color));
+    TEST_EQ_FUNC(src.GetSize(), 0);
+  }
+
+  static void builder_move_assign_before_finish_test() {
+    SrcBuilder src;
+    auto root_offset1 = populate1(src);
+    DestBuilder dst;
+    populate2(dst);
+    dst = std::move(src);
+    dst.Finish(root_offset1);
+    TEST_ASSERT_FUNC(release_n_verify(dst, m1_name, m1_color));
+    TEST_EQ_FUNC(src.GetSize(), 0);
+  }
+
+  static void builder_move_assign_after_finish_test() {
+    SrcBuilder src;
+    auto root_offset1 = populate1(src);
+    src.Finish(root_offset1);
+    auto src_size = src.GetSize();
+    DestBuilder dst;
+    auto root_offset2 = populate2(dst);
+    dst.Finish(root_offset2);
+    dst = std::move(src);
+    TEST_EQ_FUNC(dst.GetSize(), src_size);
+    TEST_ASSERT_FUNC(release_n_verify(dst, m1_name, m1_color));
+    TEST_EQ_FUNC(src.GetSize(), 0);
+  }
+
+  static void builder_move_assign_after_release_test() {
+    DestBuilder dst;
+    auto root_offset1 = populate1(dst);
+    dst.Finish(root_offset1);
+    {
+      flatbuffers::DetachedBuffer dst_detached = dst.Release();
+      // detached buffer is deleted
+    }
+    SrcBuilder src;
+    auto root_offset2 = populate2(src);
+    src.Finish(root_offset2);
+    auto src_size = src.GetSize();
+    // Move into a released builder.
+    dst = std::move(src);
+    TEST_EQ_FUNC(dst.GetSize(), src_size);
+    TEST_ASSERT_FUNC(release_n_verify(dst, m2_name, m2_color));
+    TEST_EQ_FUNC(src.GetSize(), 0);
+  }
+  // clang-format off
+  #endif  // !defined(FLATBUFFERS_CPP98_STL)
+  // clang-format on
+
+  static void builder_swap_before_finish_test(bool run = is_same<DestBuilder, SrcBuilder>::value) {
+    /// Swap is allowed only when lhs and rhs are the same concrete type.
+    if(run) {
+      SrcBuilder src;
+      auto root_offset1 = populate1(src);
+      auto size1 = src.GetSize();
+      DestBuilder dst;
+      auto root_offset2 = populate2(dst);
+      auto size2 = dst.GetSize();
+      src.Swap(dst);
+      src.Finish(root_offset2);
+      dst.Finish(root_offset1);
+      TEST_EQ_FUNC(src.GetSize() > size2, true);
+      TEST_EQ_FUNC(dst.GetSize() > size1, true);
+      TEST_ASSERT_FUNC(release_n_verify(src, m2_name, m2_color));
+      TEST_ASSERT_FUNC(release_n_verify(dst, m1_name, m1_color));
+    }
+  }
+
+  static void builder_swap_after_finish_test(bool run = is_same<DestBuilder, SrcBuilder>::value) {
+    /// Swap is allowed only when lhs and rhs are the same concrete type.
+    if(run) {
+      SrcBuilder src;
+      auto root_offset1 = populate1(src);
+      src.Finish(root_offset1);
+      auto size1 = src.GetSize();
+      DestBuilder dst;
+      auto root_offset2 = populate2(dst);
+      dst.Finish(root_offset2);
+      auto size2 = dst.GetSize();
+      src.Swap(dst);
+      TEST_EQ_FUNC(src.GetSize(), size2);
+      TEST_EQ_FUNC(dst.GetSize(), size1);
+      TEST_ASSERT_FUNC(release_n_verify(src, m2_name, m2_color));
+      TEST_ASSERT_FUNC(release_n_verify(dst, m1_name, m1_color));
+    }
+  }
+
+  static void all_tests() {
+    // clang-format off
+    #if !defined(FLATBUFFERS_CPP98_STL)
+    // clang-format on
+    empty_builder_movector_test();
+    nonempty_builder_movector_test();
+    builder_movector_before_finish_test();
+    builder_movector_after_finish_test();
+    builder_move_assign_before_finish_test();
+    builder_move_assign_after_finish_test();
+    builder_move_assign_after_release_test();
+    builder_move_assign_after_releaseraw_test(DestBuilder());
+    // clang-format off
+    #endif   // !defined(FLATBUFFERS_CPP98_STL)
+    // clang-format on
+    builder_swap_before_finish_test();
+    builder_swap_after_finish_test();
+  }
+};
+
+enum BuilderReuseTestSelector {
+  REUSABLE_AFTER_RELEASE = 1,
+  REUSABLE_AFTER_RELEASE_RAW = 2,
+  REUSABLE_AFTER_RELEASE_MESSAGE = 3,
+  REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN = 4,
+  REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN = 5,
+  REUSABLE_AFTER_RELEASE_MESSAGE_AND_MOVE_ASSIGN = 6
+};
+
+typedef std::set<BuilderReuseTestSelector> TestSelector;
+
+template <class DestBuilder, class SrcBuilder>
+struct BuilderReuseTests {
+  static void builder_reusable_after_release_test(TestSelector selector) {
+    if (!selector.count(REUSABLE_AFTER_RELEASE)) {
+      return;
+    }
+
+    DestBuilder fbb;
+    std::vector<flatbuffers::DetachedBuffer> buffers;
+    for (int i = 0; i < 5; ++i) {
+      auto root_offset1 = populate1(fbb);
+      fbb.Finish(root_offset1);
+      buffers.push_back(fbb.Release());
+      TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
+    }
+  }
+
+  static void builder_reusable_after_releaseraw_test(TestSelector selector) {
+    if (!selector.count(REUSABLE_AFTER_RELEASE_RAW)) {
+      return;
+    }
+
+    DestBuilder fbb;
+    for (int i = 0; i < 5; ++i) {
+      auto root_offset1 = populate1(fbb);
+      fbb.Finish(root_offset1);
+      size_t size, offset;
+      uint8_t *buf = release_raw_base(fbb, size, offset);
+      TEST_ASSERT_FUNC(verify(buf, offset, m1_name, m1_color));
+      free_raw(fbb, buf);
+    }
+  }
+
+  // clang-format off
+  #if !defined(FLATBUFFERS_CPP98_STL)
+  // clang-format on
+  static void builder_reusable_after_release_and_move_assign_test(TestSelector selector) {
+    if (!selector.count(REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN)) {
+      return;
+    }
+
+    DestBuilder dst;
+    std::vector<flatbuffers::DetachedBuffer> buffers;
+    for (int i = 0; i < 5; ++i) {
+      auto root_offset1 = populate1(dst);
+      dst.Finish(root_offset1);
+      buffers.push_back(dst.Release());
+      TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
+      SrcBuilder src;
+      dst = std::move(src);
+      TEST_EQ_FUNC(src.GetSize(), 0);
+    }
+  }
+
+  static void builder_reusable_after_releaseraw_and_move_assign_test(TestSelector selector) {
+    if (!selector.count(REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN)) {
+      return;
+    }
+
+    DestBuilder dst;
+    for (int i = 0; i < 5; ++i) {
+      auto root_offset1 = populate1(dst);
+      dst.Finish(root_offset1);
+      size_t size, offset;
+      uint8_t *buf = release_raw_base(dst, size, offset);
+      TEST_ASSERT_FUNC(verify(buf, offset, m1_name, m1_color));
+      free_raw(dst, buf);
+      SrcBuilder src;
+      dst = std::move(src);
+      TEST_EQ_FUNC(src.GetSize(), 0);
+    }
+  }
+  // clang-format off
+  #endif  // !defined(FLATBUFFERS_CPP98_STL)
+  // clang-format on
+
+  static void run_tests(TestSelector selector) {
+    builder_reusable_after_release_test(selector);
+    builder_reusable_after_releaseraw_test(selector);
+    // clang-format off
+    #if !defined(FLATBUFFERS_CPP98_STL)
+    // clang-format on
+    builder_reusable_after_release_and_move_assign_test(selector);
+    builder_reusable_after_releaseraw_and_move_assign_test(selector);
+    // clang-format off
+    #endif  // !defined(FLATBUFFERS_CPP98_STL)
+    // clang-format on
+  }
+};
+
+#endif // TEST_BUILDER_H
diff --git a/tests/unicode_test.json b/tests/unicode_test.json
new file mode 100644
index 0000000..2894f0c
--- /dev/null
+++ b/tests/unicode_test.json
@@ -0,0 +1,31 @@
+{
+  "name": "unicode_test",
+  "testarrayofstring": [
+    "Цлїςσδε",
+    "フムアムカモケモ",
+    "フムヤムカモケモ",
+    "㊀㊁㊂㊃㊄",
+    "☳☶☲",
+    "𡇙𝌆"
+  ],
+  "testarrayoftables": [
+    {
+      "name": "Цлїςσδε"
+    },
+    {
+      "name": "フムアムカモケモ"
+    },
+    {
+      "name": "フムヤムカモケモ"
+    },
+    {
+      "name": "㊀㊁㊂㊃㊄"
+    },
+    {
+      "name": "☳☶☲"
+    },
+    {
+      "name": "𡇙𝌆"
+    }
+  ]
+}
diff --git a/tests/union_vector/Attacker.cs b/tests/union_vector/Attacker.cs
new file mode 100644
index 0000000..0e3300a
--- /dev/null
+++ b/tests/union_vector/Attacker.cs
@@ -0,0 +1,35 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+using global::System;
+using global::FlatBuffers;
+
+public struct Attacker : IFlatbufferObject
+{
+  private Table __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_11_1(); }
+  public static Attacker GetRootAsAttacker(ByteBuffer _bb) { return GetRootAsAttacker(_bb, new Attacker()); }
+  public static Attacker GetRootAsAttacker(ByteBuffer _bb, Attacker obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+  public Attacker __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public int SwordAttackDamage { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetInt(o + __p.bb_pos) : (int)0; } }
+  public bool MutateSwordAttackDamage(int sword_attack_damage) { int o = __p.__offset(4); if (o != 0) { __p.bb.PutInt(o + __p.bb_pos, sword_attack_damage); return true; } else { return false; } }
+
+  public static Offset<Attacker> CreateAttacker(FlatBufferBuilder builder,
+      int sword_attack_damage = 0) {
+    builder.StartTable(1);
+    Attacker.AddSwordAttackDamage(builder, sword_attack_damage);
+    return Attacker.EndAttacker(builder);
+  }
+
+  public static void StartAttacker(FlatBufferBuilder builder) { builder.StartTable(1); }
+  public static void AddSwordAttackDamage(FlatBufferBuilder builder, int swordAttackDamage) { builder.AddInt(0, swordAttackDamage, 0); }
+  public static Offset<Attacker> EndAttacker(FlatBufferBuilder builder) {
+    int o = builder.EndTable();
+    return new Offset<Attacker>(o);
+  }
+};
+
diff --git a/tests/union_vector/Attacker.java b/tests/union_vector/Attacker.java
new file mode 100644
index 0000000..afe6945
--- /dev/null
+++ b/tests/union_vector/Attacker.java
@@ -0,0 +1,33 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class Attacker extends Table {
+  public static void ValidateVersion() { Constants.FLATBUFFERS_1_11_1(); }
+  public static Attacker getRootAsAttacker(ByteBuffer _bb) { return getRootAsAttacker(_bb, new Attacker()); }
+  public static Attacker getRootAsAttacker(ByteBuffer _bb, Attacker obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public Attacker __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public int swordAttackDamage() { int o = __offset(4); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
+  public boolean mutateSwordAttackDamage(int sword_attack_damage) { int o = __offset(4); if (o != 0) { bb.putInt(o + bb_pos, sword_attack_damage); return true; } else { return false; } }
+
+  public static int createAttacker(FlatBufferBuilder builder,
+      int sword_attack_damage) {
+    builder.startTable(1);
+    Attacker.addSwordAttackDamage(builder, sword_attack_damage);
+    return Attacker.endAttacker(builder);
+  }
+
+  public static void startAttacker(FlatBufferBuilder builder) { builder.startTable(1); }
+  public static void addSwordAttackDamage(FlatBufferBuilder builder, int swordAttackDamage) { builder.addInt(0, swordAttackDamage, 0); }
+  public static int endAttacker(FlatBufferBuilder builder) {
+    int o = builder.endTable();
+    return o;
+  }
+}
+
diff --git a/tests/union_vector/Attacker.kt b/tests/union_vector/Attacker.kt
new file mode 100644
index 0000000..7d3dc68
--- /dev/null
+++ b/tests/union_vector/Attacker.kt
@@ -0,0 +1,51 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Attacker : Table() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : Attacker {
+        __init(_i, _bb)
+        return this
+    }
+    val swordAttackDamage : Int
+        get() {
+            val o = __offset(4)
+            return if(o != 0) bb.getInt(o + bb_pos) else 0
+        }
+    fun mutateSwordAttackDamage(swordAttackDamage: Int) : Boolean {
+        val o = __offset(4)
+        return if (o != 0) {
+            bb.putInt(o + bb_pos, swordAttackDamage)
+            true
+        } else {
+            false
+        }
+    }
+    companion object {
+        fun validateVersion() = Constants.FLATBUFFERS_1_11_1()
+        fun getRootAsAttacker(_bb: ByteBuffer): Attacker = getRootAsAttacker(_bb, Attacker())
+        fun getRootAsAttacker(_bb: ByteBuffer, obj: Attacker): Attacker {
+            _bb.order(ByteOrder.LITTLE_ENDIAN)
+            return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+        }
+        fun createAttacker(builder: FlatBufferBuilder, swordAttackDamage: Int) : Int {
+            builder.startTable(1)
+            addSwordAttackDamage(builder, swordAttackDamage)
+            return endAttacker(builder)
+        }
+        fun startAttacker(builder: FlatBufferBuilder) = builder.startTable(1)
+        fun addSwordAttackDamage(builder: FlatBufferBuilder, swordAttackDamage: Int) = builder.addInt(0, swordAttackDamage, 0)
+        fun endAttacker(builder: FlatBufferBuilder) : Int {
+            val o = builder.endTable()
+            return o
+        }
+    }
+}
diff --git a/tests/union_vector/Attacker.php b/tests/union_vector/Attacker.php
new file mode 100644
index 0000000..e3ebfe6
--- /dev/null
+++ b/tests/union_vector/Attacker.php
@@ -0,0 +1,92 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class Attacker extends Table
+{
+    /**
+     * @param ByteBuffer $bb
+     * @return Attacker
+     */
+    public static function getRootAsAttacker(ByteBuffer $bb)
+    {
+        $obj = new Attacker();
+        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
+    }
+
+    public static function AttackerIdentifier()
+    {
+        return "MOVI";
+    }
+
+    public static function AttackerBufferHasIdentifier(ByteBuffer $buf)
+    {
+        return self::__has_identifier($buf, self::AttackerIdentifier());
+    }
+
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return Attacker
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    /**
+     * @return int
+     */
+    public function getSwordAttackDamage()
+    {
+        $o = $this->__offset(4);
+        return $o != 0 ? $this->bb->getInt($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return void
+     */
+    public static function startAttacker(FlatBufferBuilder $builder)
+    {
+        $builder->StartObject(1);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return Attacker
+     */
+    public static function createAttacker(FlatBufferBuilder $builder, $sword_attack_damage)
+    {
+        $builder->startObject(1);
+        self::addSwordAttackDamage($builder, $sword_attack_damage);
+        $o = $builder->endObject();
+        return $o;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addSwordAttackDamage(FlatBufferBuilder $builder, $swordAttackDamage)
+    {
+        $builder->addIntX(0, $swordAttackDamage, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return int table offset
+     */
+    public static function endAttacker(FlatBufferBuilder $builder)
+    {
+        $o = $builder->endObject();
+        return $o;
+    }
+}
diff --git a/tests/union_vector/BookReader.cs b/tests/union_vector/BookReader.cs
new file mode 100644
index 0000000..53fe736
--- /dev/null
+++ b/tests/union_vector/BookReader.cs
@@ -0,0 +1,24 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+using global::System;
+using global::FlatBuffers;
+
+public struct BookReader : IFlatbufferObject
+{
+  private Struct __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
+  public BookReader __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public int BooksRead { get { return __p.bb.GetInt(__p.bb_pos + 0); } }
+  public void MutateBooksRead(int books_read) { __p.bb.PutInt(__p.bb_pos + 0, books_read); }
+
+  public static Offset<BookReader> CreateBookReader(FlatBufferBuilder builder, int BooksRead) {
+    builder.Prep(4, 4);
+    builder.PutInt(BooksRead);
+    return new Offset<BookReader>(builder.Offset);
+  }
+};
+
diff --git a/tests/union_vector/BookReader.java b/tests/union_vector/BookReader.java
new file mode 100644
index 0000000..20ff9e2
--- /dev/null
+++ b/tests/union_vector/BookReader.java
@@ -0,0 +1,22 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class BookReader extends Struct {
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public BookReader __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public int booksRead() { return bb.getInt(bb_pos + 0); }
+  public void mutateBooksRead(int books_read) { bb.putInt(bb_pos + 0, books_read); }
+
+  public static int createBookReader(FlatBufferBuilder builder, int booksRead) {
+    builder.prep(4, 4);
+    builder.putInt(booksRead);
+    return builder.offset();
+  }
+}
+
diff --git a/tests/union_vector/BookReader.kt b/tests/union_vector/BookReader.kt
new file mode 100644
index 0000000..fc41473
--- /dev/null
+++ b/tests/union_vector/BookReader.kt
@@ -0,0 +1,27 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class BookReader : Struct() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : BookReader {
+        __init(_i, _bb)
+        return this
+    }
+    val booksRead : Int get() = bb.getInt(bb_pos + 0)
+    fun mutateBooksRead(booksRead: Int) : ByteBuffer = bb.putInt(bb_pos + 0, booksRead)
+    companion object {
+        fun createBookReader(builder: FlatBufferBuilder, booksRead: Int) : Int {
+            builder.prep(4, 4)
+            builder.putInt(booksRead)
+            return builder.offset()
+        }
+    }
+}
diff --git a/tests/union_vector/BookReader.php b/tests/union_vector/BookReader.php
new file mode 100644
index 0000000..1f8f8d8
--- /dev/null
+++ b/tests/union_vector/BookReader.php
@@ -0,0 +1,41 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class BookReader extends Struct
+{
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return BookReader
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    /**
+     * @return int
+     */
+    public function GetBooksRead()
+    {
+        return $this->bb->getInt($this->bb_pos + 0);
+    }
+
+
+    /**
+     * @return int offset
+     */
+    public static function createBookReader(FlatBufferBuilder $builder, $booksRead)
+    {
+        $builder->prep(4, 4);
+        $builder->putInt($booksRead);
+        return $builder->offset();
+    }
+}
diff --git a/tests/union_vector/Character.cs b/tests/union_vector/Character.cs
new file mode 100644
index 0000000..73a5cba
--- /dev/null
+++ b/tests/union_vector/Character.cs
@@ -0,0 +1,15 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+public enum Character : byte
+{
+  NONE = 0,
+  MuLan = 1,
+  Rapunzel = 2,
+  Belle = 3,
+  BookFan = 4,
+  Other = 5,
+  Unused = 6,
+};
+
diff --git a/tests/union_vector/Character.java b/tests/union_vector/Character.java
new file mode 100644
index 0000000..5d6c5b7
--- /dev/null
+++ b/tests/union_vector/Character.java
@@ -0,0 +1,17 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+public final class Character {
+  private Character() { }
+  public static final byte NONE = 0;
+  public static final byte MuLan = 1;
+  public static final byte Rapunzel = 2;
+  public static final byte Belle = 3;
+  public static final byte BookFan = 4;
+  public static final byte Other = 5;
+  public static final byte Unused = 6;
+
+  public static final String[] names = { "NONE", "MuLan", "Rapunzel", "Belle", "BookFan", "Other", "Unused", };
+
+  public static String name(int e) { return names[e]; }
+}
+
diff --git a/tests/union_vector/Character.kt b/tests/union_vector/Character.kt
new file mode 100644
index 0000000..ff7dd5e
--- /dev/null
+++ b/tests/union_vector/Character.kt
@@ -0,0 +1,17 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Character_ private constructor() {
+    companion object {
+        const val NONE: UByte = 0u
+        const val MuLan: UByte = 1u
+        const val Rapunzel: UByte = 2u
+        const val Belle: UByte = 3u
+        const val BookFan: UByte = 4u
+        const val Other: UByte = 5u
+        const val Unused: UByte = 6u
+        val names : Array<String> = arrayOf("NONE", "MuLan", "Rapunzel", "Belle", "BookFan", "Other", "Unused")
+        fun name(e: Int) : String = names[e]
+    }
+}
diff --git a/tests/union_vector/Character.php b/tests/union_vector/Character.php
new file mode 100644
index 0000000..755958b
--- /dev/null
+++ b/tests/union_vector/Character.php
@@ -0,0 +1,31 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+class Character
+{
+    const NONE = 0;
+    const MuLan = 1;
+    const Rapunzel = 2;
+    const Belle = 3;
+    const BookFan = 4;
+    const Other = 5;
+    const Unused = 6;
+
+    private static $names = array(
+        Character::NONE=>"NONE",
+        Character::MuLan=>"MuLan",
+        Character::Rapunzel=>"Rapunzel",
+        Character::Belle=>"Belle",
+        Character::BookFan=>"BookFan",
+        Character::Other=>"Other",
+        Character::Unused=>"Unused",
+    );
+
+    public static function Name($e)
+    {
+        if (!isset(self::$names[$e])) {
+            throw new \Exception();
+        }
+        return self::$names[$e];
+    }
+}
diff --git a/tests/union_vector/Movie.cs b/tests/union_vector/Movie.cs
new file mode 100644
index 0000000..13dbfac
--- /dev/null
+++ b/tests/union_vector/Movie.cs
@@ -0,0 +1,65 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+using global::System;
+using global::FlatBuffers;
+
+public struct Movie : IFlatbufferObject
+{
+  private Table __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_11_1(); }
+  public static Movie GetRootAsMovie(ByteBuffer _bb) { return GetRootAsMovie(_bb, new Movie()); }
+  public static Movie GetRootAsMovie(ByteBuffer _bb, Movie obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public static bool MovieBufferHasIdentifier(ByteBuffer _bb) { return Table.__has_identifier(_bb, "MOVI"); }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+  public Movie __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public Character MainCharacterType { get { int o = __p.__offset(4); return o != 0 ? (Character)__p.bb.Get(o + __p.bb_pos) : Character.NONE; } }
+  public bool MutateMainCharacterType(Character main_character_type) { int o = __p.__offset(4); if (o != 0) { __p.bb.Put(o + __p.bb_pos, (byte)main_character_type); return true; } else { return false; } }
+  public TTable? MainCharacter<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(6); return o != 0 ? (TTable?)__p.__union<TTable>(o) : null; }
+  public Character CharactersType(int j) { int o = __p.__offset(8); return o != 0 ? (Character)__p.bb.Get(__p.__vector(o) + j * 1) : (Character)0; }
+  public int CharactersTypeLength { get { int o = __p.__offset(8); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetCharactersTypeBytes() { return __p.__vector_as_span(8); }
+#else
+  public ArraySegment<byte>? GetCharactersTypeBytes() { return __p.__vector_as_arraysegment(8); }
+#endif
+  public Character[] GetCharactersTypeArray() { return __p.__vector_as_array<Character>(8); }
+  public bool MutateCharactersType(int j, Character characters_type) { int o = __p.__offset(8); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, (byte)characters_type); return true; } else { return false; } }
+  public TTable? Characters<TTable>(int j) where TTable : struct, IFlatbufferObject { int o = __p.__offset(10); return o != 0 ? (TTable?)__p.__union<TTable>(__p.__vector(o) + j * 4 - __p.bb_pos) : null; }
+  public int CharactersLength { get { int o = __p.__offset(10); return o != 0 ? __p.__vector_len(o) : 0; } }
+
+  public static Offset<Movie> CreateMovie(FlatBufferBuilder builder,
+      Character main_character_type = Character.NONE,
+      int main_characterOffset = 0,
+      VectorOffset characters_typeOffset = default(VectorOffset),
+      VectorOffset charactersOffset = default(VectorOffset)) {
+    builder.StartTable(4);
+    Movie.AddCharacters(builder, charactersOffset);
+    Movie.AddCharactersType(builder, characters_typeOffset);
+    Movie.AddMainCharacter(builder, main_characterOffset);
+    Movie.AddMainCharacterType(builder, main_character_type);
+    return Movie.EndMovie(builder);
+  }
+
+  public static void StartMovie(FlatBufferBuilder builder) { builder.StartTable(4); }
+  public static void AddMainCharacterType(FlatBufferBuilder builder, Character mainCharacterType) { builder.AddByte(0, (byte)mainCharacterType, 0); }
+  public static void AddMainCharacter(FlatBufferBuilder builder, int mainCharacterOffset) { builder.AddOffset(1, mainCharacterOffset, 0); }
+  public static void AddCharactersType(FlatBufferBuilder builder, VectorOffset charactersTypeOffset) { builder.AddOffset(2, charactersTypeOffset.Value, 0); }
+  public static VectorOffset CreateCharactersTypeVector(FlatBufferBuilder builder, Character[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddByte((byte)data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateCharactersTypeVectorBlock(FlatBufferBuilder builder, Character[] data) { builder.StartVector(1, data.Length, 1); builder.Add(data); return builder.EndVector(); }
+  public static void StartCharactersTypeVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); }
+  public static void AddCharacters(FlatBufferBuilder builder, VectorOffset charactersOffset) { builder.AddOffset(3, charactersOffset.Value, 0); }
+  public static VectorOffset CreateCharactersVector(FlatBufferBuilder builder, int[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateCharactersVectorBlock(FlatBufferBuilder builder, int[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
+  public static void StartCharactersVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
+  public static Offset<Movie> EndMovie(FlatBufferBuilder builder) {
+    int o = builder.EndTable();
+    return new Offset<Movie>(o);
+  }
+  public static void FinishMovieBuffer(FlatBufferBuilder builder, Offset<Movie> offset) { builder.Finish(offset.Value, "MOVI"); }
+  public static void FinishSizePrefixedMovieBuffer(FlatBufferBuilder builder, Offset<Movie> offset) { builder.FinishSizePrefixed(offset.Value, "MOVI"); }
+};
+
diff --git a/tests/union_vector/Movie.java b/tests/union_vector/Movie.java
new file mode 100644
index 0000000..0f6a19c
--- /dev/null
+++ b/tests/union_vector/Movie.java
@@ -0,0 +1,57 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class Movie extends Table {
+  public static void ValidateVersion() { Constants.FLATBUFFERS_1_11_1(); }
+  public static Movie getRootAsMovie(ByteBuffer _bb) { return getRootAsMovie(_bb, new Movie()); }
+  public static Movie getRootAsMovie(ByteBuffer _bb, Movie obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public static boolean MovieBufferHasIdentifier(ByteBuffer _bb) { return __has_identifier(_bb, "MOVI"); }
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public Movie __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public byte mainCharacterType() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) : 0; }
+  public boolean mutateMainCharacterType(byte main_character_type) { int o = __offset(4); if (o != 0) { bb.put(o + bb_pos, main_character_type); return true; } else { return false; } }
+  public Table mainCharacter(Table obj) { int o = __offset(6); return o != 0 ? __union(obj, o) : null; }
+  public byte charactersType(int j) { int o = __offset(8); return o != 0 ? bb.get(__vector(o) + j * 1) : 0; }
+  public int charactersTypeLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; }
+  public ByteBuffer charactersTypeAsByteBuffer() { return __vector_as_bytebuffer(8, 1); }
+  public ByteBuffer charactersTypeInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 8, 1); }
+  public boolean mutateCharactersType(int j, byte characters_type) { int o = __offset(8); if (o != 0) { bb.put(__vector(o) + j * 1, characters_type); return true; } else { return false; } }
+  public Table characters(Table obj, int j) { int o = __offset(10); return o != 0 ? __union(obj, __vector(o) + j * 4 - bb_pos) : null; }
+  public int charactersLength() { int o = __offset(10); return o != 0 ? __vector_len(o) : 0; }
+
+  public static int createMovie(FlatBufferBuilder builder,
+      byte main_character_type,
+      int main_characterOffset,
+      int characters_typeOffset,
+      int charactersOffset) {
+    builder.startTable(4);
+    Movie.addCharacters(builder, charactersOffset);
+    Movie.addCharactersType(builder, characters_typeOffset);
+    Movie.addMainCharacter(builder, main_characterOffset);
+    Movie.addMainCharacterType(builder, main_character_type);
+    return Movie.endMovie(builder);
+  }
+
+  public static void startMovie(FlatBufferBuilder builder) { builder.startTable(4); }
+  public static void addMainCharacterType(FlatBufferBuilder builder, byte mainCharacterType) { builder.addByte(0, mainCharacterType, 0); }
+  public static void addMainCharacter(FlatBufferBuilder builder, int mainCharacterOffset) { builder.addOffset(1, mainCharacterOffset, 0); }
+  public static void addCharactersType(FlatBufferBuilder builder, int charactersTypeOffset) { builder.addOffset(2, charactersTypeOffset, 0); }
+  public static int createCharactersTypeVector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); }
+  public static void startCharactersTypeVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
+  public static void addCharacters(FlatBufferBuilder builder, int charactersOffset) { builder.addOffset(3, charactersOffset, 0); }
+  public static int createCharactersVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
+  public static void startCharactersVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
+  public static int endMovie(FlatBufferBuilder builder) {
+    int o = builder.endTable();
+    return o;
+  }
+  public static void finishMovieBuffer(FlatBufferBuilder builder, int offset) { builder.finish(offset, "MOVI"); }
+  public static void finishSizePrefixedMovieBuffer(FlatBufferBuilder builder, int offset) { builder.finishSizePrefixed(offset, "MOVI"); }
+}
+
diff --git a/tests/union_vector/Movie.kt b/tests/union_vector/Movie.kt
new file mode 100644
index 0000000..b8a135b
--- /dev/null
+++ b/tests/union_vector/Movie.kt
@@ -0,0 +1,114 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Movie : Table() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : Movie {
+        __init(_i, _bb)
+        return this
+    }
+    val mainCharacterType : UByte
+        get() {
+            val o = __offset(4)
+            return if(o != 0) bb.get(o + bb_pos).toUByte() else 0u
+        }
+    fun mutateMainCharacterType(mainCharacterType: UByte) : Boolean {
+        val o = __offset(4)
+        return if (o != 0) {
+            bb.put(o + bb_pos, mainCharacterType.toByte())
+            true
+        } else {
+            false
+        }
+    }
+    fun mainCharacter(obj: Table) : Table? {
+        val o = __offset(6); return if (o != 0) __union(obj, o) else null
+    }
+    fun charactersType(j: Int) : UByte {
+        val o = __offset(8)
+        return if (o != 0) {
+            bb.get(__vector(o) + j * 1).toUByte()
+        } else {
+            0u
+        }
+    }
+    val charactersTypeLength : Int
+        get() {
+            val o = __offset(8); return if (o != 0) __vector_len(o) else 0
+        }
+    val charactersTypeAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(8, 1)
+    fun charactersTypeInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 8, 1)
+    fun mutateCharactersType(j: Int, charactersType: UByte) : Boolean {
+        val o = __offset(8)
+        return if (o != 0) {
+            bb.put(__vector(o) + j * 1, charactersType.toByte())
+            true
+        } else {
+            false
+        }
+    }
+    fun characters(obj: Table, j: Int) : Table? {
+        val o = __offset(10)
+        return if (o != 0) {
+            __union(obj, __vector(o) + j * 4 - bb_pos)
+        } else {
+            null
+        }
+    }
+    val charactersLength : Int
+        get() {
+            val o = __offset(10); return if (o != 0) __vector_len(o) else 0
+        }
+    companion object {
+        fun validateVersion() = Constants.FLATBUFFERS_1_11_1()
+        fun getRootAsMovie(_bb: ByteBuffer): Movie = getRootAsMovie(_bb, Movie())
+        fun getRootAsMovie(_bb: ByteBuffer, obj: Movie): Movie {
+            _bb.order(ByteOrder.LITTLE_ENDIAN)
+            return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+        }
+        fun MovieBufferHasIdentifier(_bb: ByteBuffer) : Boolean = __has_identifier(_bb, "MOVI")
+        fun createMovie(builder: FlatBufferBuilder, mainCharacterType: UByte, mainCharacterOffset: Int, charactersTypeOffset: Int, charactersOffset: Int) : Int {
+            builder.startTable(4)
+            addCharacters(builder, charactersOffset)
+            addCharactersType(builder, charactersTypeOffset)
+            addMainCharacter(builder, mainCharacterOffset)
+            addMainCharacterType(builder, mainCharacterType)
+            return endMovie(builder)
+        }
+        fun startMovie(builder: FlatBufferBuilder) = builder.startTable(4)
+        fun addMainCharacterType(builder: FlatBufferBuilder, mainCharacterType: UByte) = builder.addByte(0, mainCharacterType.toByte(), 0)
+        fun addMainCharacter(builder: FlatBufferBuilder, mainCharacter: Int) = builder.addOffset(1, mainCharacter, 0)
+        fun addCharactersType(builder: FlatBufferBuilder, charactersType: Int) = builder.addOffset(2, charactersType, 0)
+        fun createCharactersTypeVector(builder: FlatBufferBuilder, data: UByteArray) : Int {
+            builder.startVector(1, data.size, 1)
+            for (i in data.size - 1 downTo 0) {
+                builder.addByte(data[i].toByte())
+            }
+            return builder.endVector()
+        }
+        fun startCharactersTypeVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(1, numElems, 1)
+        fun addCharacters(builder: FlatBufferBuilder, characters: Int) = builder.addOffset(3, characters, 0)
+        fun createCharactersVector(builder: FlatBufferBuilder, data: IntArray) : Int {
+            builder.startVector(4, data.size, 4)
+            for (i in data.size - 1 downTo 0) {
+                builder.addOffset(data[i])
+            }
+            return builder.endVector()
+        }
+        fun startCharactersVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(4, numElems, 4)
+        fun endMovie(builder: FlatBufferBuilder) : Int {
+            val o = builder.endTable()
+            return o
+        }
+        fun finishMovieBuffer(builder: FlatBufferBuilder, offset: Int) = builder.finish(offset, "MOVI")
+        fun finishSizePrefixedMovieBuffer(builder: FlatBufferBuilder, offset: Int) = builder.finishSizePrefixed(offset, "MOVI")
+    }
+}
diff --git a/tests/union_vector/Movie.php b/tests/union_vector/Movie.php
new file mode 100644
index 0000000..216cd28
--- /dev/null
+++ b/tests/union_vector/Movie.php
@@ -0,0 +1,220 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class Movie extends Table
+{
+    /**
+     * @param ByteBuffer $bb
+     * @return Movie
+     */
+    public static function getRootAsMovie(ByteBuffer $bb)
+    {
+        $obj = new Movie();
+        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
+    }
+
+    public static function MovieIdentifier()
+    {
+        return "MOVI";
+    }
+
+    public static function MovieBufferHasIdentifier(ByteBuffer $buf)
+    {
+        return self::__has_identifier($buf, self::MovieIdentifier());
+    }
+
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return Movie
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    /**
+     * @return byte
+     */
+    public function getMainCharacterType()
+    {
+        $o = $this->__offset(4);
+        return $o != 0 ? $this->bb->getByte($o + $this->bb_pos) : \Character::NONE;
+    }
+
+    /**
+     * @returnint
+     */
+    public function getMainCharacter($obj)
+    {
+        $o = $this->__offset(6);
+        return $o != 0 ? $this->__union($obj, $o) : null;
+    }
+
+    /**
+     * @param int offset
+     * @return byte
+     */
+    public function getCharactersType($j)
+    {
+        $o = $this->__offset(8);
+        return $o != 0 ? $this->bb->getByte($this->__vector($o) + $j * 1) : \Character::NONE;
+    }
+
+    /**
+     * @return int
+     */
+    public function getCharactersTypeLength()
+    {
+        $o = $this->__offset(8);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @param int offset
+     * @return Table
+     */
+    public function getCharacters($j, $obj)
+    {
+        $o = $this->__offset(10);
+        return $o != 0 ? $this->__union($obj, $this->__vector($o) + $j * 4 - $this->bb_pos) : null;
+    }
+
+    /**
+     * @return int
+     */
+    public function getCharactersLength()
+    {
+        $o = $this->__offset(10);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return void
+     */
+    public static function startMovie(FlatBufferBuilder $builder)
+    {
+        $builder->StartObject(4);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return Movie
+     */
+    public static function createMovie(FlatBufferBuilder $builder, $main_character_type, $main_character, $characters_type, $characters)
+    {
+        $builder->startObject(4);
+        self::addMainCharacterType($builder, $main_character_type);
+        self::addMainCharacter($builder, $main_character);
+        self::addCharactersType($builder, $characters_type);
+        self::addCharacters($builder, $characters);
+        $o = $builder->endObject();
+        return $o;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param byte
+     * @return void
+     */
+    public static function addMainCharacterType(FlatBufferBuilder $builder, $mainCharacterType)
+    {
+        $builder->addByteX(0, $mainCharacterType, 0);
+    }
+
+    public static function addMainCharacter(FlatBufferBuilder $builder, $offset)
+    {
+        $builder->addOffsetX(1, $offset, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addCharactersType(FlatBufferBuilder $builder, $charactersType)
+    {
+        $builder->addOffsetX(2, $charactersType, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createCharactersTypeVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(1, count($data), 1);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putByte($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startCharactersTypeVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(1, $numElems, 1);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addCharacters(FlatBufferBuilder $builder, $characters)
+    {
+        $builder->addOffsetX(3, $characters, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createCharactersVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(4, count($data), 4);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putOffset($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startCharactersVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(4, $numElems, 4);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return int table offset
+     */
+    public static function endMovie(FlatBufferBuilder $builder)
+    {
+        $o = $builder->endObject();
+        return $o;
+    }
+
+    public static function finishMovieBuffer(FlatBufferBuilder $builder, $offset)
+    {
+        $builder->finish($offset, "MOVI");
+    }
+}
diff --git a/tests/union_vector/Rapunzel.cs b/tests/union_vector/Rapunzel.cs
new file mode 100644
index 0000000..cb05d4a
--- /dev/null
+++ b/tests/union_vector/Rapunzel.cs
@@ -0,0 +1,24 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+using global::System;
+using global::FlatBuffers;
+
+public struct Rapunzel : IFlatbufferObject
+{
+  private Struct __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
+  public Rapunzel __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public int HairLength { get { return __p.bb.GetInt(__p.bb_pos + 0); } }
+  public void MutateHairLength(int hair_length) { __p.bb.PutInt(__p.bb_pos + 0, hair_length); }
+
+  public static Offset<Rapunzel> CreateRapunzel(FlatBufferBuilder builder, int HairLength) {
+    builder.Prep(4, 4);
+    builder.PutInt(HairLength);
+    return new Offset<Rapunzel>(builder.Offset);
+  }
+};
+
diff --git a/tests/union_vector/Rapunzel.java b/tests/union_vector/Rapunzel.java
new file mode 100644
index 0000000..852c061
--- /dev/null
+++ b/tests/union_vector/Rapunzel.java
@@ -0,0 +1,22 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class Rapunzel extends Struct {
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public Rapunzel __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public int hairLength() { return bb.getInt(bb_pos + 0); }
+  public void mutateHairLength(int hair_length) { bb.putInt(bb_pos + 0, hair_length); }
+
+  public static int createRapunzel(FlatBufferBuilder builder, int hairLength) {
+    builder.prep(4, 4);
+    builder.putInt(hairLength);
+    return builder.offset();
+  }
+}
+
diff --git a/tests/union_vector/Rapunzel.kt b/tests/union_vector/Rapunzel.kt
new file mode 100644
index 0000000..080a7f7
--- /dev/null
+++ b/tests/union_vector/Rapunzel.kt
@@ -0,0 +1,27 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Rapunzel : Struct() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : Rapunzel {
+        __init(_i, _bb)
+        return this
+    }
+    val hairLength : Int get() = bb.getInt(bb_pos + 0)
+    fun mutateHairLength(hairLength: Int) : ByteBuffer = bb.putInt(bb_pos + 0, hairLength)
+    companion object {
+        fun createRapunzel(builder: FlatBufferBuilder, hairLength: Int) : Int {
+            builder.prep(4, 4)
+            builder.putInt(hairLength)
+            return builder.offset()
+        }
+    }
+}
diff --git a/tests/union_vector/Rapunzel.php b/tests/union_vector/Rapunzel.php
new file mode 100644
index 0000000..9842d95
--- /dev/null
+++ b/tests/union_vector/Rapunzel.php
@@ -0,0 +1,41 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class Rapunzel extends Struct
+{
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return Rapunzel
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    /**
+     * @return int
+     */
+    public function GetHairLength()
+    {
+        return $this->bb->getInt($this->bb_pos + 0);
+    }
+
+
+    /**
+     * @return int offset
+     */
+    public static function createRapunzel(FlatBufferBuilder $builder, $hairLength)
+    {
+        $builder->prep(4, 4);
+        $builder->putInt($hairLength);
+        return $builder->offset();
+    }
+}
diff --git a/tests/union_vector/union_vector.fbs b/tests/union_vector/union_vector.fbs
new file mode 100644
index 0000000..495076f
--- /dev/null
+++ b/tests/union_vector/union_vector.fbs
@@ -0,0 +1,31 @@
+// Demonstrates the ability to have vectors of unions, and also to
+// store structs and strings in unions.
+
+table Attacker {
+  sword_attack_damage: int;
+}
+
+struct Rapunzel {
+  hair_length: int;
+}
+
+struct BookReader {
+  books_read: int;
+}
+
+union Character {
+  MuLan: Attacker,  // Can have name be different from type.
+  Rapunzel,         // Or just both the same, as before.
+  Belle: BookReader,
+  BookFan: BookReader,
+  Other: string,
+  Unused: string
+}
+
+table Movie {
+  main_character: Character;
+  characters: [Character];
+}
+
+root_type Movie;
+file_identifier "MOVI";
diff --git a/tests/union_vector/union_vector.json b/tests/union_vector/union_vector.json
new file mode 100644
index 0000000..af0c9cb
--- /dev/null
+++ b/tests/union_vector/union_vector.json
@@ -0,0 +1,26 @@
+{
+  "main_character_type": "Rapunzel",
+  "main_character": {
+    "hair_length": 6
+  },
+  "characters_type": [
+    "Belle",
+    "MuLan",
+    "BookFan",
+    "Other",
+    "Unused"
+  ],
+  "characters": [
+    {
+      "books_read": 7
+    },
+    {
+      "sword_attack_damage": 5
+    },
+    {
+      "books_read": 2
+    },
+    "Other",
+    "Unused"
+  ]
+}
diff --git a/tests/union_vector/union_vector_generated.h b/tests/union_vector/union_vector_generated.h
new file mode 100644
index 0000000..150c8f4
--- /dev/null
+++ b/tests/union_vector/union_vector_generated.h
@@ -0,0 +1,859 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+#ifndef FLATBUFFERS_GENERATED_UNIONVECTOR_H_
+#define FLATBUFFERS_GENERATED_UNIONVECTOR_H_
+
+#include "flatbuffers/flatbuffers.h"
+
+struct Attacker;
+struct AttackerT;
+
+struct Rapunzel;
+
+struct BookReader;
+
+struct Movie;
+struct MovieT;
+
+bool operator==(const AttackerT &lhs, const AttackerT &rhs);
+bool operator!=(const AttackerT &lhs, const AttackerT &rhs);
+bool operator==(const Rapunzel &lhs, const Rapunzel &rhs);
+bool operator!=(const Rapunzel &lhs, const Rapunzel &rhs);
+bool operator==(const BookReader &lhs, const BookReader &rhs);
+bool operator!=(const BookReader &lhs, const BookReader &rhs);
+bool operator==(const MovieT &lhs, const MovieT &rhs);
+bool operator!=(const MovieT &lhs, const MovieT &rhs);
+
+inline const flatbuffers::TypeTable *AttackerTypeTable();
+
+inline const flatbuffers::TypeTable *RapunzelTypeTable();
+
+inline const flatbuffers::TypeTable *BookReaderTypeTable();
+
+inline const flatbuffers::TypeTable *MovieTypeTable();
+
+enum Character {
+  Character_NONE = 0,
+  Character_MuLan = 1,
+  Character_Rapunzel = 2,
+  Character_Belle = 3,
+  Character_BookFan = 4,
+  Character_Other = 5,
+  Character_Unused = 6,
+  Character_MIN = Character_NONE,
+  Character_MAX = Character_Unused
+};
+
+inline const Character (&EnumValuesCharacter())[7] {
+  static const Character values[] = {
+    Character_NONE,
+    Character_MuLan,
+    Character_Rapunzel,
+    Character_Belle,
+    Character_BookFan,
+    Character_Other,
+    Character_Unused
+  };
+  return values;
+}
+
+inline const char * const *EnumNamesCharacter() {
+  static const char * const names[8] = {
+    "NONE",
+    "MuLan",
+    "Rapunzel",
+    "Belle",
+    "BookFan",
+    "Other",
+    "Unused",
+    nullptr
+  };
+  return names;
+}
+
+inline const char *EnumNameCharacter(Character e) {
+  if (e < Character_NONE || e > Character_Unused) return "";
+  const size_t index = static_cast<size_t>(e);
+  return EnumNamesCharacter()[index];
+}
+
+struct CharacterUnion {
+  Character type;
+  void *value;
+
+  CharacterUnion() : type(Character_NONE), value(nullptr) {}
+  CharacterUnion(CharacterUnion&& u) FLATBUFFERS_NOEXCEPT :
+    type(Character_NONE), value(nullptr)
+    { std::swap(type, u.type); std::swap(value, u.value); }
+  CharacterUnion(const CharacterUnion &) FLATBUFFERS_NOEXCEPT;
+  CharacterUnion &operator=(const CharacterUnion &u) FLATBUFFERS_NOEXCEPT
+    { CharacterUnion t(u); std::swap(type, t.type); std::swap(value, t.value); return *this; }
+  CharacterUnion &operator=(CharacterUnion &&u) FLATBUFFERS_NOEXCEPT
+    { std::swap(type, u.type); std::swap(value, u.value); return *this; }
+  ~CharacterUnion() { Reset(); }
+
+  void Reset();
+
+  static void *UnPack(const void *obj, Character type, const flatbuffers::resolver_function_t *resolver);
+  flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher = nullptr) const;
+
+  AttackerT *AsMuLan() {
+    return type == Character_MuLan ?
+      reinterpret_cast<AttackerT *>(value) : nullptr;
+  }
+  const AttackerT *AsMuLan() const {
+    return type == Character_MuLan ?
+      reinterpret_cast<const AttackerT *>(value) : nullptr;
+  }
+  Rapunzel *AsRapunzel() {
+    return type == Character_Rapunzel ?
+      reinterpret_cast<Rapunzel *>(value) : nullptr;
+  }
+  const Rapunzel *AsRapunzel() const {
+    return type == Character_Rapunzel ?
+      reinterpret_cast<const Rapunzel *>(value) : nullptr;
+  }
+  BookReader *AsBelle() {
+    return type == Character_Belle ?
+      reinterpret_cast<BookReader *>(value) : nullptr;
+  }
+  const BookReader *AsBelle() const {
+    return type == Character_Belle ?
+      reinterpret_cast<const BookReader *>(value) : nullptr;
+  }
+  BookReader *AsBookFan() {
+    return type == Character_BookFan ?
+      reinterpret_cast<BookReader *>(value) : nullptr;
+  }
+  const BookReader *AsBookFan() const {
+    return type == Character_BookFan ?
+      reinterpret_cast<const BookReader *>(value) : nullptr;
+  }
+  std::string *AsOther() {
+    return type == Character_Other ?
+      reinterpret_cast<std::string *>(value) : nullptr;
+  }
+  const std::string *AsOther() const {
+    return type == Character_Other ?
+      reinterpret_cast<const std::string *>(value) : nullptr;
+  }
+  std::string *AsUnused() {
+    return type == Character_Unused ?
+      reinterpret_cast<std::string *>(value) : nullptr;
+  }
+  const std::string *AsUnused() const {
+    return type == Character_Unused ?
+      reinterpret_cast<const std::string *>(value) : nullptr;
+  }
+};
+
+
+inline bool operator==(const CharacterUnion &lhs, const CharacterUnion &rhs) {
+  if (lhs.type != rhs.type) return false;
+  switch (lhs.type) {
+    case Character_NONE: {
+      return true;
+    }
+    case Character_MuLan: {
+      return *(reinterpret_cast<const AttackerT *>(lhs.value)) ==
+             *(reinterpret_cast<const AttackerT *>(rhs.value));
+    }
+    case Character_Rapunzel: {
+      return *(reinterpret_cast<const Rapunzel *>(lhs.value)) ==
+             *(reinterpret_cast<const Rapunzel *>(rhs.value));
+    }
+    case Character_Belle: {
+      return *(reinterpret_cast<const BookReader *>(lhs.value)) ==
+             *(reinterpret_cast<const BookReader *>(rhs.value));
+    }
+    case Character_BookFan: {
+      return *(reinterpret_cast<const BookReader *>(lhs.value)) ==
+             *(reinterpret_cast<const BookReader *>(rhs.value));
+    }
+    case Character_Other: {
+      return *(reinterpret_cast<const std::string *>(lhs.value)) ==
+             *(reinterpret_cast<const std::string *>(rhs.value));
+    }
+    case Character_Unused: {
+      return *(reinterpret_cast<const std::string *>(lhs.value)) ==
+             *(reinterpret_cast<const std::string *>(rhs.value));
+    }
+    default: {
+      return false;
+    }
+  }
+}
+
+inline bool operator!=(const CharacterUnion &lhs, const CharacterUnion &rhs) {
+    return !(lhs == rhs);
+}
+
+bool VerifyCharacter(flatbuffers::Verifier &verifier, const void *obj, Character type);
+bool VerifyCharacterVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types);
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Rapunzel FLATBUFFERS_FINAL_CLASS {
+ private:
+  int32_t hair_length_;
+
+ public:
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return RapunzelTypeTable();
+  }
+  Rapunzel() {
+    memset(static_cast<void *>(this), 0, sizeof(Rapunzel));
+  }
+  Rapunzel(int32_t _hair_length)
+      : hair_length_(flatbuffers::EndianScalar(_hair_length)) {
+  }
+  int32_t hair_length() const {
+    return flatbuffers::EndianScalar(hair_length_);
+  }
+  void mutate_hair_length(int32_t _hair_length) {
+    flatbuffers::WriteScalar(&hair_length_, _hair_length);
+  }
+};
+FLATBUFFERS_STRUCT_END(Rapunzel, 4);
+
+inline bool operator==(const Rapunzel &lhs, const Rapunzel &rhs) {
+  return
+      (lhs.hair_length() == rhs.hair_length());
+}
+
+inline bool operator!=(const Rapunzel &lhs, const Rapunzel &rhs) {
+    return !(lhs == rhs);
+}
+
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) BookReader FLATBUFFERS_FINAL_CLASS {
+ private:
+  int32_t books_read_;
+
+ public:
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return BookReaderTypeTable();
+  }
+  BookReader() {
+    memset(static_cast<void *>(this), 0, sizeof(BookReader));
+  }
+  BookReader(int32_t _books_read)
+      : books_read_(flatbuffers::EndianScalar(_books_read)) {
+  }
+  int32_t books_read() const {
+    return flatbuffers::EndianScalar(books_read_);
+  }
+  void mutate_books_read(int32_t _books_read) {
+    flatbuffers::WriteScalar(&books_read_, _books_read);
+  }
+};
+FLATBUFFERS_STRUCT_END(BookReader, 4);
+
+inline bool operator==(const BookReader &lhs, const BookReader &rhs) {
+  return
+      (lhs.books_read() == rhs.books_read());
+}
+
+inline bool operator!=(const BookReader &lhs, const BookReader &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct AttackerT : public flatbuffers::NativeTable {
+  typedef Attacker TableType;
+  int32_t sword_attack_damage;
+  AttackerT()
+      : sword_attack_damage(0) {
+  }
+};
+
+inline bool operator==(const AttackerT &lhs, const AttackerT &rhs) {
+  return
+      (lhs.sword_attack_damage == rhs.sword_attack_damage);
+}
+
+inline bool operator!=(const AttackerT &lhs, const AttackerT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct Attacker FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef AttackerT NativeTableType;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return AttackerTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_SWORD_ATTACK_DAMAGE = 4
+  };
+  int32_t sword_attack_damage() const {
+    return GetField<int32_t>(VT_SWORD_ATTACK_DAMAGE, 0);
+  }
+  bool mutate_sword_attack_damage(int32_t _sword_attack_damage) {
+    return SetField<int32_t>(VT_SWORD_ATTACK_DAMAGE, _sword_attack_damage, 0);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<int32_t>(verifier, VT_SWORD_ATTACK_DAMAGE) &&
+           verifier.EndTable();
+  }
+  AttackerT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(AttackerT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<Attacker> Pack(flatbuffers::FlatBufferBuilder &_fbb, const AttackerT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct AttackerBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_sword_attack_damage(int32_t sword_attack_damage) {
+    fbb_.AddElement<int32_t>(Attacker::VT_SWORD_ATTACK_DAMAGE, sword_attack_damage, 0);
+  }
+  explicit AttackerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  AttackerBuilder &operator=(const AttackerBuilder &);
+  flatbuffers::Offset<Attacker> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Attacker>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Attacker> CreateAttacker(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    int32_t sword_attack_damage = 0) {
+  AttackerBuilder builder_(_fbb);
+  builder_.add_sword_attack_damage(sword_attack_damage);
+  return builder_.Finish();
+}
+
+flatbuffers::Offset<Attacker> CreateAttacker(flatbuffers::FlatBufferBuilder &_fbb, const AttackerT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+struct MovieT : public flatbuffers::NativeTable {
+  typedef Movie TableType;
+  CharacterUnion main_character;
+  std::vector<CharacterUnion> characters;
+  MovieT() {
+  }
+};
+
+inline bool operator==(const MovieT &lhs, const MovieT &rhs) {
+  return
+      (lhs.main_character == rhs.main_character) &&
+      (lhs.characters == rhs.characters);
+}
+
+inline bool operator!=(const MovieT &lhs, const MovieT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct Movie FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef MovieT NativeTableType;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return MovieTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_MAIN_CHARACTER_TYPE = 4,
+    VT_MAIN_CHARACTER = 6,
+    VT_CHARACTERS_TYPE = 8,
+    VT_CHARACTERS = 10
+  };
+  Character main_character_type() const {
+    return static_cast<Character>(GetField<uint8_t>(VT_MAIN_CHARACTER_TYPE, 0));
+  }
+  bool mutate_main_character_type(Character _main_character_type) {
+    return SetField<uint8_t>(VT_MAIN_CHARACTER_TYPE, static_cast<uint8_t>(_main_character_type), 0);
+  }
+  const void *main_character() const {
+    return GetPointer<const void *>(VT_MAIN_CHARACTER);
+  }
+  const Attacker *main_character_as_MuLan() const {
+    return main_character_type() == Character_MuLan ? static_cast<const Attacker *>(main_character()) : nullptr;
+  }
+  const Rapunzel *main_character_as_Rapunzel() const {
+    return main_character_type() == Character_Rapunzel ? static_cast<const Rapunzel *>(main_character()) : nullptr;
+  }
+  const BookReader *main_character_as_Belle() const {
+    return main_character_type() == Character_Belle ? static_cast<const BookReader *>(main_character()) : nullptr;
+  }
+  const BookReader *main_character_as_BookFan() const {
+    return main_character_type() == Character_BookFan ? static_cast<const BookReader *>(main_character()) : nullptr;
+  }
+  const flatbuffers::String *main_character_as_Other() const {
+    return main_character_type() == Character_Other ? static_cast<const flatbuffers::String *>(main_character()) : nullptr;
+  }
+  const flatbuffers::String *main_character_as_Unused() const {
+    return main_character_type() == Character_Unused ? static_cast<const flatbuffers::String *>(main_character()) : nullptr;
+  }
+  void *mutable_main_character() {
+    return GetPointer<void *>(VT_MAIN_CHARACTER);
+  }
+  const flatbuffers::Vector<uint8_t> *characters_type() const {
+    return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_CHARACTERS_TYPE);
+  }
+  flatbuffers::Vector<uint8_t> *mutable_characters_type() {
+    return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_CHARACTERS_TYPE);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<void>> *characters() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<void>> *>(VT_CHARACTERS);
+  }
+  flatbuffers::Vector<flatbuffers::Offset<void>> *mutable_characters() {
+    return GetPointer<flatbuffers::Vector<flatbuffers::Offset<void>> *>(VT_CHARACTERS);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<uint8_t>(verifier, VT_MAIN_CHARACTER_TYPE) &&
+           VerifyOffset(verifier, VT_MAIN_CHARACTER) &&
+           VerifyCharacter(verifier, main_character(), main_character_type()) &&
+           VerifyOffset(verifier, VT_CHARACTERS_TYPE) &&
+           verifier.VerifyVector(characters_type()) &&
+           VerifyOffset(verifier, VT_CHARACTERS) &&
+           verifier.VerifyVector(characters()) &&
+           VerifyCharacterVector(verifier, characters(), characters_type()) &&
+           verifier.EndTable();
+  }
+  MovieT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(MovieT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<Movie> Pack(flatbuffers::FlatBufferBuilder &_fbb, const MovieT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct MovieBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_main_character_type(Character main_character_type) {
+    fbb_.AddElement<uint8_t>(Movie::VT_MAIN_CHARACTER_TYPE, static_cast<uint8_t>(main_character_type), 0);
+  }
+  void add_main_character(flatbuffers::Offset<void> main_character) {
+    fbb_.AddOffset(Movie::VT_MAIN_CHARACTER, main_character);
+  }
+  void add_characters_type(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> characters_type) {
+    fbb_.AddOffset(Movie::VT_CHARACTERS_TYPE, characters_type);
+  }
+  void add_characters(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<void>>> characters) {
+    fbb_.AddOffset(Movie::VT_CHARACTERS, characters);
+  }
+  explicit MovieBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  MovieBuilder &operator=(const MovieBuilder &);
+  flatbuffers::Offset<Movie> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Movie>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Movie> CreateMovie(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    Character main_character_type = Character_NONE,
+    flatbuffers::Offset<void> main_character = 0,
+    flatbuffers::Offset<flatbuffers::Vector<uint8_t>> characters_type = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<void>>> characters = 0) {
+  MovieBuilder builder_(_fbb);
+  builder_.add_characters(characters);
+  builder_.add_characters_type(characters_type);
+  builder_.add_main_character(main_character);
+  builder_.add_main_character_type(main_character_type);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<Movie> CreateMovieDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    Character main_character_type = Character_NONE,
+    flatbuffers::Offset<void> main_character = 0,
+    const std::vector<uint8_t> *characters_type = nullptr,
+    const std::vector<flatbuffers::Offset<void>> *characters = nullptr) {
+  auto characters_type__ = characters_type ? _fbb.CreateVector<uint8_t>(*characters_type) : 0;
+  auto characters__ = characters ? _fbb.CreateVector<flatbuffers::Offset<void>>(*characters) : 0;
+  return CreateMovie(
+      _fbb,
+      main_character_type,
+      main_character,
+      characters_type__,
+      characters__);
+}
+
+flatbuffers::Offset<Movie> CreateMovie(flatbuffers::FlatBufferBuilder &_fbb, const MovieT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+inline AttackerT *Attacker::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = new AttackerT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+inline void Attacker::UnPackTo(AttackerT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+  { auto _e = sword_attack_damage(); _o->sword_attack_damage = _e; };
+}
+
+inline flatbuffers::Offset<Attacker> Attacker::Pack(flatbuffers::FlatBufferBuilder &_fbb, const AttackerT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateAttacker(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<Attacker> CreateAttacker(flatbuffers::FlatBufferBuilder &_fbb, const AttackerT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const AttackerT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  auto _sword_attack_damage = _o->sword_attack_damage;
+  return CreateAttacker(
+      _fbb,
+      _sword_attack_damage);
+}
+
+inline MovieT *Movie::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = new MovieT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+inline void Movie::UnPackTo(MovieT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+  { auto _e = main_character_type(); _o->main_character.type = _e; };
+  { auto _e = main_character(); if (_e) _o->main_character.value = CharacterUnion::UnPack(_e, main_character_type(), _resolver); };
+  { auto _e = characters_type(); if (_e) { _o->characters.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->characters[_i].type = static_cast<Character>(_e->Get(_i)); } } };
+  { auto _e = characters(); if (_e) { _o->characters.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->characters[_i].value = CharacterUnion::UnPack(_e->Get(_i), characters_type()->GetEnum<Character>(_i), _resolver); } } };
+}
+
+inline flatbuffers::Offset<Movie> Movie::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MovieT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateMovie(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<Movie> CreateMovie(flatbuffers::FlatBufferBuilder &_fbb, const MovieT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const MovieT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  auto _main_character_type = _o->main_character.type;
+  auto _main_character = _o->main_character.Pack(_fbb);
+  auto _characters_type = _o->characters.size() ? _fbb.CreateVector<uint8_t>(_o->characters.size(), [](size_t i, _VectorArgs *__va) { return static_cast<uint8_t>(__va->__o->characters[i].type); }, &_va) : 0;
+  auto _characters = _o->characters.size() ? _fbb.CreateVector<flatbuffers::Offset<void>>(_o->characters.size(), [](size_t i, _VectorArgs *__va) { return __va->__o->characters[i].Pack(*__va->__fbb, __va->__rehasher); }, &_va) : 0;
+  return CreateMovie(
+      _fbb,
+      _main_character_type,
+      _main_character,
+      _characters_type,
+      _characters);
+}
+
+inline bool VerifyCharacter(flatbuffers::Verifier &verifier, const void *obj, Character type) {
+  switch (type) {
+    case Character_NONE: {
+      return true;
+    }
+    case Character_MuLan: {
+      auto ptr = reinterpret_cast<const Attacker *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    case Character_Rapunzel: {
+      return verifier.Verify<Rapunzel>(static_cast<const uint8_t *>(obj), 0);
+    }
+    case Character_Belle: {
+      return verifier.Verify<BookReader>(static_cast<const uint8_t *>(obj), 0);
+    }
+    case Character_BookFan: {
+      return verifier.Verify<BookReader>(static_cast<const uint8_t *>(obj), 0);
+    }
+    case Character_Other: {
+      auto ptr = reinterpret_cast<const flatbuffers::String *>(obj);
+      return verifier.VerifyString(ptr);
+    }
+    case Character_Unused: {
+      auto ptr = reinterpret_cast<const flatbuffers::String *>(obj);
+      return verifier.VerifyString(ptr);
+    }
+    default: return false;
+  }
+}
+
+inline bool VerifyCharacterVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) {
+  if (!values || !types) return !values && !types;
+  if (values->size() != types->size()) return false;
+  for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
+    if (!VerifyCharacter(
+        verifier,  values->Get(i), types->GetEnum<Character>(i))) {
+      return false;
+    }
+  }
+  return true;
+}
+
+inline void *CharacterUnion::UnPack(const void *obj, Character type, const flatbuffers::resolver_function_t *resolver) {
+  switch (type) {
+    case Character_MuLan: {
+      auto ptr = reinterpret_cast<const Attacker *>(obj);
+      return ptr->UnPack(resolver);
+    }
+    case Character_Rapunzel: {
+      auto ptr = reinterpret_cast<const Rapunzel *>(obj);
+      return new Rapunzel(*ptr);
+    }
+    case Character_Belle: {
+      auto ptr = reinterpret_cast<const BookReader *>(obj);
+      return new BookReader(*ptr);
+    }
+    case Character_BookFan: {
+      auto ptr = reinterpret_cast<const BookReader *>(obj);
+      return new BookReader(*ptr);
+    }
+    case Character_Other: {
+      auto ptr = reinterpret_cast<const flatbuffers::String *>(obj);
+      return new std::string(ptr->c_str(), ptr->size());
+    }
+    case Character_Unused: {
+      auto ptr = reinterpret_cast<const flatbuffers::String *>(obj);
+      return new std::string(ptr->c_str(), ptr->size());
+    }
+    default: return nullptr;
+  }
+}
+
+inline flatbuffers::Offset<void> CharacterUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher) const {
+  switch (type) {
+    case Character_MuLan: {
+      auto ptr = reinterpret_cast<const AttackerT *>(value);
+      return CreateAttacker(_fbb, ptr, _rehasher).Union();
+    }
+    case Character_Rapunzel: {
+      auto ptr = reinterpret_cast<const Rapunzel *>(value);
+      return _fbb.CreateStruct(*ptr).Union();
+    }
+    case Character_Belle: {
+      auto ptr = reinterpret_cast<const BookReader *>(value);
+      return _fbb.CreateStruct(*ptr).Union();
+    }
+    case Character_BookFan: {
+      auto ptr = reinterpret_cast<const BookReader *>(value);
+      return _fbb.CreateStruct(*ptr).Union();
+    }
+    case Character_Other: {
+      auto ptr = reinterpret_cast<const std::string *>(value);
+      return _fbb.CreateString(*ptr).Union();
+    }
+    case Character_Unused: {
+      auto ptr = reinterpret_cast<const std::string *>(value);
+      return _fbb.CreateString(*ptr).Union();
+    }
+    default: return 0;
+  }
+}
+
+inline CharacterUnion::CharacterUnion(const CharacterUnion &u) FLATBUFFERS_NOEXCEPT : type(u.type), value(nullptr) {
+  switch (type) {
+    case Character_MuLan: {
+      value = new AttackerT(*reinterpret_cast<AttackerT *>(u.value));
+      break;
+    }
+    case Character_Rapunzel: {
+      value = new Rapunzel(*reinterpret_cast<Rapunzel *>(u.value));
+      break;
+    }
+    case Character_Belle: {
+      value = new BookReader(*reinterpret_cast<BookReader *>(u.value));
+      break;
+    }
+    case Character_BookFan: {
+      value = new BookReader(*reinterpret_cast<BookReader *>(u.value));
+      break;
+    }
+    case Character_Other: {
+      value = new std::string(*reinterpret_cast<std::string *>(u.value));
+      break;
+    }
+    case Character_Unused: {
+      value = new std::string(*reinterpret_cast<std::string *>(u.value));
+      break;
+    }
+    default:
+      break;
+  }
+}
+
+inline void CharacterUnion::Reset() {
+  switch (type) {
+    case Character_MuLan: {
+      auto ptr = reinterpret_cast<AttackerT *>(value);
+      delete ptr;
+      break;
+    }
+    case Character_Rapunzel: {
+      auto ptr = reinterpret_cast<Rapunzel *>(value);
+      delete ptr;
+      break;
+    }
+    case Character_Belle: {
+      auto ptr = reinterpret_cast<BookReader *>(value);
+      delete ptr;
+      break;
+    }
+    case Character_BookFan: {
+      auto ptr = reinterpret_cast<BookReader *>(value);
+      delete ptr;
+      break;
+    }
+    case Character_Other: {
+      auto ptr = reinterpret_cast<std::string *>(value);
+      delete ptr;
+      break;
+    }
+    case Character_Unused: {
+      auto ptr = reinterpret_cast<std::string *>(value);
+      delete ptr;
+      break;
+    }
+    default: break;
+  }
+  value = nullptr;
+  type = Character_NONE;
+}
+
+inline const flatbuffers::TypeTable *CharacterTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SEQUENCE, 0, -1 },
+    { flatbuffers::ET_SEQUENCE, 0, 0 },
+    { flatbuffers::ET_SEQUENCE, 0, 1 },
+    { flatbuffers::ET_SEQUENCE, 0, 2 },
+    { flatbuffers::ET_SEQUENCE, 0, 2 },
+    { flatbuffers::ET_STRING, 0, -1 },
+    { flatbuffers::ET_STRING, 0, -1 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    AttackerTypeTable,
+    RapunzelTypeTable,
+    BookReaderTypeTable
+  };
+  static const char * const names[] = {
+    "NONE",
+    "MuLan",
+    "Rapunzel",
+    "Belle",
+    "BookFan",
+    "Other",
+    "Unused"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_UNION, 7, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *AttackerTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_INT, 0, -1 }
+  };
+  static const char * const names[] = {
+    "sword_attack_damage"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 1, type_codes, nullptr, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *RapunzelTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_INT, 0, -1 }
+  };
+  static const int64_t values[] = { 0, 4 };
+  static const char * const names[] = {
+    "hair_length"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_STRUCT, 1, type_codes, nullptr, values, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *BookReaderTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_INT, 0, -1 }
+  };
+  static const int64_t values[] = { 0, 4 };
+  static const char * const names[] = {
+    "books_read"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_STRUCT, 1, type_codes, nullptr, values, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *MovieTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_UTYPE, 0, 0 },
+    { flatbuffers::ET_SEQUENCE, 0, 0 },
+    { flatbuffers::ET_UTYPE, 1, 0 },
+    { flatbuffers::ET_SEQUENCE, 1, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    CharacterTypeTable
+  };
+  static const char * const names[] = {
+    "main_character_type",
+    "main_character",
+    "characters_type",
+    "characters"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 4, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+inline const Movie *GetMovie(const void *buf) {
+  return flatbuffers::GetRoot<Movie>(buf);
+}
+
+inline const Movie *GetSizePrefixedMovie(const void *buf) {
+  return flatbuffers::GetSizePrefixedRoot<Movie>(buf);
+}
+
+inline Movie *GetMutableMovie(void *buf) {
+  return flatbuffers::GetMutableRoot<Movie>(buf);
+}
+
+inline const char *MovieIdentifier() {
+  return "MOVI";
+}
+
+inline bool MovieBufferHasIdentifier(const void *buf) {
+  return flatbuffers::BufferHasIdentifier(
+      buf, MovieIdentifier());
+}
+
+inline bool VerifyMovieBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifyBuffer<Movie>(MovieIdentifier());
+}
+
+inline bool VerifySizePrefixedMovieBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifySizePrefixedBuffer<Movie>(MovieIdentifier());
+}
+
+inline void FinishMovieBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<Movie> root) {
+  fbb.Finish(root, MovieIdentifier());
+}
+
+inline void FinishSizePrefixedMovieBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<Movie> root) {
+  fbb.FinishSizePrefixed(root, MovieIdentifier());
+}
+
+inline flatbuffers::unique_ptr<MovieT> UnPackMovie(
+    const void *buf,
+    const flatbuffers::resolver_function_t *res = nullptr) {
+  return flatbuffers::unique_ptr<MovieT>(GetMovie(buf)->UnPack(res));
+}
+
+inline flatbuffers::unique_ptr<MovieT> UnPackSizePrefixedMovie(
+    const void *buf,
+    const flatbuffers::resolver_function_t *res = nullptr) {
+  return flatbuffers::unique_ptr<MovieT>(GetSizePrefixedMovie(buf)->UnPack(res));
+}
+
+#endif  // FLATBUFFERS_GENERATED_UNIONVECTOR_H_
diff --git a/tests/union_vector/union_vector_generated.js b/tests/union_vector/union_vector_generated.js
new file mode 100644
index 0000000..406cb2f
--- /dev/null
+++ b/tests/union_vector/union_vector_generated.js
@@ -0,0 +1,505 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+/**
+ * @enum {number}
+ */
+var Character = {
+  NONE: 0,
+  MuLan: 1,
+  Rapunzel: 2,
+  Belle: 3,
+  BookFan: 4,
+  Other: 5,
+  Unused: 6
+};
+
+/**
+ * @enum {string}
+ */
+var CharacterName = {
+  0: 'NONE',
+  1: 'MuLan',
+  2: 'Rapunzel',
+  3: 'Belle',
+  4: 'BookFan',
+  5: 'Other',
+  6: 'Unused'
+};
+
+/**
+ * @constructor
+ */
+function Attacker() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+}
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {Attacker}
+ */
+Attacker.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {Attacker=} obj
+ * @returns {Attacker}
+ */
+Attacker.getRootAsAttacker = function(bb, obj) {
+  return (obj || new Attacker).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {Attacker=} obj
+ * @returns {Attacker}
+ */
+Attacker.getSizePrefixedRootAsAttacker = function(bb, obj) {
+  return (obj || new Attacker).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @returns {number}
+ */
+Attacker.prototype.swordAttackDamage = function() {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+  return offset ? this.bb.readInt32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+Attacker.prototype.mutate_sword_attack_damage = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ */
+Attacker.startAttacker = function(builder) {
+  builder.startObject(1);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} swordAttackDamage
+ */
+Attacker.addSwordAttackDamage = function(builder, swordAttackDamage) {
+  builder.addFieldInt32(0, swordAttackDamage, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @returns {flatbuffers.Offset}
+ */
+Attacker.endAttacker = function(builder) {
+  var offset = builder.endObject();
+  return offset;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} swordAttackDamage
+ * @returns {flatbuffers.Offset}
+ */
+Attacker.createAttacker = function(builder, swordAttackDamage) {
+  Attacker.startAttacker(builder);
+  Attacker.addSwordAttackDamage(builder, swordAttackDamage);
+  return Attacker.endAttacker(builder);
+}
+
+/**
+ * @constructor
+ */
+function Rapunzel() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+}
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {Rapunzel}
+ */
+Rapunzel.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @returns {number}
+ */
+Rapunzel.prototype.hairLength = function() {
+  return this.bb.readInt32(this.bb_pos);
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+Rapunzel.prototype.mutate_hair_length = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 0);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} hair_length
+ * @returns {flatbuffers.Offset}
+ */
+Rapunzel.createRapunzel = function(builder, hair_length) {
+  builder.prep(4, 4);
+  builder.writeInt32(hair_length);
+  return builder.offset();
+};
+
+/**
+ * @constructor
+ */
+function BookReader() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+}
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {BookReader}
+ */
+BookReader.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @returns {number}
+ */
+BookReader.prototype.booksRead = function() {
+  return this.bb.readInt32(this.bb_pos);
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+BookReader.prototype.mutate_books_read = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 0);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} books_read
+ * @returns {flatbuffers.Offset}
+ */
+BookReader.createBookReader = function(builder, books_read) {
+  builder.prep(4, 4);
+  builder.writeInt32(books_read);
+  return builder.offset();
+};
+
+/**
+ * @constructor
+ */
+function Movie() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+}
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {Movie}
+ */
+Movie.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {Movie=} obj
+ * @returns {Movie}
+ */
+Movie.getRootAsMovie = function(bb, obj) {
+  return (obj || new Movie).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {Movie=} obj
+ * @returns {Movie}
+ */
+Movie.getSizePrefixedRootAsMovie = function(bb, obj) {
+  return (obj || new Movie).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {boolean}
+ */
+Movie.bufferHasIdentifier = function(bb) {
+  return bb.__has_identifier('MOVI');
+};
+
+/**
+ * @returns {Character}
+ */
+Movie.prototype.mainCharacterType = function() {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+  return offset ? /** @type {Character} */ (this.bb.readUint8(this.bb_pos + offset)) : Character.NONE;
+};
+
+/**
+ * @param {Character} value
+ * @returns {boolean}
+ */
+Movie.prototype.mutate_main_character_type = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {flatbuffers.Table} obj
+ * @returns {?flatbuffers.Table}
+ */
+Movie.prototype.mainCharacter = function(obj) {
+  var offset = this.bb.__offset(this.bb_pos, 6);
+  return offset ? this.bb.__union(obj, this.bb_pos + offset) : null;
+};
+
+/**
+ * @param {number} index
+ * @returns {Character}
+ */
+Movie.prototype.charactersType = function(index) {
+  var offset = this.bb.__offset(this.bb_pos, 8);
+  return offset ? /** @type {Character} */ (this.bb.readUint8(this.bb.__vector(this.bb_pos + offset) + index)) : /** @type {Character} */ (0);
+};
+
+/**
+ * @returns {number}
+ */
+Movie.prototype.charactersTypeLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 8);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns {Uint8Array}
+ */
+Movie.prototype.charactersTypeArray = function() {
+  var offset = this.bb.__offset(this.bb_pos, 8);
+  return offset ? new Uint8Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @param {number} index
+ * @param {flatbuffers.Table=} obj
+ * @returns {?flatbuffers.Table}
+ */
+Movie.prototype.characters = function(index, obj) {
+  var offset = this.bb.__offset(this.bb_pos, 10);
+  return offset ? this.bb.__union(obj, this.bb.__vector(this.bb_pos + offset) + index * 4) : null;
+};
+
+/**
+ * @returns {number}
+ */
+Movie.prototype.charactersLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 10);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ */
+Movie.startMovie = function(builder) {
+  builder.startObject(4);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Character} mainCharacterType
+ */
+Movie.addMainCharacterType = function(builder, mainCharacterType) {
+  builder.addFieldInt8(0, mainCharacterType, Character.NONE);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} mainCharacterOffset
+ */
+Movie.addMainCharacter = function(builder, mainCharacterOffset) {
+  builder.addFieldOffset(1, mainCharacterOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} charactersTypeOffset
+ */
+Movie.addCharactersType = function(builder, charactersTypeOffset) {
+  builder.addFieldOffset(2, charactersTypeOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<Character>} data
+ * @returns {flatbuffers.Offset}
+ */
+Movie.createCharactersTypeVector = function(builder, data) {
+  builder.startVector(1, data.length, 1);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt8(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+Movie.startCharactersTypeVector = function(builder, numElems) {
+  builder.startVector(1, numElems, 1);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} charactersOffset
+ */
+Movie.addCharacters = function(builder, charactersOffset) {
+  builder.addFieldOffset(3, charactersOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<flatbuffers.Offset>} data
+ * @returns {flatbuffers.Offset}
+ */
+Movie.createCharactersVector = function(builder, data) {
+  builder.startVector(4, data.length, 4);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addOffset(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+Movie.startCharactersVector = function(builder, numElems) {
+  builder.startVector(4, numElems, 4);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @returns {flatbuffers.Offset}
+ */
+Movie.endMovie = function(builder) {
+  var offset = builder.endObject();
+  return offset;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} offset
+ */
+Movie.finishMovieBuffer = function(builder, offset) {
+  builder.finish(offset, 'MOVI');
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} offset
+ */
+Movie.finishSizePrefixedMovieBuffer = function(builder, offset) {
+  builder.finish(offset, 'MOVI', true);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Character} mainCharacterType
+ * @param {flatbuffers.Offset} mainCharacterOffset
+ * @param {flatbuffers.Offset} charactersTypeOffset
+ * @param {flatbuffers.Offset} charactersOffset
+ * @returns {flatbuffers.Offset}
+ */
+Movie.createMovie = function(builder, mainCharacterType, mainCharacterOffset, charactersTypeOffset, charactersOffset) {
+  Movie.startMovie(builder);
+  Movie.addMainCharacterType(builder, mainCharacterType);
+  Movie.addMainCharacter(builder, mainCharacterOffset);
+  Movie.addCharactersType(builder, charactersTypeOffset);
+  Movie.addCharacters(builder, charactersOffset);
+  return Movie.endMovie(builder);
+}
+
+// Exports for Node.js and RequireJS
+this.Character = Character;
+this.CharacterName = CharacterName;
+this.Attacker = Attacker;
+this.Rapunzel = Rapunzel;
+this.BookReader = BookReader;
+this.Movie = Movie;
diff --git a/tests/union_vector/union_vector_generated.ts b/tests/union_vector/union_vector_generated.ts
new file mode 100644
index 0000000..642f672
--- /dev/null
+++ b/tests/union_vector/union_vector_generated.ts
@@ -0,0 +1,442 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+/**
+ * @enum {number}
+ */
+export enum Character{
+  NONE= 0,
+  MuLan= 1,
+  Rapunzel= 2,
+  Belle= 3,
+  BookFan= 4,
+  Other= 5,
+  Unused= 6
+};
+
+/**
+ * @constructor
+ */
+export class Attacker {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns Attacker
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):Attacker {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param Attacker= obj
+ * @returns Attacker
+ */
+static getRootAsAttacker(bb:flatbuffers.ByteBuffer, obj?:Attacker):Attacker {
+  return (obj || new Attacker).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param Attacker= obj
+ * @returns Attacker
+ */
+static getSizePrefixedRootAsAttacker(bb:flatbuffers.ByteBuffer, obj?:Attacker):Attacker {
+  return (obj || new Attacker).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @returns number
+ */
+swordAttackDamage():number {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+  return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_sword_attack_damage(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ */
+static startAttacker(builder:flatbuffers.Builder) {
+  builder.startObject(1);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number swordAttackDamage
+ */
+static addSwordAttackDamage(builder:flatbuffers.Builder, swordAttackDamage:number) {
+  builder.addFieldInt32(0, swordAttackDamage, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @returns flatbuffers.Offset
+ */
+static endAttacker(builder:flatbuffers.Builder):flatbuffers.Offset {
+  var offset = builder.endObject();
+  return offset;
+};
+
+static createAttacker(builder:flatbuffers.Builder, swordAttackDamage:number):flatbuffers.Offset {
+  Attacker.startAttacker(builder);
+  Attacker.addSwordAttackDamage(builder, swordAttackDamage);
+  return Attacker.endAttacker(builder);
+}
+}
+/**
+ * @constructor
+ */
+export class Rapunzel {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns Rapunzel
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):Rapunzel {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @returns number
+ */
+hairLength():number {
+  return this.bb!.readInt32(this.bb_pos);
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_hair_length(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 0);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number hair_length
+ * @returns flatbuffers.Offset
+ */
+static createRapunzel(builder:flatbuffers.Builder, hair_length: number):flatbuffers.Offset {
+  builder.prep(4, 4);
+  builder.writeInt32(hair_length);
+  return builder.offset();
+};
+
+}
+/**
+ * @constructor
+ */
+export class BookReader {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns BookReader
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):BookReader {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @returns number
+ */
+booksRead():number {
+  return this.bb!.readInt32(this.bb_pos);
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_books_read(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 0);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number books_read
+ * @returns flatbuffers.Offset
+ */
+static createBookReader(builder:flatbuffers.Builder, books_read: number):flatbuffers.Offset {
+  builder.prep(4, 4);
+  builder.writeInt32(books_read);
+  return builder.offset();
+};
+
+}
+/**
+ * @constructor
+ */
+export class Movie {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns Movie
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):Movie {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param Movie= obj
+ * @returns Movie
+ */
+static getRootAsMovie(bb:flatbuffers.ByteBuffer, obj?:Movie):Movie {
+  return (obj || new Movie).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param Movie= obj
+ * @returns Movie
+ */
+static getSizePrefixedRootAsMovie(bb:flatbuffers.ByteBuffer, obj?:Movie):Movie {
+  return (obj || new Movie).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @returns boolean
+ */
+static bufferHasIdentifier(bb:flatbuffers.ByteBuffer):boolean {
+  return bb.__has_identifier('MOVI');
+};
+
+/**
+ * @returns Character
+ */
+mainCharacterType():Character {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+  return offset ? /**  */ (this.bb!.readUint8(this.bb_pos + offset)) : Character.NONE;
+};
+
+/**
+ * @param Character value
+ * @returns boolean
+ */
+mutate_main_character_type(value:Character):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param flatbuffers.Table obj
+ * @returns ?flatbuffers.Table
+ */
+mainCharacter<T extends flatbuffers.Table>(obj:T):T|null {
+  var offset = this.bb!.__offset(this.bb_pos, 6);
+  return offset ? this.bb!.__union(obj, this.bb_pos + offset) : null;
+};
+
+/**
+ * @param number index
+ * @returns Character
+ */
+charactersType(index: number):Character|null {
+  var offset = this.bb!.__offset(this.bb_pos, 8);
+  return offset ? /**  */ (this.bb!.readUint8(this.bb!.__vector(this.bb_pos + offset) + index)) : /**  */ (0);
+};
+
+/**
+ * @returns number
+ */
+charactersTypeLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 8);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns Uint8Array
+ */
+charactersTypeArray():Uint8Array|null {
+  var offset = this.bb!.__offset(this.bb_pos, 8);
+  return offset ? new Uint8Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @param number index
+ * @param flatbuffers.Table= obj
+ * @returns ?flatbuffers.Table
+ */
+characters<T extends flatbuffers.Table>(index: number, obj:T):T|null {
+  var offset = this.bb!.__offset(this.bb_pos, 10);
+  return offset ? this.bb!.__union(obj, this.bb!.__vector(this.bb_pos + offset) + index * 4) : null;
+};
+
+/**
+ * @returns number
+ */
+charactersLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 10);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ */
+static startMovie(builder:flatbuffers.Builder) {
+  builder.startObject(4);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Character mainCharacterType
+ */
+static addMainCharacterType(builder:flatbuffers.Builder, mainCharacterType:Character) {
+  builder.addFieldInt8(0, mainCharacterType, Character.NONE);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset mainCharacterOffset
+ */
+static addMainCharacter(builder:flatbuffers.Builder, mainCharacterOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(1, mainCharacterOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset charactersTypeOffset
+ */
+static addCharactersType(builder:flatbuffers.Builder, charactersTypeOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(2, charactersTypeOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<Character> data
+ * @returns flatbuffers.Offset
+ */
+static createCharactersTypeVector(builder:flatbuffers.Builder, data:Character[]):flatbuffers.Offset {
+  builder.startVector(1, data.length, 1);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt8(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startCharactersTypeVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(1, numElems, 1);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset charactersOffset
+ */
+static addCharacters(builder:flatbuffers.Builder, charactersOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(3, charactersOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<flatbuffers.Offset> data
+ * @returns flatbuffers.Offset
+ */
+static createCharactersVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
+  builder.startVector(4, data.length, 4);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addOffset(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startCharactersVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(4, numElems, 4);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @returns flatbuffers.Offset
+ */
+static endMovie(builder:flatbuffers.Builder):flatbuffers.Offset {
+  var offset = builder.endObject();
+  return offset;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset offset
+ */
+static finishMovieBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {
+  builder.finish(offset, 'MOVI');
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset offset
+ */
+static finishSizePrefixedMovieBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {
+  builder.finish(offset, 'MOVI', true);
+};
+
+static createMovie(builder:flatbuffers.Builder, mainCharacterType:Character, mainCharacterOffset:flatbuffers.Offset, charactersTypeOffset:flatbuffers.Offset, charactersOffset:flatbuffers.Offset):flatbuffers.Offset {
+  Movie.startMovie(builder);
+  Movie.addMainCharacterType(builder, mainCharacterType);
+  Movie.addMainCharacter(builder, mainCharacterOffset);
+  Movie.addCharactersType(builder, charactersTypeOffset);
+  Movie.addCharacters(builder, charactersOffset);
+  return Movie.endMovie(builder);
+}
+}