diff --git a/include/flatbuffers/reflection.h b/include/flatbuffers/reflection.h
new file mode 100644
index 0000000..580ae62
--- /dev/null
+++ b/include/flatbuffers/reflection.h
@@ -0,0 +1,477 @@
+/*
+ * Copyright 2015 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FLATBUFFERS_REFLECTION_H_
+#define FLATBUFFERS_REFLECTION_H_
+
+// This is somewhat of a circular dependency because flatc (and thus this
+// file) is needed to generate this header in the first place.
+// Should normally not be a problem since it can be generated by the
+// previous version of flatc whenever this code needs to change.
+// See reflection/generate_code.sh
+#include "flatbuffers/reflection_generated.h"
+
+// Helper functionality for reflection.
+
+namespace flatbuffers {
+
+// ------------------------- GETTERS -------------------------
+
+inline bool IsScalar(reflection::BaseType t) {
+  return t >= reflection::UType && t <= reflection::Double;
+}
+inline bool IsInteger(reflection::BaseType t) {
+  return t >= reflection::UType && t <= reflection::ULong;
+}
+inline bool IsFloat(reflection::BaseType t) {
+  return t == reflection::Float || t == reflection::Double;
+}
+inline bool IsLong(reflection::BaseType t) {
+  return t == reflection::Long || t == reflection::ULong;
+}
+
+// Size of a basic type, don't use with structs.
+inline size_t GetTypeSize(reflection::BaseType base_type) {
+  // This needs to correspond to the BaseType enum.
+  static size_t sizes[] = { 0, 1, 1, 1, 1, 2, 2, 4, 4, 8, 8, 4, 8, 4, 4, 4, 4 };
+  return sizes[base_type];
+}
+
+// Same as above, but now correctly returns the size of a struct if
+// the field (or vector element) is a struct.
+inline size_t GetTypeSizeInline(reflection::BaseType base_type, int type_index,
+                                const reflection::Schema &schema) {
+  if (base_type == reflection::Obj &&
+      schema.objects()->Get(type_index)->is_struct()) {
+    return schema.objects()->Get(type_index)->bytesize();
+  } else {
+    return GetTypeSize(base_type);
+  }
+}
+
+// Get the root, regardless of what type it is.
+inline Table *GetAnyRoot(uint8_t *flatbuf) {
+  return GetMutableRoot<Table>(flatbuf);
+}
+inline const Table *GetAnyRoot(const uint8_t *flatbuf) {
+  return GetRoot<Table>(flatbuf);
+}
+
+// Get a field's default, if you know it's an integer, and its exact type.
+template<typename T> T GetFieldDefaultI(const reflection::Field &field) {
+  FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type()));
+  return static_cast<T>(field.default_integer());
+}
+
+// Get a field's default, if you know it's floating point and its exact type.
+template<typename T> T GetFieldDefaultF(const reflection::Field &field) {
+  FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type()));
+  return static_cast<T>(field.default_real());
+}
+
+// Get a field, if you know it's an integer, and its exact type.
+template<typename T>
+T GetFieldI(const Table &table, const reflection::Field &field) {
+  FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type()));
+  return table.GetField<T>(field.offset(),
+                           static_cast<T>(field.default_integer()));
+}
+
+// Get a field, if you know it's floating point and its exact type.
+template<typename T>
+T GetFieldF(const Table &table, const reflection::Field &field) {
+  FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type()));
+  return table.GetField<T>(field.offset(),
+                           static_cast<T>(field.default_real()));
+}
+
+// Get a field, if you know it's a string.
+inline const String *GetFieldS(const Table &table,
+                               const reflection::Field &field) {
+  FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::String);
+  return table.GetPointer<const String *>(field.offset());
+}
+
+// Get a field, if you know it's a vector.
+template<typename T>
+Vector<T> *GetFieldV(const Table &table, const reflection::Field &field) {
+  FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Vector &&
+                     sizeof(T) == GetTypeSize(field.type()->element()));
+  return table.GetPointer<Vector<T> *>(field.offset());
+}
+
+// Get a field, if you know it's a vector, generically.
+// To actually access elements, use the return value together with
+// field.type()->element() in any of GetAnyVectorElemI below etc.
+inline VectorOfAny *GetFieldAnyV(const Table &table,
+                                 const reflection::Field &field) {
+  return table.GetPointer<VectorOfAny *>(field.offset());
+}
+
+// Get a field, if you know it's a table.
+inline Table *GetFieldT(const Table &table, const reflection::Field &field) {
+  FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Obj ||
+                     field.type()->base_type() == reflection::Union);
+  return table.GetPointer<Table *>(field.offset());
+}
+
+// Get a field, if you know it's a struct.
+inline const Struct *GetFieldStruct(const Table &table,
+                                    const reflection::Field &field) {
+  // TODO: This does NOT check if the field is a table or struct, but we'd need
+  // access to the schema to check the is_struct flag.
+  FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Obj);
+  return table.GetStruct<const Struct *>(field.offset());
+}
+
+// Get a structure's field, if you know it's a struct.
+inline const Struct *GetFieldStruct(const Struct &structure,
+                                    const reflection::Field &field) {
+  FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Obj);
+  return structure.GetStruct<const Struct *>(field.offset());
+}
+
+// Raw helper functions used below: get any value in memory as a 64bit int, a
+// double or a string.
+// All scalars get static_cast to an int64_t, strings use strtoull, every other
+// data type returns 0.
+int64_t GetAnyValueI(reflection::BaseType type, const uint8_t *data);
+// All scalars static cast to double, strings use strtod, every other data
+// type is 0.0.
+double GetAnyValueF(reflection::BaseType type, const uint8_t *data);
+// All scalars converted using stringstream, strings as-is, and all other
+// data types provide some level of debug-pretty-printing.
+std::string GetAnyValueS(reflection::BaseType type, const uint8_t *data,
+                         const reflection::Schema *schema, int type_index);
+
+// Get any table field as a 64bit int, regardless of what type it is.
+inline int64_t GetAnyFieldI(const Table &table,
+                            const reflection::Field &field) {
+  auto field_ptr = table.GetAddressOf(field.offset());
+  return field_ptr ? GetAnyValueI(field.type()->base_type(), field_ptr)
+                   : field.default_integer();
+}
+
+// Get any table field as a double, regardless of what type it is.
+inline double GetAnyFieldF(const Table &table, const reflection::Field &field) {
+  auto field_ptr = table.GetAddressOf(field.offset());
+  return field_ptr ? GetAnyValueF(field.type()->base_type(), field_ptr)
+                   : field.default_real();
+}
+
+// Get any table field as a string, regardless of what type it is.
+// You may pass nullptr for the schema if you don't care to have fields that
+// are of table type pretty-printed.
+inline std::string GetAnyFieldS(const Table &table,
+                                const reflection::Field &field,
+                                const reflection::Schema *schema) {
+  auto field_ptr = table.GetAddressOf(field.offset());
+  return field_ptr ? GetAnyValueS(field.type()->base_type(), field_ptr, schema,
+                                  field.type()->index())
+                   : "";
+}
+
+// Get any struct field as a 64bit int, regardless of what type it is.
+inline int64_t GetAnyFieldI(const Struct &st, const reflection::Field &field) {
+  return GetAnyValueI(field.type()->base_type(),
+                      st.GetAddressOf(field.offset()));
+}
+
+// Get any struct field as a double, regardless of what type it is.
+inline double GetAnyFieldF(const Struct &st, const reflection::Field &field) {
+  return GetAnyValueF(field.type()->base_type(),
+                      st.GetAddressOf(field.offset()));
+}
+
+// Get any struct field as a string, regardless of what type it is.
+inline std::string GetAnyFieldS(const Struct &st,
+                                const reflection::Field &field) {
+  return GetAnyValueS(field.type()->base_type(),
+                      st.GetAddressOf(field.offset()), nullptr, -1);
+}
+
+// Get any vector element as a 64bit int, regardless of what type it is.
+inline int64_t GetAnyVectorElemI(const VectorOfAny *vec,
+                                 reflection::BaseType elem_type, size_t i) {
+  return GetAnyValueI(elem_type, vec->Data() + GetTypeSize(elem_type) * i);
+}
+
+// Get any vector element as a double, regardless of what type it is.
+inline double GetAnyVectorElemF(const VectorOfAny *vec,
+                                reflection::BaseType elem_type, size_t i) {
+  return GetAnyValueF(elem_type, vec->Data() + GetTypeSize(elem_type) * i);
+}
+
+// Get any vector element as a string, regardless of what type it is.
+inline std::string GetAnyVectorElemS(const VectorOfAny *vec,
+                                     reflection::BaseType elem_type, size_t i) {
+  return GetAnyValueS(elem_type, vec->Data() + GetTypeSize(elem_type) * i,
+                      nullptr, -1);
+}
+
+// Get a vector element that's a table/string/vector from a generic vector.
+// Pass Table/String/VectorOfAny as template parameter.
+// Warning: does no typechecking.
+template<typename T>
+T *GetAnyVectorElemPointer(const VectorOfAny *vec, size_t i) {
+  auto elem_ptr = vec->Data() + sizeof(uoffset_t) * i;
+  return reinterpret_cast<T*>(elem_ptr + ReadScalar<uoffset_t>(elem_ptr));
+}
+
+// Get the inline-address of a vector element. Useful for Structs (pass Struct
+// as template arg), or being able to address a range of scalars in-line.
+// Get elem_size from GetTypeSizeInline().
+// Note: little-endian data on all platforms, use EndianScalar() instead of
+// raw pointer access with scalars).
+template<typename T>
+T *GetAnyVectorElemAddressOf(const VectorOfAny *vec, size_t i,
+                             size_t elem_size) {
+  return reinterpret_cast<T *>(vec->Data() + elem_size * i);
+}
+
+// Similarly, for elements of tables.
+template<typename T>
+T *GetAnyFieldAddressOf(const Table &table, const reflection::Field &field) {
+  return reinterpret_cast<T *>(table.GetAddressOf(field.offset()));
+}
+
+// Similarly, for elements of structs.
+template<typename T>
+T *GetAnyFieldAddressOf(const Struct &st, const reflection::Field &field) {
+  return reinterpret_cast<T *>(st.GetAddressOf(field.offset()));
+}
+
+// ------------------------- SETTERS -------------------------
+
+// Set any scalar field, if you know its exact type.
+template<typename T>
+bool SetField(Table *table, const reflection::Field &field, T val) {
+  reflection::BaseType type = field.type()->base_type();
+  if (!IsScalar(type)) { return false; }
+  FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(type));
+  T def;
+  if (IsInteger(type)) {
+    def = GetFieldDefaultI<T>(field);
+  } else {
+    FLATBUFFERS_ASSERT(IsFloat(type));
+    def = GetFieldDefaultF<T>(field);
+  }
+  return table->SetField(field.offset(), val, def);
+}
+
+// Raw helper functions used below: set any value in memory as a 64bit int, a
+// double or a string.
+// These work for all scalar values, but do nothing for other data types.
+// To set a string, see SetString below.
+void SetAnyValueI(reflection::BaseType type, uint8_t *data, int64_t val);
+void SetAnyValueF(reflection::BaseType type, uint8_t *data, double val);
+void SetAnyValueS(reflection::BaseType type, uint8_t *data, const char *val);
+
+// Set any table field as a 64bit int, regardless of type what it is.
+inline bool SetAnyFieldI(Table *table, const reflection::Field &field,
+                         int64_t val) {
+  auto field_ptr = table->GetAddressOf(field.offset());
+  if (!field_ptr) return val == GetFieldDefaultI<int64_t>(field);
+  SetAnyValueI(field.type()->base_type(), field_ptr, val);
+  return true;
+}
+
+// Set any table field as a double, regardless of what type it is.
+inline bool SetAnyFieldF(Table *table, const reflection::Field &field,
+                         double val) {
+  auto field_ptr = table->GetAddressOf(field.offset());
+  if (!field_ptr) return val == GetFieldDefaultF<double>(field);
+  SetAnyValueF(field.type()->base_type(), field_ptr, val);
+  return true;
+}
+
+// Set any table field as a string, regardless of what type it is.
+inline bool SetAnyFieldS(Table *table, const reflection::Field &field,
+                         const char *val) {
+  auto field_ptr = table->GetAddressOf(field.offset());
+  if (!field_ptr) return false;
+  SetAnyValueS(field.type()->base_type(), field_ptr, val);
+  return true;
+}
+
+// Set any struct field as a 64bit int, regardless of type what it is.
+inline void SetAnyFieldI(Struct *st, const reflection::Field &field,
+                         int64_t val) {
+  SetAnyValueI(field.type()->base_type(), st->GetAddressOf(field.offset()),
+               val);
+}
+
+// Set any struct field as a double, regardless of type what it is.
+inline void SetAnyFieldF(Struct *st, const reflection::Field &field,
+                         double val) {
+  SetAnyValueF(field.type()->base_type(), st->GetAddressOf(field.offset()),
+               val);
+}
+
+// Set any struct field as a string, regardless of type what it is.
+inline void SetAnyFieldS(Struct *st, const reflection::Field &field,
+                         const char *val) {
+  SetAnyValueS(field.type()->base_type(), st->GetAddressOf(field.offset()),
+               val);
+}
+
+// Set any vector element as a 64bit int, regardless of type what it is.
+inline void SetAnyVectorElemI(VectorOfAny *vec, reflection::BaseType elem_type,
+                              size_t i, int64_t val) {
+  SetAnyValueI(elem_type, vec->Data() + GetTypeSize(elem_type) * i, val);
+}
+
+// Set any vector element as a double, regardless of type what it is.
+inline void SetAnyVectorElemF(VectorOfAny *vec, reflection::BaseType elem_type,
+                              size_t i, double val) {
+  SetAnyValueF(elem_type, vec->Data() + GetTypeSize(elem_type) * i, val);
+}
+
+// Set any vector element as a string, regardless of type what it is.
+inline void SetAnyVectorElemS(VectorOfAny *vec, reflection::BaseType elem_type,
+                              size_t i, const char *val) {
+  SetAnyValueS(elem_type, vec->Data() + GetTypeSize(elem_type) * i, val);
+}
+
+// ------------------------- RESIZING SETTERS -------------------------
+
+// "smart" pointer for use with resizing vectors: turns a pointer inside
+// a vector into a relative offset, such that it is not affected by resizes.
+template<typename T, typename U> class pointer_inside_vector {
+ public:
+  pointer_inside_vector(T *ptr, std::vector<U> &vec)
+      : offset_(reinterpret_cast<uint8_t *>(ptr) -
+                reinterpret_cast<uint8_t *>(flatbuffers::vector_data(vec))),
+        vec_(vec) {}
+
+  T *operator*() const {
+    return reinterpret_cast<T *>(
+        reinterpret_cast<uint8_t *>(flatbuffers::vector_data(vec_)) + offset_);
+  }
+  T *operator->() const { return operator*(); }
+  void operator=(const pointer_inside_vector &piv);
+
+ private:
+  size_t offset_;
+  std::vector<U> &vec_;
+};
+
+// Helper to create the above easily without specifying template args.
+template<typename T, typename U>
+pointer_inside_vector<T, U> piv(T *ptr, std::vector<U> &vec) {
+  return pointer_inside_vector<T, U>(ptr, vec);
+}
+
+inline const char *UnionTypeFieldSuffix() { return "_type"; }
+
+// Helper to figure out the actual table type a union refers to.
+inline const reflection::Object &GetUnionType(
+    const reflection::Schema &schema, const reflection::Object &parent,
+    const reflection::Field &unionfield, const Table &table) {
+  auto enumdef = schema.enums()->Get(unionfield.type()->index());
+  // TODO: this is clumsy and slow, but no other way to find it?
+  auto type_field = parent.fields()->LookupByKey(
+      (unionfield.name()->str() + UnionTypeFieldSuffix()).c_str());
+  FLATBUFFERS_ASSERT(type_field);
+  auto union_type = GetFieldI<uint8_t>(table, *type_field);
+  auto enumval = enumdef->values()->LookupByKey(union_type);
+  return *enumval->object();
+}
+
+// Changes the contents of a string inside a FlatBuffer. FlatBuffer must
+// live inside a std::vector so we can resize the buffer if needed.
+// "str" must live inside "flatbuf" and may be invalidated after this call.
+// If your FlatBuffer's root table is not the schema's root table, you should
+// pass in your root_table type as well.
+void SetString(const reflection::Schema &schema, const std::string &val,
+               const String *str, std::vector<uint8_t> *flatbuf,
+               const reflection::Object *root_table = nullptr);
+
+// Resizes a flatbuffers::Vector inside a FlatBuffer. FlatBuffer must
+// live inside a std::vector so we can resize the buffer if needed.
+// "vec" must live inside "flatbuf" and may be invalidated after this call.
+// If your FlatBuffer's root table is not the schema's root table, you should
+// pass in your root_table type as well.
+uint8_t *ResizeAnyVector(const reflection::Schema &schema, uoffset_t newsize,
+                         const VectorOfAny *vec, uoffset_t num_elems,
+                         uoffset_t elem_size, std::vector<uint8_t> *flatbuf,
+                         const reflection::Object *root_table = nullptr);
+
+template<typename T>
+void ResizeVector(const reflection::Schema &schema, uoffset_t newsize, T val,
+                  const Vector<T> *vec, std::vector<uint8_t> *flatbuf,
+                  const reflection::Object *root_table = nullptr) {
+  auto delta_elem = static_cast<int>(newsize) - static_cast<int>(vec->size());
+  auto newelems = ResizeAnyVector(
+      schema, newsize, reinterpret_cast<const VectorOfAny *>(vec), vec->size(),
+      static_cast<uoffset_t>(sizeof(T)), flatbuf, root_table);
+  // Set new elements to "val".
+  for (int i = 0; i < delta_elem; i++) {
+    auto loc = newelems + i * sizeof(T);
+    auto is_scalar = flatbuffers::is_scalar<T>::value;
+    if (is_scalar) {
+      WriteScalar(loc, val);
+    } else {  // struct
+      *reinterpret_cast<T *>(loc) = val;
+    }
+  }
+}
+
+// Adds any new data (in the form of a new FlatBuffer) to an existing
+// FlatBuffer. This can be used when any of the above methods are not
+// sufficient, in particular for adding new tables and new fields.
+// This is potentially slightly less efficient than a FlatBuffer constructed
+// in one piece, since the new FlatBuffer doesn't share any vtables with the
+// existing one.
+// The return value can now be set using Vector::MutateOffset or SetFieldT
+// below.
+const uint8_t *AddFlatBuffer(std::vector<uint8_t> &flatbuf,
+                             const uint8_t *newbuf, size_t newlen);
+
+inline bool SetFieldT(Table *table, const reflection::Field &field,
+                      const uint8_t *val) {
+  FLATBUFFERS_ASSERT(sizeof(uoffset_t) ==
+                     GetTypeSize(field.type()->base_type()));
+  return table->SetPointer(field.offset(), val);
+}
+
+// ------------------------- COPYING -------------------------
+
+// Generic copying of tables from a FlatBuffer into a FlatBuffer builder.
+// Can be used to do any kind of merging/selecting you may want to do out
+// of existing buffers. Also useful to reconstruct a whole buffer if the
+// above resizing functionality has introduced garbage in a buffer you want
+// to remove.
+// Note: this does not deal with DAGs correctly. If the table passed forms a
+// DAG, the copy will be a tree instead (with duplicates). Strings can be
+// shared however, by passing true for use_string_pooling.
+
+Offset<const Table *> CopyTable(FlatBufferBuilder &fbb,
+                                const reflection::Schema &schema,
+                                const reflection::Object &objectdef,
+                                const Table &table,
+                                bool use_string_pooling = false);
+
+// Verifies the provided flatbuffer using reflection.
+// root should point to the root type for this flatbuffer.
+// buf should point to the start of flatbuffer data.
+// length specifies the size of the flatbuffer data.
+bool Verify(const reflection::Schema &schema, const reflection::Object &root,
+            const uint8_t *buf, size_t length);
+
+}  // namespace flatbuffers
+
+#endif  // FLATBUFFERS_REFLECTION_H_
