diff --git a/java/com/google/flatbuffers/ArrayReadWriteBuf.java b/java/com/google/flatbuffers/ArrayReadWriteBuf.java
new file mode 100644
index 0000000..b7573d6
--- /dev/null
+++ b/java/com/google/flatbuffers/ArrayReadWriteBuf.java
@@ -0,0 +1,252 @@
+package com.google.flatbuffers;
+
+import java.util.Arrays;
+
+/**
+ * Implements {@code ReadBuf} using an array of bytes
+ * as a backing storage. Using array of bytes are
+ * usually faster than {@code ByteBuffer}.
+ *
+ * This class is not thread-safe, meaning that
+ * it must operate on a single thread. Operating from
+ * multiple thread leads into a undefined behavior
+ */
+public class ArrayReadWriteBuf implements ReadWriteBuf {
+
+  private byte[] buffer;
+  private int writePos;
+
+  public ArrayReadWriteBuf() {
+    this(10);
+  }
+
+  public ArrayReadWriteBuf(int initialCapacity) {
+    this(new byte[initialCapacity]);
+  }
+
+  public ArrayReadWriteBuf(byte[] buffer) {
+    this.buffer = buffer;
+    this.writePos = 0;
+  }
+
+  public ArrayReadWriteBuf(byte[] buffer, int startPos) {
+    this.buffer = buffer;
+    this.writePos = startPos;
+  }
+
+  @Override
+  public void clear() {
+    this.writePos = 0;
+  }
+
+  @Override
+  public boolean getBoolean(int index) {
+    return buffer[index] != 0;
+  }
+
+  @Override
+  public byte get(int index) {
+    return buffer[index];
+  }
+
+  @Override
+  public short getShort(int index) {
+    return (short) ((buffer[index+ 1] << 8) | (buffer[index] & 0xff));
+  }
+
+  @Override
+  public int getInt(int index) {
+    return (((buffer[index + 3]) << 24) |
+      ((buffer[index + 2] & 0xff) << 16) |
+      ((buffer[index + 1] & 0xff) << 8) |
+      ((buffer[index] & 0xff)));
+  }
+
+  @Override
+  public long getLong(int index) {
+    return ((((long) buffer[index++] & 0xff)) |
+      (((long) buffer[index++] & 0xff) << 8) |
+      (((long) buffer[index++] & 0xff) << 16) |
+      (((long) buffer[index++] & 0xff) << 24) |
+      (((long) buffer[index++] & 0xff) << 32) |
+      (((long) buffer[index++] & 0xff) << 40) |
+      (((long) buffer[index++] & 0xff) << 48) |
+      (((long) buffer[index]) << 56));
+  }
+
+  @Override
+  public float getFloat(int index) {
+    return Float.intBitsToFloat(getInt(index));
+  }
+
+  @Override
+  public double getDouble(int index) {
+    return Double.longBitsToDouble(getLong(index));
+  }
+
+  @Override
+  public String getString(int start, int size) {
+    return Utf8Safe.decodeUtf8Array(buffer, start, size);
+  }
+
+  @Override
+  public byte[] data() {
+    return buffer;
+  }
+
+
+  @Override
+  public void putBoolean(boolean value) {
+      setBoolean(writePos, value);
+      writePos++;
+  }
+
+  @Override
+  public void put(byte[] value, int start, int length) {
+    set(writePos, value, start, length);
+    writePos+=length;
+  }
+
+  @Override
+  public void put(byte value) {
+    set(writePos, value);
+    writePos++;
+  }
+
+  @Override
+  public void putShort(short value) {
+    setShort(writePos, value);
+    writePos +=2;
+  }
+
+  @Override
+  public void putInt(int value) {
+    setInt(writePos, value);
+    writePos +=4;
+  }
+
+  @Override
+  public void putLong(long value) {
+    setLong(writePos, value);
+    writePos +=8;
+  }
+
+  @Override
+  public void putFloat(float value) {
+    setFloat(writePos, value);
+    writePos +=4;
+  }
+
+  @Override
+  public void putDouble(double value) {
+    setDouble(writePos, value);
+    writePos +=8;
+  }
+
+  @Override
+  public void setBoolean(int index, boolean value) {
+    set(index, value ? (byte)1 : (byte)0);
+  }
+
+  @Override
+  public void set(int index, byte value) {
+    requestCapacity(index + 1);
+    buffer[index] = value;
+  }
+
+  @Override
+  public void set(int index, byte[] toCopy, int start, int length) {
+    requestCapacity(index + (length - start));
+    System.arraycopy(toCopy, start, buffer, index, length);
+  }
+
+  @Override
+  public void setShort(int index, short value) {
+    requestCapacity(index + 2);
+
+    buffer[index++] = (byte) ((value) & 0xff);
+    buffer[index  ] = (byte) ((value >> 8) & 0xff);
+  }
+
+  @Override
+  public void setInt(int index, int value) {
+    requestCapacity(index + 4);
+
+    buffer[index++] = (byte) ((value) & 0xff);
+    buffer[index++] = (byte) ((value >>  8) & 0xff);
+    buffer[index++] = (byte) ((value >> 16) & 0xff);
+    buffer[index  ] = (byte) ((value >> 24) & 0xff);
+  }
+
+  @Override
+  public void setLong(int index, long value) {
+    requestCapacity(index + 8);
+
+    int i = (int) value;
+    buffer[index++] = (byte) ((i) & 0xff);
+    buffer[index++] = (byte) ((i >>  8) & 0xff);
+    buffer[index++] = (byte) ((i >> 16) & 0xff);
+    buffer[index++] = (byte) ((i >> 24) & 0xff);
+    i = (int) (value >> 32);
+    buffer[index++] = (byte) ((i) & 0xff);
+    buffer[index++] = (byte) ((i >>  8) & 0xff);
+    buffer[index++] = (byte) ((i >> 16) & 0xff);
+    buffer[index  ] = (byte) ((i >> 24) & 0xff);
+  }
+
+  @Override
+  public void setFloat(int index, float value) {
+    requestCapacity(index + 4);
+
+    int iValue = Float.floatToRawIntBits(value);
+    buffer[index++] = (byte) ((iValue) & 0xff);
+    buffer[index++] = (byte) ((iValue >>  8) & 0xff);
+    buffer[index++] = (byte) ((iValue >> 16) & 0xff);
+    buffer[index  ] = (byte) ((iValue >> 24) & 0xff);
+  }
+
+  @Override
+  public void setDouble(int index, double value) {
+    requestCapacity(index + 8);
+
+    long lValue = Double.doubleToRawLongBits(value);
+    int i = (int) lValue;
+    buffer[index++] = (byte) ((i) & 0xff);
+    buffer[index++] = (byte) ((i >>  8) & 0xff);
+    buffer[index++] = (byte) ((i >> 16) & 0xff);
+    buffer[index++] = (byte) ((i >> 24) & 0xff);
+    i = (int) (lValue >> 32);
+    buffer[index++] = (byte) ((i) & 0xff);
+    buffer[index++] = (byte) ((i >>  8) & 0xff);
+    buffer[index++] = (byte) ((i >> 16) & 0xff);
+    buffer[index  ] = (byte) ((i >> 24) & 0xff);
+  }
+
+  @Override
+  public int limit() {
+    return writePos;
+  }
+
+  @Override
+  public int writePosition() {
+    return writePos;
+  }
+
+  @Override
+  public boolean requestCapacity(int capacity) {
+    if (capacity < 0) {
+      throw new IllegalArgumentException("Capacity may not be negative (likely a previous int overflow)");
+    }
+    if (buffer.length >= capacity) {
+      return true;
+    }
+    // implemented in the same growing fashion as ArrayList
+    int oldCapacity = buffer.length;
+    int newCapacity = oldCapacity + (oldCapacity >> 1);
+    if (newCapacity < capacity) {  // Note: this also catches newCapacity int overflow
+      newCapacity = capacity;
+    }
+    buffer = Arrays.copyOf(buffer, newCapacity);
+    return true;
+  }
+}
diff --git a/java/com/google/flatbuffers/BaseVector.java b/java/com/google/flatbuffers/BaseVector.java
new file mode 100644
index 0000000..9230da7
--- /dev/null
+++ b/java/com/google/flatbuffers/BaseVector.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2019 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.flatbuffers;
+
+import java.nio.ByteBuffer;
+
+/// @cond FLATBUFFERS_INTERNAL
+
+/**
+ * All vector access objects derive from this class, and add their own accessors.
+ */
+public class BaseVector {
+  /** Used to hold the vector data position. */
+  private int vector;
+  /** Used to hold the vector size. */
+  private int length;
+  /** Used to hold the vector element size in table. */
+  private int element_size;
+  /** The underlying ByteBuffer to hold the data of the vector. */
+  protected ByteBuffer bb;
+
+  /**
+   * Get the start data of a vector.
+   *
+   * @return Returns the start of the vector data.
+   */
+  protected int __vector() {
+    return vector;
+  }
+
+  /**
+   * Gets the element position in vector's ByteBuffer.
+   *
+   * @param j An `int` index of element into a vector.
+   * @return Returns the position of the vector element in a ByteBuffer.
+   */
+  protected int __element(int j) {
+    return vector + j * element_size;
+  }
+
+  /**
+   * Re-init the internal state with an external buffer {@code ByteBuffer}, an offset within and
+   * element size.
+   *
+   * This method exists primarily to allow recycling vector instances without risking memory leaks
+   * due to {@code ByteBuffer} references.
+   */
+  protected void __reset(int _vector, int _element_size, ByteBuffer _bb) { 
+    bb = _bb;
+    if (bb != null) {
+      vector = _vector;
+      length = bb.getInt(_vector - Constants.SIZEOF_INT);
+      element_size = _element_size;
+    } else {
+      vector = 0;
+      length = 0;
+      element_size = 0;
+    }
+  }
+
+  /**
+   * Resets the internal state with a null {@code ByteBuffer} and a zero position.
+   *
+   * This method exists primarily to allow recycling vector instances without risking memory leaks
+   * due to {@code ByteBuffer} references. The instance will be unusable until it is assigned
+   * again to a {@code ByteBuffer}.
+   */
+  public void reset() {
+    __reset(0, 0, null);
+  }
+
+  /**
+   * Get the length of a vector.
+   *
+   * @return Returns the length of the vector.
+   */
+  public int length() {
+    return length;
+  }
+}
+
+/// @endcond
diff --git a/java/com/google/flatbuffers/BooleanVector.java b/java/com/google/flatbuffers/BooleanVector.java
new file mode 100644
index 0000000..1c2a4cd
--- /dev/null
+++ b/java/com/google/flatbuffers/BooleanVector.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2019 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.flatbuffers;
+
+import static com.google.flatbuffers.Constants.*;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+
+/**
+ * Helper type for accessing vector of booleans.
+ */
+public final class BooleanVector extends BaseVector {
+  /**
+   * Assigns vector access object to vector data.
+   *
+   * @param _vector Start data of a vector.
+   * @param _bb Table's ByteBuffer.
+   * @return Returns current vector access object assigned to vector data whose offset is stored at
+   *         `vector`.
+   */
+  public BooleanVector __assign(int _vector, ByteBuffer _bb) {
+    __reset(_vector, Constants.SIZEOF_BYTE, _bb); return this;
+  }
+
+  /**
+   * Reads the boolean at the given index.
+   *
+   * @param j The index from which the boolean will be read.
+   * @return the boolean value at the given index.
+   */
+  public boolean get(int j) { 
+    return 0 != bb.get(__element(j));
+  }
+}
diff --git a/java/com/google/flatbuffers/ByteBufferReadWriteBuf.java b/java/com/google/flatbuffers/ByteBufferReadWriteBuf.java
new file mode 100644
index 0000000..aaf72fe
--- /dev/null
+++ b/java/com/google/flatbuffers/ByteBufferReadWriteBuf.java
@@ -0,0 +1,170 @@
+package com.google.flatbuffers;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+public class ByteBufferReadWriteBuf implements ReadWriteBuf {
+
+  private final ByteBuffer buffer;
+
+  public ByteBufferReadWriteBuf(ByteBuffer bb) {
+    this.buffer = bb;
+    this.buffer.order(ByteOrder.LITTLE_ENDIAN);
+  }
+
+  @Override
+  public void clear() {
+    buffer.clear();
+  }
+
+  @Override
+  public boolean getBoolean(int index) {
+    return get(index) != 0;
+  }
+
+  @Override
+  public byte get(int index) {
+    return buffer.get(index);
+  }
+
+  @Override
+  public short getShort(int index) {
+    return buffer.getShort(index);
+  }
+
+  @Override
+  public int getInt(int index) {
+    return buffer.getInt(index);
+  }
+
+  @Override
+  public long getLong(int index) {
+    return buffer.getLong(index);
+  }
+
+  @Override
+  public float getFloat(int index) {
+    return buffer.getFloat(index);
+  }
+
+  @Override
+  public double getDouble(int index) {
+    return buffer.getDouble(index);
+  }
+
+  @Override
+  public String getString(int start, int size) {
+    return Utf8Safe.decodeUtf8Buffer(buffer, start, size);
+  }
+
+  @Override
+  public byte[] data() {
+    return buffer.array();
+  }
+
+  @Override
+  public void putBoolean(boolean value) {
+    buffer.put(value ? (byte)1 : (byte)0);
+  }
+
+  @Override
+  public void put(byte[] value, int start, int length) {
+    buffer.put(value, start, length);
+  }
+
+  @Override
+  public void put(byte value) {
+    buffer.put(value);
+  }
+
+  @Override
+  public void putShort(short value) {
+    buffer.putShort(value);
+  }
+
+  @Override
+  public void putInt(int value) {
+    buffer.putInt(value);
+  }
+
+  @Override
+  public void putLong(long value) {
+    buffer.putLong(value);
+  }
+
+  @Override
+  public void putFloat(float value) {
+    buffer.putFloat(value);
+  }
+
+  @Override
+  public void putDouble(double value) {
+    buffer.putDouble(value);
+  }
+
+  @Override
+  public void setBoolean(int index, boolean value) {
+    set(index, value ? (byte)1 : (byte)0);
+  }
+
+  @Override
+  public void set(int index, byte value) {
+    requestCapacity(index + 1);
+    buffer.put(index, value);
+  }
+
+  @Override
+  public void set(int index, byte[] value, int start, int length) {
+    requestCapacity(index + (length - start));
+    int curPos = buffer.position();
+    buffer.position(index);
+    buffer.put(value, start, length);
+    buffer.position(curPos);
+  }
+
+  @Override
+  public void setShort(int index, short value) {
+    requestCapacity(index + 2);
+    buffer.putShort(index, value);
+  }
+
+  @Override
+  public void setInt(int index, int value) {
+    requestCapacity(index + 4);
+    buffer.putInt(index, value);
+  }
+
+  @Override
+  public void setLong(int index, long value) {
+    requestCapacity(index + 8);
+    buffer.putLong(index, value);
+  }
+
+  @Override
+  public void setFloat(int index, float value) {
+    requestCapacity(index + 4);
+    buffer.putFloat(index, value);
+  }
+
+  @Override
+  public void setDouble(int index, double value) {
+    requestCapacity(index + 8);
+    buffer.putDouble(index, value);
+  }
+
+  @Override
+  public int writePosition() {
+    return buffer.position();
+  }
+
+  @Override
+  public int limit() {
+    return buffer.limit();
+  }
+
+  @Override
+  public boolean requestCapacity(int capacity) {
+    return capacity <= buffer.limit();
+  }
+
+}
diff --git a/java/com/google/flatbuffers/ByteVector.java b/java/com/google/flatbuffers/ByteVector.java
new file mode 100644
index 0000000..8bc715b
--- /dev/null
+++ b/java/com/google/flatbuffers/ByteVector.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2019 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.flatbuffers;
+
+import static com.google.flatbuffers.Constants.*;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+
+/**
+ * Helper type for accessing vector of signed or unsigned 8-bit values.
+ */
+public final class ByteVector extends BaseVector {
+  /**
+   * Assigns vector access object to vector data.
+   *
+   * @param vector Start data of a vector.
+   * @param bb Table's ByteBuffer.
+   * @return Returns current vector access object assigned to vector data whose offset is stored at
+   *         `vector`.
+   */
+  public ByteVector __assign(int vector, ByteBuffer bb) { 
+    __reset(vector, Constants.SIZEOF_BYTE, bb); return this;
+  }
+
+  /**
+   * Reads the byte at the given index.
+   *
+   * @param j The index from which the byte will be read.
+   * @return the 8-bit value at the given index.
+   */
+  public byte get(int j) {
+     return bb.get(__element(j));
+  }
+
+  /**
+   * Reads the byte at the given index, zero-extends it to type int, and returns the result,
+   * which is therefore in the range 0 through 255.
+   *
+   * @param j The index from which the byte will be read.
+   * @return the unsigned 8-bit at the given index.
+   */
+  public int getAsUnsigned(int j) {
+    return (int) get(j) & 0xFF;
+  }
+}
diff --git a/java/com/google/flatbuffers/Constants.java b/java/com/google/flatbuffers/Constants.java
index e974a80..0623b94 100644
--- a/java/com/google/flatbuffers/Constants.java
+++ b/java/com/google/flatbuffers/Constants.java
@@ -46,7 +46,7 @@
     Changes to the Java implementation need to be sure to change
     the version here and in the code generator on every possible
     incompatible change */
-    public static void FLATBUFFERS_1_11_1() {}
+    public static void FLATBUFFERS_1_12_0() {}
 }
 
 /// @endcond
diff --git a/java/com/google/flatbuffers/DoubleVector.java b/java/com/google/flatbuffers/DoubleVector.java
new file mode 100644
index 0000000..fd4a3a4
--- /dev/null
+++ b/java/com/google/flatbuffers/DoubleVector.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2019 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.flatbuffers;
+
+import static com.google.flatbuffers.Constants.*;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+
+/**
+ * Helper type for accessing vector of double values.
+ */
+public final class DoubleVector extends BaseVector {
+  /**
+   * Assigns vector access object to vector data.
+   *
+   * @param _vector Start data of a vector.
+   * @param _bb Table's ByteBuffer.
+   * @return Returns current vector access object assigned to vector data whose offset is stored at
+   *         `vector`.
+   */
+  public DoubleVector __assign(int _vector, ByteBuffer _bb) {
+     __reset(_vector, Constants.SIZEOF_DOUBLE, _bb); return this;
+  }
+
+  /**
+   * Reads the double value at the given index.
+   *
+   * @param j The index from which the double value will be read.
+   * @return the double value at the given index.
+   */
+  public double get(int j) {
+    return bb.getDouble(__element(j));
+  }
+}
diff --git a/java/com/google/flatbuffers/FlatBufferBuilder.java b/java/com/google/flatbuffers/FlatBufferBuilder.java
index f224610..a954d9f 100644
--- a/java/com/google/flatbuffers/FlatBufferBuilder.java
+++ b/java/com/google/flatbuffers/FlatBufferBuilder.java
@@ -22,6 +22,9 @@
 import java.io.InputStream;
 import java.nio.*;
 import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.lang.Integer;
 
 /// @file
 /// @addtogroup flatbuffers_java_api
@@ -33,22 +36,36 @@
  */
 public class FlatBufferBuilder {
     /// @cond FLATBUFFERS_INTERNAL
-    ByteBuffer bb;                  // Where we construct the FlatBuffer.
-    int space;                      // Remaining space in the ByteBuffer.
-    int minalign = 1;               // Minimum alignment encountered so far.
-    int[] vtable = null;            // The vtable for the current table.
-    int vtable_in_use = 0;          // The amount of fields we're actually using.
-    boolean nested = false;         // Whether we are currently serializing a table.
-    boolean finished = false;       // Whether the buffer is finished.
-    int object_start;               // Starting offset of the current struct/table.
-    int[] vtables = new int[16];    // List of offsets of all vtables.
-    int num_vtables = 0;            // Number of entries in `vtables` in use.
-    int vector_num_elems = 0;       // For the current vector being built.
-    boolean force_defaults = false; // False omits default values from the serialized data.
-    ByteBufferFactory bb_factory;   // Factory for allocating the internal buffer
-    final Utf8 utf8;                // UTF-8 encoder to use
+    ByteBuffer bb;                    // Where we construct the FlatBuffer.
+    int space;                        // Remaining space in the ByteBuffer.
+    int minalign = 1;                 // Minimum alignment encountered so far.
+    int[] vtable = null;              // The vtable for the current table.
+    int vtable_in_use = 0;            // The amount of fields we're actually using.
+    boolean nested = false;           // Whether we are currently serializing a table.
+    boolean finished = false;         // Whether the buffer is finished.
+    int object_start;                 // Starting offset of the current struct/table.
+    int[] vtables = new int[16];      // List of offsets of all vtables.
+    int num_vtables = 0;              // Number of entries in `vtables` in use.
+    int vector_num_elems = 0;         // For the current vector being built.
+    boolean force_defaults = false;   // False omits default values from the serialized data.
+    ByteBufferFactory bb_factory;     // Factory for allocating the internal buffer
+    final Utf8 utf8;                  // UTF-8 encoder to use
+    Map<String, Integer> string_pool; // map used to cache shared strings.
     /// @endcond
 
+
+    /**
+     * Maximum size of buffer to allocate. If we're allocating arrays on the heap,
+     * the header size of the array counts towards its maximum size.
+     */
+    private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
+
+    /**
+     * Default buffer size that is allocated if an initial size is not given, or is
+     * non positive.
+     */
+    private static final int DEFAULT_BUFFER_SIZE = 1024;
+
     /**
      * Start with a buffer of size `initial_size`, then grow as required.
      *
@@ -70,9 +87,8 @@
     public FlatBufferBuilder(int initial_size, ByteBufferFactory bb_factory,
                              ByteBuffer existing_bb, Utf8 utf8) {
         if (initial_size <= 0) {
-          initial_size = 1;
+          initial_size = DEFAULT_BUFFER_SIZE;
         }
-        space = initial_size;
         this.bb_factory = bb_factory;
         if (existing_bb != null) {
           bb = existing_bb;
@@ -82,6 +98,7 @@
           bb = bb_factory.newByteBuffer(initial_size);
         }
         this.utf8 = utf8;
+        space = bb.capacity();
     }
 
    /**
@@ -97,7 +114,7 @@
      * Start with a buffer of 1KiB, then grow as required.
      */
     public FlatBufferBuilder() {
-        this(1024);
+        this(DEFAULT_BUFFER_SIZE);
     }
 
     /**
@@ -147,6 +164,9 @@
         object_start = 0;
         num_vtables = 0;
         vector_num_elems = 0;
+        if (string_pool != null) {
+            string_pool.clear();
+        }
         return this;
     }
 
@@ -199,6 +219,17 @@
         }
     }
 
+   /**
+   * Helper function to test if a field is present in the table
+   *
+   * @param table Flatbuffer table
+   * @param offset virtual table offset
+   * @return true if the filed is present
+   */
+   public static boolean isFieldPresent(Table table, int offset) {
+     return table.__offset(offset) != 0;
+   }
+
     /**
      * Reset the FlatBufferBuilder by purging all data that it holds.
      */
@@ -213,6 +244,9 @@
         object_start = 0;
         num_vtables = 0;
         vector_num_elems = 0;
+        if (string_pool != null) {
+            string_pool.clear();
+        }
     }
 
     /**
@@ -226,11 +260,22 @@
      */
     static ByteBuffer growByteBuffer(ByteBuffer bb, ByteBufferFactory bb_factory) {
         int old_buf_size = bb.capacity();
-        if ((old_buf_size & 0xC0000000) != 0)  // Ensure we don't grow beyond what fits in an int.
-            throw new AssertionError("FlatBuffers: cannot grow buffer beyond 2 gigabytes.");
-        int new_buf_size = old_buf_size == 0 ? 1 : old_buf_size << 1;
+
+        int new_buf_size;
+
+        if (old_buf_size == 0) {
+            new_buf_size = DEFAULT_BUFFER_SIZE;
+        }
+        else {
+            if (old_buf_size == MAX_BUFFER_SIZE) { // Ensure we don't grow beyond what fits in an int.
+                throw new AssertionError("FlatBuffers: cannot grow buffer beyond 2 gigabytes.");
+            }
+            new_buf_size = (old_buf_size & 0xC0000000) != 0 ? MAX_BUFFER_SIZE : old_buf_size << 1;
+        }
+
         bb.position(0);
         ByteBuffer nbb = bb_factory.newByteBuffer(new_buf_size);
+        new_buf_size = nbb.clear().capacity(); // Ensure the returned buffer is treated as empty
         nbb.position(new_buf_size - old_buf_size);
         nbb.put(bb);
         return nbb;
@@ -515,6 +560,37 @@
         return createVectorOfTables(offsets);
     }
 
+    /**
+    * Encode the String `s` in the buffer using UTF-8. If a String with
+    * this exact contents has already been serialized using this method,
+    * instead simply returns the offset of the existing String.
+    *
+    * Usage of the method will incur into additional allocations,
+    * so it is advisable to use it only when it is known upfront that
+    * your message will have several repeated strings.
+    *
+    * @param s The String to encode.
+    * @return The offset in the buffer where the encoded String starts.
+    */
+    public int createSharedString(String s) {
+
+        if (string_pool == null) {
+            string_pool = new HashMap<>();
+            int offset = createString(s);
+            string_pool.put(s, offset);
+            return offset;
+
+        }
+
+        Integer offset = string_pool.get(s);
+
+        if(offset == null) {
+            offset = createString(s);
+            string_pool.put(s, offset);
+        }
+        return offset;
+    }
+
    /**
     * Encode the string `s` in the buffer using UTF-8.  If {@code s} is
     * already a {@link CharBuffer}, this method is allocation free.
@@ -560,6 +636,38 @@
         return endVector();
     }
 
+    /**
+     * Create a byte array in the buffer.
+     *
+     * @param arr a source array with data.
+     * @param offset the offset in the source array to start copying from.
+     * @param length the number of bytes to copy from the source array.
+     * @return The offset in the buffer where the encoded array starts.
+     */
+    public int createByteVector(byte[] arr, int offset, int length) {
+        startVector(1, length, 1);
+        bb.position(space -= length);
+        bb.put(arr, offset, length);
+        return endVector();
+    }
+
+    /**
+     * Create a byte array in the buffer.
+     *
+     * The source {@link ByteBuffer} position is advanced by {@link ByteBuffer#remaining()} places
+     * after this call.
+     *
+     * @param byteBuffer A source {@link ByteBuffer} with data.
+     * @return The offset in the buffer where the encoded array starts.
+     */
+    public int createByteVector(ByteBuffer byteBuffer) {
+        int length = byteBuffer.remaining();
+        startVector(1, length, 1);
+        bb.position(space -= length);
+        bb.put(byteBuffer);
+        return endVector();
+    }
+
    /// @cond FLATBUFFERS_INTERNAL
    /**
     * Should not be accessing the final buffer before it is finished.
diff --git a/java/com/google/flatbuffers/FlexBuffers.java b/java/com/google/flatbuffers/FlexBuffers.java
new file mode 100644
index 0000000..8263f9a
--- /dev/null
+++ b/java/com/google/flatbuffers/FlexBuffers.java
@@ -0,0 +1,1211 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.flatbuffers;
+
+
+import static com.google.flatbuffers.FlexBuffers.Unsigned.byteToUnsignedInt;
+import static com.google.flatbuffers.FlexBuffers.Unsigned.intToUnsignedLong;
+import static com.google.flatbuffers.FlexBuffers.Unsigned.shortToUnsignedInt;
+
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+
+/// @file
+/// @addtogroup flatbuffers_java_api
+/// @{
+
+/**
+ * This class can be used to parse FlexBuffer messages.
+ * <p>
+ * For generating FlexBuffer messages, use {@link FlexBuffersBuilder}.
+ * <p>
+ * Example of usage:
+ * <pre>
+ * ReadBuf bb = ... // load message from file or network
+ * FlexBuffers.Reference r = FlexBuffers.getRoot(bb); // Reads the root element
+ * FlexBuffers.Map map = r.asMap(); // We assumed root object is a map
+ * System.out.println(map.get("name").asString()); // prints element with key "name"
+ * </pre>
+ */
+public class FlexBuffers {
+
+    // These are used as the upper 6 bits of a type field to indicate the actual
+    // type.
+    /** Represent a null type */
+    public static final int FBT_NULL = 0;
+    /** Represent a signed integer type */
+    public static final int FBT_INT = 1;
+    /** Represent a unsigned type */
+    public static final int FBT_UINT = 2;
+    /** Represent a float type */
+    public static final int FBT_FLOAT = 3; // Types above stored inline, types below store an offset.
+    /** Represent a key to a map type */
+    public static final int FBT_KEY = 4;
+    /** Represent a string type */
+    public static final int FBT_STRING = 5;
+    /** Represent a indirect signed integer type */
+    public static final int FBT_INDIRECT_INT = 6;
+    /** Represent a indirect unsigned integer type */
+    public static final int FBT_INDIRECT_UINT = 7;
+    /** Represent a indirect float type */
+    public static final int FBT_INDIRECT_FLOAT = 8;
+    /** Represent a map type */
+    public static final int FBT_MAP = 9;
+    /** Represent a vector type */
+    public static final int FBT_VECTOR = 10; // Untyped.
+    /** Represent a vector of signed integers type */
+    public static final int FBT_VECTOR_INT = 11;  // Typed any size  = stores no type table).
+    /** Represent a vector of unsigned integers type */
+    public static final int FBT_VECTOR_UINT = 12;
+    /** Represent a vector of floats type */
+    public static final int FBT_VECTOR_FLOAT = 13;
+    /** Represent a vector of keys type */
+    public static final int FBT_VECTOR_KEY = 14;
+    /** Represent a vector of strings type */
+    // DEPRECATED, use FBT_VECTOR or FBT_VECTOR_KEY instead.
+    // more info on thttps://github.com/google/flatbuffers/issues/5627.
+    public static final int FBT_VECTOR_STRING_DEPRECATED = 15;
+
+    /// @cond FLATBUFFERS_INTERNAL
+    public static final int FBT_VECTOR_INT2 = 16;  // Typed tuple  = no type table; no size field).
+    public static final int FBT_VECTOR_UINT2 = 17;
+    public static final int FBT_VECTOR_FLOAT2 = 18;
+    public static final int FBT_VECTOR_INT3 = 19;  // Typed triple  = no type table; no size field).
+    public static final int FBT_VECTOR_UINT3 = 20;
+    public static final int FBT_VECTOR_FLOAT3 = 21;
+    public static final int FBT_VECTOR_INT4 = 22;  // Typed quad  = no type table; no size field).
+    public static final int FBT_VECTOR_UINT4 = 23;
+    public static final int FBT_VECTOR_FLOAT4 = 24;
+    /// @endcond FLATBUFFERS_INTERNAL
+
+    /** Represent a blob type */
+    public static final int FBT_BLOB = 25;
+    /** Represent a boolean type */
+    public static final int FBT_BOOL = 26;
+    /** Represent a vector of booleans type */
+    public static final int FBT_VECTOR_BOOL = 36;  // To Allow the same type of conversion of type to vector type
+
+    private static final ReadBuf EMPTY_BB = new ArrayReadWriteBuf(new byte[] {0}, 1);
+
+    /**
+     * Checks where a type is a typed vector
+     *
+     * @param type type to be checked
+     * @return true if typed vector
+     */
+    static boolean isTypedVector(int type) {
+        return (type >= FBT_VECTOR_INT && type <= FBT_VECTOR_STRING_DEPRECATED) || type == FBT_VECTOR_BOOL;
+    }
+
+    /**
+     * Check whether you can access type directly (no indirection) or not.
+     *
+     * @param type type to be checked
+     * @return true if inline type
+     */
+    static boolean isTypeInline(int type) {
+        return type <= FBT_FLOAT || type == FBT_BOOL;
+    }
+
+    static int toTypedVectorElementType(int original_type) {
+        return original_type - FBT_VECTOR_INT + FBT_INT;
+    }
+
+    /**
+     * Return a vector type our of a original element type
+     *
+     * @param type        element type
+     * @param fixedLength size of element
+     * @return typed vector type
+     */
+    static int toTypedVector(int type, int fixedLength) {
+        assert (isTypedVectorElementType(type));
+        switch (fixedLength) {
+            case 0: return type - FBT_INT + FBT_VECTOR_INT;
+            case 2: return type - FBT_INT + FBT_VECTOR_INT2;
+            case 3: return type - FBT_INT + FBT_VECTOR_INT3;
+            case 4: return type - FBT_INT + FBT_VECTOR_INT4;
+            default:
+                assert (false);
+                return FBT_NULL;
+        }
+    }
+
+    static boolean isTypedVectorElementType(int type) {
+        return (type >= FBT_INT && type <= FBT_KEY) || type == FBT_BOOL;
+    }
+
+    // return position of the element that the offset is pointing to
+    private static int indirect(ReadBuf bb, int offset, int byteWidth) {
+        // we assume all offset fits on a int, since ReadBuf operates with that assumption
+        return (int) (offset - readUInt(bb, offset, byteWidth));
+    }
+
+    // read unsigned int with size byteWidth and return as a 64-bit integer
+    private static long readUInt(ReadBuf buff, int end, int byteWidth) {
+        switch (byteWidth) {
+            case 1: return byteToUnsignedInt(buff.get(end));
+            case 2: return shortToUnsignedInt(buff.getShort(end));
+            case 4: return intToUnsignedLong(buff.getInt(end));
+            case 8: return buff.getLong(end); // We are passing signed long here. Losing information (user should know)
+            default: return -1; // we should never reach here
+        }
+    }
+
+    // read signed int of size byteWidth and return as 32-bit int
+    private static int readInt(ReadBuf buff, int end, int byteWidth) {
+        return (int) readLong(buff, end, byteWidth);
+    }
+
+    // read signed int of size byteWidth and return as 64-bit int
+    private static long readLong(ReadBuf buff, int end, int byteWidth) {
+        switch (byteWidth) {
+            case 1: return buff.get(end);
+            case 2: return buff.getShort(end);
+            case 4: return buff.getInt(end);
+            case 8: return buff.getLong(end);
+            default: return -1; // we should never reach here
+        }
+    }
+
+    private static double readDouble(ReadBuf buff, int end, int byteWidth) {
+        switch (byteWidth) {
+            case 4: return buff.getFloat(end);
+            case 8: return buff.getDouble(end);
+            default: return -1; // we should never reach here
+        }
+    }
+
+    /**
+     * Reads a FlexBuffer message in ReadBuf and returns {@link Reference} to
+     * the root element.
+     * @param buffer ReadBuf containing FlexBuffer message
+     * @return {@link Reference} to the root object
+     */
+    @Deprecated
+    public static Reference getRoot(ByteBuffer buffer) {
+        return getRoot( buffer.hasArray() ? new ArrayReadWriteBuf(buffer.array(), buffer.limit()) : new ByteBufferReadWriteBuf(buffer));
+    }
+
+        /**
+     * Reads a FlexBuffer message in ReadBuf and returns {@link Reference} to
+     * the root element.
+     * @param buffer ReadBuf containing FlexBuffer message
+     * @return {@link Reference} to the root object
+     */
+    public static Reference getRoot(ReadBuf buffer) {
+        // See Finish() below for the serialization counterpart of this.
+        // The root ends at the end of the buffer, so we parse backwards from there.
+        int end = buffer.limit();
+        int byteWidth = buffer.get(--end);
+        int packetType = byteToUnsignedInt(buffer.get(--end));
+        end -= byteWidth;  // The root data item.
+        return new Reference(buffer, end, byteWidth, packetType);
+    }
+
+    /**
+     * Represents an generic element in the buffer.
+     */
+    public static class Reference {
+
+        private static final Reference NULL_REFERENCE = new Reference(EMPTY_BB, 0, 1, 0);
+        private ReadBuf bb;
+        private int end;
+        private int parentWidth;
+        private int byteWidth;
+        private int type;
+
+        Reference(ReadBuf bb, int end, int parentWidth, int packedType) {
+            this(bb, end, parentWidth, (1 << (packedType & 3)), packedType >> 2);
+        }
+
+        Reference(ReadBuf bb, int end, int parentWidth, int byteWidth, int type) {
+            this.bb = bb;
+            this.end = end;
+            this.parentWidth = parentWidth;
+            this.byteWidth = byteWidth;
+            this.type = type;
+        }
+
+        /**
+         * Return element type
+         * @return element type as integer
+         */
+        public int getType() {
+            return type;
+        }
+
+        /**
+         * Checks whether the element is null type
+         * @return true if null type
+         */
+        public boolean isNull() {
+            return type == FBT_NULL;
+        }
+
+        /**
+         * Checks whether the element is boolean type
+         * @return true if boolean type
+         */
+        public boolean isBoolean() {
+            return type == FBT_BOOL;
+        }
+
+        /**
+         * Checks whether the element type is numeric (signed/unsigned integers and floats)
+         * @return true if numeric type
+         */
+        public boolean isNumeric() {
+            return isIntOrUInt() || isFloat();
+        }
+
+        /**
+         * Checks whether the element type is signed or unsigned integers
+         * @return true if an integer type
+         */
+        public boolean isIntOrUInt() {
+            return isInt() || isUInt();
+        }
+
+        /**
+         * Checks whether the element type is float
+         * @return true if a float type
+         */
+        public boolean isFloat() {
+            return type == FBT_FLOAT || type == FBT_INDIRECT_FLOAT;
+        }
+
+        /**
+         * Checks whether the element type is signed integer
+         * @return true if a signed integer type
+         */
+        public boolean isInt() {
+            return type == FBT_INT || type == FBT_INDIRECT_INT;
+        }
+
+        /**
+         * Checks whether the element type is signed integer
+         * @return true if a signed integer type
+         */
+        public boolean isUInt() {
+            return type == FBT_UINT || type == FBT_INDIRECT_UINT;
+        }
+
+        /**
+         * Checks whether the element type is string
+         * @return true if a string type
+         */
+        public boolean isString() {
+            return type == FBT_STRING;
+        }
+
+        /**
+         * Checks whether the element type is key
+         * @return true if a key type
+         */
+        public boolean isKey() {
+            return type == FBT_KEY;
+        }
+
+        /**
+         * Checks whether the element type is vector
+         * @return true if a vector type
+         */
+        public boolean isVector() {
+            return type == FBT_VECTOR || type == FBT_MAP;
+        }
+
+        /**
+         * Checks whether the element type is typed vector
+         * @return true if a typed vector type
+         */
+        public boolean isTypedVector() {
+            return FlexBuffers.isTypedVector(type);
+        }
+
+        /**
+         * Checks whether the element type is a map
+         * @return true if a map type
+         */
+        public boolean isMap() {
+            return type == FBT_MAP;
+        }
+
+        /**
+         * Checks whether the element type is a blob
+         * @return true if a blob type
+         */
+        public boolean isBlob() {
+            return type == FBT_BLOB;
+        }
+
+        /**
+         * Returns element as 32-bit integer.
+         * <p> For vector element, it will return size of the vector</p>
+         * <p> For String element, it will type to be parsed as integer</p>
+         * <p> Unsigned elements will become negative</p>
+         * <p> Float elements will be casted to integer </p>
+         * @return 32-bit integer or 0 if fail to convert element to integer.
+         */
+        public int asInt() {
+            if (type == FBT_INT) {
+                // A fast path for the common case.
+                return readInt(bb, end, parentWidth);
+            } else
+                switch (type) {
+                    case FBT_INDIRECT_INT: return readInt(bb, indirect(bb, end, parentWidth), byteWidth);
+                    case FBT_UINT: return (int) readUInt(bb, end, parentWidth);
+                    case FBT_INDIRECT_UINT: return (int) readUInt(bb, indirect(bb, end, parentWidth), parentWidth);
+                    case FBT_FLOAT: return (int) readDouble(bb, end, parentWidth);
+                    case FBT_INDIRECT_FLOAT: return (int) readDouble(bb, indirect(bb, end, parentWidth), byteWidth);
+                    case FBT_NULL: return 0;
+                    case FBT_STRING: return Integer.parseInt(asString());
+                    case FBT_VECTOR: return asVector().size();
+                    case FBT_BOOL: return readInt(bb, end, parentWidth);
+                    default:
+                        // Convert other things to int.
+                        return 0;
+                }
+        }
+
+        /**
+         * Returns element as unsigned 64-bit integer.
+         * <p> For vector element, it will return size of the vector</p>
+         * <p> For String element, it will type to be parsed as integer</p>
+         * <p> Negative signed elements will become unsigned counterpart</p>
+         * <p> Float elements will be casted to integer </p>
+         * @return 64-bit integer or 0 if fail to convert element to integer.
+         */
+        public long asUInt() {
+            if (type == FBT_UINT) {
+                // A fast path for the common case.
+                return readUInt(bb, end, parentWidth);
+            } else
+                switch (type) {
+                    case FBT_INDIRECT_UINT: return readUInt(bb, indirect(bb, end, parentWidth), byteWidth);
+                    case FBT_INT: return readLong(bb, end, parentWidth);
+                    case FBT_INDIRECT_INT: return readLong(bb, indirect(bb, end, parentWidth), byteWidth);
+                    case FBT_FLOAT: return (long) readDouble(bb, end, parentWidth);
+                    case FBT_INDIRECT_FLOAT: return (long) readDouble(bb,  indirect(bb, end, parentWidth), parentWidth);
+                    case FBT_NULL: return 0;
+                    case FBT_STRING: return Long.parseLong(asString());
+                    case FBT_VECTOR: return asVector().size();
+                    case FBT_BOOL: return readInt(bb, end, parentWidth);
+                    default:
+                        // Convert other things to uint.
+                        return 0;
+                }
+        }
+
+        /**
+         * Returns element as 64-bit integer.
+         * <p> For vector element, it will return size of the vector</p>
+         * <p> For String element, it will type to be parsed as integer</p>
+         * <p> Unsigned elements will become negative</p>
+         * <p> Float elements will be casted to integer </p>
+         * @return 64-bit integer or 0 if fail to convert element to long.
+         */
+        public long asLong() {
+            if (type == FBT_INT) {
+                // A fast path for the common case.
+                return readLong(bb, end, parentWidth);
+            } else
+                switch (type) {
+                    case FBT_INDIRECT_INT: return readLong(bb, indirect(bb, end, parentWidth), byteWidth);
+                    case FBT_UINT: return readUInt(bb, end, parentWidth);
+                    case FBT_INDIRECT_UINT: return readUInt(bb, indirect(bb, end, parentWidth), parentWidth);
+                    case FBT_FLOAT: return (long) readDouble(bb, end, parentWidth);
+                    case FBT_INDIRECT_FLOAT: return (long) readDouble(bb, indirect(bb, end, parentWidth), byteWidth);
+                    case FBT_NULL: return 0;
+                    case FBT_STRING: {
+                        try {
+                            return Long.parseLong(asString());
+                        } catch (NumberFormatException nfe) {
+                            return 0; //same as C++ implementation
+                        }
+                    }
+                    case FBT_VECTOR: return asVector().size();
+                    case FBT_BOOL: return readInt(bb, end, parentWidth);
+                    default:
+                        // Convert other things to int.
+                        return 0;
+                }
+        }
+
+        /**
+         * Returns element as 64-bit integer.
+         * <p> For vector element, it will return size of the vector</p>
+         * <p> For String element, it will type to be parsed as integer</p>
+         * @return 64-bit integer or 0 if fail to convert element to long.
+         */
+        public double asFloat() {
+            if (type == FBT_FLOAT) {
+                // A fast path for the common case.
+                return readDouble(bb, end, parentWidth);
+            } else
+                switch (type) {
+                    case FBT_INDIRECT_FLOAT: return readDouble(bb, indirect(bb, end, parentWidth), byteWidth);
+                    case FBT_INT: return readInt(bb, end, parentWidth);
+                    case FBT_UINT:
+                    case FBT_BOOL:
+                        return readUInt(bb, end, parentWidth);
+                    case FBT_INDIRECT_INT: return readInt(bb, indirect(bb, end, parentWidth), byteWidth);
+                    case FBT_INDIRECT_UINT: return readUInt(bb, indirect(bb, end, parentWidth), byteWidth);
+                    case FBT_NULL: return 0.0;
+                    case FBT_STRING: return Double.parseDouble(asString());
+                    case FBT_VECTOR: return asVector().size();
+                    default:
+                        // Convert strings and other things to float.
+                        return 0;
+                }
+        }
+
+        /**
+         * Returns element as a {@link Key}
+         * @return key or {@link Key#empty()} if element is not a key
+         */
+        public Key asKey() {
+            if (isKey()) {
+                return new Key(bb, indirect(bb, end, parentWidth), byteWidth);
+            } else {
+                return Key.empty();
+            }
+        }
+
+        /**
+         * Returns element as a `String`
+         * @return element as `String` or empty `String` if fail
+         */
+        public String asString() {
+            if (isString()) {
+                int start = indirect(bb, end, parentWidth);
+                int size = (int) readUInt(bb, start - byteWidth, byteWidth);
+                return bb.getString(start, size);
+            }
+            else if (isKey()){
+                int start = indirect(bb, end, byteWidth);
+                for (int i = start; ; i++) {
+                    if (bb.get(i) == 0) {
+                        return bb.getString(start, i - start);
+                    }
+                }
+            } else {
+                return "";
+            }
+        }
+
+        /**
+         * Returns element as a {@link Map}
+         * @return element as {@link Map} or empty {@link Map} if fail
+         */
+        public Map asMap() {
+            if (isMap()) {
+                return new Map(bb, indirect(bb, end, parentWidth), byteWidth);
+            } else {
+                return Map.empty();
+            }
+        }
+
+        /**
+         * Returns element as a {@link Vector}
+         * @return element as {@link Vector} or empty {@link Vector} if fail
+         */
+        public Vector asVector() {
+            if (isVector()) {
+                return new Vector(bb, indirect(bb, end, parentWidth), byteWidth);
+            } else if(type == FlexBuffers.FBT_VECTOR_STRING_DEPRECATED) {
+                // deprecated. Should be treated as key vector
+                return new TypedVector(bb, indirect(bb, end, parentWidth), byteWidth, FlexBuffers.FBT_KEY);
+            } else if (FlexBuffers.isTypedVector(type)) {
+                return new TypedVector(bb, indirect(bb, end, parentWidth), byteWidth, FlexBuffers.toTypedVectorElementType(type));
+            } else {
+                return Vector.empty();
+            }
+        }
+
+        /**
+         * Returns element as a {@link Blob}
+         * @return element as {@link Blob} or empty {@link Blob} if fail
+         */
+        public Blob asBlob() {
+            if (isBlob() || isString()) {
+                return new Blob(bb, indirect(bb, end, parentWidth), byteWidth);
+            } else {
+                return Blob.empty();
+            }
+        }
+
+        /**
+         * Returns element as a boolean
+         * <p>If element type is not boolean, it will be casted to integer and compared against 0</p>
+         * @return element as boolean
+         */
+        public boolean asBoolean() {
+            if (isBoolean()) {
+                return bb.get(end) != 0;
+            }
+            return asUInt() != 0;
+        }
+
+        /**
+         * Returns text representation of the element (JSON)
+         * @return String containing text representation of the element
+         */
+        @Override
+        public String toString() {
+            return toString(new StringBuilder(128)).toString();
+        }
+
+        /**
+         * Appends a text(JSON) representation to a `StringBuilder`
+         */
+        StringBuilder toString(StringBuilder sb) {
+            //TODO: Original C++ implementation escape strings.
+            // probably we should do it as well.
+            switch (type) {
+                case FBT_NULL:
+                    return sb.append("null");
+                case FBT_INT:
+                case FBT_INDIRECT_INT:
+                    return sb.append(asLong());
+                case FBT_UINT:
+                case FBT_INDIRECT_UINT:
+                    return sb.append(asUInt());
+                case FBT_INDIRECT_FLOAT:
+                case FBT_FLOAT:
+                    return sb.append(asFloat());
+                case FBT_KEY:
+                    return asKey().toString(sb.append('"')).append('"');
+                case FBT_STRING:
+                    return sb.append('"').append(asString()).append('"');
+                case FBT_MAP:
+                    return asMap().toString(sb);
+                case FBT_VECTOR:
+                    return asVector().toString(sb);
+                case FBT_BLOB:
+                    return asBlob().toString(sb);
+                case FBT_BOOL:
+                    return sb.append(asBoolean());
+                case FBT_VECTOR_INT:
+                case FBT_VECTOR_UINT:
+                case FBT_VECTOR_FLOAT:
+                case FBT_VECTOR_KEY:
+                case FBT_VECTOR_STRING_DEPRECATED:
+                case FBT_VECTOR_BOOL:
+                    return sb.append(asVector());
+                case FBT_VECTOR_INT2:
+                case FBT_VECTOR_UINT2:
+                case FBT_VECTOR_FLOAT2:
+                case FBT_VECTOR_INT3:
+                case FBT_VECTOR_UINT3:
+                case FBT_VECTOR_FLOAT3:
+                case FBT_VECTOR_INT4:
+                case FBT_VECTOR_UINT4:
+                case FBT_VECTOR_FLOAT4:
+
+                    throw new FlexBufferException("not_implemented:" + type);
+                default:
+                    return sb;
+            }
+        }
+    }
+
+    /**
+     * Base class of all types below.
+     * Points into the data buffer and allows access to one type.
+     */
+    private static abstract class Object {
+        ReadBuf bb;
+        int end;
+        int byteWidth;
+
+        Object(ReadBuf buff, int end, int byteWidth) {
+            this.bb = buff;
+            this.end = end;
+            this.byteWidth = byteWidth;
+        }
+
+        @Override
+        public String toString() {
+            return toString(new StringBuilder(128)).toString();
+        }
+
+        public abstract StringBuilder toString(StringBuilder sb);
+    }
+
+    // Stores size in `byte_width_` bytes before end position.
+    private static abstract class Sized extends Object {
+
+        protected final int size;
+
+        Sized(ReadBuf buff, int end, int byteWidth) {
+            super(buff, end, byteWidth);
+            size = readInt(bb, end - byteWidth, byteWidth);
+        }
+
+        public int size() {
+            return size;
+        }
+    }
+
+    /**
+     * Represents a array of bytes element in the buffer
+     *
+     * <p>It can be converted to `ReadBuf` using {@link data()},
+     * copied into a byte[] using {@link getBytes()} or
+     * have individual bytes accessed individually using {@link get(int)}</p>
+     */
+    public static class Blob extends Sized {
+        static final Blob EMPTY = new Blob(EMPTY_BB, 1, 1);
+
+        Blob(ReadBuf buff, int end, int byteWidth) {
+            super(buff, end, byteWidth);
+        }
+
+        /** Return an empty {@link Blob} */
+        public static Blob empty() {
+            return EMPTY;
+        }
+
+        /**
+         * Return {@link Blob} as `ReadBuf`
+         * @return blob as `ReadBuf`
+         */
+        public ByteBuffer data() {
+            ByteBuffer dup = ByteBuffer.wrap(bb.data());
+            dup.position(end);
+            dup.limit(end + size());
+            return dup.asReadOnlyBuffer().slice();
+        }
+
+        /**
+         * Copy blob into a byte[]
+         * @return blob as a byte[]
+         */
+        public byte[] getBytes() {
+            int size = size();
+            byte[] result = new byte[size];
+            for (int i = 0; i < size; i++) {
+                result[i] = bb.get(end + i);
+            }
+            return result;
+        }
+
+        /**
+         * Return individual byte at a given position
+         * @param pos position of the byte to be read
+         */
+        public byte get(int pos) {
+            assert pos >=0 && pos <= size();
+            return bb.get(end + pos);
+        }
+
+        /**
+         * Returns a text(JSON) representation of the {@link Blob}
+         */
+        @Override
+        public String toString() {
+            return bb.getString(end, size());
+        }
+
+        /**
+         * Append a text(JSON) representation of the {@link Blob} into a `StringBuilder`
+         */
+        @Override
+        public StringBuilder toString(StringBuilder sb) {
+            sb.append('"');
+            sb.append(bb.getString(end, size()));
+            return sb.append('"');
+        }
+    }
+
+    /**
+     * Represents a key element in the buffer. Keys are
+     * used to reference objects in a {@link Map}
+     */
+    public static class Key extends Object {
+
+        private static final Key EMPTY = new Key(EMPTY_BB, 0, 0);
+
+        Key(ReadBuf buff, int end, int byteWidth) {
+            super(buff, end, byteWidth);
+        }
+
+        /**
+         * Return an empty {@link Key}
+         * @return empty {@link Key}
+         * */
+        public static Key empty() {
+            return Key.EMPTY;
+        }
+
+        /**
+         * Appends a text(JSON) representation to a `StringBuilder`
+         */
+        @Override
+        public StringBuilder toString(StringBuilder sb) {
+            return sb.append(toString());
+        }
+
+        @Override
+        public String toString() {
+            int size;
+            for (int i = end; ; i++) {
+                if (bb.get(i) == 0) {
+                    size = i - end;
+                    break;
+                }
+            }
+            return bb.getString(end, size);
+        }
+
+        int compareTo(byte[] other) {
+            int ia = end;
+            int io = 0;
+            byte c1, c2;
+            do {
+                c1 = bb.get(ia);
+                c2 = other[io];
+                if (c1 == '\0')
+                    return c1 - c2;
+                ia++;
+                io++;
+                if (io == other.length) {
+                    // in our buffer we have an additional \0 byte
+                    // but this does not exist in regular Java strings, so we return now
+                    return c1 - c2;
+                }
+            }
+            while (c1 == c2);
+            return c1 - c2;
+        }
+
+        /**
+         *  Compare keys
+         *  @param obj other key to compare
+         *  @return true if keys are the same
+         */
+        @Override
+        public boolean equals(java.lang.Object obj) {
+            if (!(obj instanceof Key))
+                return false;
+
+            return ((Key) obj).end == end && ((Key) obj).byteWidth == byteWidth;
+        }
+
+        public int hashCode() {
+          return end ^ byteWidth;
+        }
+    }
+
+    /**
+     * Map object representing a set of key-value pairs.
+     */
+    public static class Map extends Vector {
+        private static final Map EMPTY_MAP = new Map(EMPTY_BB, 1, 1);
+        // cache for converting UTF-8 codepoints into
+        // Java chars. Used to speed up String comparison
+        private final byte[] comparisonBuffer = new byte[4];
+
+        Map(ReadBuf bb, int end, int byteWidth) {
+            super(bb, end, byteWidth);
+        }
+
+        /**
+         * Returns an empty {@link Map}
+         * @return an empty {@link Map}
+         */
+        public static Map empty() {
+            return EMPTY_MAP;
+        }
+
+        /**
+         * @param key access key to element on map
+         * @return reference to value in map
+         */
+        public Reference get(String key) {
+            int index = binarySearch(key);
+            if (index >= 0 && index < size) {
+                return get(index);
+            }
+            return Reference.NULL_REFERENCE;
+        }
+
+        /**
+         * @param key access key to element on map. Keys are assumed to be encoded in UTF-8
+         * @return reference to value in map
+         */
+        public Reference get(byte[] key) {
+            int index = binarySearch(key);
+            if (index >= 0 && index < size) {
+                return get(index);
+            }
+            return Reference.NULL_REFERENCE;
+        }
+
+        /**
+         * Get a vector or keys in the map
+         *
+         * @return vector of keys
+         */
+        public KeyVector keys() {
+            final int num_prefixed_fields = 3;
+            int keysOffset = end - (byteWidth * num_prefixed_fields);
+            return new KeyVector(new TypedVector(bb,
+                    indirect(bb, keysOffset, byteWidth),
+                    readInt(bb, keysOffset + byteWidth, byteWidth),
+                    FBT_KEY));
+        }
+
+        /**
+         * @return {@code Vector} of values from map
+         */
+        public Vector values() {
+            return new Vector(bb, end, byteWidth);
+        }
+
+        /**
+         * Writes text (json) representation of map in a {@code StringBuilder}.
+         *
+         * @param builder {@code StringBuilder} to be appended to
+         * @return Same {@code StringBuilder} with appended text
+         */
+        public StringBuilder toString(StringBuilder builder) {
+            builder.append("{ ");
+            KeyVector keys = keys();
+            int size = size();
+            Vector vals = values();
+            for (int i = 0; i < size; i++) {
+                builder.append('"')
+                        .append(keys.get(i).toString())
+                        .append("\" : ");
+                builder.append(vals.get(i).toString());
+                if (i != size - 1)
+                    builder.append(", ");
+            }
+            builder.append(" }");
+            return builder;
+        }
+
+        // Performs a binary search on a key vector and return index of the key in key vector
+        private int binarySearch(CharSequence searchedKey) {
+            int low = 0;
+            int high = size - 1;
+            final int num_prefixed_fields = 3;
+            int keysOffset = end - (byteWidth * num_prefixed_fields);
+            int keysStart = indirect(bb, keysOffset, byteWidth);
+            int keyByteWidth = readInt(bb, keysOffset + byteWidth, byteWidth);
+            while (low <= high) {
+                int mid = (low + high) >>> 1;
+                int keyPos = indirect(bb, keysStart + mid * keyByteWidth, keyByteWidth);
+                int cmp = compareCharSequence(keyPos, searchedKey);
+                if (cmp < 0)
+                    low = mid + 1;
+                else if (cmp > 0)
+                    high = mid - 1;
+                else
+                    return mid; // key found
+            }
+            return -(low + 1);  // key not found
+        }
+
+        private int binarySearch(byte[] searchedKey) {
+            int low = 0;
+            int high = size - 1;
+            final int num_prefixed_fields = 3;
+            int keysOffset = end - (byteWidth * num_prefixed_fields);
+            int keysStart = indirect(bb, keysOffset, byteWidth);
+            int keyByteWidth = readInt(bb, keysOffset + byteWidth, byteWidth);
+
+            while (low <= high) {
+                int mid = (low + high) >>> 1;
+                int keyPos = indirect(bb, keysStart + mid * keyByteWidth, keyByteWidth);
+                int cmp = compareBytes(bb, keyPos, searchedKey);
+                if (cmp < 0)
+                    low = mid + 1;
+                else if (cmp > 0)
+                    high = mid - 1;
+                else
+                    return mid; // key found
+            }
+            return -(low + 1);  // key not found
+        }
+
+        // compares a byte[] against a FBT_KEY
+        private int compareBytes(ReadBuf bb, int start, byte[] other) {
+            int l1 = start;
+            int l2 = 0;
+            byte c1, c2;
+            do {
+                c1 = bb.get(l1);
+                c2 = other[l2];
+                if (c1 == '\0')
+                    return c1 - c2;
+                l1++;
+                l2++;
+                if (l2 == other.length) {
+                    // in our buffer we have an additional \0 byte
+                    // but this does not exist in regular Java strings, so we return now
+                    return c1 - c2;
+                }
+            }
+            while (c1 == c2);
+            return c1 - c2;
+        }
+
+        // compares a CharSequence against a FBT_KEY
+        private int compareCharSequence(int start, CharSequence other) {
+            int bufferPos = start;
+            int otherPos = 0;
+            int limit = bb.limit();
+            int otherLimit = other.length();
+
+            // special loop for ASCII characters. Most of keys should be ASCII only, so this
+            // loop should be optimized for that.
+            // breaks if a multi-byte character is found
+            while (otherPos < otherLimit) {
+                char c2 = other.charAt(otherPos);
+
+                if (c2 >= 0x80) {
+                    // not a single byte codepoint
+                    break;
+                }
+
+                byte b = bb.get(bufferPos);
+
+                if (b == 0) {
+                    return -c2;
+                } else if (b < 0) {
+                    break;
+                } else if ((char) b != c2) {
+                    return b - c2;
+                }
+                ++bufferPos;
+                ++otherPos;
+            }
+
+            while (bufferPos < limit) {
+
+                int sizeInBuff = Utf8.encodeUtf8CodePoint(other, otherPos, comparisonBuffer);
+
+                if (sizeInBuff == 0) {
+                    // That means we finish with other and there are not more chars to
+                    // compare. String in the buffer is bigger.
+                    return bb.get(bufferPos);
+                }
+
+                for (int i = 0; i < sizeInBuff; i++) {
+                    byte bufferByte = bb.get(bufferPos++);
+                    byte otherByte = comparisonBuffer[i];
+                    if (bufferByte == 0) {
+                        // Our key is finished, so other is bigger
+                        return -otherByte;
+                    } else if (bufferByte != otherByte) {
+                        return bufferByte - otherByte;
+                    }
+                }
+
+                otherPos += sizeInBuff == 4 ? 2 : 1;
+            }
+            return 0;
+        }
+    }
+
+    /**
+     * Object that represents a set of elements in the buffer
+     */
+    public static class Vector extends Sized {
+
+        private static final Vector EMPTY_VECTOR = new Vector(EMPTY_BB, 1, 1);
+
+        Vector(ReadBuf bb, int end, int byteWidth) {
+            super(bb, end, byteWidth);
+        }
+
+        /**
+         * Returns an empty {@link Map}
+         * @return an empty {@link Map}
+         */
+        public static Vector empty() {
+            return EMPTY_VECTOR;
+        }
+
+        /**
+         * Checks if the vector is empty
+         * @return true if vector is empty
+         */
+        public boolean isEmpty() {
+            return this == EMPTY_VECTOR;
+        }
+
+        /**
+         * Appends a text(JSON) representation to a `StringBuilder`
+         */
+        @Override
+        public StringBuilder toString(StringBuilder sb) {
+            sb.append("[ ");
+            int size = size();
+            for (int i = 0; i < size; i++) {
+                get(i).toString(sb);
+                if (i != size - 1) {
+                    sb.append(", ");
+                }
+            }
+            sb.append(" ]");
+            return sb;
+        }
+
+        /**
+         * Get a element in a vector by index
+         *
+         * @param index position of the element
+         * @return {@code Reference} to the element
+         */
+        public Reference get(int index) {
+            long len = size();
+            if (index >= len) {
+                return Reference.NULL_REFERENCE;
+            }
+            int packedType = byteToUnsignedInt(bb.get((int) (end + (len * byteWidth) + index)));
+            int obj_end = end + index * byteWidth;
+            return new Reference(bb, obj_end, byteWidth, packedType);
+        }
+    }
+
+    /**
+     * Object that represents a set of elements with the same type
+     */
+    public static class TypedVector extends Vector {
+
+        private static final TypedVector EMPTY_VECTOR = new TypedVector(EMPTY_BB, 1, 1, FBT_INT);
+
+        private final int elemType;
+
+        TypedVector(ReadBuf bb, int end, int byteWidth, int elemType) {
+            super(bb, end, byteWidth);
+            this.elemType = elemType;
+        }
+
+        public static TypedVector empty() {
+            return EMPTY_VECTOR;
+        }
+
+        /**
+         * Returns whether the vector is empty
+         *
+         * @return true if empty
+         */
+        public boolean isEmptyVector() {
+            return this == EMPTY_VECTOR;
+        }
+
+        /**
+         * Return element type for all elements in the vector
+         *
+         * @return element type
+         */
+        public int getElemType() {
+            return elemType;
+        }
+
+        /**
+         * Get reference to an object in the {@code Vector}
+         *
+         * @param pos position of the object in {@code Vector}
+         * @return reference to element
+         */
+        @Override
+        public Reference get(int pos) {
+            int len = size();
+            if (pos >= len) return Reference.NULL_REFERENCE;
+            int childPos = end + pos * byteWidth;
+            return new Reference(bb, childPos, byteWidth, 1, elemType);
+        }
+    }
+
+    /**
+     * Represent a vector of keys in a map
+     */
+    public static class KeyVector {
+
+        private final TypedVector vec;
+
+        KeyVector(TypedVector vec) {
+            this.vec = vec;
+        }
+
+        /**
+         * Return key
+         *
+         * @param pos position of the key in key vector
+         * @return key
+         */
+        public Key get(int pos) {
+            int len = size();
+            if (pos >= len) return Key.EMPTY;
+            int childPos = vec.end + pos * vec.byteWidth;
+            return new Key(vec.bb, indirect(vec.bb, childPos, vec.byteWidth), 1);
+        }
+
+        /**
+         * Returns size of key vector
+         *
+         * @return size
+         */
+        public int size() {
+            return vec.size();
+        }
+
+        /**
+         * Returns a text(JSON) representation
+         */
+        public String toString() {
+            StringBuilder b = new StringBuilder();
+            b.append('[');
+            for (int i = 0; i < vec.size(); i++) {
+                vec.get(i).toString(b);
+                if (i != vec.size() - 1) {
+                    b.append(", ");
+                }
+            }
+            return b.append("]").toString();
+        }
+    }
+
+    public static class FlexBufferException extends RuntimeException {
+        FlexBufferException(String msg) {
+            super(msg);
+        }
+    }
+
+    static class Unsigned {
+
+        static int byteToUnsignedInt(byte x) {
+            return ((int) x) & 0xff;
+        }
+
+        static int shortToUnsignedInt(short x) {
+            return ((int) x) & 0xffff;
+        }
+
+        static long intToUnsignedLong(int x) {
+            return ((long) x) & 0xffffffffL;
+        }
+    }
+}
+/// @}
diff --git a/java/com/google/flatbuffers/FlexBuffersBuilder.java b/java/com/google/flatbuffers/FlexBuffersBuilder.java
new file mode 100644
index 0000000..dc0df96
--- /dev/null
+++ b/java/com/google/flatbuffers/FlexBuffersBuilder.java
@@ -0,0 +1,781 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.flatbuffers;
+
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+
+import static com.google.flatbuffers.FlexBuffers.*;
+import static com.google.flatbuffers.FlexBuffers.Unsigned.byteToUnsignedInt;
+import static com.google.flatbuffers.FlexBuffers.Unsigned.intToUnsignedLong;
+import static com.google.flatbuffers.FlexBuffers.Unsigned.shortToUnsignedInt;
+
+/// @file
+/// @addtogroup flatbuffers_java_api
+/// @{
+
+/**
+ * Helper class that builds FlexBuffers
+ * <p> This class presents all necessary APIs to create FlexBuffers. A `ByteBuffer` will be used to store the
+ * data. It can be created internally, or passed down in the constructor.</p>
+ *
+ * <p>There are some limitations when compared to original implementation in C++. Most notably:
+ * <ul>
+ *   <li><p> No support for mutations (might change in the future).</p></li>
+ *   <li><p> Buffer size limited to {@link Integer#MAX_VALUE}</p></li>
+ *   <li><p> Since Java does not support unsigned type, all unsigned operations accepts an immediate higher representation
+ *   of similar type.</p></li>
+ * </ul>
+ * </p>
+ */
+public class FlexBuffersBuilder {
+
+    /**
+     * No keys or strings will be shared
+     */
+    public static final int BUILDER_FLAG_NONE = 0;
+    /**
+     * Keys will be shared between elements. Identical keys will only be serialized once, thus possibly saving space.
+     * But serialization performance might be slower and consumes more memory.
+     */
+    public static final int BUILDER_FLAG_SHARE_KEYS = 1;
+    /**
+     * Strings will be shared between elements. Identical strings will only be serialized once, thus possibly saving space.
+     * But serialization performance might be slower and consumes more memory. This is ideal if you expect many repeated
+     * strings on the message.
+     */
+    public static final int BUILDER_FLAG_SHARE_STRINGS = 2;
+    /**
+     * Strings and keys will be shared between elements.
+     */
+    public static final int BUILDER_FLAG_SHARE_KEYS_AND_STRINGS = 3;
+    /**
+     * Reserved for the future.
+     */
+    public static final int BUILDER_FLAG_SHARE_KEY_VECTORS = 4;
+    /**
+     * Reserved for the future.
+     */
+    public static final int BUILDER_FLAG_SHARE_ALL = 7;
+
+    /// @cond FLATBUFFERS_INTERNAL
+    private static final int WIDTH_8 = 0;
+    private static final int WIDTH_16 = 1;
+    private static final int WIDTH_32 = 2;
+    private static final int WIDTH_64 = 3;
+    private final ReadWriteBuf bb;
+    private final ArrayList<Value> stack = new ArrayList<>();
+    private final HashMap<String, Integer> keyPool = new HashMap<>();
+    private final HashMap<String, Integer> stringPool = new HashMap<>();
+    private final int flags;
+    private boolean finished = false;
+
+    // A lambda to sort map keys
+    private Comparator<Value> keyComparator = new Comparator<Value>() {
+        @Override
+        public int compare(Value o1, Value o2) {
+            int ia = o1.key;
+            int io =  o2.key;
+            byte c1, c2;
+            do {
+                c1 = bb.get(ia);
+                c2 = bb.get(io);
+                if (c1 == 0)
+                    return c1 - c2;
+                ia++;
+                io++;
+            }
+            while (c1 == c2);
+            return c1 - c2;
+        }
+    };
+    /// @endcond
+
+    /**
+     * Constructs a newly allocated {@code FlexBuffersBuilder} with {@link #BUILDER_FLAG_SHARE_KEYS} set.
+     * @param bufSize size of buffer in bytes.
+     */
+    public FlexBuffersBuilder(int bufSize) {
+        this(new ArrayReadWriteBuf(bufSize), BUILDER_FLAG_SHARE_KEYS);
+    }
+
+    /**
+     * Constructs a newly allocated {@code FlexBuffersBuilder} with {@link #BUILDER_FLAG_SHARE_KEYS} set.
+     */
+    public FlexBuffersBuilder() {
+        this(256);
+    }
+
+    /**
+     * Constructs a newly allocated {@code FlexBuffersBuilder}.
+     *
+     * @param bb    `ByteBuffer` that will hold the message
+     * @param flags Share flags
+     */
+    @Deprecated
+    public FlexBuffersBuilder(ByteBuffer bb, int flags) {
+        this(new ArrayReadWriteBuf(bb.array()), flags);
+    }
+
+    public FlexBuffersBuilder(ReadWriteBuf bb, int flags) {
+        this.bb = bb;
+        this.flags = flags;
+    }
+
+    /**
+     * Constructs a newly allocated {@code FlexBuffersBuilder}.
+     * By default same keys will be serialized only once
+     * @param bb `ByteBuffer` that will hold the message
+     */
+    public FlexBuffersBuilder(ByteBuffer bb) {
+        this(bb, BUILDER_FLAG_SHARE_KEYS);
+    }
+
+    /**
+     * Reset the FlexBuffersBuilder by purging all data that it holds.
+     */
+    public void clear(){
+        bb.clear();
+        stack.clear();
+        keyPool.clear();
+        stringPool.clear();
+        finished = false;
+    }
+
+    /**
+     * Return `ByteBuffer` containing FlexBuffer message. {@code #finish()} must be called before calling this
+     * function otherwise an assert will trigger.
+     *
+     * @return `ByteBuffer` with finished message
+     */
+    public ReadWriteBuf getBuffer() {
+        assert (finished);
+        return bb;
+    }
+
+    /**
+     * Insert a single boolean into the buffer
+     * @param val true or false
+     */
+    public void putBoolean(boolean val) {
+        putBoolean(null, val);
+    }
+
+    /**
+     * Insert a single boolean into the buffer
+     * @param key key used to store element in map
+     * @param val true or false
+     */
+    public void putBoolean(String key, boolean val) {
+        stack.add(Value.bool(putKey(key), val));
+    }
+
+    private int putKey(String key) {
+        if (key == null) {
+            return -1;
+        }
+        int pos = bb.writePosition();
+        if ((flags & BUILDER_FLAG_SHARE_KEYS) != 0) {
+            Integer keyFromPool = keyPool.get(key);
+            if (keyFromPool == null) {
+                byte[]  keyBytes = key.getBytes(StandardCharsets.UTF_8);
+                bb.put(keyBytes, 0, keyBytes.length);
+                bb.put((byte) 0);
+                keyPool.put(key, pos);
+            } else {
+                pos = keyFromPool;
+            }
+        } else {
+            byte[]  keyBytes = key.getBytes(StandardCharsets.UTF_8);
+            bb.put(keyBytes, 0, keyBytes.length);
+            bb.put((byte) 0);
+            keyPool.put(key, pos);
+        }
+        return pos;
+    }
+
+    /**
+     * Adds a integer into the buff
+     * @param val integer
+     */
+    public void putInt(int val) {
+        putInt(null, val);
+    }
+
+    /**
+     * Adds a integer into the buff
+     * @param key key used to store element in map
+     * @param val integer
+     */
+    public void putInt(String key, int val) {
+        putInt(key, (long) val);
+    }
+
+    /**
+     * Adds a integer into the buff
+     * @param key key used to store element in map
+     * @param val 64-bit integer
+     */
+    public void putInt(String key, long val) {
+        int iKey = putKey(key);
+        if (Byte.MIN_VALUE <= val && val <= Byte.MAX_VALUE) {
+            stack.add(Value.int8(iKey, (int) val));
+        } else if (Short.MIN_VALUE <= val && val <= Short.MAX_VALUE) {
+            stack.add(Value.int16(iKey, (int) val));
+        } else if (Integer.MIN_VALUE <= val && val <= Integer.MAX_VALUE) {
+            stack.add(Value.int32(iKey, (int) val));
+        } else {
+            stack.add(Value.int64(iKey, val));
+        }
+    }
+
+    /**
+     * Adds a 64-bit integer into the buff
+     * @param value integer
+     */
+    public void putInt(long value) {
+        putInt(null, value);
+    }
+
+    /**
+     * Adds a unsigned integer into the buff.
+     * @param value integer representing unsigned value
+     */
+    public void putUInt(int value) {
+        putUInt(null, (long) value);
+    }
+
+    /**
+     * Adds a unsigned integer (stored in a signed 64-bit integer) into the buff.
+     * @param value integer representing unsigned value
+     */
+    public void putUInt(long value) {
+        putUInt(null, value);
+    }
+
+    /**
+     * Adds a 64-bit unsigned integer (stored as {@link BigInteger}) into the buff.
+     * Warning: This operation might be very slow.
+     * @param value integer representing unsigned value
+     */
+    public void putUInt64(BigInteger value) {
+        putUInt64(null, value.longValue());
+    }
+
+    private void putUInt64(String key, long value) {
+        stack.add(Value.uInt64(putKey(key), value));
+    }
+
+    private void putUInt(String key, long value) {
+        int iKey = putKey(key);
+        Value vVal;
+
+        int width = widthUInBits(value);
+
+        if (width == WIDTH_8) {
+            vVal = Value.uInt8(iKey, (int)value);
+        } else if (width == WIDTH_16) {
+            vVal = Value.uInt16(iKey, (int)value);
+        } else if (width == WIDTH_32) {
+            vVal = Value.uInt32(iKey, (int)value);
+        } else {
+            vVal = Value.uInt64(iKey, value);
+        }
+        stack.add(vVal);
+    }
+
+    /**
+     * Adds a 32-bit float into the buff.
+     * @param value float representing value
+     */
+    public void putFloat(float value) {
+        putFloat(null, value);
+    }
+
+    /**
+     * Adds a 32-bit float into the buff.
+     * @param key key used to store element in map
+     * @param value float representing value
+     */
+    public void putFloat(String key, float val) {
+        stack.add(Value.float32(putKey(key), val));
+    }
+
+    /**
+     * Adds a 64-bit float into the buff.
+     * @param value float representing value
+     */
+    public void putFloat(double value) {
+        putFloat(null, value);
+    }
+
+    /**
+     * Adds a 64-bit float into the buff.
+     * @param key key used to store element in map
+     * @param value float representing value
+     */
+    public void putFloat(String key, double val) {
+        stack.add(Value.float64(putKey(key), val));
+    }
+
+    /**
+     * Adds a String into the buffer
+     * @param value string
+     * @return start position of string in the buffer
+     */
+    public int putString(String value) {
+        return putString(null, value);
+    }
+
+    /**
+     * Adds a String into the buffer
+     * @param key key used to store element in map
+     * @param value string
+     * @return start position of string in the buffer
+     */
+    public int putString(String key, String val) {
+        int iKey = putKey(key);
+        if ((flags & FlexBuffersBuilder.BUILDER_FLAG_SHARE_STRINGS) != 0) {
+            Integer i = stringPool.get(val);
+            if (i == null) {
+                Value value = writeString(iKey, val);
+                stringPool.put(val, (int) value.iValue);
+                stack.add(value);
+                return (int) value.iValue;
+            } else {
+                int bitWidth = widthUInBits(val.length());
+                stack.add(Value.blob(iKey, i, FBT_STRING, bitWidth));
+                return i;
+            }
+        } else {
+            Value value = writeString(iKey, val);
+            stack.add(value);
+            return (int) value.iValue;
+        }
+    }
+
+    private Value writeString(int key, String s) {
+        return writeBlob(key, s.getBytes(StandardCharsets.UTF_8), FBT_STRING, true);
+    }
+
+    // in bits to fit a unsigned int
+    static int widthUInBits(long len) {
+        if (len <= byteToUnsignedInt((byte)0xff)) return WIDTH_8;
+        if (len <= shortToUnsignedInt((short)0xffff)) return WIDTH_16;
+        if (len <= intToUnsignedLong(0xffff_ffff)) return WIDTH_32;
+        return WIDTH_64;
+    }
+
+    private Value writeBlob(int key, byte[] blob, int type, boolean trailing) {
+        int bitWidth = widthUInBits(blob.length);
+        int byteWidth = align(bitWidth);
+        writeInt(blob.length, byteWidth);
+        int sloc = bb.writePosition();
+        bb.put(blob, 0, blob.length);
+        if (trailing) {
+            bb.put((byte) 0);
+        }
+        return Value.blob(key, sloc, type, bitWidth);
+    }
+
+    // Align to prepare for writing a scalar with a certain size.
+    private int align(int alignment) {
+        int byteWidth = 1 << alignment;
+        int padBytes = Value.paddingBytes(bb.writePosition(), byteWidth);
+        while (padBytes-- != 0) {
+            bb.put((byte) 0);
+        }
+        return byteWidth;
+    }
+
+    private void writeInt(long value, int byteWidth) {
+        switch (byteWidth) {
+            case 1: bb.put((byte) value); break;
+            case 2: bb.putShort((short) value); break;
+            case 4: bb.putInt((int) value); break;
+            case 8: bb.putLong(value); break;
+        }
+    }
+
+    /**
+     * Adds a byte array into the message
+     * @param value byte array
+     * @return position in buffer as the start of byte array
+     */
+    public int putBlob(byte[] value) {
+        return putBlob(null, value);
+    }
+
+    /**
+     * Adds a byte array into the message
+     * @param key key used to store element in map
+     * @param value byte array
+     * @return position in buffer as the start of byte array
+     */
+    public int putBlob(String key, byte[] val) {
+        int iKey = putKey(key);
+        Value value = writeBlob(iKey, val, FBT_BLOB, false);
+        stack.add(value);
+        return (int) value.iValue;
+    }
+
+    /**
+     * Start a new vector in the buffer.
+     * @return a reference indicating position of the vector in buffer. This
+     * reference must be passed along when the vector is finished using endVector()
+     */
+    public int startVector() {
+        return stack.size();
+    }
+
+    /**
+     * Finishes a vector, but writing the information in the buffer
+     * @param key   key used to store element in map
+     * @param start reference for begining of the vector. Returned by {@link startVector()}
+     * @param typed boolean indicating wether vector is typed
+     * @param fixed boolean indicating wether vector is fixed
+     * @return      Reference to the vector
+     */
+    public int endVector(String key, int start, boolean typed, boolean fixed) {
+        int iKey = putKey(key);
+        Value vec = createVector(iKey, start, stack.size() - start, typed, fixed, null);
+        // Remove temp elements and return vector.
+        while (stack.size() > start) {
+            stack.remove(stack.size() - 1);
+        }
+        stack.add(vec);
+        return (int) vec.iValue;
+    }
+
+    /**
+     * Finish writing the message into the buffer. After that no other element must
+     * be inserted into the buffer. Also, you must call this function before start using the
+     * FlexBuffer message
+     * @return `ByteBuffer` containing the FlexBuffer message
+     */
+    public ByteBuffer finish() {
+        // If you hit this assert, you likely have objects that were never included
+        // in a parent. You need to have exactly one root to finish a buffer.
+        // Check your Start/End calls are matched, and all objects are inside
+        // some other object.
+        assert (stack.size() == 1);
+        // Write root value.
+        int byteWidth = align(stack.get(0).elemWidth(bb.writePosition(), 0));
+        writeAny(stack.get(0), byteWidth);
+        // Write root type.
+        bb.put(stack.get(0).storedPackedType());
+        // Write root size. Normally determined by parent, but root has no parent :)
+        bb.put((byte) byteWidth);
+        this.finished = true;
+        return ByteBuffer.wrap(bb.data(), 0, bb.writePosition());
+    }
+
+    /*
+     * Create a vector based on the elements stored in the stack
+     *
+     * @param key    reference to its key
+     * @param start  element in the stack
+     * @param length size of the vector
+     * @param typed  whether is TypedVector or not
+     * @param fixed  whether is Fixed vector or not
+     * @param keys   Value representing key vector
+     * @return Value representing the created vector
+     */
+    private Value createVector(int key, int start, int length, boolean typed, boolean fixed, Value keys) {
+        assert (!fixed || typed); // typed=false, fixed=true combination is not supported.
+        // Figure out smallest bit width we can store this vector with.
+        int bitWidth = Math.max(WIDTH_8, widthUInBits(length));
+        int prefixElems = 1;
+        if (keys != null) {
+            // If this vector is part of a map, we will pre-fix an offset to the keys
+            // to this vector.
+            bitWidth = Math.max(bitWidth, keys.elemWidth(bb.writePosition(), 0));
+            prefixElems += 2;
+        }
+        int vectorType = FBT_KEY;
+        // Check bit widths and types for all elements.
+        for (int i = start; i < stack.size(); i++) {
+            int elemWidth = stack.get(i).elemWidth(bb.writePosition(), i + prefixElems);
+            bitWidth = Math.max(bitWidth, elemWidth);
+            if (typed) {
+                if (i == start) {
+                    vectorType = stack.get(i).type;
+                    if (!FlexBuffers.isTypedVectorElementType(vectorType)) {
+                        throw new FlexBufferException("TypedVector does not support this element type");
+                    }
+                } else {
+                    // If you get this assert, you are writing a typed vector with
+                    // elements that are not all the same type.
+                    assert (vectorType == stack.get(i).type);
+                }
+            }
+        }
+        // If you get this assert, your fixed types are not one of:
+        // Int / UInt / Float / Key.
+        assert (!fixed || FlexBuffers.isTypedVectorElementType(vectorType));
+
+        int byteWidth = align(bitWidth);
+        // Write vector. First the keys width/offset if available, and size.
+        if (keys != null) {
+            writeOffset(keys.iValue, byteWidth);
+            writeInt(1L << keys.minBitWidth, byteWidth);
+        }
+        if (!fixed) {
+            writeInt(length, byteWidth);
+        }
+        // Then the actual data.
+        int vloc = bb.writePosition();
+        for (int i = start; i < stack.size(); i++) {
+            writeAny(stack.get(i), byteWidth);
+        }
+        // Then the types.
+        if (!typed) {
+            for (int i = start; i < stack.size(); i++) {
+                bb.put(stack.get(i).storedPackedType(bitWidth));
+            }
+        }
+        return new Value(key, keys != null ? FBT_MAP
+                : (typed ? FlexBuffers.toTypedVector(vectorType, fixed ? length : 0)
+                : FBT_VECTOR), bitWidth, vloc);
+    }
+
+    private void writeOffset(long val, int byteWidth) {
+        int reloff = (int) (bb.writePosition() - val);
+        assert (byteWidth == 8 || reloff < 1L << (byteWidth * 8));
+        writeInt(reloff, byteWidth);
+    }
+
+    private void writeAny(final Value val, int byteWidth) {
+        switch (val.type) {
+            case FBT_NULL:
+            case FBT_BOOL:
+            case FBT_INT:
+            case FBT_UINT:
+                writeInt(val.iValue, byteWidth);
+                break;
+            case FBT_FLOAT:
+                writeDouble(val.dValue, byteWidth);
+                break;
+            default:
+                writeOffset(val.iValue, byteWidth);
+                break;
+        }
+    }
+
+    private void writeDouble(double val, int byteWidth) {
+        if (byteWidth == 4) {
+            bb.putFloat((float) val);
+        } else if (byteWidth == 8) {
+            bb.putDouble(val);
+        }
+    }
+
+    /**
+     * Start a new map in the buffer.
+     * @return a reference indicating position of the map in buffer. This
+     * reference must be passed along when the map is finished using endMap()
+     */
+    public int startMap() {
+        return stack.size();
+    }
+
+    /**
+     * Finishes a map, but writing the information in the buffer
+     * @param key   key used to store element in map
+     * @param start reference for begining of the map. Returned by {@link startMap()}
+     * @return      Reference to the map
+     */
+    public int endMap(String key, int start) {
+        int iKey = putKey(key);
+
+        Collections.sort(stack.subList(start, stack.size()), keyComparator);
+
+        Value keys = createKeyVector(start, stack.size() - start);
+        Value vec = createVector(iKey, start, stack.size() - start, false, false, keys);
+        // Remove temp elements and return map.
+        while (stack.size() > start) {
+            stack.remove(stack.size() - 1);
+        }
+        stack.add(vec);
+        return (int) vec.iValue;
+    }
+
+    private Value createKeyVector(int start, int length) {
+        // Figure out smallest bit width we can store this vector with.
+        int bitWidth = Math.max(WIDTH_8, widthUInBits(length));
+        int prefixElems = 1;
+        // Check bit widths and types for all elements.
+        for (int i = start; i < stack.size(); i++) {
+            int elemWidth = Value.elemWidth(FBT_KEY, WIDTH_8, stack.get(i).key, bb.writePosition(), i + prefixElems);
+            bitWidth = Math.max(bitWidth, elemWidth);
+        }
+
+        int byteWidth = align(bitWidth);
+        // Write vector. First the keys width/offset if available, and size.
+        writeInt(length, byteWidth);
+        // Then the actual data.
+        int vloc = bb.writePosition();
+        for (int i = start; i < stack.size(); i++) {
+            int pos = stack.get(i).key;
+            assert(pos != -1);
+            writeOffset(stack.get(i).key, byteWidth);
+        }
+        // Then the types.
+        return new Value(-1, FlexBuffers.toTypedVector(FBT_KEY,0), bitWidth, vloc);
+    }
+
+    private static class Value {
+        final int type;
+        // for scalars, represents scalar size in bytes
+        // for vectors, represents the size
+        // for string, length
+        final int minBitWidth;
+        // float value
+        final double dValue;
+        // integer value
+        long iValue;
+        // position of the key associated with this value in buffer
+        int key;
+
+        Value(int key, int type, int bitWidth, long iValue) {
+            this.key = key;
+            this.type = type;
+            this.minBitWidth = bitWidth;
+            this.iValue = iValue;
+            this.dValue = Double.MIN_VALUE;
+        }
+
+        Value(int key, int type, int bitWidth, double dValue) {
+            this.key = key;
+            this.type = type;
+            this.minBitWidth = bitWidth;
+            this.dValue = dValue;
+            this.iValue = Long.MIN_VALUE;
+        }
+
+        static Value bool(int key, boolean b) {
+            return new Value(key, FBT_BOOL, WIDTH_8, b ? 1 : 0);
+        }
+
+        static Value blob(int key, int position, int type, int bitWidth) {
+            return new Value(key, type, bitWidth, position);
+        }
+
+        static Value int8(int key, int value) {
+            return new Value(key, FBT_INT, WIDTH_8, value);
+        }
+
+        static Value int16(int key, int value) {
+            return new Value(key, FBT_INT, WIDTH_16, value);
+        }
+
+        static Value int32(int key, int value) {
+            return new Value(key, FBT_INT, WIDTH_32, value);
+        }
+
+        static Value int64(int key, long value) {
+            return new Value(key, FBT_INT, WIDTH_64, value);
+        }
+
+        static Value uInt8(int key, int value) {
+            return new Value(key, FBT_UINT, WIDTH_8, value);
+        }
+
+        static Value uInt16(int key, int value) {
+            return new Value(key, FBT_UINT, WIDTH_16, value);
+        }
+
+        static Value uInt32(int key, int value) {
+            return new Value(key, FBT_UINT, WIDTH_32, value);
+        }
+
+        static Value uInt64(int key, long value) {
+            return new Value(key, FBT_UINT, WIDTH_64, value);
+        }
+
+        static Value float32(int key, float value) {
+            return new Value(key, FBT_FLOAT, WIDTH_32, value);
+        }
+
+        static Value float64(int key, double value) {
+            return new Value(key, FBT_FLOAT, WIDTH_64, value);
+        }
+
+        private byte storedPackedType() {
+            return storedPackedType(WIDTH_8);
+        }
+
+        private byte storedPackedType(int parentBitWidth) {
+            return packedType(storedWidth(parentBitWidth), type);
+        }
+
+        private static byte packedType(int bitWidth, int type) {
+            return (byte) (bitWidth | (type << 2));
+        }
+
+        private int storedWidth(int parentBitWidth) {
+            if (FlexBuffers.isTypeInline(type)) {
+                return Math.max(minBitWidth, parentBitWidth);
+            } else {
+                return minBitWidth;
+            }
+        }
+
+        private int elemWidth(int bufSize, int elemIndex) {
+            return elemWidth(type, minBitWidth, iValue, bufSize, elemIndex);
+        }
+
+        private static int elemWidth(int type, int minBitWidth, long iValue, int bufSize, int elemIndex) {
+            if (FlexBuffers.isTypeInline(type)) {
+                return minBitWidth;
+            } else {
+                // We have an absolute offset, but want to store a relative offset
+                // elem_index elements beyond the current buffer end. Since whether
+                // the relative offset fits in a certain byte_width depends on
+                // the size of the elements before it (and their alignment), we have
+                // to test for each size in turn.
+
+                // Original implementation checks for largest scalar
+                // which is long unsigned int
+                for (int byteWidth = 1; byteWidth <= 32; byteWidth *= 2) {
+                    // Where are we going to write this offset?
+                    int offsetLoc = bufSize + paddingBytes(bufSize, byteWidth) + (elemIndex * byteWidth);
+                    // Compute relative offset.
+                    long offset = offsetLoc - iValue;
+                    // Does it fit?
+                    int bitWidth = widthUInBits((int) offset);
+                    if (((1L) << bitWidth) == byteWidth)
+                        return bitWidth;
+                }
+                assert (false);  // Must match one of the sizes above.
+                return WIDTH_64;
+            }
+        }
+
+        private static int paddingBytes(int bufSize, int scalarSize) {
+            return ((~bufSize) + 1) & (scalarSize - 1);
+        }
+    }
+}
+
+/// @}
diff --git a/java/com/google/flatbuffers/FloatVector.java b/java/com/google/flatbuffers/FloatVector.java
new file mode 100644
index 0000000..5c505ba
--- /dev/null
+++ b/java/com/google/flatbuffers/FloatVector.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2019 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.flatbuffers;
+
+import static com.google.flatbuffers.Constants.*;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+
+/**
+ * Helper type for accessing vector of float values.
+ */
+public final class FloatVector extends BaseVector {
+  /**
+   * Assigns vector access object to vector data.
+   *
+   * @param _vector Start data of a vector.
+   * @param _bb Table's ByteBuffer.
+   * @return Returns current vector access object assigned to vector data whose offset is stored at
+   *         `vector`.
+   */
+  public FloatVector __assign(int _vector, ByteBuffer _bb) {
+    __reset(_vector, Constants.SIZEOF_FLOAT, _bb); return this;
+  }
+
+  /**
+   * Reads the float value at the given index.
+   *
+   * @param j The index from which the float value will be read.
+   * @return the float value at the given index.
+   */
+  public float get(int j) { 
+    return bb.getFloat(__element(j));
+  }
+}
diff --git a/java/com/google/flatbuffers/IntVector.java b/java/com/google/flatbuffers/IntVector.java
new file mode 100644
index 0000000..85549f4
--- /dev/null
+++ b/java/com/google/flatbuffers/IntVector.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2019 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.flatbuffers;
+
+import static com.google.flatbuffers.Constants.*;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+
+/**
+ * Helper type for accessing vector of signed or unsigned 32-bit values.
+ */
+public final class IntVector extends BaseVector {
+  /**
+   * Assigns vector access object to vector data.
+   *
+   * @param _vector Start data of a vector.
+   * @param _bb Table's ByteBuffer.
+   * @return Returns current vector access object assigned to vector data whose offset is stored at
+   *         `vector`.
+   */
+  public IntVector __assign(int _vector, ByteBuffer _bb) {
+    __reset(_vector, Constants.SIZEOF_INT, _bb); return this;
+  }
+
+  /**
+   * Reads the integer at the given index.
+   *
+   * @param j The index from which the integer will be read.
+   * @return the 32-bit value at the given index.
+   */
+  public int get(int j) {
+    return bb.getInt(__element(j));
+  }
+
+  /**
+   * Reads the integer at the given index, zero-extends it to type long, and returns the result,
+   * which is therefore in the range 0 through 4294967295.
+   *
+   * @param j The index from which the integer will be read.
+   * @return the unsigned 32-bit at the given index.
+   */
+  public long getAsUnsigned(int j) {
+    return (long) get(j) & 0xFFFFFFFFL;
+  }
+}
diff --git a/java/com/google/flatbuffers/LongVector.java b/java/com/google/flatbuffers/LongVector.java
new file mode 100644
index 0000000..0ca5ab8
--- /dev/null
+++ b/java/com/google/flatbuffers/LongVector.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2019 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.flatbuffers;
+
+import static com.google.flatbuffers.Constants.*;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+
+/**
+ * Helper type for accessing vector of long values.
+ */
+public final class LongVector extends BaseVector {
+  /**
+   * Assigns vector access object to vector data.
+   *
+   * @param _vector Start data of a vector.
+   * @param _bb Table's ByteBuffer.
+   * @return Returns current vector access object assigned to vector data whose offset is stored at
+   *         `vector`.
+   */
+  public LongVector __assign(int _vector, ByteBuffer _bb) {
+    __reset(_vector, Constants.SIZEOF_LONG, _bb); return this;
+  }
+
+  /**
+   * Reads the long value at the given index.
+   *
+   * @param j The index from which the long value will be read.
+   * @return the signed 64-bit value at the given index.
+   */
+  public long get(int j) {
+    return bb.getLong(__element(j));
+  }
+}
diff --git a/java/com/google/flatbuffers/ReadBuf.java b/java/com/google/flatbuffers/ReadBuf.java
new file mode 100644
index 0000000..751361f
--- /dev/null
+++ b/java/com/google/flatbuffers/ReadBuf.java
@@ -0,0 +1,81 @@
+package com.google.flatbuffers;
+
+/**
+ *  Represent a chunk of data, where FlexBuffers will read from.
+ */
+public interface ReadBuf {
+
+  /**
+   * Read boolean from data. Booleans as stored as single byte
+   * @param index position of the element in ReadBuf
+   * @return boolean element
+   */
+  boolean getBoolean(int index);
+
+  /**
+   * Read a byte from data.
+   * @param index position of the element in ReadBuf
+   * @return a byte
+   */
+  byte get(int index);
+
+  /**
+   * Read a short from data.
+   * @param index position of the element in ReadBuf
+   * @return a short
+   */
+  short getShort(int index);
+
+  /**
+   * Read a 32-bit int from data.
+   * @param index position of the element in ReadBuf
+   * @return an int
+   */
+  int getInt(int index);
+
+  /**
+   * Read a 64-bit long from data.
+   * @param index position of the element in ReadBuf
+   * @return a long
+   */
+  long getLong(int index);
+
+  /**
+   * Read a 32-bit float from data.
+   * @param index position of the element in ReadBuf
+   * @return a float
+   */
+  float getFloat(int index);
+
+  /**
+   * Read a 64-bit float from data.
+   * @param index position of the element in ReadBuf
+   * @return a double
+   */
+  double getDouble(int index);
+
+  /**
+   * Read an UTF-8 string from data.
+   * @param start initial element of the string
+   * @param size size of the string in bytes.
+   * @return a {@code String}
+   */
+  String getString(int start, int size);
+
+  /**
+   * Expose ReadBuf as an array of bytes.
+   * This method is meant to be as efficient as possible, so for a array-backed ReadBuf, it should
+   * return its own internal data. In case access to internal data is not possible,
+   * a copy of the data into an array of bytes might occur.
+   * @return ReadBuf as an array of bytes
+   */
+  byte[] data();
+
+  /**
+   * Defines the size of the message in the buffer. It also determines last position that buffer
+   * can be read. Last byte to be accessed is in position {@code limit() -1}.
+   * @return indicate last position
+   */
+  int limit();
+
+}
diff --git a/java/com/google/flatbuffers/ReadWriteBuf.java b/java/com/google/flatbuffers/ReadWriteBuf.java
new file mode 100644
index 0000000..6eb43bd
--- /dev/null
+++ b/java/com/google/flatbuffers/ReadWriteBuf.java
@@ -0,0 +1,142 @@
+package com.google.flatbuffers;
+
+/**
+ * Interface to represent a read-write buffer. This interface will be used to access and write
+ * FlexBuffers message.
+ */
+public interface ReadWriteBuf extends ReadBuf {
+
+    /**
+     * Clears (resets) the buffer so that it can be reused. Write position will be set to the
+     * start.
+     */
+    void clear();
+
+    /**
+     * Put a boolean into the buffer at {@code writePosition()} . Booleans as stored as single
+     * byte. Write position will be incremented.
+     * @return boolean element
+     */
+    void putBoolean(boolean value);
+
+    /**
+     * Put an array of bytes into the buffer at {@code writePosition()}. Write position will be
+     * incremented.
+     * @param value the data to be copied
+     * @param start initial position on value to be copied
+     * @param length amount of bytes to be copied
+     */
+    void put (byte[] value, int start, int length);
+
+    /**
+     * Write a byte into the buffer at {@code writePosition()}. Write position will be
+     * incremented.
+     */
+    void put(byte value);
+
+    /**
+     * Write a 16-bit into in the buffer at {@code writePosition()}. Write position will be
+     * incremented.
+     */
+    void putShort(short value);
+
+    /**
+     * Write a 32-bit into in the buffer at {@code writePosition()}. Write position will be
+     * incremented.
+     */
+    void putInt(int value);
+
+    /**
+     * Write a 64-bit into in the buffer at {@code writePosition()}. Write position will be
+     * incremented.
+     */
+    void putLong(long value);
+
+    /**
+     * Write a 32-bit float into the buffer at {@code writePosition()}. Write position will be
+     * incremented.
+     */
+    void putFloat(float value);
+
+    /**
+     * Write a 64-bit float into the buffer at {@code writePosition()}. Write position will be
+     * incremented.
+     */
+    void putDouble(double value);
+
+    /**
+     * Write boolean into a given position on the buffer. Booleans as stored as single byte.
+     * @param index position of the element in buffer
+     */
+    void setBoolean(int index, boolean value);
+
+    /**
+     * Read a byte from data.
+     * @param index position of the element in the buffer
+     * @return a byte
+     */
+    void set(int index, byte value);
+
+    /**
+     * Write an array of bytes into the buffer.
+     * @param index initial position of the buffer to be written
+     * @param value the data to be copied
+     * @param start initial position on value to be copied
+     * @param length amount of bytes to be copied
+     */
+    void set(int index, byte[] value, int start, int length);
+
+    /**
+     * Read a short from data.
+     * @param index position of the element in ReadBuf
+     * @return a short
+     */
+    void setShort(int index, short value);
+
+    /**
+     * Read a 32-bit int from data.
+     * @param index position of the element in ReadBuf
+     * @return an int
+     */
+    void setInt(int index, int value);
+
+    /**
+     * Read a 64-bit long from data.
+     * @param index position of the element in ReadBuf
+     * @return a long
+     */
+    void setLong(int index, long value);
+
+    /**
+     * Read a 32-bit float from data.
+     * @param index position of the element in ReadBuf
+     * @return a float
+     */
+    void setFloat(int index, float value);
+
+    /**
+     * Read a 64-bit float from data.
+     * @param index position of the element in ReadBuf
+     * @return a double
+     */
+    void setDouble(int index, double value);
+
+
+    int writePosition();
+    /**
+     * Defines the size of the message in the buffer. It also determines last position that buffer
+     * can be read or write. Last byte to be accessed is in position {@code limit() -1}.
+     * @return indicate last position
+     */
+    int limit();
+
+    /**
+     * Request capacity of the buffer. In case buffer is already larger
+     * than the requested, this method will just return true. Otherwise
+     * It might try to resize the buffer.
+     *
+     * @return true if buffer is able to offer
+     * the requested capacity
+     */
+    boolean requestCapacity(int capacity);
+}
diff --git a/java/com/google/flatbuffers/ShortVector.java b/java/com/google/flatbuffers/ShortVector.java
new file mode 100644
index 0000000..b02ac3e
--- /dev/null
+++ b/java/com/google/flatbuffers/ShortVector.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2019 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.flatbuffers;
+
+import static com.google.flatbuffers.Constants.*;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+
+/**
+ * Helper type for accessing vector of signed or unsigned 16-bit values.
+ */
+public final class ShortVector extends BaseVector {
+  /**
+   * Assigns vector access object to vector data.
+   *
+   * @param _vector Start data of a vector.
+   * @param _bb Table's ByteBuffer.
+   * @return Returns current vector access object assigned to vector data whose offset is stored at
+   *         `vector`.
+   */
+  public ShortVector __assign(int _vector, ByteBuffer _bb) {
+    __reset(_vector, Constants.SIZEOF_SHORT, _bb); return this;
+  }
+
+  /**
+   * Reads the short value at the given index.
+   *
+   * @param j The index from which the short value will be read.
+   * @return the 16-bit value at the given index.
+   */
+  public short get(int j) {
+    return bb.getShort(__element(j));
+  }
+
+  /**
+   * Reads the short at the given index, zero-extends it to type int, and returns the result,
+   * which is therefore in the range 0 through 65535.
+   *
+   * @param j The index from which the short value will be read.
+   * @return the unsigned 16-bit at the given index.
+   */
+  public int getAsUnsigned(int j) {
+    return (int) get(j) & 0xFFFF;
+  }
+}
diff --git a/java/com/google/flatbuffers/StringVector.java b/java/com/google/flatbuffers/StringVector.java
new file mode 100644
index 0000000..6c20775
--- /dev/null
+++ b/java/com/google/flatbuffers/StringVector.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2019 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.flatbuffers;
+
+import static com.google.flatbuffers.Constants.*;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+
+/**
+ * Helper type for accessing vector of String.
+ */
+public final class StringVector extends BaseVector {
+  private Utf8 utf8 = Utf8.getDefault();
+
+  /**
+   * Assigns vector access object to vector data.
+   *
+   * @param _vector Start data of a vector.
+   * @param _element_size Size of a vector element.
+   * @param _bb Table's ByteBuffer.
+   * @return Returns current vector access object assigned to vector data whose offset is stored at
+   *         `vector`.
+   */
+  public StringVector __assign(int _vector, int _element_size, ByteBuffer _bb) {
+    __reset(_vector, _element_size, _bb); return this;
+  }
+
+  /**
+   * Reads the String at the given index.
+   *
+   * @param j The index from which the String value will be read.
+   * @return the String at the given index.
+   */
+  public String get(int j) {
+    return Table.__string(__element(j), bb, utf8);
+  }
+}
diff --git a/java/com/google/flatbuffers/Table.java b/java/com/google/flatbuffers/Table.java
index ff069f2..7f41639 100644
--- a/java/com/google/flatbuffers/Table.java
+++ b/java/com/google/flatbuffers/Table.java
@@ -19,7 +19,6 @@
 import static com.google.flatbuffers.Constants.*;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
-import java.nio.charset.Charset;
 
 /// @cond FLATBUFFERS_INTERNAL
 
@@ -27,12 +26,6 @@
  * All tables in the generated code derive from this class, and add their own accessors.
  */
 public class Table {
-  public final static ThreadLocal<Charset> UTF8_CHARSET = new ThreadLocal<Charset>() {
-    @Override
-    protected Charset initialValue() {
-      return Charset.forName("UTF-8");
-    }
-  };
   /** Used to hold the position of the `bb` buffer. */
   protected int bb_pos;
   /** The underlying ByteBuffer to hold the data of the Table. */
@@ -75,6 +68,13 @@
     return offset + bb.getInt(offset);
   }
 
+  /**
+   * Retrieve a relative offset.
+   *
+   * @param offset An `int` index into a ByteBuffer containing the relative offset.
+   * @param bb from which the relative offset will be retrieved.
+   * @return Returns the relative offset stored at `offset`.
+   */
   protected static int __indirect(int offset, ByteBuffer bb) {
     return offset + bb.getInt(offset);
   }
@@ -91,6 +91,23 @@
    * @return Returns a `String` from the data stored inside the FlatBuffer at `offset`.
    */
   protected String __string(int offset) {
+    return __string(offset, bb, utf8);
+  }
+
+  /**
+   * Create a Java `String` from UTF-8 data stored inside the FlatBuffer.
+   *
+   * This allocates a new string and converts to wide chars upon each access,
+   * which is not very efficient. Instead, each FlatBuffer string also comes with an
+   * accessor based on __vector_as_bytebuffer below, which is much more efficient,
+   * assuming your Java program can handle UTF-8 data directly.
+   *
+   * @param offset An `int` index into the Table's ByteBuffer.
+   * @param bb Table ByteBuffer used to read a string at given offset.
+   * @param utf8 decoder that creates a Java `String` from UTF-8 characters.
+   * @return Returns a `String` from the data stored inside the FlatBuffer at `offset`.
+   */
+  protected static String __string(int offset, ByteBuffer bb, Utf8 utf8) {
     offset += bb.getInt(offset);
     int length = bb.getInt(offset);
     return utf8.decodeUtf8(bb, offset + SIZEOF_INT, length);
@@ -169,11 +186,19 @@
    * @return Returns the Table that points to the union at `offset`.
    */
   protected Table __union(Table t, int offset) {
-    offset += bb_pos;
-    t.bb_pos = offset + bb.getInt(offset);
-    t.bb = bb;
-    t.vtable_start = t.bb_pos - bb.getInt(t.bb_pos);
-    t.vtable_size = bb.getShort(t.vtable_start);
+    return __union(t, offset, bb);
+  }
+
+  /**
+   * Initialize any Table-derived type to point to the union at the given `offset`.
+   *
+   * @param t A `Table`-derived type that should point to the union at `offset`.
+   * @param offset An `int` index into the Table's ByteBuffer.
+   * @param bb Table ByteBuffer used to initialize the object Table-derived type.
+   * @return Returns the Table that points to the union at `offset`.
+   */
+  protected static Table __union(Table t, int offset, ByteBuffer bb) {
+    t.__reset(__indirect(offset, bb), bb);
     return t;
   }
 
diff --git a/java/com/google/flatbuffers/UnionVector.java b/java/com/google/flatbuffers/UnionVector.java
new file mode 100644
index 0000000..986cfea
--- /dev/null
+++ b/java/com/google/flatbuffers/UnionVector.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2019 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.flatbuffers;
+
+import static com.google.flatbuffers.Constants.*;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+
+/**
+ * Helper type for accessing vector of unions.
+ */
+public final class UnionVector extends BaseVector {
+  /**
+   * Assigns vector access object to vector data.
+   *
+   * @param _vector Start data of a vector.
+   * @param _element_size Size of a vector element.
+   * @param _bb Table's ByteBuffer.
+   * @return Returns current vector access object assigned to vector data whose offset is stored at
+   *         `vector`.
+   */
+  public UnionVector __assign(int _vector, int _element_size, ByteBuffer _bb) {
+    __reset(_vector, _element_size, _bb); return this;
+  }
+
+
+  /**
+   * Initialize any Table-derived type to point to the union at the given `index`.
+   *
+   * @param obj A `Table`-derived type that should point to the union at `index`.
+   * @param j An `int` index into the union vector.
+   * @return Returns the Table that points to the union at `index`.
+   */
+  public Table get(Table obj, int j) {
+    return Table.__union(obj, __element(j), bb);
+  }
+}
diff --git a/java/com/google/flatbuffers/Utf8.java b/java/com/google/flatbuffers/Utf8.java
index efb6811..e8af8ad 100644
--- a/java/com/google/flatbuffers/Utf8.java
+++ b/java/com/google/flatbuffers/Utf8.java
@@ -18,9 +18,13 @@
 
 import java.nio.ByteBuffer;
 
+import static java.lang.Character.MAX_SURROGATE;
+import static java.lang.Character.MIN_SURROGATE;
 import static java.lang.Character.MIN_HIGH_SURROGATE;
 import static java.lang.Character.MIN_LOW_SURROGATE;
 import static java.lang.Character.MIN_SUPPLEMENTARY_CODE_POINT;
+import static java.lang.Character.isSurrogatePair;
+import static java.lang.Character.toCodePoint;
 
 public abstract class Utf8 {
 
@@ -74,6 +78,56 @@
   }
 
   /**
+   * Encode a Java's CharSequence UTF8 codepoint into a byte array.
+   * @param in CharSequence to be encoded
+   * @param start start position of the first char in the codepoint
+   * @param out byte array of 4 bytes to be filled
+   * @return return the amount of bytes occupied by the codepoint
+   */
+  public static int encodeUtf8CodePoint(CharSequence in, int start, byte[] out) {
+    // utf8 codepoint needs at least 4 bytes
+    assert out.length >= 4;
+
+    final int inLength = in.length();
+    if (start >= inLength) {
+      return 0;
+    }
+
+    char c = in.charAt(start);
+     if (c < 0x80) {
+       // One byte (0xxx xxxx)
+       out[0] = (byte) c;
+       return 1;
+     } else if (c < 0x800) {
+      // Two bytes (110x xxxx 10xx xxxx)
+      out[0] = (byte) (0xC0 | (c >>> 6));
+      out[1] = (byte) (0x80 | (0x3F & c));
+      return 2;
+    } else if (c < MIN_SURROGATE || MAX_SURROGATE < c) {
+      // Three bytes (1110 xxxx 10xx xxxx 10xx xxxx)
+      // Maximum single-char code point is 0xFFFF, 16 bits.
+      out[0] = (byte) (0xE0 | (c >>> 12));
+      out[1] =(byte) (0x80 | (0x3F & (c >>> 6)));
+      out[2] = (byte) (0x80 | (0x3F & c));
+      return 3;
+    } else {
+      // Four bytes (1111 xxxx 10xx xxxx 10xx xxxx 10xx xxxx)
+      // Minimum code point represented by a surrogate pair is 0x10000, 17 bits, four UTF-8
+      // bytes
+      final char low;
+      if (start + 1 == inLength || !isSurrogatePair(c, (low = in.charAt(start+1)))) {
+        throw new UnpairedSurrogateException(start, inLength);
+      }
+      int codePoint = toCodePoint(c, low);
+      out[0] = (byte) ((0xF << 4) | (codePoint >>> 18));
+      out[1] = (byte) (0x80 | (0x3F & (codePoint >>> 12)));
+      out[2] = (byte) (0x80 | (0x3F & (codePoint >>> 6)));
+      out[3] = (byte) (0x80 | (0x3F & codePoint));
+      return 4;
+    }
+  }
+
+  /**
    * Utility methods for decoding bytes into {@link String}. Callers are responsible for extracting
    * bytes (possibly using Unsafe methods), and checking remaining bytes. All other UTF-8 validity
    * checks and codepoint conversion happen in this class.
diff --git a/java/com/google/flatbuffers/Utf8Safe.java b/java/com/google/flatbuffers/Utf8Safe.java
index 06ea420..523e3f1 100644
--- a/java/com/google/flatbuffers/Utf8Safe.java
+++ b/java/com/google/flatbuffers/Utf8Safe.java
@@ -123,7 +123,7 @@
     return utf8Length;
   }
 
-  private static String decodeUtf8Array(byte[] bytes, int index, int size) {
+  public static String decodeUtf8Array(byte[] bytes, int index, int size) {
     // Bitwise OR combines the sign bits so any negative value fails the check.
     if ((index | size | bytes.length - index - size) < 0) {
       throw new ArrayIndexOutOfBoundsException(
@@ -197,7 +197,7 @@
     return new String(resultArr, 0, resultPos);
   }
 
-  private static String decodeUtf8Buffer(ByteBuffer buffer, int offset,
+  public static String decodeUtf8Buffer(ByteBuffer buffer, int offset,
                                          int length) {
     // Bitwise OR combines the sign bits so any negative value fails the check.
     if ((offset | length | buffer.limit() - offset - length) < 0) {
