diff --git a/dart/CHANGELOG.md b/dart/CHANGELOG.md
new file mode 100644
index 0000000..5e2d2de
--- /dev/null
+++ b/dart/CHANGELOG.md
@@ -0,0 +1,14 @@
+# CHANGELOG
+
+## 1.9.2
+
+- Ensure `_writeString` adds enough padding to null terminate strings.
+
+## 1.9.1
+
+- Changed constant identifiers to be compatible with Dart 2.x
+- No longer supports Dart 1.x
+
+## 1.9.0
+
+- Initial release, supports Dart 1.x and many dev versions of Dart 2.x
\ No newline at end of file
diff --git a/dart/LICENSE b/dart/LICENSE
new file mode 100644
index 0000000..b2ae013
--- /dev/null
+++ b/dart/LICENSE
@@ -0,0 +1,233 @@
+The code in lib/flat_buffers.dart is based on code that was releases under the 
+following license:
+
+Copyright 2012, the Dart project authors. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Google Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+To the extent permissible, the changes to that code and the other assets in 
+this package are licensed under the Apache2 license:
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright 2014 Google Inc.
+
+   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.
diff --git a/dart/README.md b/dart/README.md
new file mode 100644
index 0000000..11bc0c4
--- /dev/null
+++ b/dart/README.md
@@ -0,0 +1,13 @@
+# FlatBuffers for Dart
+
+This package is used to read and write FlatBuffer files in Dart.
+
+Most consumers will want to use the [`flatc`](https://github.com/google/flatbuffers)
+compiler to generate Dart code from a FlatBuffers IDL schema.  For example, the
+`monster_my_game.sample_generated.dart` was generated with `flatc` from
+`monster.fbs` in the example folder. The generated classes can be used to read
+or write binary files that are interoperable with other languages and platforms
+supported by FlatBuffers, as illustrated in the `example.dart` in the
+examples folder.
+
+Additional documentation and examples are available [at the FlatBuffers site](https://google.github.io/flatbuffers/index.html)
\ No newline at end of file
diff --git a/dart/example/example.dart b/dart/example/example.dart
new file mode 100644
index 0000000..d95bb31
--- /dev/null
+++ b/dart/example/example.dart
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2018 Dan Field. 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 'package:flat_buffers/flat_buffers.dart' as fb;
+import './monster_my_game.sample_generated.dart' as myGame;
+
+// Example how to use FlatBuffers to create and read binary buffers.
+
+void main() {
+  builderTest();
+  objectBuilderTest();
+}
+
+void builderTest() {
+  final builder = new fb.Builder(initialSize: 1024);
+  final int weaponOneName = builder.writeString("Sword");
+  final int weaponOneDamage = 3;
+
+  final int weaponTwoName = builder.writeString("Axe");
+  final int weaponTwoDamage = 5;
+
+  final swordBuilder = new myGame.WeaponBuilder(builder)
+    ..begin()
+    ..addNameOffset(weaponOneName)
+    ..addDamage(weaponOneDamage);
+  final int sword = swordBuilder.finish();
+
+  final axeBuilder = new myGame.WeaponBuilder(builder)
+    ..begin()
+    ..addNameOffset(weaponTwoName)
+    ..addDamage(weaponTwoDamage);
+  final int axe = axeBuilder.finish();
+
+  // Serialize a name for our monster, called "Orc".
+  final int name = builder.writeString('Orc');
+
+  // Create a list representing the inventory of the Orc. Each number
+  // could correspond to an item that can be claimed after he is slain.
+  final List<int> treasure = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+  final inventory = builder.writeListUint8(treasure);
+  final weapons = builder.writeList([sword, axe]);
+
+  // Struct builders are very easy to reuse.
+  final vec3Builder = new myGame.Vec3Builder(builder);
+
+  vec3Builder.finish(4.0, 5.0, 6.0);
+  vec3Builder.finish(1.0, 2.0, 3.0);
+  // Set his hit points to 300 and his mana to 150.
+  final int hp = 300;
+  final int mana = 150;
+
+  final monster = new myGame.MonsterBuilder(builder)
+    ..begin()
+    ..addNameOffset(name)
+    ..addInventoryOffset(inventory)
+    ..addWeaponsOffset(weapons)
+    ..addEquippedType(myGame.EquipmentTypeId.Weapon)
+    ..addEquippedOffset(axe)
+    ..addHp(hp)
+    ..addMana(mana)
+    ..addPos(vec3Builder.finish(1.0, 2.0, 3.0))
+    ..addColor(myGame.Color.Red);
+
+  final int monsteroff = monster.finish();
+  final buffer = builder.finish(monsteroff);
+  if (verify(buffer)) {
+    print(
+        "The FlatBuffer was successfully created with a builder and verified!");
+  }
+}
+
+void objectBuilderTest() {
+  // Create the builder here so we can use it for both weapons and equipped
+  // the actual data will only be written to the buffer once.
+  var axe = new myGame.WeaponObjectBuilder(name: 'Axe', damage: 5);
+
+  var monsterBuilder = new myGame.MonsterObjectBuilder(
+    pos: new myGame.Vec3ObjectBuilder(x: 1.0, y: 2.0, z: 3.0),
+    mana: 150,
+    hp: 300,
+    name: 'Orc',
+    inventory: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
+    color: myGame.Color.Red,
+    weapons: [new myGame.WeaponObjectBuilder(name: 'Sword', damage: 3), axe],
+    equippedType: myGame.EquipmentTypeId.Weapon,
+    equipped: axe,
+  );
+
+  var buffer = monsterBuilder.toBytes();
+
+  // We now have a FlatBuffer we can store on disk or send over a network.
+
+  // ** file/network code goes here :) **
+
+  // Instead, we're going to access it right away (as if we just received it).
+  if (verify(buffer)) {
+    print(
+        "The FlatBuffer was successfully created with an object builder and verified!");
+  }
+}
+
+bool verify(List<int> buffer) {
+  // Get access to the root:
+  var monster = new myGame.Monster(buffer);
+
+  // Get and test some scalar types from the FlatBuffer.
+  assert(monster.hp == 80);
+  assert(monster.mana == 150); // default
+  assert(monster.name == "MyMonster");
+
+  // Get and test a field of the FlatBuffer's `struct`.
+  var pos = monster.pos;
+  assert(pos != null);
+  assert(pos.z == 3.0);
+
+  // Get a test an element from the `inventory` FlatBuffer's `vector`.
+  var inv = monster.inventory;
+  assert(inv != null);
+  assert(inv.length == 10);
+  assert(inv[9] == 9);
+
+  // Get and test the `weapons` FlatBuffers's `vector`.
+  var expected_weapon_names = ["Sword", "Axe"];
+  var expected_weapon_damages = [3, 5];
+  var weps = monster.weapons;
+  for (int i = 0; i < weps.length; i++) {
+    assert(weps[i].name == expected_weapon_names[i]);
+    assert(weps[i].damage == expected_weapon_damages[i]);
+  }
+
+  // Get and test the `Equipment` union (`equipped` field).
+  assert(monster.equippedType.value == myGame.EquipmentTypeId.Weapon.value);
+  assert(monster.equippedType == myGame.EquipmentTypeId.Weapon);
+
+  assert(monster.equipped is myGame.Weapon);
+  var equipped = monster.equipped as myGame.Weapon;
+  assert(equipped.name == "Axe");
+  assert(equipped.damage == 5);
+
+  print(monster);
+  return true;
+}
diff --git a/dart/example/monster_my_game.sample_generated.dart b/dart/example/monster_my_game.sample_generated.dart
new file mode 100644
index 0000000..2c7c10d
--- /dev/null
+++ b/dart/example/monster_my_game.sample_generated.dart
@@ -0,0 +1,440 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+// ignore_for_file: unused_import, non_constant_identifier_names
+
+library my_game.sample;
+
+import 'dart:typed_data' show Uint8List;
+import 'package:flat_buffers/flat_buffers.dart' as fb;
+
+
+class Color {
+  final int value;
+  const Color._(this.value);
+
+  factory Color.fromValue(int value) {
+    if (value == null) return null;
+    if (!values.containsKey(value)) {
+      throw new StateError('Invalid value $value for bit flag enum Color');
+    }
+    return values[value];
+  }
+
+  static const int minValue = 0;
+  static const int maxValue = 2;
+  static bool containsValue(int value) => values.containsKey(value);
+
+  static const Color Red = const Color._(0);
+  static const Color Green = const Color._(1);
+  static const Color Blue = const Color._(2);
+  static get values => {0: Red,1: Green,2: 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 EquipmentTypeId {
+  final int value;
+  const EquipmentTypeId._(this.value);
+
+  factory EquipmentTypeId.fromValue(int value) {
+    if (value == null) return null;
+    if (!values.containsKey(value)) {
+      throw new StateError('Invalid value $value for bit flag enum EquipmentTypeId');
+    }
+    return values[value];
+  }
+
+  static const int minValue = 0;
+  static const int maxValue = 1;
+  static bool containsValue(int value) => values.containsKey(value);
+
+  static const EquipmentTypeId NONE = const EquipmentTypeId._(0);
+  static const EquipmentTypeId Weapon = const EquipmentTypeId._(1);
+  static get values => {0: NONE,1: Weapon,};
+
+  static const fb.Reader<EquipmentTypeId> reader = const _EquipmentTypeIdReader();
+
+  @override
+  String toString() {
+    return 'EquipmentTypeId{value: $value}';
+  }
+}
+
+class _EquipmentTypeIdReader extends fb.Reader<EquipmentTypeId> {
+  const _EquipmentTypeIdReader();
+
+  @override
+  int get size => 1;
+
+  @override
+  EquipmentTypeId read(fb.BufferContext bc, int offset) =>
+      new EquipmentTypeId.fromValue(const fb.Uint8Reader().read(bc, offset));
+}
+
+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);
+
+  @override
+  String toString() {
+    return 'Vec3{x: $x, y: $y, z: $z}';
+  }
+}
+
+class _Vec3Reader extends fb.StructReader<Vec3> {
+  const _Vec3Reader();
+
+  @override
+  int get size => 12;
+
+  @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) {
+    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;
+
+  Vec3ObjectBuilder({
+    double x,
+    double y,
+    double z,
+  })
+      : _x = x,
+        _y = y,
+        _z = z;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+
+    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 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, 2));
+  List<Weapon> get weapons => const fb.ListReader<Weapon>(Weapon.reader).vTableGet(_bc, _bcOffset, 18, null);
+  EquipmentTypeId get equippedType => new EquipmentTypeId.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 20, null));
+  dynamic get equipped {
+    switch (equippedType?.value) {
+      case 1: return Weapon.reader.vTableGet(_bc, _bcOffset, 22, null);
+      default: return null;
+    }
+  }
+  List<Vec3> get path => const fb.ListReader<Vec3>(Vec3.reader).vTableGet(_bc, _bcOffset, 24, null);
+
+  @override
+  String toString() {
+    return 'Monster{pos: $pos, mana: $mana, hp: $hp, name: $name, inventory: $inventory, color: $color, weapons: $weapons, equippedType: $equippedType, equipped: $equipped, path: $path}';
+  }
+}
+
+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 addWeaponsOffset(int offset) {
+    fbBuilder.addOffset(7, offset);
+    return fbBuilder.offset;
+  }
+  int addEquippedType(EquipmentTypeId equippedType) {
+    fbBuilder.addUint8(8, equippedType?.value);
+    return fbBuilder.offset;
+  }
+  int addEquippedOffset(int offset) {
+    fbBuilder.addOffset(9, offset);
+    return fbBuilder.offset;
+  }
+  int addPathOffset(int offset) {
+    fbBuilder.addOffset(10, 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 List<WeaponObjectBuilder> _weapons;
+  final EquipmentTypeId _equippedType;
+  final dynamic _equipped;
+  final List<Vec3ObjectBuilder> _path;
+
+  MonsterObjectBuilder({
+    Vec3ObjectBuilder pos,
+    int mana,
+    int hp,
+    String name,
+    List<int> inventory,
+    Color color,
+    List<WeaponObjectBuilder> weapons,
+    EquipmentTypeId equippedType,
+    dynamic equipped,
+    List<Vec3ObjectBuilder> path,
+  })
+      : _pos = pos,
+        _mana = mana,
+        _hp = hp,
+        _name = name,
+        _inventory = inventory,
+        _color = color,
+        _weapons = weapons,
+        _equippedType = equippedType,
+        _equipped = equipped,
+        _path = path;
+
+  /// 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 weaponsOffset = _weapons?.isNotEmpty == true
+        ? fbBuilder.writeList(_weapons.map((b) => b.getOrCreateOffset(fbBuilder)).toList())
+        : null;
+    final int equippedOffset = _equipped?.getOrCreateOffset(fbBuilder);
+    final int pathOffset = _path?.isNotEmpty == true
+        ? fbBuilder.writeListOfStructs(_path)
+        : 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);
+    if (weaponsOffset != null) {
+      fbBuilder.addOffset(7, weaponsOffset);
+    }
+    fbBuilder.addUint8(8, _equippedType?.value);
+    if (equippedOffset != null) {
+      fbBuilder.addOffset(9, equippedOffset);
+    }
+    if (pathOffset != null) {
+      fbBuilder.addOffset(10, pathOffset);
+    }
+    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 Weapon {
+  Weapon._(this._bc, this._bcOffset);
+  factory Weapon(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<Weapon> reader = const _WeaponReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  String get name => const fb.StringReader().vTableGet(_bc, _bcOffset, 4, null);
+  int get damage => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 6, null);
+
+  @override
+  String toString() {
+    return 'Weapon{name: $name, damage: $damage}';
+  }
+}
+
+class _WeaponReader extends fb.TableReader<Weapon> {
+  const _WeaponReader();
+
+  @override
+  Weapon createObject(fb.BufferContext bc, int offset) => 
+    new Weapon._(bc, offset);
+}
+
+class WeaponBuilder {
+  WeaponBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  void begin() {
+    fbBuilder.startTable();
+  }
+
+  int addNameOffset(int offset) {
+    fbBuilder.addOffset(0, offset);
+    return fbBuilder.offset;
+  }
+  int addDamage(int damage) {
+    fbBuilder.addInt16(1, damage);
+    return fbBuilder.offset;
+  }
+
+  int finish() {
+    return fbBuilder.endTable();
+  }
+}
+
+class WeaponObjectBuilder extends fb.ObjectBuilder {
+  final String _name;
+  final int _damage;
+
+  WeaponObjectBuilder({
+    String name,
+    int damage,
+  })
+      : _name = name,
+        _damage = damage;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+    final int nameOffset = fbBuilder.writeString(_name);
+
+    fbBuilder.startTable();
+    if (nameOffset != null) {
+      fbBuilder.addOffset(0, nameOffset);
+    }
+    fbBuilder.addInt16(1, _damage);
+    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/lib/flat_buffers.dart b/dart/lib/flat_buffers.dart
new file mode 100644
index 0000000..e251260
--- /dev/null
+++ b/dart/lib/flat_buffers.dart
@@ -0,0 +1,1241 @@
+// 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:collection';
+import 'dart:convert';
+import 'dart:math';
+import 'dart:typed_data';
+
+const int _sizeofUint8 = 1;
+const int _sizeofUint16 = 2;
+const int _sizeofUint32 = 4;
+const int _sizeofUint64 = 8;
+const int _sizeofInt8 = 1;
+const int _sizeofInt16 = 2;
+const int _sizeofInt32 = 4;
+const int _sizeofInt64 = 8;
+const int _sizeofFloat32 = 4;
+const int _sizeofFloat64 = 8;
+
+/// Callback used to invoke a struct builder's finish method.
+///
+/// This callback is used by other struct's `finish` methods to write the nested
+/// struct's fields inline.
+typedef void StructBuilder();
+
+/// Buffer with data and some context about it.
+class BufferContext {
+  final ByteData _buffer;
+
+  factory BufferContext.fromBytes(List<int> byteList) {
+    Uint8List uint8List = _asUint8List(byteList);
+    ByteData buf = new ByteData.view(uint8List.buffer, uint8List.offsetInBytes);
+    return new BufferContext._(buf);
+  }
+
+  BufferContext._(this._buffer);
+
+  int derefObject(int offset) {
+    return offset + _getUint32(offset);
+  }
+
+  Uint8List _asUint8LIst(int offset, int length) =>
+      _buffer.buffer.asUint8List(_buffer.offsetInBytes + offset, length);
+
+  double _getFloat64(int offset) =>
+      _buffer.getFloat64(offset, Endian.little);
+
+  double _getFloat32(int offset) =>
+      _buffer.getFloat32(offset, Endian.little);
+
+  int _getInt64(int offset) =>
+      _buffer.getInt64(offset, Endian.little);
+
+  int _getInt32(int offset) =>
+      _buffer.getInt32(offset, Endian.little);
+
+  int _getInt16(int offset) =>
+      _buffer.getInt16(offset, Endian.little);
+
+  int _getInt8(int offset) => _buffer.getInt8(offset);
+
+  int _getUint64(int offset) =>
+      _buffer.getUint64(offset, Endian.little);
+
+  int _getUint32(int offset) =>
+      _buffer.getUint32(offset, Endian.little);
+
+  int _getUint16(int offset) =>
+      _buffer.getUint16(offset, Endian.little);
+
+  int _getUint8(int offset) => _buffer.getUint8(offset);
+
+  /// If the [byteList] is already a [Uint8List] return it.
+  /// Otherwise return a [Uint8List] copy of the [byteList].
+  static Uint8List _asUint8List(List<int> byteList) {
+    if (byteList is Uint8List) {
+      return byteList;
+    } else {
+      return new Uint8List.fromList(byteList);
+    }
+  }
+}
+
+/// Class implemented by typed builders generated by flatc.
+abstract class ObjectBuilder {
+  int _firstOffset;
+
+  /// Can be used to write the data represented by this builder to the [Builder]
+  /// and reuse the offset created in multiple tables.
+  ///
+  /// Note that this method assumes you call it using the same [Builder] instance
+  /// every time. The returned offset is only good for the [Builder] used in the
+  /// first call to this method.
+  int getOrCreateOffset(Builder fbBuilder) {
+    _firstOffset ??= finish(fbBuilder);
+    return _firstOffset;
+  }
+
+  /// Writes the data in this helper to the [Builder].
+  int finish(Builder fbBuilder);
+
+  /// Convenience method that will create a new [Builder], [finish]es the data,
+  /// and returns the buffer as a [Uint8List] of bytes.
+  Uint8List toBytes();
+}
+
+/// Class that helps building flat buffers.
+class Builder {
+  final int initialSize;
+
+  /// The list of existing VTable(s).
+  //final List<_VTable> _vTables = <_VTable>[];
+  final List<int> _vTables = <int>[];
+
+  ByteData _buf;
+
+  /// The maximum alignment that has been seen so far.  If [_buf] has to be
+  /// reallocated in the future (to insert room at its start for more bytes) the
+  /// reallocation will need to be a multiple of this many bytes.
+  int _maxAlign;
+
+  /// The number of bytes that have been written to the buffer so far.  The
+  /// most recently written byte is this many bytes from the end of [_buf].
+  int _tail;
+
+  /// The location of the end of the current table, measured in bytes from the
+  /// end of [_buf], or `null` if a table is not currently being built.
+  int _currentTableEndTail;
+
+  _VTable _currentVTable;
+
+  /// Map containing all strings that have been written so far.  This allows us
+  /// to avoid duplicating strings.
+  ///
+  /// Allocated only if `internStrings` is set to true on the constructor.
+  Map<String, int> _strings;
+
+  /// Creates a new FlatBuffers Builder.
+  ///
+  /// `initialSize` is the initial array size in bytes.  The [Builder] will
+  /// automatically grow the array if/as needed.  `internStrings`, if set to
+  /// true, will cause [writeString] to pool strings in the buffer so that
+  /// identical strings will always use the same offset in tables.
+  Builder({this.initialSize: 1024, bool internStrings = false}) {
+    if (internStrings == true) {
+      _strings = new Map<String, int>();
+    }
+    reset();
+  }
+
+  /// Add the [field] with the given boolean [value].  The field is not added if
+  /// the [value] is equal to [def].  Booleans are stored as 8-bit fields with
+  /// `0` for `false` and `1` for `true`.
+  void addBool(int field, bool value, [bool def]) {
+    _ensureCurrentVTable();
+    if (value != null && value != def) {
+      _prepare(_sizeofUint8, 1);
+      _trackField(field);
+      _buf.setInt8(_buf.lengthInBytes - _tail, value ? 1 : 0);
+    }
+  }
+
+  /// Add the [field] with the given 32-bit signed integer [value].  The field is
+  /// not added if the [value] is equal to [def].
+  void addInt32(int field, int value, [int def]) {
+    _ensureCurrentVTable();
+    if (value != null && value != def) {
+      _prepare(_sizeofInt32, 1);
+      _trackField(field);
+      _setInt32AtTail(_buf, _tail, value);
+    }
+  }
+
+  /// Add the [field] with the given 32-bit signed integer [value].  The field is
+  /// not added if the [value] is equal to [def].
+  void addInt16(int field, int value, [int def]) {
+    _ensureCurrentVTable();
+    if (value != null && value != def) {
+      _prepare(_sizeofInt16, 1);
+      _trackField(field);
+      _setInt16AtTail(_buf, _tail, value);
+    }
+  }
+
+  /// Add the [field] with the given 8-bit signed integer [value].  The field is
+  /// not added if the [value] is equal to [def].
+  void addInt8(int field, int value, [int def]) {
+    _ensureCurrentVTable();
+    if (value != null && value != def) {
+      _prepare(_sizeofInt8, 1);
+      _trackField(field);
+      _setInt8AtTail(_buf, _tail, value);
+    }
+  }
+
+  void addStruct(int field, int offset) {
+    _ensureCurrentVTable();
+    _trackField(field);
+    _currentVTable.addField(field, offset);
+  }
+
+  /// Add the [field] referencing an object with the given [offset].
+  void addOffset(int field, int offset) {
+    _ensureCurrentVTable();
+    if (offset != null) {
+      _prepare(_sizeofUint32, 1);
+      _trackField(field);
+      _setUint32AtTail(_buf, _tail, _tail - offset);
+    }
+  }
+
+  /// Add the [field] with the given 32-bit unsigned integer [value].  The field
+  /// is not added if the [value] is equal to [def].
+  void addUint32(int field, int value, [int def]) {
+    _ensureCurrentVTable();
+    if (value != null && value != def) {
+      _prepare(_sizeofUint32, 1);
+      _trackField(field);
+      _setUint32AtTail(_buf, _tail, value);
+    }
+  }
+
+  /// Add the [field] with the given 32-bit unsigned integer [value].  The field
+  /// is not added if the [value] is equal to [def].
+  void addUint16(int field, int value, [int def]) {
+    _ensureCurrentVTable();
+    if (value != null && value != def) {
+      _prepare(_sizeofUint16, 1);
+      _trackField(field);
+      _setUint16AtTail(_buf, _tail, value);
+    }
+  }
+
+  /// Add the [field] with the given 8-bit unsigned integer [value].  The field
+  /// is not added if the [value] is equal to [def].
+  void addUint8(int field, int value, [int def]) {
+    _ensureCurrentVTable();
+    if (value != null && value != def) {
+      _prepare(_sizeofUint8, 1);
+      _trackField(field);
+      _setUint8AtTail(_buf, _tail, value);
+    }
+  }
+
+  /// Add the [field] with the given 32-bit float [value].  The field
+  /// is not added if the [value] is equal to [def].
+  void addFloat32(int field, double value, [double def]) {
+    _ensureCurrentVTable();
+    if (value != null && value != def) {
+      _prepare(_sizeofFloat32, 1);
+      _trackField(field);
+      _setFloat32AtTail(_buf, _tail, value);
+    }
+  }
+
+  /// Add the [field] with the given 64-bit double [value].  The field
+  /// is not added if the [value] is equal to [def].
+  void addFloat64(int field, double value, [double def]) {
+    _ensureCurrentVTable();
+    if (value != null && value != def) {
+      _prepare(_sizeofFloat64, 1);
+      _trackField(field);
+      _setFloat64AtTail(_buf, _tail, value);
+    }
+  }
+
+  /// Add the [field] with the given 64-bit unsigned integer [value].  The field
+  /// is not added if the [value] is equal to [def].
+  void addUint64(int field, int value, [double def]) {
+    _ensureCurrentVTable();
+    if (value != null && value != def) {
+      _prepare(_sizeofUint64, 1);
+      _trackField(field);
+      _setUint64AtTail(_buf, _tail, value);
+    }
+  }
+
+  /// Add the [field] with the given 64-bit unsigned integer [value].  The field
+  /// is not added if the [value] is equal to [def].
+  void addInt64(int field, int value, [double def]) {
+    _ensureCurrentVTable();
+    if (value != null && value != def) {
+      _prepare(_sizeofInt64, 1);
+      _trackField(field);
+      _setInt64AtTail(_buf, _tail, value);
+    }
+  }
+
+  /// End the current table and return its offset.
+  int endTable() {
+    if (_currentVTable == null) {
+      throw new StateError('Start a table before ending it.');
+    }
+    // Prepare for writing the VTable.
+    _prepare(_sizeofInt32, 1);
+    int tableTail = _tail;
+    // Prepare the size of the current table.
+    _currentVTable.tableSize = tableTail - _currentTableEndTail;
+    // Prepare the VTable to use for the current table.
+    int vTableTail;
+    {
+      _currentVTable.computeFieldOffsets(tableTail);
+      // Try to find an existing compatible VTable.
+      // Search backward - more likely to have recently used one
+      for (int i = _vTables.length - 1; i >= 0; i--) {
+        final int vt2Offset = _vTables[i];
+        final int vt2Start = _buf.lengthInBytes - vt2Offset;
+        final int vt2Size = _buf.getUint16(vt2Start, Endian.little);
+
+        if (_currentVTable._vTableSize == vt2Size &&
+            _currentVTable._offsetsMatch(vt2Start, _buf)) {
+          vTableTail = vt2Offset;
+          break;
+        }
+      }
+      // Write a new VTable.
+      if (vTableTail == null) {
+        _prepare(_sizeofUint16, _currentVTable.numOfUint16);
+        vTableTail = _tail;
+        _currentVTable.tail = vTableTail;
+        _currentVTable.output(_buf, _buf.lengthInBytes - _tail);
+        _vTables.add(_currentVTable.tail);
+      }
+    }
+    // Set the VTable offset.
+    _setInt32AtTail(_buf, tableTail, vTableTail - tableTail);
+    // Done with this table.
+    _currentVTable = null;
+    return tableTail;
+  }
+
+  /// This method low level method can be used to return a raw piece of the buffer
+  /// after using the the put* methods.
+  ///
+  /// Most clients should prefer calling [finish].
+  Uint8List lowFinish() {
+    int alignedTail = _tail + ((-_tail) % _maxAlign);
+    return _buf.buffer.asUint8List(_buf.lengthInBytes - alignedTail);
+  }
+
+  /// Finish off the creation of the buffer.  The given [offset] is used as the
+  /// root object offset, and usually references directly or indirectly every
+  /// written object.  If [fileIdentifier] is specified (and not `null`), it is
+  /// interpreted as a 4-byte Latin-1 encoded string that should be placed at
+  /// bytes 4-7 of the file.
+  Uint8List finish(int offset, [String fileIdentifier]) {
+    _prepare(max(_sizeofUint32, _maxAlign), fileIdentifier == null ? 1 : 2);
+    int alignedTail = _tail + ((-_tail) % _maxAlign);
+    _setUint32AtTail(_buf, alignedTail, alignedTail - offset);
+    if (fileIdentifier != null) {
+      for (int i = 0; i < 4; i++) {
+        _setUint8AtTail(_buf, alignedTail - _sizeofUint32 - i,
+            fileIdentifier.codeUnitAt(i));
+      }
+    }
+    return _buf.buffer.asUint8List(_buf.lengthInBytes - alignedTail);
+  }
+
+  /// Writes a Float64 to the tail of the buffer after preparing space for it.
+  ///
+  /// Updates the [offset] pointer.  This method is intended for use when writing structs to the buffer.
+  void putFloat64(double value) {
+    _prepare(_sizeofFloat64, 1);
+    _setFloat32AtTail(_buf, _tail, value);
+  }
+
+  /// Writes a Float32 to the tail of the buffer after preparing space for it.
+  ///
+  /// Updates the [offset] pointer.  This method is intended for use when writing structs to the buffer.
+  void putFloat32(double value) {
+    _prepare(_sizeofFloat32, 1);
+    _setFloat32AtTail(_buf, _tail, value);
+  }
+
+  /// Writes a Int64 to the tail of the buffer after preparing space for it.
+  ///
+  /// Updates the [offset] pointer.  This method is intended for use when writing structs to the buffer.
+  void putInt64(int value) {
+    _prepare(_sizeofInt64, 1);
+    _setInt64AtTail(_buf, _tail, value);
+  }
+
+  /// Writes a Uint32 to the tail of the buffer after preparing space for it.
+  ///
+  /// Updates the [offset] pointer.  This method is intended for use when writing structs to the buffer.
+  void putInt32(int value) {
+    _prepare(_sizeofInt32, 1);
+    _setInt32AtTail(_buf, _tail, value);
+  }
+
+  /// Writes a Uint16 to the tail of the buffer after preparing space for it.
+  ///
+  /// Updates the [offset] pointer.  This method is intended for use when writing structs to the buffer.
+  void putInt16(int value) {
+    _prepare(_sizeofInt16, 1);
+    _setInt16AtTail(_buf, _tail, value);
+  }
+
+  /// Writes a Uint8 to the tail of the buffer after preparing space for it.
+  ///
+  /// Updates the [offset] pointer.  This method is intended for use when writing structs to the buffer.
+  void putInt8(int value) {
+    _prepare(_sizeofInt8, 1);
+    _buf.setInt8(_buf.lengthInBytes - _tail, value);
+  }
+
+  /// Writes a Uint64 to the tail of the buffer after preparing space for it.
+  ///
+  /// Updates the [offset] pointer.  This method is intended for use when writing structs to the buffer.
+  void putUint64(int value) {
+    _prepare(_sizeofUint64, 1);
+    _setUint64AtTail(_buf, _tail, value);
+  }
+
+  /// Writes a Uint32 to the tail of the buffer after preparing space for it.
+  ///
+  /// Updates the [offset] pointer.  This method is intended for use when writing structs to the buffer.
+  void putUint32(int value) {
+    _prepare(_sizeofUint32, 1);
+    _setUint32AtTail(_buf, _tail, value);
+  }
+
+  /// Writes a Uint16 to the tail of the buffer after preparing space for it.
+  ///
+  /// Updates the [offset] pointer.  This method is intended for use when writing structs to the buffer.
+  void putUint16(int value) {
+    _prepare(_sizeofUint16, 1);
+    _setUint16AtTail(_buf, _tail, value);
+  }
+
+  /// Writes a Uint8 to the tail of the buffer after preparing space for it.
+  ///
+  /// Updates the [offset] pointer.  This method is intended for use when writing structs to the buffer.
+  void putUint8(int value) {
+    _prepare(_sizeofUint8, 1);
+    _buf.setUint8(_buf.lengthInBytes - _tail, value);
+  }
+
+  /// Reset the builder and make it ready for filling a new buffer.
+  void reset() {
+    _buf = new ByteData(initialSize);
+    _maxAlign = 1;
+    _tail = 0;
+    _currentVTable = null;
+    if (_strings != null) {
+      _strings = new Map<String, int>();
+    }
+  }
+
+  /// Start a new table.  Must be finished with [endTable] invocation.
+  void startTable() {
+    if (_currentVTable != null) {
+      throw new StateError('Inline tables are not supported.');
+    }
+    _currentVTable = new _VTable();
+    _currentTableEndTail = _tail;
+  }
+
+  /// Finish a Struct vector.  Most callers should preferto use [writeListOfStructs].
+  ///
+  /// Most callers should prefer [writeListOfStructs].
+  int endStructVector(int count) {
+    putUint32(count);
+    return _tail;
+  }
+
+  /// Writes a list of Structs to the buffer, returning the offset
+  int writeListOfStructs(List<ObjectBuilder> structBuilders) {
+    _ensureNoVTable();
+    for (int i = structBuilders.length - 1; i >= 0; i--) {
+      structBuilders[i].finish(this);
+    }
+    return endStructVector(structBuilders.length);
+  }
+
+  /// Write the given list of [values].
+  int writeList(List<int> values) {
+    _ensureNoVTable();
+    _prepare(_sizeofUint32, 1 + values.length);
+    final int result = _tail;
+    int tail = _tail;
+    _setUint32AtTail(_buf, tail, values.length);
+    tail -= _sizeofUint32;
+    for (int value in values) {
+      _setUint32AtTail(_buf, tail, tail - value);
+      tail -= _sizeofUint32;
+    }
+    return result;
+  }
+
+  /// Write the given list of 64-bit float [values].
+  int writeListFloat64(List<double> values) {
+    _ensureNoVTable();
+    _prepare(4, 1 + (2 * values.length));
+    final int result = _tail;
+    int tail = _tail;
+    _setUint32AtTail(_buf, tail, values.length);
+    tail -= _sizeofUint32;
+    for (double value in values) {
+      _setFloat64AtTail(_buf, tail, value);
+      tail -= _sizeofFloat64;
+    }
+    return result;
+  }
+
+  /// Write the given list of 32-bit float [values].
+  int writeListFloat32(List<double> values) {
+    _ensureNoVTable();
+    _prepare(_sizeofFloat32, 1 + values.length);
+    final int result = _tail;
+    int tail = _tail;
+    _setUint32AtTail(_buf, tail, values.length);
+    tail -= _sizeofUint32;
+    for (double value in values) {
+      _setFloat32AtTail(_buf, tail, value);
+      tail -= _sizeofFloat32;
+    }
+    return result;
+  }
+
+  /// Write the given list of signed 64-bit integer [values].
+  int writeListInt64(List<int> values) {
+    _ensureNoVTable();
+    _prepare(_sizeofUint32, 2 * values.length);
+    final int result = _tail;
+    int tail = _tail;
+    _setUint32AtTail(_buf, tail, values.length);
+    tail -= _sizeofUint32;
+    for (int value in values) {
+      _setInt64AtTail(_buf, tail, value);
+      tail -= _sizeofInt64;
+    }
+    return result;
+  }
+
+  /// Write the given list of signed 64-bit integer [values].
+  int writeListUint64(List<int> values) {
+    _ensureNoVTable();
+    _prepare(_sizeofUint32, 2 * values.length);
+    final int result = _tail;
+    int tail = _tail;
+    _setUint32AtTail(_buf, tail, values.length);
+    tail -= _sizeofUint32;
+    for (int value in values) {
+      _setUint64AtTail(_buf, tail, value);
+      tail -= _sizeofUint64;
+    }
+    return result;
+  }
+
+  /// Write the given list of signed 32-bit integer [values].
+  int writeListInt32(List<int> values) {
+    _ensureNoVTable();
+    _prepare(_sizeofUint32, 1 + values.length);
+    final int result = _tail;
+    int tail = _tail;
+    _setUint32AtTail(_buf, tail, values.length);
+    tail -= _sizeofUint32;
+    for (int value in values) {
+      _setInt32AtTail(_buf, tail, value);
+      tail -= _sizeofInt32;
+    }
+    return result;
+  }
+
+  /// Write the given list of unsigned 32-bit integer [values].
+  int writeListUint32(List<int> values) {
+    _ensureNoVTable();
+    _prepare(_sizeofUint32, 1 + values.length);
+    final int result = _tail;
+    int tail = _tail;
+    _setUint32AtTail(_buf, tail, values.length);
+    tail -= _sizeofUint32;
+    for (int value in values) {
+      _setUint32AtTail(_buf, tail, value);
+      tail -= _sizeofUint32;
+    }
+    return result;
+  }
+
+  /// Write the given list of signed 16-bit integer [values].
+  int writeListInt16(List<int> values) {
+    _ensureNoVTable();
+    _prepare(_sizeofUint32, 1, additionalBytes: 2 * values.length);
+    final int result = _tail;
+    int tail = _tail;
+    _setUint32AtTail(_buf, tail, values.length);
+    tail -= _sizeofUint32;
+    for (int value in values) {
+      _setInt16AtTail(_buf, tail, value);
+      tail -= _sizeofInt16;
+    }
+    return result;
+  }
+
+  /// Write the given list of unsigned 16-bit integer [values].
+  int writeListUint16(List<int> values) {
+    _ensureNoVTable();
+    _prepare(_sizeofUint32, 1, additionalBytes: 2 * values.length);
+    final int result = _tail;
+    int tail = _tail;
+    _setUint32AtTail(_buf, tail, values.length);
+    tail -= _sizeofUint32;
+    for (int value in values) {
+      _setUint16AtTail(_buf, tail, value);
+      tail -= _sizeofUint16;
+    }
+    return result;
+  }
+
+  /// Write the given list of bools as unsigend 8-bit integer [values].
+  int writeListBool(List<bool> values) {
+    return writeListUint8(values?.map((b) => b ? 1 : 0)?.toList());
+  }
+
+  /// Write the given list of signed 8-bit integer [values].
+  int writeListInt8(List<int> values) {
+    _ensureNoVTable();
+    _prepare(_sizeofUint32, 1, additionalBytes: values.length);
+    final int result = _tail;
+    int tail = _tail;
+    _setUint32AtTail(_buf, tail, values.length);
+    tail -= _sizeofUint32;
+    for (int value in values) {
+      _setInt8AtTail(_buf, tail, value);
+      tail -= _sizeofUint8;
+    }
+    return result;
+  }
+
+  /// Write the given list of unsigned 8-bit integer [values].
+  int writeListUint8(List<int> values) {
+    _ensureNoVTable();
+    _prepare(_sizeofUint32, 1, additionalBytes: values.length);
+    final int result = _tail;
+    int tail = _tail;
+    _setUint32AtTail(_buf, tail, values.length);
+    tail -= _sizeofUint32;
+    for (int value in values) {
+      _setUint8AtTail(_buf, tail, value);
+      tail -= _sizeofUint8;
+    }
+    return result;
+  }
+
+  /// Write the given string [value] and return its offset, or `null` if
+  /// the [value] is `null`.
+  int writeString(String value) {
+    _ensureNoVTable();
+    if (value != null) {
+      if (_strings != null) {
+        return _strings.putIfAbsent(value, () => _writeString(value));
+      } else {
+        return _writeString(value);
+      }
+    }
+    return null;
+  }
+
+  int _writeString(String value) {
+    // TODO(scheglov) optimize for ASCII strings
+    List<int> bytes = utf8.encode(value);
+    int length = bytes.length;
+    _prepare(4, 1, additionalBytes: length + 1);
+    final int result = _tail;
+    _setUint32AtTail(_buf, _tail, length);
+    int offset = _buf.lengthInBytes - _tail + 4;
+    for (int i = 0; i < length; i++) {
+      _buf.setUint8(offset++, bytes[i]);
+    }
+    return result;
+  }
+
+  /// Throw an exception if there is not currently a vtable.
+  void _ensureCurrentVTable() {
+    if (_currentVTable == null) {
+      throw new StateError('Start a table before adding values.');
+    }
+  }
+
+  /// Throw an exception if there is currently a vtable.
+  void _ensureNoVTable() {
+    if (_currentVTable != null) {
+      throw new StateError(
+          'Cannot write a non-scalar value while writing a table.');
+    }
+  }
+
+  /// The number of bytes that have been written to the buffer so far.  The
+  /// most recently written byte is this many bytes from the end of the buffer.
+  int get offset => _tail;
+
+  /// Zero-pads the buffer, which may be required for some struct layouts.
+  void pad(int howManyBytes) {
+    for (int i = 0; i < howManyBytes; i++) putUint8(0);
+  }
+
+  /// Prepare for writing the given `count` of scalars of the given `size`.
+  /// Additionally allocate the specified `additionalBytes`. Update the current
+  /// tail pointer to point at the allocated space.
+  void _prepare(int size, int count, {int additionalBytes = 0}) {
+    // Update the alignment.
+    if (_maxAlign < size) {
+      _maxAlign = size;
+    }
+    // Prepare amount of required space.
+    int dataSize = size * count + additionalBytes;
+    int alignDelta = (-(_tail + dataSize)) % size;
+    int bufSize = alignDelta + dataSize;
+    // Ensure that we have the required amount of space.
+    {
+      int oldCapacity = _buf.lengthInBytes;
+      if (_tail + bufSize > oldCapacity) {
+        int desiredNewCapacity = (oldCapacity + bufSize) * 2;
+        int deltaCapacity = desiredNewCapacity - oldCapacity;
+        deltaCapacity += (-deltaCapacity) % _maxAlign;
+        int newCapacity = oldCapacity + deltaCapacity;
+        ByteData newBuf = new ByteData(newCapacity);
+        newBuf.buffer
+            .asUint8List()
+            .setAll(deltaCapacity, _buf.buffer.asUint8List());
+        _buf = newBuf;
+      }
+    }
+    // Update the tail pointer.
+    _tail += bufSize;
+  }
+
+  /// Record the offset of the given [field].
+  void _trackField(int field) {
+    _currentVTable.addField(field, _tail);
+  }
+
+  static void _setFloat64AtTail(ByteData _buf, int tail, double x) {
+    _buf.setFloat64(_buf.lengthInBytes - tail, x, Endian.little);
+  }
+
+  static void _setFloat32AtTail(ByteData _buf, int tail, double x) {
+    _buf.setFloat32(_buf.lengthInBytes - tail, x, Endian.little);
+  }
+
+  static void _setUint64AtTail(ByteData _buf, int tail, int x) {
+    _buf.setUint64(_buf.lengthInBytes - tail, x, Endian.little);
+  }
+
+  static void _setInt64AtTail(ByteData _buf, int tail, int x) {
+    _buf.setInt64(_buf.lengthInBytes - tail, x, Endian.little);
+  }
+
+  static void _setInt32AtTail(ByteData _buf, int tail, int x) {
+    _buf.setInt32(_buf.lengthInBytes - tail, x, Endian.little);
+  }
+
+  static void _setUint32AtTail(ByteData _buf, int tail, int x) {
+    _buf.setUint32(_buf.lengthInBytes - tail, x, Endian.little);
+  }
+
+  static void _setInt16AtTail(ByteData _buf, int tail, int x) {
+    _buf.setInt16(_buf.lengthInBytes - tail, x, Endian.little);
+  }
+
+  static void _setUint16AtTail(ByteData _buf, int tail, int x) {
+    _buf.setUint16(_buf.lengthInBytes - tail, x, Endian.little);
+  }
+
+  static void _setInt8AtTail(ByteData _buf, int tail, int x) {
+    _buf.setInt8(_buf.lengthInBytes - tail, x);
+  }
+
+  static void _setUint8AtTail(ByteData _buf, int tail, int x) {
+    _buf.setUint8(_buf.lengthInBytes - tail, x);
+  }
+}
+
+/// Reader of lists of boolean values.
+///
+/// The returned unmodifiable lists lazily read values on access.
+class BoolListReader extends Reader<List<bool>> {
+  const BoolListReader();
+
+  @override
+  int get size => _sizeofUint32;
+
+  @override
+  List<bool> read(BufferContext bc, int offset) =>
+      new _FbBoolList(bc, bc.derefObject(offset));
+}
+
+/// The reader of booleans.
+class BoolReader extends Reader<bool> {
+  const BoolReader() : super();
+
+  @override
+  int get size => _sizeofUint8;
+
+  @override
+  bool read(BufferContext bc, int offset) => bc._getInt8(offset) != 0;
+}
+
+/// The reader of lists of 64-bit float values.
+///
+/// The returned unmodifiable lists lazily read values on access.
+class Float64ListReader extends Reader<List<double>> {
+  const Float64ListReader();
+
+  @override
+  int get size => _sizeofFloat64;
+
+  @override
+  List<double> read(BufferContext bc, int offset) =>
+      new _FbFloat64List(bc, bc.derefObject(offset));
+}
+
+class Float32ListReader extends Reader<List<double>> {
+  const Float32ListReader();
+
+  @override
+  int get size => _sizeofFloat32;
+
+  @override
+  List<double> read(BufferContext bc, int offset) =>
+      new _FbFloat32List(bc, bc.derefObject(offset));
+}
+
+class Float64Reader extends Reader<double> {
+  const Float64Reader();
+
+  @override
+  int get size => _sizeofFloat64;
+
+  @override
+  double read(BufferContext bc, int offset) => bc._getFloat64(offset);
+}
+
+class Float32Reader extends Reader<double> {
+  const Float32Reader();
+
+  @override
+  int get size => _sizeofFloat32;
+
+  @override
+  double read(BufferContext bc, int offset) => bc._getFloat32(offset);
+}
+
+class Int64Reader extends Reader<int> {
+  const Int64Reader() : super();
+  @override
+  int get size => _sizeofInt64;
+
+  @override
+  int read(BufferContext bc, int offset) => bc._getInt64(offset);
+}
+
+/// The reader of signed 32-bit integers.
+class Int32Reader extends Reader<int> {
+  const Int32Reader() : super();
+
+  @override
+  int get size => _sizeofInt32;
+
+  @override
+  int read(BufferContext bc, int offset) => bc._getInt32(offset);
+}
+
+/// The reader of signed 32-bit integers.
+class Int16Reader extends Reader<int> {
+  const Int16Reader() : super();
+
+  @override
+  int get size => _sizeofInt16;
+
+  @override
+  int read(BufferContext bc, int offset) => bc._getInt16(offset);
+}
+
+/// The reader of 8-bit signed integers.
+class Int8Reader extends Reader<int> {
+  const Int8Reader() : super();
+
+  @override
+  int get size => _sizeofInt8;
+
+  @override
+  int read(BufferContext bc, int offset) => bc._getInt8(offset);
+}
+
+/// The reader of lists of objects.
+///
+/// The returned unmodifiable lists lazily read objects on access.
+class ListReader<E> extends Reader<List<E>> {
+  final Reader<E> _elementReader;
+
+  const ListReader(this._elementReader);
+
+  @override
+  int get size => _sizeofUint32;
+
+  @override
+  List<E> read(BufferContext bc, int offset) =>
+      new _FbGenericList<E>(_elementReader, bc, bc.derefObject(offset));
+}
+
+/// Object that can read a value at a [BufferContext].
+abstract class Reader<T> {
+  const Reader();
+
+  /// The size of the value in bytes.
+  int get size;
+
+  /// Read the value at the given [offset] in [bc].
+  T read(BufferContext bc, int offset);
+
+  /// Read the value of the given [field] in the given [object].
+  T vTableGet(BufferContext object, int offset, int field, [T defaultValue]) {
+    int vTableSOffset = object._getInt32(offset);
+    int vTableOffset = offset - vTableSOffset;
+    int vTableSize = object._getUint16(vTableOffset);
+    int vTableFieldOffset = field;
+    if (vTableFieldOffset < vTableSize) {
+      int fieldOffsetInObject =
+          object._getUint16(vTableOffset + vTableFieldOffset);
+      if (fieldOffsetInObject != 0) {
+        return read(object, offset + fieldOffsetInObject);
+      }
+    }
+    return defaultValue;
+  }
+}
+
+/// The reader of string values.
+class StringReader extends Reader<String> {
+  const StringReader() : super();
+
+  @override
+  int get size => 4;
+
+  @override
+  String read(BufferContext bc, int offset) {
+    int strOffset = bc.derefObject(offset);
+    int length = bc._getUint32(strOffset);
+    Uint8List bytes = bc._asUint8LIst(strOffset + 4, length);
+    if (_isLatin(bytes)) {
+      return new String.fromCharCodes(bytes);
+    }
+    return utf8.decode(bytes);
+  }
+
+  static bool _isLatin(Uint8List bytes) {
+    int length = bytes.length;
+    for (int i = 0; i < length; i++) {
+      if (bytes[i] > 127) {
+        return false;
+      }
+    }
+    return true;
+  }
+}
+
+/// An abstract reader for structs.
+abstract class StructReader<T> extends Reader<T> {
+  const StructReader();
+
+  /// Return the object at `offset`.
+  T createObject(BufferContext bc, int offset);
+
+  T read(BufferContext bp, int offset) {
+    return createObject(bp, offset);
+  }
+}
+
+/// An abstract reader for tables.
+abstract class TableReader<T> extends Reader<T> {
+  const TableReader();
+
+  @override
+  int get size => 4;
+
+  /// Return the object at [offset].
+  T createObject(BufferContext bc, int offset);
+
+  @override
+  T read(BufferContext bp, int offset) {
+    int objectOffset = bp.derefObject(offset);
+    return createObject(bp, objectOffset);
+  }
+}
+
+/// Reader of lists of unsigned 32-bit integer values.
+///
+/// The returned unmodifiable lists lazily read values on access.
+class Uint32ListReader extends Reader<List<int>> {
+  const Uint32ListReader();
+
+  @override
+  int get size => _sizeofUint32;
+
+  @override
+  List<int> read(BufferContext bc, int offset) =>
+      new _FbUint32List(bc, bc.derefObject(offset));
+}
+
+/// The reader of unsigned 64-bit integers.
+///
+/// WARNING: May have compatibility issues with JavaScript
+class Uint64Reader extends Reader<int> {
+  const Uint64Reader() : super();
+
+  @override
+  int get size => _sizeofUint64;
+
+  @override
+  int read(BufferContext bc, int offset) => bc._getUint64(offset);
+}
+
+/// The reader of unsigned 32-bit integers.
+class Uint32Reader extends Reader<int> {
+  const Uint32Reader() : super();
+
+  @override
+  int get size => _sizeofUint32;
+
+  @override
+  int read(BufferContext bc, int offset) => bc._getUint32(offset);
+}
+
+/// Reader of lists of unsigned 32-bit integer values.
+///
+/// The returned unmodifiable lists lazily read values on access.
+class Uint16ListReader extends Reader<List<int>> {
+  const Uint16ListReader();
+
+  @override
+  int get size => _sizeofUint32;
+
+  @override
+  List<int> read(BufferContext bc, int offset) =>
+      new _FbUint16List(bc, bc.derefObject(offset));
+}
+
+/// The reader of unsigned 32-bit integers.
+class Uint16Reader extends Reader<int> {
+  const Uint16Reader() : super();
+
+  @override
+  int get size => _sizeofUint16;
+
+  @override
+  int read(BufferContext bc, int offset) => bc._getUint16(offset);
+}
+
+/// Reader of lists of unsigned 8-bit integer values.
+///
+/// The returned unmodifiable lists lazily read values on access.
+class Uint8ListReader extends Reader<List<int>> {
+  const Uint8ListReader();
+
+  @override
+  int get size => _sizeofUint32;
+
+  @override
+  List<int> read(BufferContext bc, int offset) =>
+      new _FbUint8List(bc, bc.derefObject(offset));
+}
+
+/// The reader of unsigned 8-bit integers.
+class Uint8Reader extends Reader<int> {
+  const Uint8Reader() : super();
+
+  @override
+  int get size => _sizeofUint8;
+
+  @override
+  int read(BufferContext bc, int offset) => bc._getUint8(offset);
+}
+
+/// The list backed by 64-bit values - Uint64 length and Float64.
+class _FbFloat64List extends _FbList<double> {
+  _FbFloat64List(BufferContext bc, int offset) : super(bc, offset);
+
+  @override
+  double operator [](int i) {
+    return bc._getFloat64(offset + 4 + 8 * i);
+  }
+}
+
+/// The list backed by 32-bit values - Float32.
+class _FbFloat32List extends _FbList<double> {
+  _FbFloat32List(BufferContext bc, int offset) : super(bc, offset);
+
+  @override
+  double operator [](int i) {
+    return bc._getFloat32(offset + 4 + 4 * i);
+  }
+}
+
+/// List backed by a generic object which may have any size.
+class _FbGenericList<E> extends _FbList<E> {
+  final Reader<E> elementReader;
+
+  List<E> _items;
+
+  _FbGenericList(this.elementReader, BufferContext bp, int offset)
+      : super(bp, offset);
+
+  @override
+  E operator [](int i) {
+    _items ??= new List<E>(length);
+    E item = _items[i];
+    if (item == null) {
+      item = elementReader.read(bc, offset + 4 + elementReader.size * i);
+      _items[i] = item;
+    }
+    return item;
+  }
+}
+
+/// The base class for immutable lists read from flat buffers.
+abstract class _FbList<E> extends Object with ListMixin<E> implements List<E> {
+  final BufferContext bc;
+  final int offset;
+  int _length;
+
+  _FbList(this.bc, this.offset);
+
+  @override
+  int get length {
+    _length ??= bc._getUint32(offset);
+    return _length;
+  }
+
+  @override
+  void set length(int i) =>
+      throw new StateError('Attempt to modify immutable list');
+
+  @override
+  void operator []=(int i, E e) =>
+      throw new StateError('Attempt to modify immutable list');
+}
+
+/// List backed by 32-bit unsigned integers.
+class _FbUint32List extends _FbList<int> {
+  _FbUint32List(BufferContext bc, int offset) : super(bc, offset);
+
+  @override
+  int operator [](int i) {
+    return bc._getUint32(offset + 4 + 4 * i);
+  }
+}
+
+/// List backed by 16-bit unsigned integers.
+class _FbUint16List extends _FbList<int> {
+  _FbUint16List(BufferContext bc, int offset) : super(bc, offset);
+
+  @override
+  int operator [](int i) {
+    return bc._getUint16(offset + 4 + 2 * i);
+  }
+}
+
+/// List backed by 8-bit unsigned integers.
+class _FbUint8List extends _FbList<int> {
+  _FbUint8List(BufferContext bc, int offset) : super(bc, offset);
+
+  @override
+  int operator [](int i) {
+    return bc._getUint8(offset + 4 + i);
+  }
+}
+
+/// List backed by 8-bit unsigned integers.
+class _FbBoolList extends _FbList<bool> {
+  _FbBoolList(BufferContext bc, int offset) : super(bc, offset);
+
+  @override
+  bool operator [](int i) {
+    return bc._getUint8(offset + 4 + i) == 1 ? true : false;
+  }
+}
+
+/// Class that describes the structure of a table.
+class _VTable {
+  static const int _metadataLength = 4;
+
+  final List<int> fieldTails = <int>[];
+  final List<int> fieldOffsets = <int>[];
+
+  /// The size of the table that uses this VTable.
+  int tableSize;
+
+  /// The tail of this VTable.  It is used to share the same VTable between
+  /// multiple tables of identical structure.
+  int tail;
+
+  int get _vTableSize => numOfUint16 * _sizeofUint16;
+
+  int get numOfUint16 => 1 + 1 + fieldTails.length;
+
+  void addField(int field, int offset) {
+    while (fieldTails.length <= field) {
+      fieldTails.add(null);
+    }
+    fieldTails[field] = offset;
+  }
+
+  bool _offsetsMatch(int vt2Start, ByteData buf) {
+    for (int i = 0; i < fieldOffsets.length; i++) {
+      if (fieldOffsets[i] !=
+          buf.getUint16(
+              vt2Start + _metadataLength + (2 * i), Endian.little)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /// Fill the [fieldOffsets] field.
+  void computeFieldOffsets(int tableTail) {
+    assert(fieldOffsets.isEmpty);
+    for (int fieldTail in fieldTails) {
+      int fieldOffset = fieldTail == null ? 0 : tableTail - fieldTail;
+      fieldOffsets.add(fieldOffset);
+    }
+  }
+
+  /// Outputs this VTable to [buf], which is is expected to be aligned to 16-bit
+  /// and have at least [numOfUint16] 16-bit words available.
+  void output(ByteData buf, int bufOffset) {
+    // VTable size.
+    buf.setUint16(bufOffset, numOfUint16 * 2, Endian.little);
+    bufOffset += 2;
+    // Table size.
+    buf.setUint16(bufOffset, tableSize, Endian.little);
+    bufOffset += 2;
+    // Field offsets.
+    for (int fieldOffset in fieldOffsets) {
+      buf.setUint16(bufOffset, fieldOffset, Endian.little);
+      bufOffset += 2;
+    }
+  }
+}
diff --git a/dart/publish.sh b/dart/publish.sh
new file mode 100755
index 0000000..167a4a3
--- /dev/null
+++ b/dart/publish.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# 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.
+#
+# Note to pub consumers: this file is used to assist with publishing the
+# pub package from the flatbuffers repository and is not meant for general use.
+# As pub does not currently provide a way to exclude files, it is included here.
+
+command -v pub >/dev/null 2>&1 || { echo >&2 "Require `pub` but it's not installed.  Aborting."; exit 1; }
+
+cp ../samples/monster.fbs example/
+cp ../tests/monster_test.fbs test/
+pub publish
+
+rm example/monster.fbs
+rm test/monster_test.fbs
\ No newline at end of file
diff --git a/dart/pubspec.yaml b/dart/pubspec.yaml
new file mode 100644
index 0000000..4761ffc
--- /dev/null
+++ b/dart/pubspec.yaml
@@ -0,0 +1,20 @@
+name: flat_buffers
+version: 1.11.0
+description: >
+  FlatBuffers reading and writing library for Dart.  Use the flatc compiler to
+  generate Dart classes for a FlatBuffers schema, and this library to assist with
+  reading and writing the binary format.
+
+  Based on original work by Konstantin Scheglov and Paul Berry of the Dart SDK team.
+authors:
+- Dan Field <dfield@gmail.com>
+- Konstantin Scheglov
+- Paul Berry
+homepage: https://github.com/google/flatbuffers
+documentation: https://google.github.io/flatbuffers/index.html
+dev_dependencies:
+  test: ^1.3.0
+  test_reflective_loader: ^0.1.4
+  path: ^1.5.1
+environment:
+  sdk: '>=2.0.0-dev.28.0 <3.0.0'
\ No newline at end of file
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);
+  }
+}
