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