diff --git a/dart/test/flat_buffers_test.dart b/dart/test/flat_buffers_test.dart
new file mode 100644
index 0000000..f9c5e01
--- /dev/null
+++ b/dart/test/flat_buffers_test.dart
@@ -0,0 +1,573 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:typed_data';
+import 'dart:io' as io;
+
+import 'package:path/path.dart' as path;
+
+import 'package:flat_buffers/flat_buffers.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import './monster_test_my_game.example_generated.dart' as example;
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(BuilderTest);
+    defineReflectiveTests(CheckOtherLangaugesData);
+  });
+}
+
+int indexToField(int index) {
+  return (1 + 1 + index) * 2;
+}
+
+@reflectiveTest
+class CheckOtherLangaugesData {
+  test_cppData() async {
+    List<int> data = await new io.File(path.join(
+      path.dirname(io.Platform.script.path),
+      'monsterdata_test.mon',
+    ))
+        .readAsBytes();
+    example.Monster mon = new example.Monster(data);
+    expect(mon.hp, 80);
+    expect(mon.mana, 150);
+    expect(mon.name, 'MyMonster');
+    expect(mon.pos.x, 1.0);
+    expect(mon.pos.y, 2.0);
+    expect(mon.pos.z, 3.0);
+    expect(mon.pos.test1, 3.0);
+    expect(mon.pos.test2.value, 2.0);
+    expect(mon.pos.test3.a, 5);
+    expect(mon.pos.test3.b, 6);
+    expect(mon.testType.value, example.AnyTypeId.Monster.value);
+    expect(mon.test is example.Monster, true);
+    final monster2 = mon.test as example.Monster;
+    expect(monster2.name, "Fred");
+
+    expect(mon.inventory.length, 5);
+    expect(mon.inventory.reduce((cur, next) => cur + next), 10);
+    expect(mon.test4.length, 2);
+    expect(
+        mon.test4[0].a + mon.test4[0].b + mon.test4[1].a + mon.test4[1].b, 100);
+    expect(mon.testarrayofstring.length, 2);
+    expect(mon.testarrayofstring[0], "test1");
+    expect(mon.testarrayofstring[1], "test2");
+
+    // this will fail if accessing any field fails.
+    expect(mon.toString(),
+        'Monster{pos: Vec3{x: 1.0, y: 2.0, z: 3.0, test1: 3.0, test2: Color{value: 2}, test3: Test{a: 5, b: 6}}, mana: 150, hp: 80, name: MyMonster, inventory: [0, 1, 2, 3, 4], color: Color{value: 8}, testType: AnyTypeId{value: 1}, test: Monster{pos: null, mana: 150, hp: 100, name: Fred, inventory: null, color: Color{value: 8}, testType: AnyTypeId{value: 0}, test: null, test4: null, testarrayofstring: null, testarrayoftables: null, enemy: null, testnestedflatbuffer: null, testempty: null, testbool: false, testhashs32Fnv1: 0, testhashu32Fnv1: 0, testhashs64Fnv1: 0, testhashu64Fnv1: 0, testhashs32Fnv1a: 0, testhashu32Fnv1a: 0, testhashs64Fnv1a: 0, testhashu64Fnv1a: 0, testarrayofbools: null, testf: 3.14159, testf2: 3.0, testf3: 0.0, testarrayofstring2: null, testarrayofsortedstruct: null, flex: null, test5: null, vectorOfLongs: null, vectorOfDoubles: null, parentNamespaceTest: null, vectorOfReferrables: null, singleWeakReference: 0, vectorOfWeakReferences: null, vectorOfStrongReferrables: null, coOwningReference: 0, vectorOfCoOwningReferences: null, nonOwningReference: 0, vectorOfNonOwningReferences: null}, test4: [Test{a: 10, b: 20}, Test{a: 30, b: 40}], testarrayofstring: [test1, test2], testarrayoftables: null, enemy: Monster{pos: null, mana: 150, hp: 100, name: Fred, inventory: null, color: Color{value: 8}, testType: AnyTypeId{value: 0}, test: null, test4: null, testarrayofstring: null, testarrayoftables: null, enemy: null, testnestedflatbuffer: null, testempty: null, testbool: false, testhashs32Fnv1: 0, testhashu32Fnv1: 0, testhashs64Fnv1: 0, testhashu64Fnv1: 0, testhashs32Fnv1a: 0, testhashu32Fnv1a: 0, testhashs64Fnv1a: 0, testhashu64Fnv1a: 0, testarrayofbools: null, testf: 3.14159, testf2: 3.0, testf3: 0.0, testarrayofstring2: null, testarrayofsortedstruct: null, flex: null, test5: null, vectorOfLongs: null, vectorOfDoubles: null, parentNamespaceTest: null, vectorOfReferrables: null, singleWeakReference: 0, vectorOfWeakReferences: null, vectorOfStrongReferrables: null, coOwningReference: 0, vectorOfCoOwningReferences: null, nonOwningReference: 0, vectorOfNonOwningReferences: null}, testnestedflatbuffer: null, testempty: null, testbool: false, testhashs32Fnv1: -579221183, testhashu32Fnv1: 3715746113, testhashs64Fnv1: 7930699090847568257, testhashu64Fnv1: 7930699090847568257, testhashs32Fnv1a: -1904106383, testhashu32Fnv1a: 2390860913, testhashs64Fnv1a: 4898026182817603057, testhashu64Fnv1a: 4898026182817603057, testarrayofbools: [true, false, true], testf: 3.14159, testf2: 3.0, testf3: 0.0, testarrayofstring2: null, testarrayofsortedstruct: null, flex: null, test5: [Test{a: 10, b: 20}, Test{a: 30, b: 40}], vectorOfLongs: [1, 100, 10000, 1000000, 100000000], vectorOfDoubles: [-1.7976931348623157e+308, 0.0, 1.7976931348623157e+308], parentNamespaceTest: null, vectorOfReferrables: null, singleWeakReference: 0, vectorOfWeakReferences: null, vectorOfStrongReferrables: null, coOwningReference: 0, vectorOfCoOwningReferences: null, nonOwningReference: 0, vectorOfNonOwningReferences: null}');
+  }
+}
+
+@reflectiveTest
+class BuilderTest {
+  void test_monsterBuilder() {
+    final fbBuilder = new Builder();
+    final str = fbBuilder.writeString('MyMonster');
+
+    fbBuilder.writeString('test1');
+    fbBuilder.writeString('test2');
+    final testArrayOfString = fbBuilder.endStructVector(2);
+
+    final fred = fbBuilder.writeString('Fred');
+
+    final List<int> treasure = [0, 1, 2, 3, 4];
+    final inventory = fbBuilder.writeListUint8(treasure);
+
+    final monBuilder = new example.MonsterBuilder(fbBuilder)
+      ..begin()
+      ..addNameOffset(fred);
+    final mon2 = monBuilder.finish();
+
+    final testBuilder = new example.TestBuilder(fbBuilder);
+    testBuilder.finish(10, 20);
+    testBuilder.finish(30, 40);
+    final test4 = fbBuilder.endStructVector(2);
+
+
+    monBuilder
+      ..begin()
+      ..addPos(
+        new example.Vec3Builder(fbBuilder).finish(
+          1.0,
+          2.0,
+          3.0,
+          3.0,
+          example.Color.Green,
+          () => testBuilder.finish(5, 6),
+        ),
+      )
+      ..addHp(80)
+      ..addNameOffset(str)
+      ..addInventoryOffset(inventory)
+      ..addTestType(example.AnyTypeId.Monster)
+      ..addTestOffset(mon2)
+      ..addTest4Offset(test4)
+      ..addTestarrayofstringOffset(testArrayOfString);
+    final mon = monBuilder.finish();
+    fbBuilder.finish(mon);
+  }
+
+  void test_error_addInt32_withoutStartTable() {
+    Builder builder = new Builder();
+    expect(() {
+      builder.addInt32(0, 0);
+    }, throwsStateError);
+  }
+
+  void test_error_addOffset_withoutStartTable() {
+    Builder builder = new Builder();
+    expect(() {
+      builder.addOffset(0, 0);
+    }, throwsStateError);
+  }
+
+  void test_error_endTable_withoutStartTable() {
+    Builder builder = new Builder();
+    expect(() {
+      builder.endTable();
+    }, throwsStateError);
+  }
+
+  void test_error_startTable_duringTable() {
+    Builder builder = new Builder();
+    builder.startTable();
+    expect(() {
+      builder.startTable();
+    }, throwsStateError);
+  }
+
+  void test_error_writeString_duringTable() {
+    Builder builder = new Builder();
+    builder.startTable();
+    expect(() {
+      builder.writeString('12345');
+    }, throwsStateError);
+  }
+
+  void test_file_identifier() {
+    Uint8List byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      builder.startTable();
+      int offset = builder.endTable();
+      byteList = builder.finish(offset, 'Az~ÿ');
+    }
+    // Convert byteList to a ByteData so that we can read data from it.
+    ByteData byteData = byteList.buffer.asByteData(byteList.offsetInBytes);
+    // First 4 bytes are an offset to the table data.
+    int tableDataLoc = byteData.getUint32(0, Endian.little);
+    // Next 4 bytes are the file identifier.
+    expect(byteData.getUint8(4), 65); // 'a'
+    expect(byteData.getUint8(5), 122); // 'z'
+    expect(byteData.getUint8(6), 126); // '~'
+    expect(byteData.getUint8(7), 255); // 'ÿ'
+    // First 4 bytes of the table data are a backwards offset to the vtable.
+    int vTableLoc = tableDataLoc -
+        byteData.getInt32(tableDataLoc, Endian.little);
+    // First 2 bytes of the vtable are the size of the vtable in bytes, which
+    // should be 4.
+    expect(byteData.getUint16(vTableLoc, Endian.little), 4);
+    // Next 2 bytes are the size of the object in bytes (including the vtable
+    // pointer), which should be 4.
+    expect(byteData.getUint16(vTableLoc + 2, Endian.little), 4);
+  }
+
+  void test_low() {
+    Builder builder = new Builder(initialSize: 0);
+    expect((builder..putUint8(1)).lowFinish(), [1]);
+    expect((builder..putUint32(2)).lowFinish(), [2, 0, 0, 0, 0, 0, 0, 1]);
+    expect((builder..putUint8(3)).lowFinish(),
+        [0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 1]);
+    expect((builder..putUint8(4)).lowFinish(),
+        [0, 0, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]);
+    expect((builder..putUint8(5)).lowFinish(),
+        [0, 5, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]);
+    expect((builder..putUint32(6)).lowFinish(),
+        [6, 0, 0, 0, 0, 5, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]);
+  }
+
+  void test_table_default() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      builder.startTable();
+      builder.addInt32(0, 10, 10);
+      builder.addInt32(1, 20, 10);
+      int offset = builder.endTable();
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferContext buffer = new BufferContext.fromBytes(byteList);
+    int objectOffset = buffer.derefObject(0);
+    // was not written, so uses the new default value
+    expect(
+        const Int32Reader()
+            .vTableGet(buffer, objectOffset, indexToField(0), 15),
+        15);
+    // has the written value
+    expect(
+        const Int32Reader()
+            .vTableGet(buffer, objectOffset, indexToField(1), 15),
+        20);
+  }
+
+  void test_table_format() {
+    Uint8List byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      builder.startTable();
+      builder.addInt32(0, 10);
+      builder.addInt32(1, 20);
+      builder.addInt32(2, 30);
+      byteList = builder.finish(builder.endTable());
+    }
+    // Convert byteList to a ByteData so that we can read data from it.
+    ByteData byteData = byteList.buffer.asByteData(byteList.offsetInBytes);
+    // First 4 bytes are an offset to the table data.
+    int tableDataLoc = byteData.getUint32(0, Endian.little);
+    // First 4 bytes of the table data are a backwards offset to the vtable.
+    int vTableLoc = tableDataLoc -
+        byteData.getInt32(tableDataLoc, Endian.little);
+    // First 2 bytes of the vtable are the size of the vtable in bytes, which
+    // should be 10.
+    expect(byteData.getUint16(vTableLoc, Endian.little), 10);
+    // Next 2 bytes are the size of the object in bytes (including the vtable
+    // pointer), which should be 16.
+    expect(byteData.getUint16(vTableLoc + 2, Endian.little), 16);
+    // Remaining 6 bytes are the offsets within the object where the ints are
+    // located.
+    for (int i = 0; i < 3; i++) {
+      int offset =
+          byteData.getUint16(vTableLoc + 4 + 2 * i, Endian.little);
+      expect(byteData.getInt32(tableDataLoc + offset, Endian.little),
+          10 + 10 * i);
+    }
+  }
+
+  void test_table_string() {
+    String latinString = 'test';
+    String unicodeString = 'Проба пера';
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      int latinStringOffset = builder.writeString(latinString);
+      int unicodeStringOffset = builder.writeString(unicodeString);
+      builder.startTable();
+      builder.addOffset(0, latinStringOffset);
+      builder.addOffset(1, unicodeStringOffset);
+      int offset = builder.endTable();
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    int objectOffset = buf.derefObject(0);
+    expect(const StringReader().vTableGet(buf, objectOffset, indexToField(0)),
+        latinString);
+    expect(const StringReader().vTableGet(buf, objectOffset, indexToField(1)),
+        unicodeString);
+  }
+
+  void test_table_types() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      int stringOffset = builder.writeString('12345');
+      builder.startTable();
+      builder.addBool(0, true);
+      builder.addInt8(1, 10);
+      builder.addInt32(2, 20);
+      builder.addOffset(3, stringOffset);
+      builder.addInt32(4, 40);
+      builder.addUint32(5, 0x9ABCDEF0);
+      builder.addUint8(6, 0x9A);
+      int offset = builder.endTable();
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    int objectOffset = buf.derefObject(0);
+    expect(
+        const BoolReader().vTableGet(buf, objectOffset, indexToField(0)), true);
+    expect(
+        const Int8Reader().vTableGet(buf, objectOffset, indexToField(1)), 10);
+    expect(
+        const Int32Reader().vTableGet(buf, objectOffset, indexToField(2)), 20);
+    expect(const StringReader().vTableGet(buf, objectOffset, indexToField(3)),
+        '12345');
+    expect(
+        const Int32Reader().vTableGet(buf, objectOffset, indexToField(4)), 40);
+    expect(const Uint32Reader().vTableGet(buf, objectOffset, indexToField(5)),
+        0x9ABCDEF0);
+    expect(const Uint8Reader().vTableGet(buf, objectOffset, indexToField(6)),
+        0x9A);
+  }
+
+  void test_writeList_of_Uint32() {
+    List<int> values = <int>[10, 100, 12345, 0x9abcdef0];
+    // write
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      int offset = builder.writeListUint32(values);
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    List<int> items = const Uint32ListReader().read(buf, 0);
+    expect(items, hasLength(4));
+    expect(items, orderedEquals(values));
+  }
+
+  void test_writeList_ofBool() {
+    void verifyListBooleans(int len, List<int> trueBits) {
+      // write
+      List<int> byteList;
+      {
+        Builder builder = new Builder(initialSize: 0);
+        List<bool> values = new List<bool>.filled(len, false);
+        for (int bit in trueBits) {
+          values[bit] = true;
+        }
+        int offset = builder.writeListBool(values);
+        byteList = builder.finish(offset);
+      }
+      // read and verify
+      BufferContext buf = new BufferContext.fromBytes(byteList);
+      List<bool> items = const BoolListReader().read(buf, 0);
+      expect(items, hasLength(len));
+      for (int i = 0; i < items.length; i++) {
+        expect(items[i], trueBits.contains(i), reason: 'bit $i of $len');
+      }
+    }
+
+    verifyListBooleans(0, <int>[]);
+    verifyListBooleans(1, <int>[]);
+    verifyListBooleans(1, <int>[0]);
+    verifyListBooleans(31, <int>[0, 1]);
+    verifyListBooleans(31, <int>[1, 2, 24, 25, 30]);
+    verifyListBooleans(31, <int>[0, 30]);
+    verifyListBooleans(32, <int>[1, 2, 24, 25, 31]);
+    verifyListBooleans(33, <int>[1, 2, 24, 25, 32]);
+    verifyListBooleans(33, <int>[1, 2, 24, 25, 31, 32]);
+    verifyListBooleans(63, <int>[]);
+    verifyListBooleans(63, <int>[0, 1, 2, 61, 62]);
+    verifyListBooleans(63, new List<int>.generate(63, (i) => i));
+    verifyListBooleans(64, <int>[]);
+    verifyListBooleans(64, <int>[0, 1, 2, 61, 62, 63]);
+    verifyListBooleans(64, <int>[1, 2, 62]);
+    verifyListBooleans(64, <int>[0, 1, 2, 63]);
+    verifyListBooleans(64, new List<int>.generate(64, (i) => i));
+    verifyListBooleans(100, <int>[0, 3, 30, 60, 90, 99]);
+  }
+
+  void test_writeList_ofInt32() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      int offset = builder.writeListInt32(<int>[1, 2, 3, 4, 5]);
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    List<int> items = const ListReader<int>(const Int32Reader()).read(buf, 0);
+    expect(items, hasLength(5));
+    expect(items, orderedEquals(<int>[1, 2, 3, 4, 5]));
+  }
+
+  void test_writeList_ofFloat64() {
+    List<double> values = <double>[-1.234567, 3.4E+9, -5.6E-13, 7.8, 12.13];
+    // write
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      int offset = builder.writeListFloat64(values);
+      byteList = builder.finish(offset);
+    }
+
+    // read and verify
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    List<double> items = const Float64ListReader().read(buf, 0);
+
+    expect(items, hasLength(values.length));
+    for (int i = 0; i < values.length; i++) {
+      expect(values[i], closeTo(items[i], .001));
+    }
+  }
+
+  void test_writeList_ofFloat32() {
+    List<double> values = [1.0, 2.23, -3.213, 7.8, 12.13];
+    // write
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      int offset = builder.writeListFloat32(values);
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    List<double> items = const Float32ListReader().read(buf, 0);
+    expect(items, hasLength(5));
+    for (int i = 0; i < values.length; i++) {
+      expect(values[i], closeTo(items[i], .001));
+    }
+  }
+
+  void test_writeList_ofObjects() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      // write the object #1
+      int object1;
+      {
+        builder.startTable();
+        builder.addInt32(0, 10);
+        builder.addInt32(1, 20);
+        object1 = builder.endTable();
+      }
+      // write the object #1
+      int object2;
+      {
+        builder.startTable();
+        builder.addInt32(0, 100);
+        builder.addInt32(1, 200);
+        object2 = builder.endTable();
+      }
+      // write the list
+      int offset = builder.writeList([object1, object2]);
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    List<TestPointImpl> items =
+        const ListReader<TestPointImpl>(const TestPointReader()).read(buf, 0);
+    expect(items, hasLength(2));
+    expect(items[0].x, 10);
+    expect(items[0].y, 20);
+    expect(items[1].x, 100);
+    expect(items[1].y, 200);
+  }
+
+  void test_writeList_ofStrings_asRoot() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      int str1 = builder.writeString('12345');
+      int str2 = builder.writeString('ABC');
+      int offset = builder.writeList([str1, str2]);
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    List<String> items =
+        const ListReader<String>(const StringReader()).read(buf, 0);
+    expect(items, hasLength(2));
+    expect(items, contains('12345'));
+    expect(items, contains('ABC'));
+  }
+
+  void test_writeList_ofStrings_inObject() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      int listOffset = builder.writeList(
+          [builder.writeString('12345'), builder.writeString('ABC')]);
+      builder.startTable();
+      builder.addOffset(0, listOffset);
+      int offset = builder.endTable();
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    StringListWrapperImpl reader = new StringListWrapperReader().read(buf, 0);
+    List<String> items = reader.items;
+    expect(items, hasLength(2));
+    expect(items, contains('12345'));
+    expect(items, contains('ABC'));
+  }
+
+  void test_writeList_ofUint32() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      int offset = builder.writeListUint32(<int>[1, 2, 0x9ABCDEF0]);
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    List<int> items = const Uint32ListReader().read(buf, 0);
+    expect(items, hasLength(3));
+    expect(items, orderedEquals(<int>[1, 2, 0x9ABCDEF0]));
+  }
+
+  void test_writeList_ofUint16() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      int offset = builder.writeListUint16(<int>[1, 2, 60000]);
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    List<int> items = const Uint16ListReader().read(buf, 0);
+    expect(items, hasLength(3));
+    expect(items, orderedEquals(<int>[1, 2, 60000]));
+  }
+
+  void test_writeList_ofUint8() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      int offset = builder.writeListUint8(<int>[1, 2, 3, 4, 0x9A]);
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    List<int> items = const Uint8ListReader().read(buf, 0);
+    expect(items, hasLength(5));
+    expect(items, orderedEquals(<int>[1, 2, 3, 4, 0x9A]));
+  }
+}
+
+class StringListWrapperImpl {
+  final BufferContext bp;
+  final int offset;
+
+  StringListWrapperImpl(this.bp, this.offset);
+
+  List<String> get items => const ListReader<String>(const StringReader())
+      .vTableGet(bp, offset, indexToField(0));
+}
+
+class StringListWrapperReader extends TableReader<StringListWrapperImpl> {
+  const StringListWrapperReader();
+
+  @override
+  StringListWrapperImpl createObject(BufferContext object, int offset) {
+    return new StringListWrapperImpl(object, offset);
+  }
+}
+
+class TestPointImpl {
+  final BufferContext bp;
+  final int offset;
+
+  TestPointImpl(this.bp, this.offset);
+
+  int get x => const Int32Reader().vTableGet(bp, offset, indexToField(0), 0);
+
+  int get y => const Int32Reader().vTableGet(bp, offset, indexToField(1), 0);
+}
+
+class TestPointReader extends TableReader<TestPointImpl> {
+  const TestPointReader();
+
+  @override
+  TestPointImpl createObject(BufferContext object, int offset) {
+    return new TestPointImpl(object, offset);
+  }
+}
diff --git a/dart/test/monster_test_my_game.example2_generated.dart b/dart/test/monster_test_my_game.example2_generated.dart
new file mode 100644
index 0000000..9a3ab66
--- /dev/null
+++ b/dart/test/monster_test_my_game.example2_generated.dart
@@ -0,0 +1,62 @@
+// 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 'include_test1_my_game.example2_generated.dart';
+import 'include_test2_my_game.example2_generated.dart';
+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/dart/test/monster_test_my_game.example_generated.dart b/dart/test/monster_test_my_game.example_generated.dart
new file mode 100644
index 0000000..49e2ec1
--- /dev/null
+++ b/dart/test/monster_test_my_game.example_generated.dart
@@ -0,0 +1,1486 @@
+// 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 'include_test1_my_game.example_generated.dart';
+import 'include_test2_my_game.example_generated.dart';
+import './monster_test_my_game_generated.dart' as my_game;
+import './monster_test_my_game.example2_generated.dart' as my_game_example2;
+
+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);
+  static const Color Green = const Color._(2);
+  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.Int8Reader().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 T = const AnyUniqueAliasesTypeId._(2);
+  static const AnyUniqueAliasesTypeId M2 = const AnyUniqueAliasesTypeId._(3);
+  static get values => {0: NONE,1: M,2: T,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.Int8Reader().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.addInt8(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.addInt8(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.Int8Reader().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.putInt8(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.putInt8(_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.Int8Reader().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 T.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.addInt8(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.writeListInt8(_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.addInt8(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/dart/test/monster_test_my_game_generated.dart b/dart/test/monster_test_my_game_generated.dart
new file mode 100644
index 0000000..26bb73b
--- /dev/null
+++ b/dart/test/monster_test_my_game_generated.dart
@@ -0,0 +1,62 @@
+// 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 'include_test1_my_game_generated.dart';
+import 'include_test2_my_game_generated.dart';
+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);
+  }
+}
