diff --git a/js/README.md b/js/README.md
new file mode 100644
index 0000000..fc144a3
--- /dev/null
+++ b/js/README.md
@@ -0,0 +1,14 @@
+This directory contains Protocol Buffer support for JavaScript.  This code works
+in browsers and in Node.js.
+
+The packaging work for this is still in-progress.  For now you can just run the
+tests.  First you need to build the main C++ distribution because the code
+generator for JavaScript is written in C++:
+
+   $ ./autogen.sh
+   $ ./configure
+   $ make
+
+Then you can run the JavaScript tests in this directory:
+
+   $ cd js && gulp test
diff --git a/js/binary/arith.js b/js/binary/arith.js
new file mode 100644
index 0000000..70257de
--- /dev/null
+++ b/js/binary/arith.js
@@ -0,0 +1,413 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/**
+ * @fileoverview This file contains helper code used by jspb.utils to
+ * handle 64-bit integer conversion to/from strings.
+ *
+ * @author cfallin@google.com (Chris Fallin)
+ *
+ * TODO(haberman): move this to javascript/closure/math?
+ */
+
+goog.provide('jspb.arith.Int64');
+goog.provide('jspb.arith.UInt64');
+
+/**
+ * UInt64 implements some 64-bit arithmetic routines necessary for properly
+ * handling 64-bit integer fields. It implements lossless integer arithmetic on
+ * top of JavaScript's number type, which has only 53 bits of precision, by
+ * representing 64-bit integers as two 32-bit halves.
+ *
+ * @param {number} lo The low 32 bits.
+ * @param {number} hi The high 32 bits.
+ * @constructor
+ */
+jspb.arith.UInt64 = function(lo, hi) {
+  /**
+   * The low 32 bits.
+   * @public {number}
+   */
+  this.lo = lo;
+  /**
+   * The high 32 bits.
+   * @public {number}
+   */
+  this.hi = hi;
+};
+
+
+/**
+ * Compare two 64-bit numbers. Returns -1 if the first is
+ * less, +1 if the first is greater, or 0 if both are equal.
+ * @param {!jspb.arith.UInt64} other
+ * @return {number}
+ */
+jspb.arith.UInt64.prototype.cmp = function(other) {
+  if (this.hi < other.hi || (this.hi == other.hi && this.lo < other.lo)) {
+    return -1;
+  } else if (this.hi == other.hi && this.lo == other.lo) {
+    return 0;
+  } else {
+    return 1;
+  }
+};
+
+
+/**
+ * Right-shift this number by one bit.
+ * @return {!jspb.arith.UInt64}
+ */
+jspb.arith.UInt64.prototype.rightShift = function() {
+  var hi = this.hi >>> 1;
+  var lo = (this.lo >>> 1) | ((this.hi & 1) << 31);
+  return new jspb.arith.UInt64(lo >>> 0, hi >>> 0);
+};
+
+
+/**
+ * Left-shift this number by one bit.
+ * @return {!jspb.arith.UInt64}
+ */
+jspb.arith.UInt64.prototype.leftShift = function() {
+  var lo = this.lo << 1;
+  var hi = (this.hi << 1) | (this.lo >>> 31);
+  return new jspb.arith.UInt64(lo >>> 0, hi >>> 0);
+};
+
+
+/**
+ * Test the MSB.
+ * @return {boolean}
+ */
+jspb.arith.UInt64.prototype.msb = function() {
+  return !!(this.hi & 0x80000000);
+};
+
+
+/**
+ * Test the LSB.
+ * @return {boolean}
+ */
+jspb.arith.UInt64.prototype.lsb = function() {
+  return !!(this.lo & 1);
+};
+
+
+/**
+ * Test whether this number is zero.
+ * @return {boolean}
+ */
+jspb.arith.UInt64.prototype.zero = function() {
+  return this.lo == 0 && this.hi == 0;
+};
+
+
+/**
+ * Add two 64-bit numbers to produce a 64-bit number.
+ * @param {!jspb.arith.UInt64} other
+ * @return {!jspb.arith.UInt64}
+ */
+jspb.arith.UInt64.prototype.add = function(other) {
+  var lo = ((this.lo + other.lo) & 0xffffffff) >>> 0;
+  var hi =
+      (((this.hi + other.hi) & 0xffffffff) >>> 0) +
+      (((this.lo + other.lo) >= 0x100000000) ? 1 : 0);
+  return new jspb.arith.UInt64(lo >>> 0, hi >>> 0);
+};
+
+
+/**
+ * Subtract two 64-bit numbers to produce a 64-bit number.
+ * @param {!jspb.arith.UInt64} other
+ * @return {!jspb.arith.UInt64}
+ */
+jspb.arith.UInt64.prototype.sub = function(other) {
+  var lo = ((this.lo - other.lo) & 0xffffffff) >>> 0;
+  var hi =
+      (((this.hi - other.hi) & 0xffffffff) >>> 0) -
+      (((this.lo - other.lo) < 0) ? 1 : 0);
+  return new jspb.arith.UInt64(lo >>> 0, hi >>> 0);
+};
+
+
+/**
+ * Multiply two 32-bit numbers to produce a 64-bit number.
+ * @param {number} a The first integer:  must be in [0, 2^32-1).
+ * @param {number} b The second integer: must be in [0, 2^32-1).
+ * @return {!jspb.arith.UInt64}
+ */
+jspb.arith.UInt64.mul32x32 = function(a, b) {
+  // Directly multiplying two 32-bit numbers may produce up to 64 bits of
+  // precision, thus losing precision because of the 53-bit mantissa of
+  // JavaScript numbers. So we multiply with 16-bit digits (radix 65536)
+  // instead.
+  var aLow = (a & 0xffff);
+  var aHigh = (a >>> 16);
+  var bLow = (b & 0xffff);
+  var bHigh = (b >>> 16);
+  var productLow =
+      // 32-bit result, result bits 0-31, take all 32 bits
+      (aLow * bLow) +
+      // 32-bit result, result bits 16-47, take bottom 16 as our top 16
+      ((aLow * bHigh) & 0xffff) * 0x10000 +
+      // 32-bit result, result bits 16-47, take bottom 16 as our top 16
+      ((aHigh * bLow) & 0xffff) * 0x10000;
+  var productHigh =
+      // 32-bit result, result bits 32-63, take all 32 bits
+      (aHigh * bHigh) +
+      // 32-bit result, result bits 16-47, take top 16 as our bottom 16
+      ((aLow * bHigh) >>> 16) +
+      // 32-bit result, result bits 16-47, take top 16 as our bottom 16
+      ((aHigh * bLow) >>> 16);
+
+  // Carry. Note that we actually have up to *two* carries due to addition of
+  // three terms.
+  while (productLow >= 0x100000000) {
+    productLow -= 0x100000000;
+    productHigh += 1;
+  }
+
+  return new jspb.arith.UInt64(productLow >>> 0, productHigh >>> 0);
+};
+
+
+/**
+ * Multiply this number by a 32-bit number, producing a 96-bit number, then
+ * truncate the top 32 bits.
+ * @param {number} a The multiplier.
+ * @return {!jspb.arith.UInt64}
+ */
+jspb.arith.UInt64.prototype.mul = function(a) {
+  // Produce two parts: at bits 0-63, and 32-95.
+  var lo = jspb.arith.UInt64.mul32x32(this.lo, a);
+  var hi = jspb.arith.UInt64.mul32x32(this.hi, a);
+  // Left-shift hi by 32 bits, truncating its top bits. The parts will then be
+  // aligned for addition.
+  hi.hi = hi.lo;
+  hi.lo = 0;
+  return lo.add(hi);
+};
+
+
+/**
+ * Divide a 64-bit number by a 32-bit number to produce a
+ * 64-bit quotient and a 32-bit remainder.
+ * @param {number} _divisor
+ * @return {Array.<jspb.arith.UInt64>} array of [quotient, remainder],
+ * unless divisor is 0, in which case an empty array is returned.
+ */
+jspb.arith.UInt64.prototype.div = function(_divisor) {
+  if (_divisor == 0) {
+    return [];
+  }
+
+  // We perform long division using a radix-2 algorithm, for simplicity (i.e.,
+  // one bit at a time). TODO: optimize to a radix-2^32 algorithm, taking care
+  // to get the variable shifts right.
+  var quotient = new jspb.arith.UInt64(0, 0);
+  var remainder = new jspb.arith.UInt64(this.lo, this.hi);
+  var divisor = new jspb.arith.UInt64(_divisor, 0);
+  var unit = new jspb.arith.UInt64(1, 0);
+
+  // Left-shift the divisor and unit until the high bit of divisor is set.
+  while (!divisor.msb()) {
+    divisor = divisor.leftShift();
+    unit = unit.leftShift();
+  }
+
+  // Perform long division one bit at a time.
+  while (!unit.zero()) {
+    // If divisor < remainder, add unit to quotient and subtract divisor from
+    // remainder.
+    if (divisor.cmp(remainder) <= 0) {
+      quotient = quotient.add(unit);
+      remainder = remainder.sub(divisor);
+    }
+    // Right-shift the divisor and unit.
+    divisor = divisor.rightShift();
+    unit = unit.rightShift();
+  }
+
+  return [quotient, remainder];
+};
+
+
+/**
+ * Convert a 64-bit number to a string.
+ * @return {string}
+ * @override
+ */
+jspb.arith.UInt64.prototype.toString = function() {
+  var result = '';
+  var num = this;
+  while (!num.zero()) {
+    var divResult = num.div(10);
+    var quotient = divResult[0], remainder = divResult[1];
+    result = remainder.lo + result;
+    num = quotient;
+  }
+  if (result == '') {
+    result = '0';
+  }
+  return result;
+};
+
+
+/**
+ * Parse a string into a 64-bit number. Returns `null` on a parse error.
+ * @param {string} s
+ * @return {?jspb.arith.UInt64}
+ */
+jspb.arith.UInt64.fromString = function(s) {
+  var result = new jspb.arith.UInt64(0, 0);
+  // optimization: reuse this instance for each digit.
+  var digit64 = new jspb.arith.UInt64(0, 0);
+  for (var i = 0; i < s.length; i++) {
+    if (s[i] < '0' || s[i] > '9') {
+      return null;
+    }
+    var digit = parseInt(s[i], 10);
+    digit64.lo = digit;
+    result = result.mul(10).add(digit64);
+  }
+  return result;
+};
+
+
+/**
+ * Make a copy of the uint64.
+ * @return {!jspb.arith.UInt64}
+ */
+jspb.arith.UInt64.prototype.clone = function() {
+  return new jspb.arith.UInt64(this.lo, this.hi);
+};
+
+
+/**
+ * Int64 is like UInt64, but modifies string conversions to interpret the stored
+ * 64-bit value as a twos-complement-signed integer. It does *not* support the
+ * full range of operations that UInt64 does: only add, subtract, and string
+ * conversions.
+ *
+ * N.B. that multiply and divide routines are *NOT* supported. They will throw
+ * exceptions. (They are not necessary to implement string conversions, which
+ * are the only operations we really need in jspb.)
+ *
+ * @param {number} lo The low 32 bits.
+ * @param {number} hi The high 32 bits.
+ * @constructor
+ */
+jspb.arith.Int64 = function(lo, hi) {
+  /**
+   * The low 32 bits.
+   * @public {number}
+   */
+  this.lo = lo;
+  /**
+   * The high 32 bits.
+   * @public {number}
+   */
+  this.hi = hi;
+};
+
+
+/**
+ * Add two 64-bit numbers to produce a 64-bit number.
+ * @param {!jspb.arith.Int64} other
+ * @return {!jspb.arith.Int64}
+ */
+jspb.arith.Int64.prototype.add = function(other) {
+  var lo = ((this.lo + other.lo) & 0xffffffff) >>> 0;
+  var hi =
+      (((this.hi + other.hi) & 0xffffffff) >>> 0) +
+      (((this.lo + other.lo) >= 0x100000000) ? 1 : 0);
+  return new jspb.arith.Int64(lo >>> 0, hi >>> 0);
+};
+
+
+/**
+ * Subtract two 64-bit numbers to produce a 64-bit number.
+ * @param {!jspb.arith.Int64} other
+ * @return {!jspb.arith.Int64}
+ */
+jspb.arith.Int64.prototype.sub = function(other) {
+  var lo = ((this.lo - other.lo) & 0xffffffff) >>> 0;
+  var hi =
+      (((this.hi - other.hi) & 0xffffffff) >>> 0) -
+      (((this.lo - other.lo) < 0) ? 1 : 0);
+  return new jspb.arith.Int64(lo >>> 0, hi >>> 0);
+};
+
+
+/**
+ * Make a copy of the int64.
+ * @return {!jspb.arith.Int64}
+ */
+jspb.arith.Int64.prototype.clone = function() {
+  return new jspb.arith.Int64(this.lo, this.hi);
+};
+
+
+/**
+ * Convert a 64-bit number to a string.
+ * @return {string}
+ * @override
+ */
+jspb.arith.Int64.prototype.toString = function() {
+  // If the number is negative, find its twos-complement inverse.
+  var sign = (this.hi & 0x80000000) != 0;
+  var num = new jspb.arith.UInt64(this.lo, this.hi);
+  if (sign) {
+    num = new jspb.arith.UInt64(0, 0).sub(num);
+  }
+  return (sign ? '-' : '') + num.toString();
+};
+
+
+/**
+ * Parse a string into a 64-bit number. Returns `null` on a parse error.
+ * @param {string} s
+ * @return {?jspb.arith.Int64}
+ */
+jspb.arith.Int64.fromString = function(s) {
+  var hasNegative = (s.length > 0 && s[0] == '-');
+  if (hasNegative) {
+    s = s.substring(1);
+  }
+  var num = jspb.arith.UInt64.fromString(s);
+  if (num === null) {
+    return null;
+  }
+  if (hasNegative) {
+    num = new jspb.arith.UInt64(0, 0).sub(num);
+  }
+  return new jspb.arith.Int64(num.lo, num.hi);
+};
diff --git a/js/binary/arith_test.js b/js/binary/arith_test.js
new file mode 100644
index 0000000..89796bf
--- /dev/null
+++ b/js/binary/arith_test.js
@@ -0,0 +1,355 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/**
+ * @fileoverview Test cases for Int64-manipulation functions.
+ *
+ * Test suite is written using Jasmine -- see http://jasmine.github.io/
+ *
+ * @author cfallin@google.com (Chris Fallin)
+ */
+
+goog.require('goog.testing.asserts');
+goog.require('jspb.arith.Int64');
+goog.require('jspb.arith.UInt64');
+
+
+describe('binaryArithTest', function() {
+  /**
+   * Tests comparison operations.
+   */
+  it('testCompare', function() {
+    var a = new jspb.arith.UInt64(1234, 5678);
+    var b = new jspb.arith.UInt64(1234, 5678);
+    assertEquals(a.cmp(b), 0);
+    assertEquals(b.cmp(a), 0);
+    b.lo -= 1;
+    assertEquals(a.cmp(b), 1);
+    assertEquals(b.cmp(a), -1);
+    b.lo += 2;
+    assertEquals(a.cmp(b), -1);
+    assertEquals(b.cmp(a), 1);
+    b.lo = a.lo;
+    b.hi = a.hi - 1;
+    assertEquals(a.cmp(b), 1);
+    assertEquals(b.cmp(a), -1);
+
+    assertEquals(a.zero(), false);
+    assertEquals(a.msb(), false);
+    assertEquals(a.lsb(), false);
+    a.hi = 0;
+    a.lo = 0;
+    assertEquals(a.zero(), true);
+    a.hi = 0x80000000;
+    assertEquals(a.zero(), false);
+    assertEquals(a.msb(), true);
+    a.lo = 0x00000001;
+    assertEquals(a.lsb(), true);
+  });
+
+
+  /**
+   * Tests shifts.
+   */
+  it('testShifts', function() {
+    var a = new jspb.arith.UInt64(1, 0);
+    assertEquals(a.lo, 1);
+    assertEquals(a.hi, 0);
+    var orig = a;
+    a = a.leftShift();
+    assertEquals(orig.lo, 1);  // original unmodified.
+    assertEquals(orig.hi, 0);
+    assertEquals(a.lo, 2);
+    assertEquals(a.hi, 0);
+    a = a.leftShift();
+    assertEquals(a.lo, 4);
+    assertEquals(a.hi, 0);
+    for (var i = 0; i < 29; i++) {
+      a = a.leftShift();
+    }
+    assertEquals(a.lo, 0x80000000);
+    assertEquals(a.hi, 0);
+    a = a.leftShift();
+    assertEquals(a.lo, 0);
+    assertEquals(a.hi, 1);
+    a = a.leftShift();
+    assertEquals(a.lo, 0);
+    assertEquals(a.hi, 2);
+    a = a.rightShift();
+    a = a.rightShift();
+    assertEquals(a.lo, 0x80000000);
+    assertEquals(a.hi, 0);
+    a = a.rightShift();
+    assertEquals(a.lo, 0x40000000);
+    assertEquals(a.hi, 0);
+  });
+
+
+  /**
+   * Tests additions.
+   */
+  it('testAdd', function() {
+    var a = new jspb.arith.UInt64(/* lo = */ 0x89abcdef,
+                                         /* hi = */ 0x01234567);
+    var b = new jspb.arith.UInt64(/* lo = */ 0xff52ab91,
+                                         /* hi = */ 0x92fa2123);
+    // Addition with carry.
+    var c = a.add(b);
+    assertEquals(a.lo, 0x89abcdef);  // originals unmodified.
+    assertEquals(a.hi, 0x01234567);
+    assertEquals(b.lo, 0xff52ab91);
+    assertEquals(b.hi, 0x92fa2123);
+    assertEquals(c.lo, 0x88fe7980);
+    assertEquals(c.hi, 0x941d668b);
+
+    // Simple addition without carry.
+    a.lo = 2;
+    a.hi = 0;
+    b.lo = 3;
+    b.hi = 0;
+    c = a.add(b);
+    assertEquals(c.lo, 5);
+    assertEquals(c.hi, 0);
+  });
+
+
+  /**
+   * Test subtractions.
+   */
+  it('testSub', function() {
+    var kLength = 10;
+    var hiValues = [0x1682ef32,
+                    0x583902f7,
+                    0xb62f5955,
+                    0x6ea99bbf,
+                    0x25a39c20,
+                    0x0700a08b,
+                    0x00f7304d,
+                    0x91a5b5af,
+                    0x89077fd2,
+                    0xe09e347c];
+    var loValues = [0xe1538b18,
+                    0xbeacd556,
+                    0x74100758,
+                    0x96e3cb26,
+                    0x56c37c3f,
+                    0xe00b3f7d,
+                    0x859f25d7,
+                    0xc2ee614a,
+                    0xe1d21cd7,
+                    0x30aae6a4];
+    for (var i = 0; i < kLength; i++) {
+      for (var j = 0; j < kLength; j++) {
+        var a = new jspb.arith.UInt64(loValues[i], hiValues[j]);
+        var b = new jspb.arith.UInt64(loValues[j], hiValues[i]);
+        var c = a.add(b).sub(b);
+        assertEquals(c.hi, a.hi);
+        assertEquals(c.lo, a.lo);
+      }
+    }
+  });
+
+
+  /**
+   * Tests 32-by-32 multiplication.
+   */
+  it('testMul32x32', function() {
+    var testData = [
+      // a        b          low(a*b)   high(a*b)
+      [0xc0abe2f8, 0x1607898a, 0x5de711b0, 0x109471b8],
+      [0x915eb3cb, 0x4fb66d0e, 0xbd0d441a, 0x2d43d0bc],
+      [0xfe4efe70, 0x80b48c37, 0xbcddea10, 0x7fdada0c],
+      [0xe222fd4a, 0xe43d524a, 0xd5e0eb64, 0xc99d549c],
+      [0xd171f469, 0xb94ebd01, 0x4be17969, 0x979bc4fa],
+      [0x829cc1df, 0xe2598b38, 0xf4157dc8, 0x737c12ad],
+      [0xf10c3767, 0x8382881e, 0x942b3612, 0x7bd428b8],
+      [0xb0f6dd24, 0x232597e1, 0x079c98a4, 0x184bbce7],
+      [0xfcdb05a7, 0x902f55bc, 0x636199a4, 0x8e69f412],
+      [0x0dd0bfa9, 0x916e27b1, 0x6e2542d9, 0x07d92e65]
+    ];
+
+    for (var i = 0; i < testData.length; i++) {
+      var a = testData[i][0] >>> 0;
+      var b = testData[i][1] >>> 0;
+      var cLow = testData[i][2] >>> 0;
+      var cHigh = testData[i][3] >>> 0;
+      var c = jspb.arith.UInt64.mul32x32(a, b);
+      assertEquals(c.lo, cLow);
+      assertEquals(c.hi, cHigh);
+    }
+  });
+
+
+  /**
+   * Tests 64-by-32 multiplication.
+   */
+  it('testMul', function() {
+    // 64x32 bits produces 96 bits of product. The multiplication function under
+    // test truncates the top 32 bits, so we compare against a 64-bit expected
+    // product.
+    var testData = [
+      // low(a)   high(a)               low(a*b)   high(a*b)
+      [0xec10955b, 0x360eb168, 0x4b7f3f5b, 0xbfcb7c59, 0x9517da5f],
+      [0x42b000fc, 0x9d101642, 0x6fa1ab72, 0x2584c438, 0x6a9e6d2b],
+      [0xf42d4fb4, 0xae366403, 0xa65a1000, 0x92434000, 0x1ff978df],
+      [0x17e2f56b, 0x25487693, 0xf13f98c7, 0x73794e2d, 0xa96b0c6a],
+      [0x492f241f, 0x76c0eb67, 0x7377ac44, 0xd4336c3c, 0xfc4b1ebe],
+      [0xd6b92321, 0xe184fa48, 0xd6e76904, 0x93141584, 0xcbf44da1],
+      [0x4bf007ea, 0x968c0a9e, 0xf5e4026a, 0x4fdb1ae4, 0x61b9fb7d],
+      [0x10a83be7, 0x2d685ba6, 0xc9e5fb7f, 0x2ad43499, 0x3742473d],
+      [0x2f261829, 0x1aca681a, 0x3d3494e3, 0x8213205b, 0x283719f8],
+      [0xe4f2ce21, 0x2e74b7bd, 0xd801b38b, 0xbc17feeb, 0xc6c44e0f]
+    ];
+
+    for (var i = 0; i < testData.length; i++) {
+      var a = new jspb.arith.UInt64(testData[i][0], testData[i][1]);
+      var prod = a.mul(testData[i][2]);
+      assertEquals(prod.lo, testData[i][3]);
+      assertEquals(prod.hi, testData[i][4]);
+    }
+  });
+
+
+  /**
+   * Tests 64-div-by-32 division.
+   */
+  it('testDiv', function() {
+    // Compute a/b, yielding quot = a/b and rem = a%b.
+    var testData = [
+      // --- divisors in (0, 2^32-1) to test full divisor range
+      // low(a)   high(a)    b          low(quot)  high(quot) rem
+      [0x712443f1, 0xe85cefcc, 0xc1a7050b, 0x332c79ad, 0x00000001, 0x92ffa882],
+      [0x11912915, 0xb2699eb5, 0x30467cbe, 0xb21b4be4, 0x00000003, 0x283465dd],
+      [0x0d917982, 0x201f2a6e, 0x3f35bf03, 0x8217c8e4, 0x00000000, 0x153402d6],
+      [0xa072c108, 0x74020c96, 0xc60568fd, 0x95f9613e, 0x00000000, 0x3f4676c2],
+      [0xd845d5d8, 0xcdd235c4, 0x20426475, 0x6154e78b, 0x00000006, 0x202fb751],
+      [0xa4dbf71f, 0x9e90465e, 0xf08e022f, 0xa8be947f, 0x00000000, 0xbe43b5ce],
+      [0x3dbe627f, 0xa791f4b9, 0x28a5bd89, 0x1f5dfe93, 0x00000004, 0x02bf9ed4],
+      [0x5c1c53ee, 0xccf5102e, 0x198576e7, 0x07e3ae31, 0x00000008, 0x02ea8fb7],
+      [0xfef1e581, 0x04714067, 0xca6540c1, 0x059e73ec, 0x00000000, 0x31658095],
+      [0x1e2dd90c, 0x13dd6667, 0x8b2184c3, 0x248d1a42, 0x00000000, 0x4ca6d0c6],
+      // --- divisors in (0, 2^16-1) to test larger quotient high-words
+      // low(a)   high(a)    b          low(quot)  high(quot) rem
+      [0x86722b47, 0x2cd57c9a, 0x00003123, 0x2ae41b7a, 0x0000e995, 0x00000f99],
+      [0x1dd7884c, 0xf5e839bc, 0x00009eeb, 0x5c886242, 0x00018c21, 0x000099b6],
+      [0x5c53d625, 0x899fc7e5, 0x000087d7, 0xd625007a, 0x0001035c, 0x000019af],
+      [0x6932d932, 0x9d0a5488, 0x000051fb, 0x9d976143, 0x0001ea63, 0x00004981],
+      [0x4d18bb85, 0x0c92fb31, 0x00001d9f, 0x03265ab4, 0x00006cac, 0x000001b9],
+      [0xbe756768, 0xdea67ccb, 0x00008a03, 0x58add442, 0x00019cff, 0x000056a2],
+      [0xe2466f9a, 0x2521f114, 0x0000c350, 0xa0c0860d, 0x000030ab, 0x0000a48a],
+      [0xf00ddad1, 0xe2f5446a, 0x00002cfc, 0x762697a6, 0x00050b96, 0x00000b69],
+      [0xa879152a, 0x0a70e0a5, 0x00007cdf, 0xb44151b3, 0x00001567, 0x0000363d],
+      [0x7179a74c, 0x46083fff, 0x0000253c, 0x4d39ba6e, 0x0001e17f, 0x00000f84]
+    ];
+
+    for (var i = 0; i < testData.length; i++) {
+      var a = new jspb.arith.UInt64(testData[i][0], testData[i][1]);
+      var result = a.div(testData[i][2]);
+      var quotient = result[0];
+      var remainder = result[1];
+      assertEquals(quotient.lo, testData[i][3]);
+      assertEquals(quotient.hi, testData[i][4]);
+      assertEquals(remainder.lo, testData[i][5]);
+    }
+  });
+
+
+  /**
+   * Tests .toString() and .fromString().
+   */
+  it('testStrings', function() {
+    var testData = [
+        [0x5e84c935, 0xcae33d0e, '14619595947299359029'],
+        [0x62b3b8b8, 0x93480544, '10612738313170434232'],
+        [0x319bfb13, 0xc01c4172, '13843011313344445203'],
+        [0x5b8a65fb, 0xa5885b31, '11927883880638080507'],
+        [0x6bdb80f1, 0xb0d1b16b, '12741159895737008369'],
+        [0x4b82b442, 0x2e0d8c97, '3318463081876730946'],
+        [0x780d5208, 0x7d76752c, '9040542135845999112'],
+        [0x2e46800f, 0x0993778d, '690026616168284175'],
+        [0xf00a7e32, 0xcd8e3931, '14811839111111540274'],
+        [0x1baeccd6, 0x923048c4, '10533999535534820566'],
+        [0x03669d29, 0xbff3ab72, '13831587386756603177'],
+        [0x2526073e, 0x01affc81, '121593346566522686'],
+        [0xc24244e0, 0xd7f40d0e, '15561076969511732448'],
+        [0xc56a341e, 0xa68b66a7, '12000798502816461854'],
+        [0x8738d64d, 0xbfe78604, '13828168534871037517'],
+        [0x5baff03b, 0xd7572aea, '15516918227177304123'],
+        [0x4a843d8a, 0x864e132b, '9677693725920476554'],
+        [0x25b4e94d, 0x22b54dc6, '2500990681505655117'],
+        [0x6bbe664b, 0x55a5cc0e, '6171563226690381387'],
+        [0xee916c81, 0xb00aabb3, '12685140089732426881']
+    ];
+
+    for (var i = 0; i < testData.length; i++) {
+      var a = new jspb.arith.UInt64(testData[i][0], testData[i][1]);
+      var roundtrip = jspb.arith.UInt64.fromString(a.toString());
+      assertEquals(roundtrip.lo, a.lo);
+      assertEquals(roundtrip.hi, a.hi);
+      assertEquals(a.toString(), testData[i][2]);
+    }
+  });
+
+
+  /**
+   * Tests signed Int64s. These are built on UInt64s, so we only need to test
+   * the explicit overrides: .toString() and .fromString().
+   */
+  it('testSignedInt64', function() {
+    var testStrings = [
+        '-7847499644178593666',
+        '3771946501229139523',
+        '2872856549054995060',
+        '-5780049594274350904',
+        '3383785956695105201',
+        '2973055184857072610',
+        '-3879428459215627206',
+        '4589812431064156631',
+        '8484075557333689940',
+        '1075325817098092407',
+        '-4346697501012292314',
+        '2488620459718316637',
+        '6112655187423520672',
+        '-3655278273928612104',
+        '3439154019435803196',
+        '1004112478843763757',
+        '-6587790776614368413',
+        '664320065099714586',
+        '4760412909973292912',
+        '-7911903989602274672'
+    ];
+
+    for (var i = 0; i < testStrings.length; i++) {
+      var roundtrip =
+          jspb.arith.Int64.fromString(testStrings[i]).toString();
+      assertEquals(roundtrip, testStrings[i]);
+    }
+  });
+});
diff --git a/js/binary/constants.js b/js/binary/constants.js
new file mode 100644
index 0000000..a976e0b
--- /dev/null
+++ b/js/binary/constants.js
@@ -0,0 +1,320 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/**
+ * @fileoverview This file contains constants and typedefs used by
+ * jspb.BinaryReader and BinaryWriter.
+ *
+ * @author aappleby@google.com (Austin Appleby)
+ */
+
+goog.provide('jspb.AnyFieldType');
+goog.provide('jspb.BinaryConstants');
+goog.provide('jspb.BinaryMessage');
+goog.provide('jspb.BuilderFunction');
+goog.provide('jspb.ByteSource');
+goog.provide('jspb.ClonerFunction');
+goog.provide('jspb.ConstBinaryMessage');
+goog.provide('jspb.ReaderFunction');
+goog.provide('jspb.RecyclerFunction');
+goog.provide('jspb.WriterFunction');
+
+goog.forwardDeclare('jspb.Message');
+goog.forwardDeclare('jsproto.BinaryExtension');
+
+
+
+/**
+ * Base interface class for all const messages. Does __not__ define any
+ * methods, as doing so on a widely-used interface defeats dead-code
+ * elimination.
+ * @interface
+ */
+jspb.ConstBinaryMessage = function() {};
+
+
+
+/**
+ * Base interface class for all messages. Does __not__ define any methods, as
+ * doing so on a widely-used interface defeats dead-code elimination.
+ * @interface
+ * @extends {jspb.ConstBinaryMessage}
+ */
+jspb.BinaryMessage = function() {};
+
+
+/**
+ * The types convertible to Uint8Arrays. Strings are assumed to be
+ * base64-encoded.
+ * @typedef {ArrayBuffer|Uint8Array|Array<number>|string}
+ */
+jspb.ByteSource;
+
+
+/**
+ * A field in jspb can be a scalar, a block of bytes, another proto, or an
+ * array of any of the above.
+ * @typedef {boolean|number|string|Uint8Array|
+             jspb.BinaryMessage|jsproto.BinaryExtension|
+             Array<jspb.AnyFieldType>}
+ */
+jspb.AnyFieldType;
+
+
+/**
+ * A builder function creates an instance of a message object.
+ * @typedef {function():!jspb.BinaryMessage}
+ */
+jspb.BuilderFunction;
+
+
+/**
+ * A cloner function creates a deep copy of a message object.
+ * @typedef {function(jspb.ConstBinaryMessage):jspb.BinaryMessage}
+ */
+jspb.ClonerFunction;
+
+
+/**
+ * A recycler function destroys an instance of a message object.
+ * @typedef {function(!jspb.BinaryMessage):void}
+ */
+jspb.RecyclerFunction;
+
+
+/**
+ * A reader function initializes a message using data from a BinaryReader.
+ * @typedef {function(!jspb.BinaryMessage, !jspb.BinaryReader):void}
+ */
+jspb.ReaderFunction;
+
+
+/**
+ * A writer function serializes a message to a BinaryWriter.
+ * @typedef {!function(!jspb.Message, !jspb.BinaryWriter):void |
+ *           !function(!jspb.ConstBinaryMessage, !jspb.BinaryWriter):void}
+ */
+jspb.WriterFunction;
+
+
+/**
+ * Field type codes, taken from proto2/public/wire_format_lite.h.
+ * @enum {number}
+ */
+jspb.BinaryConstants.FieldType = {
+  INVALID: -1,
+  DOUBLE: 1,
+  FLOAT: 2,
+  INT64: 3,
+  UINT64: 4,
+  INT32: 5,
+  FIXED64: 6,
+  FIXED32: 7,
+  BOOL: 8,
+  STRING: 9,
+  GROUP: 10,
+  MESSAGE: 11,
+  BYTES: 12,
+  UINT32: 13,
+  ENUM: 14,
+  SFIXED32: 15,
+  SFIXED64: 16,
+  SINT32: 17,
+  SINT64: 18,
+
+  // Extended types for Javascript
+
+  FHASH64: 30, // 64-bit hash string, fixed-length encoding.
+  VHASH64: 31  // 64-bit hash string, varint encoding.
+};
+
+
+/**
+ * Wire-format type codes, taken from proto2/public/wire_format_lite.h.
+ * @enum {number}
+ */
+jspb.BinaryConstants.WireType = {
+  INVALID: -1,
+  VARINT: 0,
+  FIXED64: 1,
+  DELIMITED: 2,
+  START_GROUP: 3,
+  END_GROUP: 4,
+  FIXED32: 5
+};
+
+
+/**
+ * Translates field type to wire type.
+ * @param {jspb.BinaryConstants.FieldType} fieldType
+ * @return {jspb.BinaryConstants.WireType}
+ */
+jspb.BinaryConstants.FieldTypeToWireType = function(fieldType) {
+  var fieldTypes = jspb.BinaryConstants.FieldType;
+  var wireTypes = jspb.BinaryConstants.WireType;
+  switch (fieldType) {
+    case fieldTypes.INT32:
+    case fieldTypes.INT64:
+    case fieldTypes.UINT32:
+    case fieldTypes.UINT64:
+    case fieldTypes.SINT32:
+    case fieldTypes.SINT64:
+    case fieldTypes.BOOL:
+    case fieldTypes.ENUM:
+    case fieldTypes.VHASH64:
+      return wireTypes.VARINT;
+
+    case fieldTypes.DOUBLE:
+    case fieldTypes.FIXED64:
+    case fieldTypes.SFIXED64:
+    case fieldTypes.FHASH64:
+      return wireTypes.FIXED64;
+
+    case fieldTypes.STRING:
+    case fieldTypes.MESSAGE:
+    case fieldTypes.BYTES:
+      return wireTypes.DELIMITED;
+
+    case fieldTypes.FLOAT:
+    case fieldTypes.FIXED32:
+    case fieldTypes.SFIXED32:
+      return wireTypes.FIXED32;
+
+    case fieldTypes.INVALID:
+    case fieldTypes.GROUP:
+    default:
+      return wireTypes.INVALID;
+  }
+};
+
+
+/**
+ * Flag to indicate a missing field.
+ * @const {number}
+ */
+jspb.BinaryConstants.INVALID_FIELD_NUMBER = -1;
+
+
+/**
+ * The smallest denormal float32 value.
+ * @const {number}
+ */
+jspb.BinaryConstants.FLOAT32_EPS = 1.401298464324817e-45;
+
+
+/**
+ * The smallest normal float64 value.
+ * @const {number}
+ */
+jspb.BinaryConstants.FLOAT32_MIN = 1.1754943508222875e-38;
+
+
+/**
+ * The largest finite float32 value.
+ * @const {number}
+ */
+jspb.BinaryConstants.FLOAT32_MAX = 3.4028234663852886e+38;
+
+
+/**
+ * The smallest denormal float64 value.
+ * @const {number}
+ */
+jspb.BinaryConstants.FLOAT64_EPS = 5e-324;
+
+
+/**
+ * The smallest normal float64 value.
+ * @const {number}
+ */
+jspb.BinaryConstants.FLOAT64_MIN = 2.2250738585072014e-308;
+
+
+/**
+ * The largest finite float64 value.
+ * @const {number}
+ */
+jspb.BinaryConstants.FLOAT64_MAX = 1.7976931348623157e+308;
+
+
+/**
+ * Convenience constant equal to 2^20.
+ * @const {number}
+ */
+jspb.BinaryConstants.TWO_TO_20 = 1048576;
+
+
+/**
+ * Convenience constant equal to 2^23.
+ * @const {number}
+ */
+jspb.BinaryConstants.TWO_TO_23 = 8388608;
+
+
+/**
+ * Convenience constant equal to 2^31.
+ * @const {number}
+ */
+jspb.BinaryConstants.TWO_TO_31 = 2147483648;
+
+
+/**
+ * Convenience constant equal to 2^32.
+ * @const {number}
+ */
+jspb.BinaryConstants.TWO_TO_32 = 4294967296;
+
+
+/**
+ * Convenience constant equal to 2^52.
+ * @const {number}
+ */
+jspb.BinaryConstants.TWO_TO_52 = 4503599627370496;
+
+
+/**
+ * Convenience constant equal to 2^63.
+ * @const {number}
+ */
+jspb.BinaryConstants.TWO_TO_63 = 9223372036854775808;
+
+
+/**
+ * Convenience constant equal to 2^64.
+ * @const {number}
+ */
+jspb.BinaryConstants.TWO_TO_64 = 18446744073709551616;
+
+
+/**
+ * Eight-character string of zeros, used as the default 64-bit hash value.
+ * @const {string}
+ */
+jspb.BinaryConstants.ZERO_HASH = '\0\0\0\0\0\0\0\0';
diff --git a/js/binary/decoder.js b/js/binary/decoder.js
new file mode 100644
index 0000000..9004eff
--- /dev/null
+++ b/js/binary/decoder.js
@@ -0,0 +1,1005 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/**
+ * @fileoverview This file contains utilities for decoding primitive values
+ * (signed and unsigned integers, varints, booleans, enums, hashes, strings,
+ * and raw bytes) embedded in Uint8Arrays into their corresponding Javascript
+ * types.
+ *
+ * Major caveat - Javascript is unable to accurately represent integers larger
+ * than 2^53 due to its use of a double-precision floating point format or all
+ * numbers. If you need to guarantee that 64-bit values survive with all bits
+ * intact, you _must_ read them using one of the Hash64 methods, which return
+ * an 8-character string.
+ *
+ * @author aappleby@google.com (Austin Appleby)
+ */
+
+goog.provide('jspb.BinaryDecoder');
+goog.provide('jspb.BinaryIterator');
+
+goog.require('goog.asserts');
+goog.require('jspb.utils');
+
+
+
+/**
+ * Simple helper class for traversing the contents of repeated scalar fields.
+ * that may or may not have been packed into a wire-format blob.
+ * @param {?jspb.BinaryDecoder=} opt_decoder
+ * @param {?function(this:jspb.BinaryDecoder):(number|boolean|string)=}
+ *     opt_next The decoder method to use for next().
+ * @param {?Array.<number|boolean|string>=} opt_elements
+ * @constructor
+ * @struct
+ */
+jspb.BinaryIterator = function(opt_decoder, opt_next, opt_elements) {
+  /** @private {jspb.BinaryDecoder} */
+  this.decoder_ = null;
+
+  /**
+   * The BinaryDecoder member function used when iterating over packed data.
+   * @private {?function(this:jspb.BinaryDecoder):(number|boolean|string)}
+   */
+  this.nextMethod_ = null;
+
+  /** @private {Array.<number>} */
+  this.elements_ = null;
+
+  /** @private {number} */
+  this.cursor_ = 0;
+
+  /** @private {number|boolean|string|null} */
+  this.nextValue_ = null;
+
+  /** @private {boolean} */
+  this.atEnd_ = true;
+
+  this.init_(opt_decoder, opt_next, opt_elements);
+};
+
+
+/**
+ * @param {?jspb.BinaryDecoder=} opt_decoder
+ * @param {?function(this:jspb.BinaryDecoder):(number|boolean|string)=}
+ *     opt_next The decoder method to use for next().
+ * @param {?Array.<number|boolean|string>=} opt_elements
+ * @private
+ */
+jspb.BinaryIterator.prototype.init_ =
+    function(opt_decoder, opt_next, opt_elements) {
+  if (opt_decoder && opt_next) {
+    this.decoder_ = opt_decoder;
+    this.nextMethod_ = opt_next;
+  }
+  this.elements_ = opt_elements ? opt_elements : null;
+  this.cursor_ = 0;
+  this.nextValue_ = null;
+  this.atEnd_ = !this.decoder_ && !this.elements_;
+
+  this.next();
+};
+
+
+/**
+ * Global pool of BinaryIterator instances.
+ * @private {!Array.<!jspb.BinaryIterator>}
+ */
+jspb.BinaryIterator.instanceCache_ = [];
+
+
+/**
+ * Allocates a BinaryIterator from the cache, creating a new one if the cache
+ * is empty.
+ * @param {?jspb.BinaryDecoder=} opt_decoder
+ * @param {?function(this:jspb.BinaryDecoder):(number|boolean|string)=}
+ *     opt_next The decoder method to use for next().
+ * @param {?Array.<number|boolean|string>=} opt_elements
+ * @return {!jspb.BinaryIterator}
+ */
+jspb.BinaryIterator.alloc = function(opt_decoder, opt_next, opt_elements) {
+  if (jspb.BinaryIterator.instanceCache_.length) {
+    var iterator = jspb.BinaryIterator.instanceCache_.pop();
+    iterator.init_(opt_decoder, opt_next, opt_elements);
+    return iterator;
+  } else {
+    return new jspb.BinaryIterator(opt_decoder, opt_next, opt_elements);
+  }
+};
+
+
+/**
+ * Puts this instance back in the instance cache.
+ */
+jspb.BinaryIterator.prototype.free = function() {
+  this.clear();
+  if (jspb.BinaryIterator.instanceCache_.length < 100) {
+    jspb.BinaryIterator.instanceCache_.push(this);
+  }
+};
+
+
+/**
+ * Clears the iterator.
+ */
+jspb.BinaryIterator.prototype.clear = function() {
+  if (this.decoder_) {
+    this.decoder_.free();
+  }
+  this.decoder_ = null;
+  this.nextMethod_ = null;
+  this.elements_ = null;
+  this.cursor_ = 0;
+  this.nextValue_ = null;
+  this.atEnd_ = true;
+};
+
+
+/**
+ * Returns the element at the iterator, or null if the iterator is invalid or
+ * past the end of the decoder/array.
+ * @return {number|boolean|string|null}
+ */
+jspb.BinaryIterator.prototype.get = function() {
+  return this.nextValue_;
+};
+
+
+/**
+ * Returns true if the iterator is at the end of the decoder/array.
+ * @return {boolean}
+ */
+jspb.BinaryIterator.prototype.atEnd = function() {
+  return this.atEnd_;
+};
+
+
+/**
+ * Returns the element at the iterator and steps to the next element,
+ * equivalent to '*pointer++' in C.
+ * @return {number|boolean|string|null}
+ */
+jspb.BinaryIterator.prototype.next = function() {
+  var lastValue = this.nextValue_;
+  if (this.decoder_) {
+    if (this.decoder_.atEnd()) {
+      this.nextValue_ = null;
+      this.atEnd_ = true;
+    } else {
+      this.nextValue_ = this.nextMethod_.call(this.decoder_);
+    }
+  } else if (this.elements_) {
+    if (this.cursor_ == this.elements_.length) {
+      this.nextValue_ = null;
+      this.atEnd_ = true;
+    } else {
+      this.nextValue_ = this.elements_[this.cursor_++];
+    }
+  }
+  return lastValue;
+};
+
+
+
+/**
+ * BinaryDecoder implements the decoders for all the wire types specified in
+ * https://developers.google.com/protocol-buffers/docs/encoding.
+ *
+ * @param {jspb.ByteSource=} opt_bytes The bytes we're reading from.
+ * @param {number=} opt_start The optional offset to start reading at.
+ * @param {number=} opt_length The optional length of the block to read -
+ *     we'll throw an assertion if we go off the end of the block.
+ * @constructor
+ * @struct
+ */
+jspb.BinaryDecoder = function(opt_bytes, opt_start, opt_length) {
+  /**
+   * Typed byte-wise view of the source buffer.
+   * @private {Uint8Array}
+   */
+  this.bytes_ = null;
+
+  /**
+   * Start point of the block to read.
+   * @private {number}
+   */
+  this.start_ = 0;
+
+  /**
+   * End point of the block to read.
+   * @private {number}
+   */
+  this.end_ = 0;
+
+  /**
+   * Current read location in bytes_.
+   * @private {number}
+   */
+  this.cursor_ = 0;
+
+  /**
+   * Temporary storage for the low 32 bits of 64-bit data types that we're
+   * decoding.
+   * @private {number}
+   */
+  this.tempLow_ = 0;
+
+  /**
+   * Temporary storage for the high 32 bits of 64-bit data types that we're
+   * decoding.
+   * @private {number}
+   */
+  this.tempHigh_ = 0;
+
+  /**
+   * Set to true if this decoder encountered an error due to corrupt data.
+   * @private {boolean}
+   */
+  this.error_ = false;
+
+  if (opt_bytes) {
+    this.setBlock(opt_bytes, opt_start, opt_length);
+  }
+};
+
+
+/**
+ * Global pool of BinaryDecoder instances.
+ * @private {!Array.<!jspb.BinaryDecoder>}
+ */
+jspb.BinaryDecoder.instanceCache_ = [];
+
+
+/**
+ * Pops an instance off the instance cache, or creates one if the cache is
+ * empty.
+ * @param {jspb.ByteSource=} opt_bytes The bytes we're reading from.
+ * @param {number=} opt_start The optional offset to start reading at.
+ * @param {number=} opt_length The optional length of the block to read -
+ *     we'll throw an assertion if we go off the end of the block.
+ * @return {!jspb.BinaryDecoder}
+ */
+jspb.BinaryDecoder.alloc = function(opt_bytes, opt_start, opt_length) {
+  if (jspb.BinaryDecoder.instanceCache_.length) {
+    var newDecoder = jspb.BinaryDecoder.instanceCache_.pop();
+    if (opt_bytes) {
+      newDecoder.setBlock(opt_bytes, opt_start, opt_length);
+    }
+    return newDecoder;
+  } else {
+    return new jspb.BinaryDecoder(opt_bytes, opt_start, opt_length);
+  }
+};
+
+
+/**
+ * Puts this instance back in the instance cache.
+ */
+jspb.BinaryDecoder.prototype.free = function() {
+  this.clear();
+  if (jspb.BinaryDecoder.instanceCache_.length < 100) {
+    jspb.BinaryDecoder.instanceCache_.push(this);
+  }
+};
+
+
+/**
+ * Makes a copy of this decoder.
+ * @return {!jspb.BinaryDecoder}
+ */
+jspb.BinaryDecoder.prototype.clone = function() {
+  return jspb.BinaryDecoder.alloc(this.bytes_,
+      this.start_, this.end_ - this.start_);
+};
+
+
+/**
+ * Clears the decoder.
+ */
+jspb.BinaryDecoder.prototype.clear = function() {
+  this.bytes_ = null;
+  this.start_ = 0;
+  this.end_ = 0;
+  this.cursor_ = 0;
+  this.error_ = false;
+};
+
+
+/**
+ * Returns the raw buffer.
+ * @return {Uint8Array} The raw buffer.
+ */
+jspb.BinaryDecoder.prototype.getBuffer = function() {
+  return this.bytes_;
+};
+
+
+/**
+ * Changes the block of bytes we're decoding.
+ * @param {!jspb.ByteSource} data The bytes we're reading from.
+ * @param {number=} opt_start The optional offset to start reading at.
+ * @param {number=} opt_length The optional length of the block to read -
+ *     we'll throw an assertion if we go off the end of the block.
+ */
+jspb.BinaryDecoder.prototype.setBlock =
+    function(data, opt_start, opt_length) {
+  this.bytes_ = jspb.utils.byteSourceToUint8Array(data);
+  this.start_ = goog.isDef(opt_start) ? opt_start : 0;
+  this.end_ =
+      goog.isDef(opt_length) ? this.start_ + opt_length : this.bytes_.length;
+  this.cursor_ = this.start_;
+};
+
+
+/**
+ * @return {number}
+ */
+jspb.BinaryDecoder.prototype.getEnd = function() {
+  return this.end_;
+};
+
+
+/**
+ * @param {number} end
+ */
+jspb.BinaryDecoder.prototype.setEnd = function(end) {
+  this.end_ = end;
+};
+
+
+/**
+ * Moves the read cursor back to the start of the block.
+ */
+jspb.BinaryDecoder.prototype.reset = function() {
+  this.cursor_ = this.start_;
+};
+
+
+/**
+ * Returns the internal read cursor.
+ * @return {number} The internal read cursor.
+ */
+jspb.BinaryDecoder.prototype.getCursor = function() {
+  return this.cursor_;
+};
+
+
+/**
+ * Returns the internal read cursor.
+ * @param {number} cursor The new cursor.
+ */
+jspb.BinaryDecoder.prototype.setCursor = function(cursor) {
+  this.cursor_ = cursor;
+};
+
+
+/**
+ * Advances the stream cursor by the given number of bytes.
+ * @param {number} count The number of bytes to advance by.
+ */
+jspb.BinaryDecoder.prototype.advance = function(count) {
+  this.cursor_ += count;
+  goog.asserts.assert(this.cursor_ <= this.end_);
+};
+
+
+/**
+ * Returns true if this decoder is at the end of the block.
+ * @return {boolean}
+ */
+jspb.BinaryDecoder.prototype.atEnd = function() {
+  return this.cursor_ == this.end_;
+};
+
+
+/**
+ * Returns true if this decoder is at the end of the block.
+ * @return {boolean}
+ */
+jspb.BinaryDecoder.prototype.pastEnd = function() {
+  return this.cursor_ > this.end_;
+};
+
+
+/**
+ * Returns true if this decoder encountered an error due to corrupt data.
+ * @return {boolean}
+ */
+jspb.BinaryDecoder.prototype.getError = function() {
+  return this.error_ ||
+         (this.cursor_ < 0) ||
+         (this.cursor_ > this.end_);
+};
+
+
+/**
+ * Reads an unsigned varint from the binary stream and stores it as a split
+ * 64-bit integer. Since this does not convert the value to a number, no
+ * precision is lost.
+ *
+ * It's possible for an unsigned varint to be incorrectly encoded - more than
+ * 64 bits' worth of data could be present. If this happens, this method will
+ * throw an error.
+ *
+ * Decoding varints requires doing some funny base-128 math - for more
+ * details on the format, see
+ * https://developers.google.com/protocol-buffers/docs/encoding
+ *
+ * @private
+ */
+jspb.BinaryDecoder.prototype.readSplitVarint64_ = function() {
+  var temp;
+  var lowBits = 0;
+  var highBits = 0;
+
+  // Read the first four bytes of the varint, stopping at the terminator if we
+  // see it.
+  for (var i = 0; i < 4; i++) {
+    temp = this.bytes_[this.cursor_++];
+    lowBits |= (temp & 0x7F) << (i * 7);
+    if (temp < 128) {
+      this.tempLow_ = lowBits >>> 0;
+      this.tempHigh_ = 0;
+      return;
+    }
+  }
+
+  // Read the fifth byte, which straddles the low and high dwords.
+  temp = this.bytes_[this.cursor_++];
+  lowBits |= (temp & 0x7F) << 28;
+  highBits |= (temp & 0x7F) >> 4;
+  if (temp < 128) {
+    this.tempLow_ = lowBits >>> 0;
+    this.tempHigh_ = highBits >>> 0;
+    return;
+  }
+
+  // Read the sixth through tenth byte.
+  for (var i = 0; i < 5; i++) {
+    temp = this.bytes_[this.cursor_++];
+    highBits |= (temp & 0x7F) << (i * 7 + 3);
+    if (temp < 128) {
+      this.tempLow_ = lowBits >>> 0;
+      this.tempHigh_ = highBits >>> 0;
+      return;
+    }
+  }
+
+  // If we did not see the terminator, the encoding was invalid.
+  goog.asserts.fail('Failed to read varint, encoding is invalid.');
+  this.error_ = true;
+};
+
+
+/**
+ * Skips over a varint in the block without decoding it.
+ */
+jspb.BinaryDecoder.prototype.skipVarint = function() {
+  while (this.bytes_[this.cursor_] & 0x80) {
+    this.cursor_++;
+  }
+  this.cursor_++;
+};
+
+
+/**
+ * Skips backwards over a varint in the block - to do this correctly, we have
+ * to know the value we're skipping backwards over or things are ambiguous.
+ * @param {number} value The varint value to unskip.
+ */
+jspb.BinaryDecoder.prototype.unskipVarint = function(value) {
+  while (value > 128) {
+    this.cursor_--;
+    value = value >>> 7;
+  }
+  this.cursor_--;
+};
+
+
+/**
+ * Reads a 32-bit varint from the binary stream. Due to a quirk of the encoding
+ * format and Javascript's handling of bitwise math, this actually works
+ * correctly for both signed and unsigned 32-bit varints.
+ *
+ * This function is called vastly more frequently than any other in
+ * BinaryDecoder, so it has been unrolled and tweaked for performance.
+ *
+ * If there are more than 32 bits of data in the varint, it _must_ be due to
+ * sign-extension. If we're in debug mode and the high 32 bits don't match the
+ * expected sign extension, this method will throw an error.
+ *
+ * Decoding varints requires doing some funny base-128 math - for more
+ * details on the format, see
+ * https://developers.google.com/protocol-buffers/docs/encoding
+ *
+ * @return {number} The decoded unsigned 32-bit varint.
+ */
+jspb.BinaryDecoder.prototype.readUnsignedVarint32 = function() {
+  var temp;
+  var bytes = this.bytes_;
+
+  temp = bytes[this.cursor_ + 0];
+  var x = (temp & 0x7F);
+  if (temp < 128) {
+    this.cursor_ += 1;
+    goog.asserts.assert(this.cursor_ <= this.end_);
+    return x;
+  }
+
+  temp = bytes[this.cursor_ + 1];
+  x |= (temp & 0x7F) << 7;
+  if (temp < 128) {
+    this.cursor_ += 2;
+    goog.asserts.assert(this.cursor_ <= this.end_);
+    return x;
+  }
+
+  temp = bytes[this.cursor_ + 2];
+  x |= (temp & 0x7F) << 14;
+  if (temp < 128) {
+    this.cursor_ += 3;
+    goog.asserts.assert(this.cursor_ <= this.end_);
+    return x;
+  }
+
+  temp = bytes[this.cursor_ + 3];
+  x |= (temp & 0x7F) << 21;
+  if (temp < 128) {
+    this.cursor_ += 4;
+    goog.asserts.assert(this.cursor_ <= this.end_);
+    return x;
+  }
+
+  temp = bytes[this.cursor_ + 4];
+  x |= (temp & 0x0F) << 28;
+  if (temp < 128) {
+    // We're reading the high bits of an unsigned varint. The byte we just read
+    // also contains bits 33 through 35, which we're going to discard. Those
+    // bits _must_ be zero, or the encoding is invalid.
+    goog.asserts.assert((temp & 0xF0) == 0);
+    this.cursor_ += 5;
+    goog.asserts.assert(this.cursor_ <= this.end_);
+    return x >>> 0;
+  }
+
+  // If we get here, we're reading the sign extension of a negative 32-bit int.
+  // We can skip these bytes, as we know in advance that they have to be all
+  // 1's if the varint is correctly encoded. Since we also know the value is
+  // negative, we don't have to coerce it to unsigned before we return it.
+
+  goog.asserts.assert((temp & 0xF0) == 0xF0);
+  goog.asserts.assert(bytes[this.cursor_ + 5] == 0xFF);
+  goog.asserts.assert(bytes[this.cursor_ + 6] == 0xFF);
+  goog.asserts.assert(bytes[this.cursor_ + 7] == 0xFF);
+  goog.asserts.assert(bytes[this.cursor_ + 8] == 0xFF);
+  goog.asserts.assert(bytes[this.cursor_ + 9] == 0x01);
+
+  this.cursor_ += 10;
+  goog.asserts.assert(this.cursor_ <= this.end_);
+  return x;
+};
+
+
+/**
+ * The readUnsignedVarint32 above deals with signed 32-bit varints correctly,
+ * so this is just an alias.
+ *
+ * @return {number} The decoded signed 32-bit varint.
+ */
+jspb.BinaryDecoder.prototype.readSignedVarint32 =
+    jspb.BinaryDecoder.prototype.readUnsignedVarint32;
+
+
+/**
+ * Reads a 32-bit unsigned variant and returns its value as a string.
+ *
+ * @return {string} The decoded unsigned 32-bit varint as a string.
+ */
+jspb.BinaryDecoder.prototype.readUnsignedVarint32String = function() {
+  // 32-bit integers fit in JavaScript numbers without loss of precision, so
+  // string variants of 32-bit varint readers can simply delegate then convert
+  // to string.
+  var value = this.readUnsignedVarint32();
+  return value.toString();
+};
+
+/**
+ * Reads a 32-bit signed variant and returns its value as a string.
+ *
+ * @return {string} The decoded signed 32-bit varint as a string.
+ */
+jspb.BinaryDecoder.prototype.readSignedVarint32String = function() {
+  // 32-bit integers fit in JavaScript numbers without loss of precision, so
+  // string variants of 32-bit varint readers can simply delegate then convert
+  // to string.
+  var value = this.readSignedVarint32();
+  return value.toString();
+};
+
+
+/**
+ * Reads a signed, zigzag-encoded 32-bit varint from the binary stream.
+ *
+ * Zigzag encoding is a modification of varint encoding that reduces the
+ * storage overhead for small negative integers - for more details on the
+ * format, see https://developers.google.com/protocol-buffers/docs/encoding
+ *
+ * @return {number} The decoded signed, zigzag-encoded 32-bit varint.
+ */
+jspb.BinaryDecoder.prototype.readZigzagVarint32 = function() {
+  var result = this.readUnsignedVarint32();
+  return (result >>> 1) ^ - (result & 1);
+};
+
+
+/**
+ * Reads an unsigned 64-bit varint from the binary stream. Note that since
+ * Javascript represents all numbers as double-precision floats, there will be
+ * precision lost if the absolute value of the varint is larger than 2^53.
+ *
+ * @return {number} The decoded unsigned varint. Precision will be lost if the
+ *     integer exceeds 2^53.
+ */
+jspb.BinaryDecoder.prototype.readUnsignedVarint64 = function() {
+  this.readSplitVarint64_();
+  return jspb.utils.joinUint64(this.tempLow_, this.tempHigh_);
+};
+
+
+/**
+ * Reads an unsigned 64-bit varint from the binary stream and returns the value
+ * as a decimal string.
+ *
+ * @return {string} The decoded unsigned varint as a decimal string.
+ */
+jspb.BinaryDecoder.prototype.readUnsignedVarint64String = function() {
+  this.readSplitVarint64_();
+  return jspb.utils.joinUnsignedDecimalString(this.tempLow_, this.tempHigh_);
+};
+
+
+/**
+ * Reads a signed 64-bit varint from the binary stream. Note that since
+ * Javascript represents all numbers as double-precision floats, there will be
+ * precision lost if the absolute value of the varint is larger than 2^53.
+ *
+ * @return {number} The decoded signed varint. Precision will be lost if the
+ *     integer exceeds 2^53.
+ */
+jspb.BinaryDecoder.prototype.readSignedVarint64 = function() {
+  this.readSplitVarint64_();
+  return jspb.utils.joinInt64(this.tempLow_, this.tempHigh_);
+};
+
+
+/**
+ * Reads an signed 64-bit varint from the binary stream and returns the value
+ * as a decimal string.
+ *
+ * @return {string} The decoded signed varint as a decimal string.
+ */
+jspb.BinaryDecoder.prototype.readSignedVarint64String = function() {
+  this.readSplitVarint64_();
+  return jspb.utils.joinSignedDecimalString(this.tempLow_, this.tempHigh_);
+};
+
+
+/**
+ * Reads a signed, zigzag-encoded 64-bit varint from the binary stream. Note
+ * that since Javascript represents all numbers as double-precision floats,
+ * there will be precision lost if the absolute value of the varint is larger
+ * than 2^53.
+ *
+ * Zigzag encoding is a modification of varint encoding that reduces the
+ * storage overhead for small negative integers - for more details on the
+ * format, see https://developers.google.com/protocol-buffers/docs/encoding
+ *
+ * @return {number} The decoded zigzag varint. Precision will be lost if the
+ *     integer exceeds 2^53.
+ */
+jspb.BinaryDecoder.prototype.readZigzagVarint64 = function() {
+  this.readSplitVarint64_();
+  return jspb.utils.joinZigzag64(this.tempLow_, this.tempHigh_);
+};
+
+
+/**
+ * Reads a raw unsigned 8-bit integer from the binary stream.
+ *
+ * @return {number} The unsigned 8-bit integer read from the binary stream.
+ */
+jspb.BinaryDecoder.prototype.readUint8 = function() {
+  var a = this.bytes_[this.cursor_ + 0];
+  this.cursor_ += 1;
+  goog.asserts.assert(this.cursor_ <= this.end_);
+  return a;
+};
+
+
+/**
+ * Reads a raw unsigned 16-bit integer from the binary stream.
+ *
+ * @return {number} The unsigned 16-bit integer read from the binary stream.
+ */
+jspb.BinaryDecoder.prototype.readUint16 = function() {
+  var a = this.bytes_[this.cursor_ + 0];
+  var b = this.bytes_[this.cursor_ + 1];
+  this.cursor_ += 2;
+  goog.asserts.assert(this.cursor_ <= this.end_);
+  return (a << 0) | (b << 8);
+};
+
+
+/**
+ * Reads a raw unsigned 32-bit integer from the binary stream.
+ *
+ * @return {number} The unsigned 32-bit integer read from the binary stream.
+ */
+jspb.BinaryDecoder.prototype.readUint32 = function() {
+  var a = this.bytes_[this.cursor_ + 0];
+  var b = this.bytes_[this.cursor_ + 1];
+  var c = this.bytes_[this.cursor_ + 2];
+  var d = this.bytes_[this.cursor_ + 3];
+  this.cursor_ += 4;
+  goog.asserts.assert(this.cursor_ <= this.end_);
+  return ((a << 0) | (b << 8) | (c << 16) | (d << 24)) >>> 0;
+};
+
+
+/**
+ * Reads a raw unsigned 64-bit integer from the binary stream. Note that since
+ * Javascript represents all numbers as double-precision floats, there will be
+ * precision lost if the absolute value of the integer is larger than 2^53.
+ *
+ * @return {number} The unsigned 64-bit integer read from the binary stream.
+ *     Precision will be lost if the integer exceeds 2^53.
+ */
+jspb.BinaryDecoder.prototype.readUint64 = function() {
+  var bitsLow = this.readUint32();
+  var bitsHigh = this.readUint32();
+  return jspb.utils.joinUint64(bitsLow, bitsHigh);
+};
+
+
+/**
+ * Reads a raw signed 8-bit integer from the binary stream.
+ *
+ * @return {number} The signed 8-bit integer read from the binary stream.
+ */
+jspb.BinaryDecoder.prototype.readInt8 = function() {
+  var a = this.bytes_[this.cursor_ + 0];
+  this.cursor_ += 1;
+  goog.asserts.assert(this.cursor_ <= this.end_);
+  return (a << 24) >> 24;
+};
+
+
+/**
+ * Reads a raw signed 16-bit integer from the binary stream.
+ *
+ * @return {number} The signed 16-bit integer read from the binary stream.
+ */
+jspb.BinaryDecoder.prototype.readInt16 = function() {
+  var a = this.bytes_[this.cursor_ + 0];
+  var b = this.bytes_[this.cursor_ + 1];
+  this.cursor_ += 2;
+  goog.asserts.assert(this.cursor_ <= this.end_);
+  return (((a << 0) | (b << 8)) << 16) >> 16;
+};
+
+
+/**
+ * Reads a raw signed 32-bit integer from the binary stream.
+ *
+ * @return {number} The signed 32-bit integer read from the binary stream.
+ */
+jspb.BinaryDecoder.prototype.readInt32 = function() {
+  var a = this.bytes_[this.cursor_ + 0];
+  var b = this.bytes_[this.cursor_ + 1];
+  var c = this.bytes_[this.cursor_ + 2];
+  var d = this.bytes_[this.cursor_ + 3];
+  this.cursor_ += 4;
+  goog.asserts.assert(this.cursor_ <= this.end_);
+  return (a << 0) | (b << 8) | (c << 16) | (d << 24);
+};
+
+
+/**
+ * Reads a raw signed 64-bit integer from the binary stream. Note that since
+ * Javascript represents all numbers as double-precision floats, there will be
+ * precision lost if the absolute vlaue of the integer is larger than 2^53.
+ *
+ * @return {number} The signed 64-bit integer read from the binary stream.
+ *     Precision will be lost if the integer exceeds 2^53.
+ */
+jspb.BinaryDecoder.prototype.readInt64 = function() {
+  var bitsLow = this.readUint32();
+  var bitsHigh = this.readUint32();
+  return jspb.utils.joinInt64(bitsLow, bitsHigh);
+};
+
+
+/**
+ * Reads a 32-bit floating-point number from the binary stream, using the
+ * temporary buffer to realign the data.
+ *
+ * @return {number} The float read from the binary stream.
+ */
+jspb.BinaryDecoder.prototype.readFloat = function() {
+  var bitsLow = this.readUint32();
+  var bitsHigh = 0;
+  return jspb.utils.joinFloat32(bitsLow, bitsHigh);
+};
+
+
+/**
+ * Reads a 64-bit floating-point number from the binary stream, using the
+ * temporary buffer to realign the data.
+ *
+ * @return {number} The double read from the binary stream.
+ */
+jspb.BinaryDecoder.prototype.readDouble = function() {
+  var bitsLow = this.readUint32();
+  var bitsHigh = this.readUint32();
+  return jspb.utils.joinFloat64(bitsLow, bitsHigh);
+};
+
+
+/**
+ * Reads a boolean value from the binary stream.
+ * @return {boolean} The boolean read from the binary stream.
+ */
+jspb.BinaryDecoder.prototype.readBool = function() {
+  return !!this.bytes_[this.cursor_++];
+};
+
+
+/**
+ * Reads an enum value from the binary stream, which are always encoded as
+ * signed varints.
+ * @return {number} The enum value read from the binary stream.
+ */
+jspb.BinaryDecoder.prototype.readEnum = function() {
+  return this.readSignedVarint32();
+};
+
+
+/**
+ * Reads and parses a UTF-8 encoded unicode string from the stream.
+ * The code is inspired by maps.vectortown.parse.StreamedDataViewReader, with
+ * the exception that the implementation here does not get confused if it
+ * encounters characters longer than three bytes. These characters are ignored
+ * though, as they are extremely rare: three UTF-8 bytes cover virtually all
+ * characters in common use (http://en.wikipedia.org/wiki/UTF-8).
+ * @param {number} length The length of the string to read.
+ * @return {string} The decoded string.
+ */
+jspb.BinaryDecoder.prototype.readString = function(length) {
+  var bytes = this.bytes_;
+  var cursor = this.cursor_;
+  var end = cursor + length;
+  var chars = [];
+
+  while (cursor < end) {
+    var c = bytes[cursor++];
+    if (c < 128) { // Regular 7-bit ASCII.
+      chars.push(c);
+    } else if (c < 192) {
+      // UTF-8 continuation mark. We are out of sync. This
+      // might happen if we attempted to read a character
+      // with more than three bytes.
+      continue;
+    } else if (c < 224) { // UTF-8 with two bytes.
+      var c2 = bytes[cursor++];
+      chars.push(((c & 31) << 6) | (c2 & 63));
+    } else if (c < 240) { // UTF-8 with three bytes.
+      var c2 = bytes[cursor++];
+      var c3 = bytes[cursor++];
+      chars.push(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
+    }
+  }
+
+  // String.fromCharCode.apply is faster than manually appending characters on
+  // Chrome 25+, and generates no additional cons string garbage.
+  var result = String.fromCharCode.apply(null, chars);
+  this.cursor_ = cursor;
+  return result;
+};
+
+
+/**
+ * Reads and parses a UTF-8 encoded unicode string (with length prefix) from
+ * the stream.
+ * @return {string} The decoded string.
+ */
+jspb.BinaryDecoder.prototype.readStringWithLength = function() {
+  var length = this.readUnsignedVarint32();
+  return this.readString(length);
+};
+
+
+/**
+ * Reads a block of raw bytes from the binary stream.
+ *
+ * @param {number} length The number of bytes to read.
+ * @return {Uint8Array} The decoded block of bytes, or null if the length was
+ *     invalid.
+ */
+jspb.BinaryDecoder.prototype.readBytes = function(length) {
+  if (length < 0 ||
+      this.cursor_ + length > this.bytes_.length) {
+    this.error_ = true;
+    return null;
+  }
+
+  var result = this.bytes_.subarray(this.cursor_, this.cursor_ + length);
+
+  this.cursor_ += length;
+  goog.asserts.assert(this.cursor_ <= this.end_);
+  return result;
+};
+
+
+/**
+ * Reads a 64-bit varint from the stream and returns it as an 8-character
+ * Unicode string for use as a hash table key.
+ *
+ * @return {string} The hash value.
+ */
+jspb.BinaryDecoder.prototype.readVarintHash64 = function() {
+  this.readSplitVarint64_();
+  return jspb.utils.joinHash64(this.tempLow_, this.tempHigh_);
+};
+
+
+/**
+ * Reads a 64-bit fixed-width value from the stream and returns it as an
+ * 8-character Unicode string for use as a hash table key.
+ *
+ * @return {string} The hash value.
+ */
+jspb.BinaryDecoder.prototype.readFixedHash64 = function() {
+  var bytes = this.bytes_;
+  var cursor = this.cursor_;
+
+  var a = bytes[cursor + 0];
+  var b = bytes[cursor + 1];
+  var c = bytes[cursor + 2];
+  var d = bytes[cursor + 3];
+  var e = bytes[cursor + 4];
+  var f = bytes[cursor + 5];
+  var g = bytes[cursor + 6];
+  var h = bytes[cursor + 7];
+
+  this.cursor_ += 8;
+
+  return String.fromCharCode(a, b, c, d, e, f, g, h);
+};
diff --git a/js/binary/decoder_test.js b/js/binary/decoder_test.js
new file mode 100644
index 0000000..27342e4
--- /dev/null
+++ b/js/binary/decoder_test.js
@@ -0,0 +1,327 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/**
+ * @fileoverview Test cases for jspb's binary protocol buffer decoder.
+ *
+ * There are two particular magic numbers that need to be pointed out -
+ * 2^64-1025 is the largest number representable as both a double and an
+ * unsigned 64-bit integer, and 2^63-513 is the largest number representable as
+ * both a double and a signed 64-bit integer.
+ *
+ * Test suite is written using Jasmine -- see http://jasmine.github.io/
+ *
+ * @author aappleby@google.com (Austin Appleby)
+ */
+
+goog.require('goog.testing.asserts');
+goog.require('jspb.BinaryConstants');
+goog.require('jspb.BinaryDecoder');
+goog.require('jspb.BinaryWriter');
+
+
+/**
+ * Tests raw encoding and decoding of unsigned types.
+ * @param {Function} readValue
+ * @param {Function} writeValue
+ * @param {number} epsilon
+ * @param {number} upperLimit
+ * @param {Function} filter
+ * @suppress {missingProperties|visibility}
+ */
+function doTestUnsignedValue(readValue,
+    writeValue, epsilon, upperLimit, filter) {
+  var writer = new jspb.BinaryWriter();
+
+  // Encode zero and limits.
+  writeValue.call(writer, filter(0));
+  writeValue.call(writer, filter(epsilon));
+  writeValue.call(writer, filter(upperLimit));
+
+  // Encode positive values.
+  for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
+    writeValue.call(writer, filter(cursor));
+  }
+
+  var reader = jspb.BinaryDecoder.alloc(writer.getResultBuffer());
+
+  // Check zero and limits.
+  assertEquals(filter(0), readValue.call(reader));
+  assertEquals(filter(epsilon), readValue.call(reader));
+  assertEquals(filter(upperLimit), readValue.call(reader));
+
+  // Check positive values.
+  for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
+    if (filter(cursor) != readValue.call(reader)) throw 'fail!';
+  }
+}
+
+
+/**
+ * Tests raw encoding and decoding of signed types.
+ * @param {Function} readValue
+ * @param {Function} writeValue
+ * @param {number} epsilon
+ * @param {number} lowerLimit
+ * @param {number} upperLimit
+ * @param {Function} filter
+ * @suppress {missingProperties}
+ */
+function doTestSignedValue(readValue,
+    writeValue, epsilon, lowerLimit, upperLimit, filter) {
+  var writer = new jspb.BinaryWriter();
+
+  // Encode zero and limits.
+  writeValue.call(writer, filter(lowerLimit));
+  writeValue.call(writer, filter(-epsilon));
+  writeValue.call(writer, filter(0));
+  writeValue.call(writer, filter(epsilon));
+  writeValue.call(writer, filter(upperLimit));
+
+  var inputValues = [];
+
+  // Encode negative values.
+  for (var cursor = lowerLimit; cursor < -epsilon; cursor /= 1.1) {
+    var val = filter(cursor);
+    writeValue.call(writer, val);
+    inputValues.push(val);
+  }
+
+  // Encode positive values.
+  for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
+    var val = filter(cursor);
+    writeValue.call(writer, val);
+    inputValues.push(val);
+  }
+
+  var reader = jspb.BinaryDecoder.alloc(writer.getResultBuffer());
+
+  // Check zero and limits.
+  assertEquals(filter(lowerLimit), readValue.call(reader));
+  assertEquals(filter(-epsilon), readValue.call(reader));
+  assertEquals(filter(0), readValue.call(reader));
+  assertEquals(filter(epsilon), readValue.call(reader));
+  assertEquals(filter(upperLimit), readValue.call(reader));
+
+  // Verify decoded values.
+  for (var i = 0; i < inputValues.length; i++) {
+    assertEquals(inputValues[i], readValue.call(reader));
+  }
+}
+
+describe('binaryDecoderTest', function() {
+  /**
+   * Tests the decoder instance cache.
+   * @suppress {visibility}
+   */
+  it('testInstanceCache', function() {
+    // Empty the instance caches.
+    jspb.BinaryDecoder.instanceCache_ = [];
+
+    // Allocating and then freeing a decoder should put it in the instance
+    // cache.
+    jspb.BinaryDecoder.alloc().free();
+
+    assertEquals(1, jspb.BinaryDecoder.instanceCache_.length);
+
+    // Allocating and then freeing three decoders should leave us with three in
+    // the cache.
+
+    var decoder1 = jspb.BinaryDecoder.alloc();
+    var decoder2 = jspb.BinaryDecoder.alloc();
+    var decoder3 = jspb.BinaryDecoder.alloc();
+    decoder1.free();
+    decoder2.free();
+    decoder3.free();
+
+    assertEquals(3, jspb.BinaryDecoder.instanceCache_.length);
+  });
+
+
+  /**
+   * Tests reading 64-bit integers as hash strings.
+   */
+  it('testHashStrings', function() {
+    var writer = new jspb.BinaryWriter();
+
+    var hashA = String.fromCharCode(0x00, 0x00, 0x00, 0x00,
+                                    0x00, 0x00, 0x00, 0x00);
+    var hashB = String.fromCharCode(0x12, 0x34, 0x00, 0x00,
+                                    0x00, 0x00, 0x00, 0x00);
+    var hashC = String.fromCharCode(0x12, 0x34, 0x56, 0x78,
+                                    0x87, 0x65, 0x43, 0x21);
+    var hashD = String.fromCharCode(0xFF, 0xFF, 0xFF, 0xFF,
+                                    0xFF, 0xFF, 0xFF, 0xFF);
+
+    writer.rawWriteVarintHash64(hashA);
+    writer.rawWriteVarintHash64(hashB);
+    writer.rawWriteVarintHash64(hashC);
+    writer.rawWriteVarintHash64(hashD);
+
+    writer.rawWriteFixedHash64(hashA);
+    writer.rawWriteFixedHash64(hashB);
+    writer.rawWriteFixedHash64(hashC);
+    writer.rawWriteFixedHash64(hashD);
+
+    var decoder = jspb.BinaryDecoder.alloc(writer.getResultBuffer());
+
+    assertEquals(hashA, decoder.readVarintHash64());
+    assertEquals(hashB, decoder.readVarintHash64());
+    assertEquals(hashC, decoder.readVarintHash64());
+    assertEquals(hashD, decoder.readVarintHash64());
+
+    assertEquals(hashA, decoder.readFixedHash64());
+    assertEquals(hashB, decoder.readFixedHash64());
+    assertEquals(hashC, decoder.readFixedHash64());
+    assertEquals(hashD, decoder.readFixedHash64());
+  });
+
+
+  /**
+   * Verifies that misuse of the decoder class triggers assertions.
+   * @suppress {checkTypes|visibility}
+   */
+  it('testDecodeErrors', function() {
+    // Reading a value past the end of the stream should trigger an assertion.
+    var decoder = jspb.BinaryDecoder.alloc([0, 1, 2]);
+    assertThrows(function() {decoder.readUint64()});
+
+    // Overlong varints should trigger assertions.
+    decoder.setBlock(
+        [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0]);
+    assertThrows(function() {decoder.readUnsignedVarint64()});
+    decoder.reset();
+    assertThrows(function() {decoder.readSignedVarint64()});
+    decoder.reset();
+    assertThrows(function() {decoder.readZigzagVarint64()});
+
+    // Positive 32-bit varints encoded with 1 bits in positions 33 through 35
+    // should trigger assertions.
+    decoder.setBlock([255, 255, 255, 255, 0x1F]);
+    assertThrows(function() {decoder.readUnsignedVarint32()});
+
+    decoder.setBlock([255, 255, 255, 255, 0x2F]);
+    assertThrows(function() {decoder.readUnsignedVarint32()});
+
+    decoder.setBlock([255, 255, 255, 255, 0x4F]);
+    assertThrows(function() {decoder.readUnsignedVarint32()});
+
+    // Negative 32-bit varints encoded with non-1 bits in the high dword should
+    // trigger assertions.
+    decoder.setBlock([255, 255, 255, 255, 255, 255, 0, 255, 255, 1]);
+    assertThrows(function() {decoder.readUnsignedVarint32()});
+
+    decoder.setBlock([255, 255, 255, 255, 255, 255, 255, 255, 255, 0]);
+    assertThrows(function() {decoder.readUnsignedVarint32()});
+  });
+
+
+  /**
+   * Tests raw encoding and decoding of unsigned integers.
+   */
+  it('testRawUnsigned', function() {
+    doTestUnsignedValue(
+        jspb.BinaryDecoder.prototype.readUint8,
+        jspb.BinaryWriter.prototype.rawWriteUint8,
+        1, 0xFF, Math.round);
+
+    doTestUnsignedValue(
+        jspb.BinaryDecoder.prototype.readUint16,
+        jspb.BinaryWriter.prototype.rawWriteUint16,
+        1, 0xFFFF, Math.round);
+
+    doTestUnsignedValue(
+        jspb.BinaryDecoder.prototype.readUint32,
+        jspb.BinaryWriter.prototype.rawWriteUint32,
+        1, 0xFFFFFFFF, Math.round);
+
+    doTestUnsignedValue(
+        jspb.BinaryDecoder.prototype.readUint64,
+        jspb.BinaryWriter.prototype.rawWriteUint64,
+        1, Math.pow(2, 64) - 1025, Math.round);
+  });
+
+
+  /**
+   * Tests raw encoding and decoding of signed integers.
+   */
+  it('testRawSigned', function() {
+    doTestSignedValue(
+        jspb.BinaryDecoder.prototype.readInt8,
+        jspb.BinaryWriter.prototype.rawWriteInt8,
+        1, -0x80, 0x7F, Math.round);
+
+    doTestSignedValue(
+        jspb.BinaryDecoder.prototype.readInt16,
+        jspb.BinaryWriter.prototype.rawWriteInt16,
+        1, -0x8000, 0x7FFF, Math.round);
+
+    doTestSignedValue(
+        jspb.BinaryDecoder.prototype.readInt32,
+        jspb.BinaryWriter.prototype.rawWriteInt32,
+        1, -0x80000000, 0x7FFFFFFF, Math.round);
+
+    doTestSignedValue(
+        jspb.BinaryDecoder.prototype.readInt64,
+        jspb.BinaryWriter.prototype.rawWriteInt64,
+        1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);
+  });
+
+
+  /**
+   * Tests raw encoding and decoding of floats.
+   */
+  it('testRawFloats', function() {
+    /**
+     * @param {number} x
+     * @return {number}
+     */
+    function truncate(x) {
+      var temp = new Float32Array(1);
+      temp[0] = x;
+      return temp[0];
+    }
+    doTestSignedValue(
+        jspb.BinaryDecoder.prototype.readFloat,
+        jspb.BinaryWriter.prototype.rawWriteFloat,
+        jspb.BinaryConstants.FLOAT32_EPS,
+        -jspb.BinaryConstants.FLOAT32_MAX,
+        jspb.BinaryConstants.FLOAT32_MAX,
+        truncate);
+
+    doTestSignedValue(
+        jspb.BinaryDecoder.prototype.readDouble,
+        jspb.BinaryWriter.prototype.rawWriteDouble,
+        jspb.BinaryConstants.FLOAT64_EPS * 10,
+        -jspb.BinaryConstants.FLOAT64_MAX,
+        jspb.BinaryConstants.FLOAT64_MAX,
+        function(x) { return x; });
+  });
+});
diff --git a/js/binary/proto_test.js b/js/binary/proto_test.js
new file mode 100644
index 0000000..1cb7ff0
--- /dev/null
+++ b/js/binary/proto_test.js
@@ -0,0 +1,487 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Test suite is written using Jasmine -- see http://jasmine.github.io/
+
+goog.require('goog.testing.asserts');
+goog.require('proto.jspb.test.ExtendsWithMessage');
+goog.require('proto.jspb.test.ForeignEnum');
+goog.require('proto.jspb.test.ForeignMessage');
+goog.require('proto.jspb.test.TestAllTypes');
+goog.require('proto.jspb.test.TestExtendable');
+
+var suite = {};
+
+/**
+ * Helper: fill all fields on a TestAllTypes message.
+ * @param {proto.jspb.test.TestAllTypes} msg
+ */
+function fillAllFields(msg) {
+  msg.setOptionalInt32(-42);
+  // can be exactly represented by JS number (64-bit double, i.e., 52-bit
+  // mantissa).
+  msg.setOptionalInt64(-0x7fffffff00000000);
+  msg.setOptionalUint32(0x80000000);
+  msg.setOptionalUint64(0xf000000000000000);
+  msg.setOptionalSint32(-100);
+  msg.setOptionalSint64(-0x8000000000000000);
+  msg.setOptionalFixed32(1234);
+  msg.setOptionalFixed64(0x1234567800000000);
+  msg.setOptionalSfixed32(-1234);
+  msg.setOptionalSfixed64(-0x1234567800000000);
+  msg.setOptionalFloat(1.5);
+  msg.setOptionalDouble(-1.5);
+  msg.setOptionalBool(true);
+  msg.setOptionalString('hello world');
+  msg.setOptionalBytes('bytes');
+  msg.setOptionalGroup(new proto.jspb.test.TestAllTypes.OptionalGroup());
+  msg.getOptionalGroup().setA(100);
+  var submsg = new proto.jspb.test.ForeignMessage();
+  submsg.setC(16);
+  msg.setOptionalForeignMessage(submsg);
+  msg.setOptionalForeignEnum(proto.jspb.test.ForeignEnum.FOREIGN_FOO);
+  msg.setOneofString('oneof');
+
+  msg.setRepeatedInt32List([-42]);
+  msg.setRepeatedInt64List([-0x7fffffff00000000]);
+  msg.setRepeatedUint32List([0x80000000]);
+  msg.setRepeatedUint64List([0xf000000000000000]);
+  msg.setRepeatedSint32List([-100]);
+  msg.setRepeatedSint64List([-0x8000000000000000]);
+  msg.setRepeatedFixed32List([1234]);
+  msg.setRepeatedFixed64List([0x1234567800000000]);
+  msg.setRepeatedSfixed32List([-1234]);
+  msg.setRepeatedSfixed64List([-0x1234567800000000]);
+  msg.setRepeatedFloatList([1.5]);
+  msg.setRepeatedDoubleList([-1.5]);
+  msg.setRepeatedBoolList([true]);
+  msg.setRepeatedStringList(['hello world']);
+  msg.setRepeatedBytesList(['bytes']);
+  msg.setRepeatedGroupList([new proto.jspb.test.TestAllTypes.RepeatedGroup()]);
+  msg.getRepeatedGroupList()[0].setA(100);
+  submsg = new proto.jspb.test.ForeignMessage();
+  submsg.setC(1000);
+  msg.setRepeatedForeignMessageList([submsg]);
+  msg.setRepeatedForeignEnumList([proto.jspb.test.ForeignEnum.FOREIGN_FOO]);
+
+  msg.setPackedRepeatedInt32List([-42]);
+  msg.setPackedRepeatedInt64List([-0x7fffffff00000000]);
+  msg.setPackedRepeatedUint32List([0x80000000]);
+  msg.setPackedRepeatedUint64List([0xf000000000000000]);
+  msg.setPackedRepeatedSint32List([-100]);
+  msg.setPackedRepeatedSint64List([-0x8000000000000000]);
+  msg.setPackedRepeatedFixed32List([1234]);
+  msg.setPackedRepeatedFixed64List([0x1234567800000000]);
+  msg.setPackedRepeatedSfixed32List([-1234]);
+  msg.setPackedRepeatedSfixed64List([-0x1234567800000000]);
+  msg.setPackedRepeatedFloatList([1.5]);
+  msg.setPackedRepeatedDoubleList([-1.5]);
+  msg.setPackedRepeatedBoolList([true]);
+}
+
+
+/**
+ * Helper: compare a bytes field to a string with codepoints 0--255.
+ * @param {Uint8Array|string} arr
+ * @param {string} str
+ * @return {boolean}
+ */
+function bytesCompare(arr, str) {
+  if (arr.length != str.length) {
+    return false;
+  }
+  if (typeof arr == 'string') {
+    for (var i = 0; i < arr.length; i++) {
+      if (arr.charCodeAt(i) != str.charCodeAt(i)) {
+        return false;
+      }
+    }
+    return true;
+  } else {
+    for (var i = 0; i < arr.length; i++) {
+      if (arr[i] != str.charCodeAt(i)) {
+        return false;
+      }
+    }
+    return true;
+  }
+}
+
+
+/**
+ * Helper: verify contents of given TestAllTypes message as set by
+ * fillAllFields().
+ * @param {proto.jspb.test.TestAllTypes} msg
+ */
+function checkAllFields(msg) {
+  assertEquals(msg.getOptionalInt32(), -42);
+  assertEquals(msg.getOptionalInt64(), -0x7fffffff00000000);
+  assertEquals(msg.getOptionalUint32(), 0x80000000);
+  assertEquals(msg.getOptionalUint64(), 0xf000000000000000);
+  assertEquals(msg.getOptionalSint32(), -100);
+  assertEquals(msg.getOptionalSint64(), -0x8000000000000000);
+  assertEquals(msg.getOptionalFixed32(), 1234);
+  assertEquals(msg.getOptionalFixed64(), 0x1234567800000000);
+  assertEquals(msg.getOptionalSfixed32(), -1234);
+  assertEquals(msg.getOptionalSfixed64(), -0x1234567800000000);
+  assertEquals(msg.getOptionalFloat(), 1.5);
+  assertEquals(msg.getOptionalDouble(), -1.5);
+  assertEquals(msg.getOptionalBool(), true);
+  assertEquals(msg.getOptionalString(), 'hello world');
+  assertEquals(true, bytesCompare(msg.getOptionalBytes(), 'bytes'));
+  assertEquals(msg.getOptionalGroup().getA(), 100);
+  assertEquals(msg.getOptionalForeignMessage().getC(), 16);
+  assertEquals(msg.getOptionalForeignEnum(),
+      proto.jspb.test.ForeignEnum.FOREIGN_FOO);
+  assertEquals(msg.getOneofString(), 'oneof');
+  assertEquals(msg.getOneofFieldCase(),
+      proto.jspb.test.TestAllTypes.OneofFieldCase.ONEOF_STRING);
+
+  assertElementsEquals(msg.getRepeatedInt32List(), [-42]);
+  assertElementsEquals(msg.getRepeatedInt64List(), [-0x7fffffff00000000]);
+  assertElementsEquals(msg.getRepeatedUint32List(), [0x80000000]);
+  assertElementsEquals(msg.getRepeatedUint64List(), [0xf000000000000000]);
+  assertElementsEquals(msg.getRepeatedSint32List(), [-100]);
+  assertElementsEquals(msg.getRepeatedSint64List(), [-0x8000000000000000]);
+  assertElementsEquals(msg.getRepeatedFixed32List(), [1234]);
+  assertElementsEquals(msg.getRepeatedFixed64List(), [0x1234567800000000]);
+  assertElementsEquals(msg.getRepeatedSfixed32List(), [-1234]);
+  assertElementsEquals(msg.getRepeatedSfixed64List(), [-0x1234567800000000]);
+  assertElementsEquals(msg.getRepeatedFloatList(), [1.5]);
+  assertElementsEquals(msg.getRepeatedDoubleList(), [-1.5]);
+  assertElementsEquals(msg.getRepeatedBoolList(), [true]);
+  assertElementsEquals(msg.getRepeatedStringList(), ['hello world']);
+  assertEquals(msg.getRepeatedBytesList().length, 1);
+  assertEquals(true, bytesCompare(msg.getRepeatedBytesList()[0], 'bytes'));
+  assertEquals(msg.getRepeatedGroupList().length, 1);
+  assertEquals(msg.getRepeatedGroupList()[0].getA(), 100);
+  assertEquals(msg.getRepeatedForeignMessageList().length, 1);
+  assertEquals(msg.getRepeatedForeignMessageList()[0].getC(), 1000);
+  assertElementsEquals(msg.getRepeatedForeignEnumList(),
+      [proto.jspb.test.ForeignEnum.FOREIGN_FOO]);
+
+  assertElementsEquals(msg.getPackedRepeatedInt32List(), [-42]);
+  assertElementsEquals(msg.getPackedRepeatedInt64List(),
+      [-0x7fffffff00000000]);
+  assertElementsEquals(msg.getPackedRepeatedUint32List(), [0x80000000]);
+  assertElementsEquals(msg.getPackedRepeatedUint64List(), [0xf000000000000000]);
+  assertElementsEquals(msg.getPackedRepeatedSint32List(), [-100]);
+  assertElementsEquals(msg.getPackedRepeatedSint64List(),
+      [-0x8000000000000000]);
+  assertElementsEquals(msg.getPackedRepeatedFixed32List(), [1234]);
+  assertElementsEquals(msg.getPackedRepeatedFixed64List(),
+      [0x1234567800000000]);
+  assertElementsEquals(msg.getPackedRepeatedSfixed32List(), [-1234]);
+  assertElementsEquals(msg.getPackedRepeatedSfixed64List(),
+      [-0x1234567800000000]);
+  assertElementsEquals(msg.getPackedRepeatedFloatList(), [1.5]);
+  assertElementsEquals(msg.getPackedRepeatedDoubleList(), [-1.5]);
+  assertElementsEquals(msg.getPackedRepeatedBoolList(), [true]);
+}
+
+
+/**
+ * Helper: verify that all expected extensions are present.
+ * @param {!proto.jspb.test.TestExtendable} msg
+ */
+function checkExtensions(msg) {
+  assertEquals(-42,
+      msg.getExtension(proto.jspb.test.extendOptionalInt32));
+  assertEquals(-0x7fffffff00000000,
+      msg.getExtension(proto.jspb.test.extendOptionalInt64));
+  assertEquals(0x80000000,
+      msg.getExtension(proto.jspb.test.extendOptionalUint32));
+  assertEquals(0xf000000000000000,
+      msg.getExtension(proto.jspb.test.extendOptionalUint64));
+  assertEquals(-100,
+      msg.getExtension(proto.jspb.test.extendOptionalSint32));
+  assertEquals(-0x8000000000000000,
+      msg.getExtension(proto.jspb.test.extendOptionalSint64));
+  assertEquals(1234,
+      msg.getExtension(proto.jspb.test.extendOptionalFixed32));
+  assertEquals(0x1234567800000000,
+      msg.getExtension(proto.jspb.test.extendOptionalFixed64));
+  assertEquals(-1234,
+      msg.getExtension(proto.jspb.test.extendOptionalSfixed32));
+  assertEquals(-0x1234567800000000,
+      msg.getExtension(proto.jspb.test.extendOptionalSfixed64));
+  assertEquals(1.5,
+      msg.getExtension(proto.jspb.test.extendOptionalFloat));
+  assertEquals(-1.5,
+      msg.getExtension(proto.jspb.test.extendOptionalDouble));
+  assertEquals(true,
+      msg.getExtension(proto.jspb.test.extendOptionalBool));
+  assertEquals('hello world',
+      msg.getExtension(proto.jspb.test.extendOptionalString));
+  assertEquals(true,
+      bytesCompare(msg.getExtension(proto.jspb.test.extendOptionalBytes),
+        'bytes'));
+  assertEquals(16,
+      msg.getExtension(
+          proto.jspb.test.ExtendsWithMessage.optionalExtension).getFoo());
+  assertEquals(proto.jspb.test.ForeignEnum.FOREIGN_FOO,
+      msg.getExtension(proto.jspb.test.extendOptionalForeignEnum));
+
+  assertElementsEquals(
+      msg.getExtension(proto.jspb.test.extendRepeatedInt32List),
+      [-42]);
+  assertElementsEquals(
+      msg.getExtension(proto.jspb.test.extendRepeatedInt64List),
+      [-0x7fffffff00000000]);
+  assertElementsEquals(
+      msg.getExtension(proto.jspb.test.extendRepeatedUint32List),
+      [0x80000000]);
+  assertElementsEquals(
+      msg.getExtension(proto.jspb.test.extendRepeatedUint64List),
+      [0xf000000000000000]);
+  assertElementsEquals(
+      msg.getExtension(proto.jspb.test.extendRepeatedSint32List),
+      [-100]);
+  assertElementsEquals(
+      msg.getExtension(proto.jspb.test.extendRepeatedSint64List),
+      [-0x8000000000000000]);
+  assertElementsEquals(
+      msg.getExtension(proto.jspb.test.extendRepeatedFixed32List),
+      [1234]);
+  assertElementsEquals(
+      msg.getExtension(proto.jspb.test.extendRepeatedFixed64List),
+      [0x1234567800000000]);
+  assertElementsEquals(
+      msg.getExtension(proto.jspb.test.extendRepeatedSfixed32List),
+      [-1234]);
+  assertElementsEquals(
+      msg.getExtension(proto.jspb.test.extendRepeatedSfixed64List),
+      [-0x1234567800000000]);
+  assertElementsEquals(
+      msg.getExtension(proto.jspb.test.extendRepeatedFloatList),
+      [1.5]);
+  assertElementsEquals(
+      msg.getExtension(proto.jspb.test.extendRepeatedDoubleList),
+      [-1.5]);
+  assertElementsEquals(
+      msg.getExtension(proto.jspb.test.extendRepeatedBoolList),
+      [true]);
+  assertElementsEquals(
+      msg.getExtension(proto.jspb.test.extendRepeatedStringList),
+      ['hello world']);
+  assertEquals(true,
+      bytesCompare(
+          msg.getExtension(proto.jspb.test.extendRepeatedBytesList)[0],
+          'bytes'));
+  assertEquals(1000,
+      msg.getExtension(
+          proto.jspb.test.ExtendsWithMessage.repeatedExtensionList)[0]
+      .getFoo());
+  assertElementsEquals(
+      msg.getExtension(proto.jspb.test.extendRepeatedForeignEnumList),
+      [proto.jspb.test.ForeignEnum.FOREIGN_FOO]);
+
+  assertElementsEquals(
+      msg.getExtension(proto.jspb.test.extendPackedRepeatedInt32List),
+      [-42]);
+  assertElementsEquals(
+      msg.getExtension(proto.jspb.test.extendPackedRepeatedInt64List),
+      [-0x7fffffff00000000]);
+  assertElementsEquals(
+      msg.getExtension(proto.jspb.test.extendPackedRepeatedUint32List),
+      [0x80000000]);
+  assertElementsEquals(
+      msg.getExtension(proto.jspb.test.extendPackedRepeatedUint64List),
+      [0xf000000000000000]);
+  assertElementsEquals(
+      msg.getExtension(proto.jspb.test.extendPackedRepeatedSint32List),
+      [-100]);
+  assertElementsEquals(
+      msg.getExtension(proto.jspb.test.extendPackedRepeatedSint64List),
+      [-0x8000000000000000]);
+  assertElementsEquals(
+      msg.getExtension(proto.jspb.test.extendPackedRepeatedFixed32List),
+      [1234]);
+  assertElementsEquals(
+      msg.getExtension(proto.jspb.test.extendPackedRepeatedFixed64List),
+      [0x1234567800000000]);
+  assertElementsEquals(
+      msg.getExtension(proto.jspb.test.extendPackedRepeatedSfixed32List),
+      [-1234]);
+  assertElementsEquals(
+      msg.getExtension(proto.jspb.test.extendPackedRepeatedSfixed64List),
+      [-0x1234567800000000]);
+  assertElementsEquals(
+      msg.getExtension(proto.jspb.test.extendPackedRepeatedFloatList),
+      [1.5]);
+  assertElementsEquals(
+      msg.getExtension(proto.jspb.test.extendPackedRepeatedDoubleList),
+      [-1.5]);
+  assertElementsEquals(
+      msg.getExtension(proto.jspb.test.extendPackedRepeatedBoolList),
+      [true]);
+  assertElementsEquals(
+      msg.getExtension(proto.jspb.test.extendPackedRepeatedForeignEnumList),
+      [proto.jspb.test.ForeignEnum.FOREIGN_FOO]);
+}
+
+
+describe('protoBinaryTest', function() {
+  /**
+   * Tests a basic serialization-deserializaton round-trip with all supported
+   * field types (on the TestAllTypes message type).
+   */
+  it('testRoundTrip', function() {
+    var msg = new proto.jspb.test.TestAllTypes();
+    fillAllFields(msg);
+    var encoded = msg.serializeBinary();
+    var decoded = proto.jspb.test.TestAllTypes.deserializeBinary(encoded);
+    checkAllFields(decoded);
+  });
+
+
+  /**
+   * Helper: fill all extension values.
+   * @param {proto.jspb.test.TestExtendable} msg
+   */
+  function fillExtensions(msg) {
+    msg.setExtension(
+        proto.jspb.test.extendOptionalInt32, -42);
+    msg.setExtension(
+        proto.jspb.test.extendOptionalInt64, -0x7fffffff00000000);
+    msg.setExtension(
+        proto.jspb.test.extendOptionalUint32, 0x80000000);
+    msg.setExtension(
+        proto.jspb.test.extendOptionalUint64, 0xf000000000000000);
+    msg.setExtension(
+        proto.jspb.test.extendOptionalSint32, -100);
+    msg.setExtension(
+        proto.jspb.test.extendOptionalSint64, -0x8000000000000000);
+    msg.setExtension(
+        proto.jspb.test.extendOptionalFixed32, 1234);
+    msg.setExtension(
+        proto.jspb.test.extendOptionalFixed64, 0x1234567800000000);
+    msg.setExtension(
+        proto.jspb.test.extendOptionalSfixed32, -1234);
+    msg.setExtension(
+        proto.jspb.test.extendOptionalSfixed64, -0x1234567800000000);
+    msg.setExtension(
+        proto.jspb.test.extendOptionalFloat, 1.5);
+    msg.setExtension(
+        proto.jspb.test.extendOptionalDouble, -1.5);
+    msg.setExtension(
+        proto.jspb.test.extendOptionalBool, true);
+    msg.setExtension(
+        proto.jspb.test.extendOptionalString, 'hello world');
+    msg.setExtension(
+        proto.jspb.test.extendOptionalBytes, 'bytes');
+    var submsg = new proto.jspb.test.ExtendsWithMessage();
+    submsg.setFoo(16);
+    msg.setExtension(
+        proto.jspb.test.ExtendsWithMessage.optionalExtension, submsg);
+    msg.setExtension(
+        proto.jspb.test.extendOptionalForeignEnum,
+        proto.jspb.test.ForeignEnum.FOREIGN_FOO);
+
+    msg.setExtension(
+        proto.jspb.test.extendRepeatedInt32List, [-42]);
+    msg.setExtension(
+        proto.jspb.test.extendRepeatedInt64List, [-0x7fffffff00000000]);
+    msg.setExtension(
+        proto.jspb.test.extendRepeatedUint32List, [0x80000000]);
+    msg.setExtension(
+        proto.jspb.test.extendRepeatedUint64List, [0xf000000000000000]);
+    msg.setExtension(
+        proto.jspb.test.extendRepeatedSint32List, [-100]);
+    msg.setExtension(
+        proto.jspb.test.extendRepeatedSint64List, [-0x8000000000000000]);
+    msg.setExtension(
+        proto.jspb.test.extendRepeatedFixed32List, [1234]);
+    msg.setExtension(
+        proto.jspb.test.extendRepeatedFixed64List, [0x1234567800000000]);
+    msg.setExtension(
+        proto.jspb.test.extendRepeatedSfixed32List, [-1234]);
+    msg.setExtension(
+        proto.jspb.test.extendRepeatedSfixed64List, [-0x1234567800000000]);
+    msg.setExtension(
+        proto.jspb.test.extendRepeatedFloatList, [1.5]);
+    msg.setExtension(
+        proto.jspb.test.extendRepeatedDoubleList, [-1.5]);
+    msg.setExtension(
+        proto.jspb.test.extendRepeatedBoolList, [true]);
+    msg.setExtension(
+        proto.jspb.test.extendRepeatedStringList, ['hello world']);
+    msg.setExtension(
+        proto.jspb.test.extendRepeatedBytesList, ['bytes']);
+    submsg = new proto.jspb.test.ExtendsWithMessage();
+    submsg.setFoo(1000);
+    msg.setExtension(
+        proto.jspb.test.ExtendsWithMessage.repeatedExtensionList, [submsg]);
+    msg.setExtension(proto.jspb.test.extendRepeatedForeignEnumList,
+        [proto.jspb.test.ForeignEnum.FOREIGN_FOO]);
+
+    msg.setExtension(
+        proto.jspb.test.extendPackedRepeatedInt32List, [-42]);
+    msg.setExtension(
+        proto.jspb.test.extendPackedRepeatedInt64List, [-0x7fffffff00000000]);
+    msg.setExtension(
+        proto.jspb.test.extendPackedRepeatedUint32List, [0x80000000]);
+    msg.setExtension(
+        proto.jspb.test.extendPackedRepeatedUint64List, [0xf000000000000000]);
+    msg.setExtension(
+        proto.jspb.test.extendPackedRepeatedSint32List, [-100]);
+    msg.setExtension(
+        proto.jspb.test.extendPackedRepeatedSint64List, [-0x8000000000000000]);
+    msg.setExtension(
+        proto.jspb.test.extendPackedRepeatedFixed32List, [1234]);
+    msg.setExtension(
+        proto.jspb.test.extendPackedRepeatedFixed64List, [0x1234567800000000]);
+    msg.setExtension(
+        proto.jspb.test.extendPackedRepeatedSfixed32List, [-1234]);
+    msg.setExtension(
+        proto.jspb.test.extendPackedRepeatedSfixed64List,
+        [-0x1234567800000000]);
+    msg.setExtension(
+        proto.jspb.test.extendPackedRepeatedFloatList, [1.5]);
+    msg.setExtension(
+        proto.jspb.test.extendPackedRepeatedDoubleList, [-1.5]);
+    msg.setExtension(
+        proto.jspb.test.extendPackedRepeatedBoolList, [true]);
+    msg.setExtension(proto.jspb.test.extendPackedRepeatedForeignEnumList,
+        [proto.jspb.test.ForeignEnum.FOREIGN_FOO]);
+  }
+
+
+  /**
+   * Tests extension serialization and deserialization.
+   */
+  it('testExtensions', function() {
+    var msg = new proto.jspb.test.TestExtendable();
+    fillExtensions(msg);
+    var encoded = msg.serializeBinary();
+    var decoded = proto.jspb.test.TestExtendable.deserializeBinary(encoded);
+    checkExtensions(decoded);
+  });
+});
diff --git a/js/binary/reader.js b/js/binary/reader.js
new file mode 100644
index 0000000..abcd166
--- /dev/null
+++ b/js/binary/reader.js
@@ -0,0 +1,1127 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/**
+ * @fileoverview This file contains utilities for converting binary,
+ * wire-format protocol buffers into Javascript data structures.
+ *
+ * jspb's BinaryReader class wraps the BinaryDecoder class to add methods
+ * that understand the protocol buffer syntax and can do the type checking and
+ * bookkeeping necessary to parse trees of nested messages.
+ *
+ * Major caveat - Users of this library _must_ keep their Javascript proto
+ * parsing code in sync with the original .proto file - presumably you'll be
+ * using the typed jspb code generator, but if you bypass that you'll need
+ * to keep things in sync by hand.
+ *
+ * @author aappleby@google.com (Austin Appleby)
+ */
+
+goog.provide('jspb.BinaryReader');
+
+goog.require('goog.asserts');
+goog.require('jspb.BinaryConstants');
+goog.require('jspb.BinaryDecoder');
+
+
+
+/**
+ * BinaryReader implements the decoders for all the wire types specified in
+ * https://developers.google.com/protocol-buffers/docs/encoding.
+ *
+ * @param {jspb.ByteSource=} opt_bytes The bytes we're reading from.
+ * @param {number=} opt_start The optional offset to start reading at.
+ * @param {number=} opt_length The optional length of the block to read -
+ *     we'll throw an assertion if we go off the end of the block.
+ * @constructor
+ * @struct
+ */
+jspb.BinaryReader = function(opt_bytes, opt_start, opt_length) {
+  /**
+   * Wire-format decoder.
+   * @private {!jspb.BinaryDecoder}
+   */
+  this.decoder_ = jspb.BinaryDecoder.alloc(opt_bytes, opt_start, opt_length);
+
+  /**
+   * Cursor immediately before the field tag.
+   * @private {number}
+   */
+  this.fieldCursor_ = this.decoder_.getCursor();
+
+  /**
+   * Field number of the next field in the buffer, filled in by nextField().
+   * @private {number}
+   */
+  this.nextField_ = jspb.BinaryConstants.INVALID_FIELD_NUMBER;
+
+  /**
+   * Wire type of the next proto field in the buffer, filled in by
+   * nextField().
+   * @private {jspb.BinaryConstants.WireType}
+   */
+  this.nextWireType_ = jspb.BinaryConstants.WireType.INVALID;
+
+  /**
+   * Set to true if this reader encountered an error due to corrupt data.
+   * @private {boolean}
+   */
+  this.error_ = false;
+
+  /**
+   * User-defined reader callbacks.
+   * @private {Object.<string, function(!jspb.BinaryReader):*>}
+   */
+  this.readCallbacks_ = null;
+};
+
+
+/**
+ * Global pool of BinaryReader instances.
+ * @private {!Array.<!jspb.BinaryReader>}
+ */
+jspb.BinaryReader.instanceCache_ = [];
+
+
+/**
+ * Pops an instance off the instance cache, or creates one if the cache is
+ * empty.
+ * @param {jspb.ByteSource=} opt_bytes The bytes we're reading from.
+ * @param {number=} opt_start The optional offset to start reading at.
+ * @param {number=} opt_length The optional length of the block to read -
+ *     we'll throw an assertion if we go off the end of the block.
+ * @return {!jspb.BinaryReader}
+ */
+jspb.BinaryReader.alloc =
+    function(opt_bytes, opt_start, opt_length) {
+  if (jspb.BinaryReader.instanceCache_.length) {
+    var newReader = jspb.BinaryReader.instanceCache_.pop();
+    if (opt_bytes) {
+      newReader.decoder_.setBlock(opt_bytes, opt_start, opt_length);
+    }
+    return newReader;
+  } else {
+    return new jspb.BinaryReader(opt_bytes, opt_start, opt_length);
+  }
+};
+
+
+/**
+ * Alias for the above method.
+ * @param {jspb.ByteSource=} opt_bytes The bytes we're reading from.
+ * @param {number=} opt_start The optional offset to start reading at.
+ * @param {number=} opt_length The optional length of the block to read -
+ *     we'll throw an assertion if we go off the end of the block.
+ * @return {!jspb.BinaryReader}
+ */
+jspb.BinaryReader.prototype.alloc = jspb.BinaryReader.alloc;
+
+
+/**
+ * Puts this instance back in the instance cache.
+ */
+jspb.BinaryReader.prototype.free = function() {
+  this.decoder_.clear();
+  this.nextField_ = jspb.BinaryConstants.INVALID_FIELD_NUMBER;
+  this.nextWireType_ = jspb.BinaryConstants.WireType.INVALID;
+  this.error_ = false;
+  this.readCallbacks_ = null;
+
+  if (jspb.BinaryReader.instanceCache_.length < 100) {
+    jspb.BinaryReader.instanceCache_.push(this);
+  }
+};
+
+
+/**
+ * Returns the cursor immediately before the current field's tag.
+ * @return {number} The internal read cursor.
+ */
+jspb.BinaryReader.prototype.getFieldCursor = function() {
+  return this.fieldCursor_;
+};
+
+
+/**
+ * Returns the internal read cursor.
+ * @return {number} The internal read cursor.
+ */
+jspb.BinaryReader.prototype.getCursor = function() {
+  return this.decoder_.getCursor();
+};
+
+
+/**
+ * Returns the raw buffer.
+ * @return {Uint8Array} The raw buffer.
+ */
+jspb.BinaryReader.prototype.getBuffer = function() {
+  return this.decoder_.getBuffer();
+};
+
+
+/**
+ * @return {number} The field number of the next field in the buffer, or
+ *     INVALID_FIELD_NUMBER if there is no next field.
+ */
+jspb.BinaryReader.prototype.getFieldNumber = function() {
+  return this.nextField_;
+};
+
+
+/**
+ * @return {jspb.BinaryConstants.WireType} The wire type of the next field
+ *     in the stream, or WireType.INVALID if there is no next field.
+ */
+jspb.BinaryReader.prototype.getWireType = function() {
+  return this.nextWireType_;
+};
+
+
+/**
+ * @return {boolean} Whether the current wire type is an end-group tag. Used as
+ * an exit condition in decoder loops in generated code.
+ */
+jspb.BinaryReader.prototype.isEndGroup = function() {
+  return this.nextWireType_ == jspb.BinaryConstants.WireType.END_GROUP;
+};
+
+
+/**
+ * Returns true if this reader hit an error due to corrupt data.
+ * @return {boolean}
+ */
+jspb.BinaryReader.prototype.getError = function() {
+  return this.error_ || this.decoder_.getError();
+};
+
+
+/**
+ * Points this reader at a new block of bytes.
+ * @param {!Uint8Array} bytes The block of bytes we're reading from.
+ * @param {number} start The offset to start reading at.
+ * @param {number} length The length of the block to read.
+ */
+jspb.BinaryReader.prototype.setBlock = function(bytes, start, length) {
+  this.decoder_.setBlock(bytes, start, length);
+  this.nextField_ = jspb.BinaryConstants.INVALID_FIELD_NUMBER;
+  this.nextWireType_ = jspb.BinaryConstants.WireType.INVALID;
+};
+
+
+/**
+ * Rewinds the stream cursor to the beginning of the buffer and resets all
+ * internal state.
+ */
+jspb.BinaryReader.prototype.reset = function() {
+  this.decoder_.reset();
+  this.nextField_ = jspb.BinaryConstants.INVALID_FIELD_NUMBER;
+  this.nextWireType_ = jspb.BinaryConstants.WireType.INVALID;
+};
+
+
+/**
+ * Advances the stream cursor by the given number of bytes.
+ * @param {number} count The number of bytes to advance by.
+ */
+jspb.BinaryReader.prototype.advance = function(count) {
+  this.decoder_.advance(count);
+};
+
+
+/**
+ * Reads the next field header in the stream if there is one, returns true if
+ * we saw a valid field header or false if we've read the whole stream.
+ * Throws an error if we encountered a deprecated START_GROUP/END_GROUP field.
+ * @return {boolean} True if the stream contains more fields.
+ */
+jspb.BinaryReader.prototype.nextField = function() {
+  // If we're at the end of the block, there are no more fields.
+  if (this.decoder_.atEnd()) {
+    return false;
+  }
+
+  // If we hit an error decoding the previous field, stop now before we
+  // try to decode anything else
+  if (this.getError()) {
+    goog.asserts.fail('Decoder hit an error');
+    return false;
+  }
+
+  // Otherwise just read the header of the next field.
+  this.fieldCursor_ = this.decoder_.getCursor();
+  var header = this.decoder_.readUnsignedVarint32();
+
+  var nextField = header >>> 3;
+  var nextWireType = /** @type {jspb.BinaryConstants.WireType} */
+      (header & 0x7);
+
+  // If the wire type isn't one of the valid ones, something's broken.
+  if (nextWireType != jspb.BinaryConstants.WireType.VARINT &&
+      nextWireType != jspb.BinaryConstants.WireType.FIXED32 &&
+      nextWireType != jspb.BinaryConstants.WireType.FIXED64 &&
+      nextWireType != jspb.BinaryConstants.WireType.DELIMITED &&
+      nextWireType != jspb.BinaryConstants.WireType.START_GROUP &&
+      nextWireType != jspb.BinaryConstants.WireType.END_GROUP) {
+    goog.asserts.fail('Invalid wire type');
+    this.error_ = true;
+    return false;
+  }
+
+  this.nextField_ = nextField;
+  this.nextWireType_ = nextWireType;
+
+  return true;
+};
+
+
+/**
+ * Winds the reader back to just before this field's header.
+ */
+jspb.BinaryReader.prototype.unskipHeader = function() {
+  this.decoder_.unskipVarint((this.nextField_ << 3) | this.nextWireType_);
+};
+
+
+/**
+ * Skips all contiguous fields whose header matches the one we just read.
+ */
+jspb.BinaryReader.prototype.skipMatchingFields = function() {
+  var field = this.nextField_;
+  this.unskipHeader();
+
+  while (this.nextField() && (this.getFieldNumber() == field)) {
+    this.skipField();
+  }
+
+  if (!this.decoder_.atEnd()) {
+    this.unskipHeader();
+  }
+};
+
+
+/**
+ * Skips over the next varint field in the binary stream.
+ */
+jspb.BinaryReader.prototype.skipVarintField = function() {
+  if (this.nextWireType_ != jspb.BinaryConstants.WireType.VARINT) {
+    goog.asserts.fail('Invalid wire type for skipVarintField');
+    this.skipField();
+    return;
+  }
+
+  this.decoder_.skipVarint();
+};
+
+
+/**
+ * Skips over the next delimited field in the binary stream.
+ */
+jspb.BinaryReader.prototype.skipDelimitedField = function() {
+  if (this.nextWireType_ != jspb.BinaryConstants.WireType.DELIMITED) {
+    goog.asserts.fail('Invalid wire type for skipDelimitedField');
+    this.skipField();
+    return;
+  }
+
+  var length = this.decoder_.readUnsignedVarint32();
+  this.decoder_.advance(length);
+};
+
+
+/**
+ * Skips over the next fixed32 field in the binary stream.
+ */
+jspb.BinaryReader.prototype.skipFixed32Field = function() {
+  if (this.nextWireType_ != jspb.BinaryConstants.WireType.FIXED32) {
+    goog.asserts.fail('Invalid wire type for skipFixed32Field');
+    this.skipField();
+    return;
+  }
+
+  this.decoder_.advance(4);
+};
+
+
+/**
+ * Skips over the next fixed64 field in the binary stream.
+ */
+jspb.BinaryReader.prototype.skipFixed64Field = function() {
+  if (this.nextWireType_ != jspb.BinaryConstants.WireType.FIXED64) {
+    goog.asserts.fail('Invalid wire type for skipFixed64Field');
+    this.skipField();
+    return;
+  }
+
+  this.decoder_.advance(8);
+};
+
+
+/**
+ * Skips over the next group field in the binary stream.
+ */
+jspb.BinaryReader.prototype.skipGroup = function() {
+  // Keep a stack of start-group tags that must be matched by end-group tags.
+  var nestedGroups = [this.nextField_];
+  do {
+    if (!this.nextField()) {
+      goog.asserts.fail('Unmatched start-group tag: stream EOF');
+      this.error_ = true;
+      return;
+    }
+    if (this.nextWireType_ ==
+        jspb.BinaryConstants.WireType.START_GROUP) {
+      // Nested group start.
+      nestedGroups.push(this.nextField_);
+    } else if (this.nextWireType_ ==
+               jspb.BinaryConstants.WireType.END_GROUP) {
+      // Group end: check that it matches top-of-stack.
+      if (this.nextField_ != nestedGroups.pop()) {
+        goog.asserts.fail('Unmatched end-group tag');
+        this.error_ = true;
+        return;
+      }
+    }
+  } while (nestedGroups.length > 0);
+};
+
+
+/**
+ * Skips over the next field in the binary stream - this is useful if we're
+ * decoding a message that contain unknown fields.
+ */
+jspb.BinaryReader.prototype.skipField = function() {
+  switch (this.nextWireType_) {
+    case jspb.BinaryConstants.WireType.VARINT:
+      this.skipVarintField();
+      break;
+    case jspb.BinaryConstants.WireType.FIXED64:
+      this.skipFixed64Field();
+      break;
+    case jspb.BinaryConstants.WireType.DELIMITED:
+      this.skipDelimitedField();
+      break;
+    case jspb.BinaryConstants.WireType.FIXED32:
+      this.skipFixed32Field();
+      break;
+    case jspb.BinaryConstants.WireType.START_GROUP:
+      this.skipGroup();
+      break;
+    default:
+      goog.asserts.fail('Invalid wire encoding for field.');
+  }
+};
+
+
+/**
+ * Registers a user-defined read callback.
+ * @param {string} callbackName
+ * @param {function(!jspb.BinaryReader):*} callback
+ */
+jspb.BinaryReader.prototype.registerReadCallback =
+    function(callbackName, callback) {
+  if (goog.isNull(this.readCallbacks_)) {
+    this.readCallbacks_ = {};
+  }
+  goog.asserts.assert(!this.readCallbacks_[callbackName]);
+  this.readCallbacks_[callbackName] = callback;
+};
+
+
+/**
+ * Runs a registered read callback.
+ * @param {string} callbackName The name the callback is registered under.
+ * @return {*} The value returned by the callback.
+ */
+jspb.BinaryReader.prototype.runReadCallback = function(callbackName) {
+  goog.asserts.assert(!goog.isNull(this.readCallbacks_));
+  var callback = this.readCallbacks_[callbackName];
+  goog.asserts.assert(callback);
+  return callback(this);
+};
+
+
+/**
+ * Reads a field of any valid non-message type from the binary stream.
+ * @param {jspb.BinaryConstants.FieldType} fieldType
+ * @return {jspb.AnyFieldType}
+ */
+jspb.BinaryReader.prototype.readAny = function(fieldType) {
+  this.nextWireType_ = jspb.BinaryConstants.FieldTypeToWireType(fieldType);
+  var fieldTypes = jspb.BinaryConstants.FieldType;
+  switch (fieldType) {
+    case fieldTypes.DOUBLE:
+      return this.readDouble();
+    case fieldTypes.FLOAT:
+      return this.readFloat();
+    case fieldTypes.INT64:
+      return this.readInt64();
+    case fieldTypes.UINT64:
+      return this.readUint64();
+    case fieldTypes.INT32:
+      return this.readInt32();
+    case fieldTypes.FIXED64:
+      return this.readFixed64();
+    case fieldTypes.FIXED32:
+      return this.readFixed32();
+    case fieldTypes.BOOL:
+      return this.readBool();
+    case fieldTypes.STRING:
+      return this.readString();
+    case fieldTypes.GROUP:
+      goog.asserts.fail('Group field type not supported in readAny()');
+    case fieldTypes.MESSAGE:
+      goog.asserts.fail('Message field type not supported in readAny()');
+    case fieldTypes.BYTES:
+      return this.readBytes();
+    case fieldTypes.UINT32:
+      return this.readUint32();
+    case fieldTypes.ENUM:
+      return this.readEnum();
+    case fieldTypes.SFIXED32:
+      return this.readSfixed32();
+    case fieldTypes.SFIXED64:
+      return this.readSfixed64();
+    case fieldTypes.SINT32:
+      return this.readSint32();
+    case fieldTypes.SINT64:
+      return this.readSint64();
+    case fieldTypes.FHASH64:
+      return this.readFixedHash64();
+    case fieldTypes.VHASH64:
+      return this.readVarintHash64();
+    default:
+      goog.asserts.fail('Invalid field type in readAny()');
+  }
+  return 0;
+};
+
+
+/**
+ * Deserialize a proto into the provided message object using the provided
+ * reader function. This function is templated as we currently have one client
+ * who is using manual deserialization instead of the code-generated versions.
+ * @template T
+ * @param {T} message
+ * @param {function(T, !jspb.BinaryReader)} reader
+ */
+jspb.BinaryReader.prototype.readMessage = function(message, reader) {
+  goog.asserts.assert(
+      this.nextWireType_ == jspb.BinaryConstants.WireType.DELIMITED);
+
+  // Save the current endpoint of the decoder and move it to the end of the
+  // embedded message.
+  var oldEnd = this.decoder_.getEnd();
+  var length = this.decoder_.readUnsignedVarint32();
+  var newEnd = this.decoder_.getCursor() + length;
+  this.decoder_.setEnd(newEnd);
+
+  // Deserialize the embedded message.
+  reader(message, this);
+
+  // Advance the decoder past the embedded message and restore the endpoint.
+  this.decoder_.setCursor(newEnd);
+  this.decoder_.setEnd(oldEnd);
+};
+
+
+/**
+ * Deserialize a proto into the provided message object using the provided
+ * reader function, assuming that the message is serialized as a group
+ * with the given tag.
+ * @template T
+ * @param {number} field
+ * @param {T} message
+ * @param {function(T, !jspb.BinaryReader)} reader
+ */
+jspb.BinaryReader.prototype.readGroup =
+    function(field, message, reader) {
+  // Ensure that the wire type is correct.
+  goog.asserts.assert(
+      this.nextWireType_ == jspb.BinaryConstants.WireType.START_GROUP);
+  // Ensure that the field number is correct.
+  goog.asserts.assert(this.nextField_ == field);
+
+  // Deserialize the message. The deserialization will stop at an END_GROUP tag.
+  reader(message, this);
+
+  if (!this.error_ &&
+      this.nextWireType_ != jspb.BinaryConstants.WireType.END_GROUP) {
+    goog.asserts.fail('Group submessage did not end with an END_GROUP tag');
+    this.error_ = true;
+  }
+};
+
+
+/**
+ * Return a decoder that wraps the current delimited field.
+ * @return {!jspb.BinaryDecoder}
+ */
+jspb.BinaryReader.prototype.getFieldDecoder = function() {
+  goog.asserts.assert(
+      this.nextWireType_ == jspb.BinaryConstants.WireType.DELIMITED);
+
+  var length = this.decoder_.readUnsignedVarint32();
+  var start = this.decoder_.getCursor();
+  var end = start + length;
+
+  var innerDecoder = jspb.BinaryDecoder.alloc(this.decoder_.getBuffer(),
+                                                 start, length);
+  this.decoder_.setCursor(end);
+  return innerDecoder;
+};
+
+
+/**
+ * Reads a signed 32-bit integer field from the binary stream, or throws an
+ * error if the next field in the stream is not of the correct wire type.
+ *
+ * @return {number} The value of the signed 32-bit integer field.
+ */
+jspb.BinaryReader.prototype.readInt32 = function() {
+  goog.asserts.assert(
+      this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT);
+  return this.decoder_.readSignedVarint32();
+};
+
+
+/**
+ * Reads a signed 32-bit integer field from the binary stream, or throws an
+ * error if the next field in the stream is not of the correct wire type.
+ *
+ * Returns the value as a string.
+ *
+ * @return {string} The value of the signed 32-bit integer field as a decimal
+ * string.
+ */
+jspb.BinaryReader.prototype.readInt32String = function() {
+  goog.asserts.assert(
+      this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT);
+  return this.decoder_.readSignedVarint32String();
+};
+
+
+/**
+ * Reads a signed 64-bit integer field from the binary stream, or throws an
+ * error if the next field in the stream is not of the correct wire type.
+ *
+ * @return {number} The value of the signed 64-bit integer field.
+ */
+jspb.BinaryReader.prototype.readInt64 = function() {
+  goog.asserts.assert(
+      this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT);
+  return this.decoder_.readSignedVarint64();
+};
+
+
+/**
+ * Reads a signed 64-bit integer field from the binary stream, or throws an
+ * error if the next field in the stream is not of the correct wire type.
+ *
+ * Returns the value as a string.
+ *
+ * @return {string} The value of the signed 64-bit integer field as a decimal
+ * string.
+ */
+jspb.BinaryReader.prototype.readInt64String = function() {
+  goog.asserts.assert(
+      this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT);
+  return this.decoder_.readSignedVarint64String();
+};
+
+
+/**
+ * Reads an unsigned 32-bit integer field from the binary stream, or throws an
+ * error if the next field in the stream is not of the correct wire type.
+ *
+ * @return {number} The value of the unsigned 32-bit integer field.
+ */
+jspb.BinaryReader.prototype.readUint32 = function() {
+  goog.asserts.assert(
+      this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT);
+  return this.decoder_.readUnsignedVarint32();
+};
+
+
+/**
+ * Reads an unsigned 32-bit integer field from the binary stream, or throws an
+ * error if the next field in the stream is not of the correct wire type.
+ *
+ * Returns the value as a string.
+ *
+ * @return {string} The value of the unsigned 32-bit integer field as a decimal
+ * string.
+ */
+jspb.BinaryReader.prototype.readUint32String = function() {
+  goog.asserts.assert(
+      this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT);
+  return this.decoder_.readUnsignedVarint32String();
+};
+
+
+/**
+ * Reads an unsigned 64-bit integer field from the binary stream, or throws an
+ * error if the next field in the stream is not of the correct wire type.
+ *
+ * @return {number} The value of the unsigned 64-bit integer field.
+ */
+jspb.BinaryReader.prototype.readUint64 = function() {
+  goog.asserts.assert(
+      this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT);
+  return this.decoder_.readUnsignedVarint64();
+};
+
+
+/**
+ * Reads an unsigned 64-bit integer field from the binary stream, or throws an
+ * error if the next field in the stream is not of the correct wire type.
+ *
+ * Returns the value as a string.
+ *
+ * @return {string} The value of the unsigned 64-bit integer field as a decimal
+ * string.
+ */
+jspb.BinaryReader.prototype.readUint64String = function() {
+  goog.asserts.assert(
+      this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT);
+  return this.decoder_.readUnsignedVarint64String();
+};
+
+
+/**
+ * Reads a signed zigzag-encoded 32-bit integer field from the binary stream,
+ * or throws an error if the next field in the stream is not of the correct
+ * wire type.
+ *
+ * @return {number} The value of the signed 32-bit integer field.
+ */
+jspb.BinaryReader.prototype.readSint32 = function() {
+  goog.asserts.assert(
+      this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT);
+  return this.decoder_.readZigzagVarint32();
+};
+
+
+/**
+ * Reads a signed zigzag-encoded 64-bit integer field from the binary stream,
+ * or throws an error if the next field in the stream is not of the correct
+ * wire type.
+ *
+ * @return {number} The value of the signed 64-bit integer field.
+ */
+jspb.BinaryReader.prototype.readSint64 = function() {
+  goog.asserts.assert(
+      this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT);
+  return this.decoder_.readZigzagVarint64();
+};
+
+
+/**
+ * Reads an unsigned 32-bit fixed-length integer fiield from the binary stream,
+ * or throws an error if the next field in the stream is not of the correct
+ * wire type.
+ *
+ * @return {number} The value of the double field.
+ */
+jspb.BinaryReader.prototype.readFixed32 = function() {
+  goog.asserts.assert(
+      this.nextWireType_ == jspb.BinaryConstants.WireType.FIXED32);
+  return this.decoder_.readUint32();
+};
+
+
+/**
+ * Reads an unsigned 64-bit fixed-length integer fiield from the binary stream,
+ * or throws an error if the next field in the stream is not of the correct
+ * wire type.
+ *
+ * @return {number} The value of the float field.
+ */
+jspb.BinaryReader.prototype.readFixed64 = function() {
+  goog.asserts.assert(
+      this.nextWireType_ == jspb.BinaryConstants.WireType.FIXED64);
+  return this.decoder_.readUint64();
+};
+
+
+/**
+ * Reads a signed 32-bit fixed-length integer fiield from the binary stream, or
+ * throws an error if the next field in the stream is not of the correct wire
+ * type.
+ *
+ * @return {number} The value of the double field.
+ */
+jspb.BinaryReader.prototype.readSfixed32 = function() {
+  goog.asserts.assert(
+      this.nextWireType_ == jspb.BinaryConstants.WireType.FIXED32);
+  return this.decoder_.readInt32();
+};
+
+
+/**
+ * Reads a signed 64-bit fixed-length integer fiield from the binary stream, or
+ * throws an error if the next field in the stream is not of the correct wire
+ * type.
+ *
+ * @return {number} The value of the float field.
+ */
+jspb.BinaryReader.prototype.readSfixed64 = function() {
+  goog.asserts.assert(
+      this.nextWireType_ == jspb.BinaryConstants.WireType.FIXED64);
+  return this.decoder_.readInt64();
+};
+
+
+/**
+ * Reads a 32-bit floating-point field from the binary stream, or throws an
+ * error if the next field in the stream is not of the correct wire type.
+ *
+ * @return {number} The value of the float field.
+ */
+jspb.BinaryReader.prototype.readFloat = function() {
+  goog.asserts.assert(
+      this.nextWireType_ == jspb.BinaryConstants.WireType.FIXED32);
+  return this.decoder_.readFloat();
+};
+
+
+/**
+ * Reads a 64-bit floating-point field from the binary stream, or throws an
+ * error if the next field in the stream is not of the correct wire type.
+ *
+ * @return {number} The value of the double field.
+ */
+jspb.BinaryReader.prototype.readDouble = function() {
+  goog.asserts.assert(
+      this.nextWireType_ == jspb.BinaryConstants.WireType.FIXED64);
+  return this.decoder_.readDouble();
+};
+
+
+/**
+ * Reads a boolean field from the binary stream, or throws an error if the next
+ * field in the stream is not of the correct wire type.
+ *
+ * @return {boolean} The value of the boolean field.
+ */
+jspb.BinaryReader.prototype.readBool = function() {
+  goog.asserts.assert(
+      this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT);
+  return !!this.decoder_.readUnsignedVarint32();
+};
+
+
+/**
+ * Reads an enum field from the binary stream, or throws an error if the next
+ * field in the stream is not of the correct wire type.
+ *
+ * @return {number} The value of the enum field.
+ */
+jspb.BinaryReader.prototype.readEnum = function() {
+  goog.asserts.assert(
+      this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT);
+  return this.decoder_.readSignedVarint64();
+};
+
+
+/**
+ * Reads a string field from the binary stream, or throws an error if the next
+ * field in the stream is not of the correct wire type.
+ *
+ * @return {string} The value of the string field.
+ */
+jspb.BinaryReader.prototype.readString = function() {
+  goog.asserts.assert(
+      this.nextWireType_ == jspb.BinaryConstants.WireType.DELIMITED);
+  var length = this.decoder_.readUnsignedVarint32();
+  return this.decoder_.readString(length);
+};
+
+
+/**
+ * Reads a length-prefixed block of bytes from the binary stream, or returns
+ * null if the next field in the stream has an invalid length value.
+ *
+ * @return {Uint8Array} The block of bytes.
+ */
+jspb.BinaryReader.prototype.readBytes = function() {
+  goog.asserts.assert(
+      this.nextWireType_ == jspb.BinaryConstants.WireType.DELIMITED);
+  var length = this.decoder_.readUnsignedVarint32();
+  return this.decoder_.readBytes(length);
+};
+
+
+/**
+ * Reads a 64-bit varint or fixed64 field from the stream and returns it as a
+ * 8-character Unicode string for use as a hash table key, or throws an error
+ * if the next field in the stream is not of the correct wire type.
+ *
+ * @return {string} The hash value.
+ */
+jspb.BinaryReader.prototype.readVarintHash64 = function() {
+  goog.asserts.assert(
+      this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT);
+  return this.decoder_.readVarintHash64();
+};
+
+
+/**
+ * Reads a 64-bit varint or fixed64 field from the stream and returns it as a
+ * 8-character Unicode string for use as a hash table key, or throws an error
+ * if the next field in the stream is not of the correct wire type.
+ *
+ * @return {string} The hash value.
+ */
+jspb.BinaryReader.prototype.readFixedHash64 = function() {
+  goog.asserts.assert(
+      this.nextWireType_ == jspb.BinaryConstants.WireType.FIXED64);
+  return this.decoder_.readFixedHash64();
+};
+
+
+/**
+ * Reads a packed scalar field using the supplied raw reader function.
+ * @param {function()} decodeMethod
+ * @return {!Array}
+ * @private
+ */
+jspb.BinaryReader.prototype.readPackedField_ = function(decodeMethod) {
+  goog.asserts.assert(
+      this.nextWireType_ == jspb.BinaryConstants.WireType.DELIMITED);
+  var length = this.decoder_.readUnsignedVarint32();
+  var end = this.decoder_.getCursor() + length;
+  var result = [];
+  while (this.decoder_.getCursor() < end) {
+    // TODO(aappleby): .call is slow
+    result.push(decodeMethod.call(this.decoder_));
+  }
+  return result;
+};
+
+
+/**
+ * Reads a packed int32 field, which consists of a length header and a list of
+ * signed varints.
+ * @return {!Array.<number>}
+ */
+jspb.BinaryReader.prototype.readPackedInt32 = function() {
+  return this.readPackedField_(this.decoder_.readSignedVarint32);
+};
+
+
+/**
+ * Reads a packed int32 field, which consists of a length header and a list of
+ * signed varints. Returns a list of strings.
+ * @return {!Array.<string>}
+ */
+jspb.BinaryReader.prototype.readPackedInt32String = function() {
+  return this.readPackedField_(this.decoder_.readSignedVarint32String);
+};
+
+
+/**
+ * Reads a packed int64 field, which consists of a length header and a list of
+ * signed varints.
+ * @return {!Array.<number>}
+ */
+jspb.BinaryReader.prototype.readPackedInt64 = function() {
+  return this.readPackedField_(this.decoder_.readSignedVarint64);
+};
+
+
+/**
+ * Reads a packed int64 field, which consists of a length header and a list of
+ * signed varints. Returns a list of strings.
+ * @return {!Array.<string>}
+ */
+jspb.BinaryReader.prototype.readPackedInt64String = function() {
+  return this.readPackedField_(this.decoder_.readSignedVarint64String);
+};
+
+
+/**
+ * Reads a packed uint32 field, which consists of a length header and a list of
+ * unsigned varints.
+ * @return {!Array.<number>}
+ */
+jspb.BinaryReader.prototype.readPackedUint32 = function() {
+  return this.readPackedField_(this.decoder_.readUnsignedVarint32);
+};
+
+
+/**
+ * Reads a packed uint32 field, which consists of a length header and a list of
+ * unsigned varints. Returns a list of strings.
+ * @return {!Array.<string>}
+ */
+jspb.BinaryReader.prototype.readPackedUint32String = function() {
+  return this.readPackedField_(this.decoder_.readUnsignedVarint32String);
+};
+
+
+/**
+ * Reads a packed uint64 field, which consists of a length header and a list of
+ * unsigned varints.
+ * @return {!Array.<number>}
+ */
+jspb.BinaryReader.prototype.readPackedUint64 = function() {
+  return this.readPackedField_(this.decoder_.readUnsignedVarint64);
+};
+
+
+/**
+ * Reads a packed uint64 field, which consists of a length header and a list of
+ * unsigned varints. Returns a list of strings.
+ * @return {!Array.<string>}
+ */
+jspb.BinaryReader.prototype.readPackedUint64String = function() {
+  return this.readPackedField_(this.decoder_.readUnsignedVarint64String);
+};
+
+
+/**
+ * Reads a packed sint32 field, which consists of a length header and a list of
+ * zigzag varints.
+ * @return {!Array.<number>}
+ */
+jspb.BinaryReader.prototype.readPackedSint32 = function() {
+  return this.readPackedField_(this.decoder_.readZigzagVarint32);
+};
+
+
+/**
+ * Reads a packed sint64 field, which consists of a length header and a list of
+ * zigzag varints.
+ * @return {!Array.<number>}
+ */
+jspb.BinaryReader.prototype.readPackedSint64 = function() {
+  return this.readPackedField_(this.decoder_.readZigzagVarint64);
+};
+
+
+/**
+ * Reads a packed fixed32 field, which consists of a length header and a list
+ * of unsigned 32-bit ints.
+ * @return {!Array.<number>}
+ */
+jspb.BinaryReader.prototype.readPackedFixed32 = function() {
+  return this.readPackedField_(this.decoder_.readUint32);
+};
+
+
+/**
+ * Reads a packed fixed64 field, which consists of a length header and a list
+ * of unsigned 64-bit ints.
+ * @return {!Array.<number>}
+ */
+jspb.BinaryReader.prototype.readPackedFixed64 = function() {
+  return this.readPackedField_(this.decoder_.readUint64);
+};
+
+
+/**
+ * Reads a packed sfixed32 field, which consists of a length header and a list
+ * of 32-bit ints.
+ * @return {!Array.<number>}
+ */
+jspb.BinaryReader.prototype.readPackedSfixed32 = function() {
+  return this.readPackedField_(this.decoder_.readInt32);
+};
+
+
+/**
+ * Reads a packed sfixed64 field, which consists of a length header and a list
+ * of 64-bit ints.
+ * @return {!Array.<number>}
+ */
+jspb.BinaryReader.prototype.readPackedSfixed64 = function() {
+  return this.readPackedField_(this.decoder_.readInt64);
+};
+
+
+/**
+ * Reads a packed float field, which consists of a length header and a list of
+ * floats.
+ * @return {!Array.<number>}
+ */
+jspb.BinaryReader.prototype.readPackedFloat = function() {
+  return this.readPackedField_(this.decoder_.readFloat);
+};
+
+
+/**
+ * Reads a packed double field, which consists of a length header and a list of
+ * doubles.
+ * @return {!Array.<number>}
+ */
+jspb.BinaryReader.prototype.readPackedDouble = function() {
+  return this.readPackedField_(this.decoder_.readDouble);
+};
+
+
+/**
+ * Reads a packed bool field, which consists of a length header and a list of
+ * unsigned varints.
+ * @return {!Array.<boolean>}
+ */
+jspb.BinaryReader.prototype.readPackedBool = function() {
+  return this.readPackedField_(this.decoder_.readBool);
+};
+
+
+/**
+ * Reads a packed enum field, which consists of a length header and a list of
+ * unsigned varints.
+ * @return {!Array.<number>}
+ */
+jspb.BinaryReader.prototype.readPackedEnum = function() {
+  return this.readPackedField_(this.decoder_.readEnum);
+};
+
+
+/**
+ * Reads a packed varint hash64 field, which consists of a length header and a
+ * list of varint hash64s.
+ * @return {!Array.<string>}
+ */
+jspb.BinaryReader.prototype.readPackedVarintHash64 = function() {
+  return this.readPackedField_(this.decoder_.readVarintHash64);
+};
+
+
+/**
+ * Reads a packed fixed hash64 field, which consists of a length header and a
+ * list of fixed hash64s.
+ * @return {!Array.<string>}
+ */
+jspb.BinaryReader.prototype.readPackedFixedHash64 = function() {
+  return this.readPackedField_(this.decoder_.readFixedHash64);
+};
diff --git a/js/binary/reader_test.js b/js/binary/reader_test.js
new file mode 100644
index 0000000..a648261
--- /dev/null
+++ b/js/binary/reader_test.js
@@ -0,0 +1,889 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/**
+ * @fileoverview Test cases for jspb's binary protocol buffer reader.
+ *
+ * There are two particular magic numbers that need to be pointed out -
+ * 2^64-1025 is the largest number representable as both a double and an
+ * unsigned 64-bit integer, and 2^63-513 is the largest number representable as
+ * both a double and a signed 64-bit integer.
+ *
+ * Test suite is written using Jasmine -- see http://jasmine.github.io/
+ *
+ * @author aappleby@google.com (Austin Appleby)
+ */
+
+goog.require('goog.testing.asserts');
+goog.require('jspb.BinaryConstants');
+goog.require('jspb.BinaryDecoder');
+goog.require('jspb.BinaryReader');
+goog.require('jspb.BinaryWriter');
+
+
+
+describe('binaryReaderTest', function() {
+  /**
+   * Tests the reader instance cache.
+   * @suppress {visibility}
+   */
+  it('testInstanceCaches', function() {
+    var writer = new jspb.BinaryWriter();
+    var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
+    writer.writeMessage(1, dummyMessage, goog.nullFunction);
+    writer.writeMessage(2, dummyMessage, goog.nullFunction);
+
+    var buffer = writer.getResultBuffer();
+
+    // Empty the instance caches.
+    jspb.BinaryReader.instanceCache_ = [];
+
+    // Allocating and then freeing three decoders should leave us with three in
+    // the cache.
+
+    var decoder1 = jspb.BinaryDecoder.alloc();
+    var decoder2 = jspb.BinaryDecoder.alloc();
+    var decoder3 = jspb.BinaryDecoder.alloc();
+    decoder1.free();
+    decoder2.free();
+    decoder3.free();
+
+    assertEquals(3, jspb.BinaryDecoder.instanceCache_.length);
+    assertEquals(0, jspb.BinaryReader.instanceCache_.length);
+
+    // Allocating and then freeing a reader should remove one decoder from its
+    // cache, but it should stay stuck to the reader afterwards since we can't
+    // have a reader without a decoder.
+    jspb.BinaryReader.alloc().free();
+
+    assertEquals(2, jspb.BinaryDecoder.instanceCache_.length);
+    assertEquals(1, jspb.BinaryReader.instanceCache_.length);
+
+    // Allocating a reader should remove a reader from the cache.
+    var reader = jspb.BinaryReader.alloc(buffer);
+
+    assertEquals(2, jspb.BinaryDecoder.instanceCache_.length);
+    assertEquals(0, jspb.BinaryReader.instanceCache_.length);
+
+    // Processing the message reuses the current reader.
+    reader.nextField();
+    assertEquals(1, reader.getFieldNumber());
+    reader.readMessage(dummyMessage, function() {
+      assertEquals(0, jspb.BinaryReader.instanceCache_.length);
+    });
+
+    reader.nextField();
+    assertEquals(2, reader.getFieldNumber());
+    reader.readMessage(dummyMessage, function() {
+      assertEquals(0, jspb.BinaryReader.instanceCache_.length);
+    });
+
+    assertEquals(false, reader.nextField());
+
+    assertEquals(2, jspb.BinaryDecoder.instanceCache_.length);
+    assertEquals(0, jspb.BinaryReader.instanceCache_.length);
+
+    // Freeing the reader should put it back into the cache.
+    reader.free();
+
+    assertEquals(2, jspb.BinaryDecoder.instanceCache_.length);
+    assertEquals(1, jspb.BinaryReader.instanceCache_.length);
+  });
+
+
+  /**
+   * @param {number} x
+   * @return {number}
+   */
+  function truncate(x) {
+    var temp = new Float32Array(1);
+    temp[0] = x;
+    return temp[0];
+  }
+
+
+  /**
+   * Verifies that misuse of the reader class triggers assertions.
+   * @suppress {checkTypes|visibility}
+   */
+  it('testReadErrors', function() {
+    // Calling readMessage on a non-delimited field should trigger an
+    // assertion.
+    var reader = jspb.BinaryReader.alloc([8, 1]);
+    var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
+    reader.nextField();
+    assertThrows(function() {
+      reader.readMessage(dummyMessage, goog.nullFunction);
+    });
+
+    // Reading past the end of the stream should trigger an assertion.
+    reader = jspb.BinaryReader.alloc([9, 1]);
+    reader.nextField();
+    assertThrows(function() {reader.readFixed64()});
+
+    // Reading past the end of a submessage should trigger an assertion.
+    reader = jspb.BinaryReader.alloc([10, 4, 13, 1, 1, 1]);
+    reader.nextField();
+    reader.readMessage(dummyMessage, function() {
+      reader.nextField();
+      assertThrows(function() {reader.readFixed32()});
+    });
+
+    // Skipping an invalid field should trigger an assertion.
+    reader = jspb.BinaryReader.alloc([12, 1]);
+    reader.nextWireType_ = 1000;
+    assertThrows(function() {reader.skipField()});
+
+    // Reading fields with the wrong wire type should assert.
+    reader = jspb.BinaryReader.alloc([9, 0, 0, 0, 0, 0, 0, 0, 0]);
+    reader.nextField();
+    assertThrows(function() {reader.readInt32()});
+    assertThrows(function() {reader.readInt32String()});
+    assertThrows(function() {reader.readInt64()});
+    assertThrows(function() {reader.readInt64String()});
+    assertThrows(function() {reader.readUint32()});
+    assertThrows(function() {reader.readUint32String()});
+    assertThrows(function() {reader.readUint64()});
+    assertThrows(function() {reader.readUint64String()});
+    assertThrows(function() {reader.readSint32()});
+    assertThrows(function() {reader.readBool()});
+    assertThrows(function() {reader.readEnum()});
+
+    reader = jspb.BinaryReader.alloc([8, 1]);
+    reader.nextField();
+    assertThrows(function() {reader.readFixed32()});
+    assertThrows(function() {reader.readFixed64()});
+    assertThrows(function() {reader.readSfixed32()});
+    assertThrows(function() {reader.readSfixed64()});
+    assertThrows(function() {reader.readFloat()});
+    assertThrows(function() {reader.readDouble()});
+
+    assertThrows(function() {reader.readString()});
+    assertThrows(function() {reader.readBytes()});
+  });
+
+
+  /**
+   * Tests encoding and decoding of unsigned field types.
+   * @param {Function} readField
+   * @param {Function} writeField
+   * @param {number} epsilon
+   * @param {number} upperLimit
+   * @param {Function} filter
+   * @private
+   * @suppress {missingProperties}
+   */
+  function doTestUnsignedField_(readField,
+      writeField, epsilon, upperLimit, filter) {
+    assertNotNull(readField);
+    assertNotNull(writeField);
+
+    var writer = new jspb.BinaryWriter();
+
+    // Encode zero and limits.
+    writeField.call(writer, 1, filter(0));
+    writeField.call(writer, 2, filter(epsilon));
+    writeField.call(writer, 3, filter(upperLimit));
+
+    // Encode positive values.
+    for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
+      writeField.call(writer, 4, filter(cursor));
+    }
+
+    var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
+
+    // Check zero and limits.
+    reader.nextField();
+    assertEquals(1, reader.getFieldNumber());
+    assertEquals(filter(0), readField.call(reader));
+
+    reader.nextField();
+    assertEquals(2, reader.getFieldNumber());
+    assertEquals(filter(epsilon), readField.call(reader));
+
+    reader.nextField();
+    assertEquals(3, reader.getFieldNumber());
+    assertEquals(filter(upperLimit), readField.call(reader));
+
+    // Check positive values.
+    for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
+      reader.nextField();
+      if (4 != reader.getFieldNumber()) throw 'fail!';
+      if (filter(cursor) != readField.call(reader)) throw 'fail!';
+    }
+  };
+
+
+  /**
+   * Tests encoding and decoding of signed field types.
+   * @param {Function} readField
+   * @param {Function} writeField
+   * @param {number} epsilon
+   * @param {number} lowerLimit
+   * @param {number} upperLimit
+   * @param {Function} filter
+   * @private
+   * @suppress {missingProperties}
+   */
+  function doTestSignedField_(readField,
+      writeField, epsilon, lowerLimit, upperLimit, filter) {
+    var writer = new jspb.BinaryWriter();
+
+    // Encode zero and limits.
+    writeField.call(writer, 1, filter(lowerLimit));
+    writeField.call(writer, 2, filter(-epsilon));
+    writeField.call(writer, 3, filter(0));
+    writeField.call(writer, 4, filter(epsilon));
+    writeField.call(writer, 5, filter(upperLimit));
+
+    var inputValues = [];
+
+    // Encode negative values.
+    for (var cursor = lowerLimit; cursor < -epsilon; cursor /= 1.1) {
+      var val = filter(cursor);
+      writeField.call(writer, 6, val);
+      inputValues.push({
+        fieldNumber: 6,
+        value: val
+      });
+    }
+
+    // Encode positive values.
+    for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
+      var val = filter(cursor);
+      writeField.call(writer, 7, val);
+      inputValues.push({
+        fieldNumber: 7,
+        value: val
+      });
+    }
+
+    var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
+
+    // Check zero and limits.
+    reader.nextField();
+    assertEquals(1, reader.getFieldNumber());
+    assertEquals(filter(lowerLimit), readField.call(reader));
+
+    reader.nextField();
+    assertEquals(2, reader.getFieldNumber());
+    assertEquals(filter(-epsilon), readField.call(reader));
+
+    reader.nextField();
+    assertEquals(3, reader.getFieldNumber());
+    assertEquals(filter(0), readField.call(reader));
+
+    reader.nextField();
+    assertEquals(4, reader.getFieldNumber());
+    assertEquals(filter(epsilon), readField.call(reader));
+
+    reader.nextField();
+    assertEquals(5, reader.getFieldNumber());
+    assertEquals(filter(upperLimit), readField.call(reader));
+
+    for (var i = 0; i < inputValues.length; i++) {
+      var expected = inputValues[i];
+      reader.nextField();
+      assertEquals(expected.fieldNumber, reader.getFieldNumber());
+      assertEquals(expected.value, readField.call(reader));
+    }
+  };
+
+
+  /**
+   * Tests fields that use varint encoding.
+   */
+  it('testVarintFields', function() {
+    assertNotNull(jspb.BinaryReader.prototype.readUint32);
+    assertNotNull(jspb.BinaryReader.prototype.writeUint32);
+    assertNotNull(jspb.BinaryReader.prototype.readUint64);
+    assertNotNull(jspb.BinaryReader.prototype.writeUint64);
+    assertNotNull(jspb.BinaryReader.prototype.readBool);
+    assertNotNull(jspb.BinaryReader.prototype.writeBool);
+    doTestUnsignedField_(
+        jspb.BinaryReader.prototype.readUint32,
+        jspb.BinaryWriter.prototype.writeUint32,
+        1, Math.pow(2, 32) - 1, Math.round);
+
+    doTestUnsignedField_(
+        jspb.BinaryReader.prototype.readUint64,
+        jspb.BinaryWriter.prototype.writeUint64,
+        1, Math.pow(2, 64) - 1025, Math.round);
+
+    doTestSignedField_(
+        jspb.BinaryReader.prototype.readInt32,
+        jspb.BinaryWriter.prototype.writeInt32,
+        1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);
+
+    doTestSignedField_(
+        jspb.BinaryReader.prototype.readInt64,
+        jspb.BinaryWriter.prototype.writeInt64,
+        1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);
+
+    doTestSignedField_(
+        jspb.BinaryReader.prototype.readEnum,
+        jspb.BinaryWriter.prototype.writeEnum,
+        1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);
+
+    doTestUnsignedField_(
+        jspb.BinaryReader.prototype.readBool,
+        jspb.BinaryWriter.prototype.writeBool,
+        1, 1, function(x) { return !!x; });
+  });
+
+
+  /**
+   * Tests 64-bit fields that are handled as strings.
+   */
+  it('testStringInt64Fields', function() {
+    var writer = new jspb.BinaryWriter();
+
+    var testSignedData = [
+        '2730538252207801776',
+        '-2688470994844604560',
+        '3398529779486536359',
+        '3568577411627971000',
+        '272477188847484900',
+        '-6649058714086158188',
+        '-7695254765712060806',
+        '-4525541438037104029',
+        '-4993706538836508568',
+        '4990160321893729138'
+    ];
+    var testUnsignedData = [
+        '7822732630241694882',
+        '6753602971916687352',
+        '2399935075244442116',
+        '8724292567325338867',
+        '16948784802625696584',
+        '4136275908516066934',
+        '3575388346793700364',
+        '5167142028379259461',
+        '1557573948689737699',
+        '17100725280812548567'
+    ];
+
+    for (var i = 0; i < testSignedData.length; i++) {
+      writer.writeInt64String(2 * i + 1, testSignedData[i]);
+      writer.writeUint64String(2 * i + 2, testUnsignedData[i]);
+    }
+
+    var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
+
+    for (var i = 0; i < testSignedData.length; i++) {
+      reader.nextField();
+      assertEquals(2 * i + 1, reader.getFieldNumber());
+      assertEquals(testSignedData[i], reader.readInt64String());
+      reader.nextField();
+      assertEquals(2 * i + 2, reader.getFieldNumber());
+      assertEquals(testUnsignedData[i], reader.readUint64String());
+    }
+  });
+
+
+  /**
+   * Tests fields that use zigzag encoding.
+   */
+  it('testZigzagFields', function() {
+    doTestSignedField_(
+        jspb.BinaryReader.prototype.readSint32,
+        jspb.BinaryWriter.prototype.writeSint32,
+        1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);
+
+    doTestSignedField_(
+        jspb.BinaryReader.prototype.readSint64,
+        jspb.BinaryWriter.prototype.writeSint64,
+        1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);
+  });
+
+
+  /**
+   * Tests fields that use fixed-length encoding.
+   */
+  it('testFixedFields', function() {
+    doTestUnsignedField_(
+        jspb.BinaryReader.prototype.readFixed32,
+        jspb.BinaryWriter.prototype.writeFixed32,
+        1, Math.pow(2, 32) - 1, Math.round);
+
+    doTestUnsignedField_(
+        jspb.BinaryReader.prototype.readFixed64,
+        jspb.BinaryWriter.prototype.writeFixed64,
+        1, Math.pow(2, 64) - 1025, Math.round);
+
+    doTestSignedField_(
+        jspb.BinaryReader.prototype.readSfixed32,
+        jspb.BinaryWriter.prototype.writeSfixed32,
+        1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);
+
+    doTestSignedField_(
+        jspb.BinaryReader.prototype.readSfixed64,
+        jspb.BinaryWriter.prototype.writeSfixed64,
+        1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);
+  });
+
+
+  /**
+   * Tests floating point fields.
+   */
+  it('testFloatFields', function() {
+    doTestSignedField_(
+        jspb.BinaryReader.prototype.readFloat,
+        jspb.BinaryWriter.prototype.writeFloat,
+        jspb.BinaryConstants.FLOAT32_MIN,
+        -jspb.BinaryConstants.FLOAT32_MAX,
+        jspb.BinaryConstants.FLOAT32_MAX,
+        truncate);
+
+    doTestSignedField_(
+        jspb.BinaryReader.prototype.readDouble,
+        jspb.BinaryWriter.prototype.writeDouble,
+        jspb.BinaryConstants.FLOAT64_EPS * 10,
+        -jspb.BinaryConstants.FLOAT64_MIN,
+        jspb.BinaryConstants.FLOAT64_MIN,
+        function(x) { return x; });
+  });
+
+
+  /**
+   * Tests length-delimited string fields.
+   */
+  it('testStringFields', function() {
+    var s1 = 'The quick brown fox jumps over the lazy dog.';
+    var s2 = '人人生而自由，在尊嚴和權利上一律平等。';
+
+    var writer = new jspb.BinaryWriter();
+
+    writer.writeString(1, s1);
+    writer.writeString(2, s2);
+
+    var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
+
+    reader.nextField();
+    assertEquals(1, reader.getFieldNumber());
+    assertEquals(s1, reader.readString());
+
+    reader.nextField();
+    assertEquals(2, reader.getFieldNumber());
+    assertEquals(s2, reader.readString());
+  });
+
+
+  /**
+   * Tests length-delimited byte fields.
+   */
+  it('testByteFields', function() {
+    var message = [];
+    var lowerLimit = 1;
+    var upperLimit = 256;
+    var scale = 1.1;
+
+    var writer = new jspb.BinaryWriter();
+
+    for (var cursor = lowerLimit; cursor < upperLimit; cursor *= 1.1) {
+      var len = Math.round(cursor);
+      var bytes = [];
+      for (var i = 0; i < len; i++) bytes.push(i % 256);
+
+      writer.writeBytes(len, bytes);
+    }
+
+    var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
+
+    for (var cursor = lowerLimit; reader.nextField(); cursor *= 1.1) {
+      var len = Math.round(cursor);
+      if (len != reader.getFieldNumber()) throw 'fail!';
+
+      var bytes = reader.readBytes();
+      if (len != bytes.length) throw 'fail!';
+      for (var i = 0; i < bytes.length; i++) {
+        if (i % 256 != bytes[i]) throw 'fail!';
+      }
+    }
+  });
+
+
+  /**
+   * Tests nested messages.
+   */
+  it('testNesting', function() {
+    var writer = new jspb.BinaryWriter();
+  var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
+
+    writer.writeInt32(1, 100);
+
+    // Add one message with 3 int fields.
+    writer.writeMessage(2, dummyMessage, function() {
+      writer.writeInt32(3, 300);
+      writer.writeInt32(4, 400);
+      writer.writeInt32(5, 500);
+    });
+
+    // Add one empty message.
+    writer.writeMessage(6, dummyMessage, goog.nullFunction);
+
+    writer.writeInt32(7, 700);
+
+    var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
+
+    // Validate outermost message.
+
+    reader.nextField();
+    assertEquals(1, reader.getFieldNumber());
+    assertEquals(100, reader.readInt32());
+
+    reader.nextField();
+    assertEquals(2, reader.getFieldNumber());
+    reader.readMessage(dummyMessage, function() {
+      // Validate embedded message 1.
+      reader.nextField();
+      assertEquals(3, reader.getFieldNumber());
+      assertEquals(300, reader.readInt32());
+
+      reader.nextField();
+      assertEquals(4, reader.getFieldNumber());
+      assertEquals(400, reader.readInt32());
+
+      reader.nextField();
+      assertEquals(5, reader.getFieldNumber());
+      assertEquals(500, reader.readInt32());
+
+      assertEquals(false, reader.nextField());
+    });
+
+    reader.nextField();
+    assertEquals(6, reader.getFieldNumber());
+    reader.readMessage(dummyMessage, function() {
+      // Validate embedded message 2.
+
+      assertEquals(false, reader.nextField());
+    });
+
+    reader.nextField();
+    assertEquals(7, reader.getFieldNumber());
+    assertEquals(700, reader.readInt32());
+
+    assertEquals(false, reader.nextField());
+  });
+
+  /**
+   * Tests skipping fields of each type by interleaving them with sentinel
+   * values and skipping everything that's not a sentinel.
+   */
+  it('testSkipField', function() {
+    var writer = new jspb.BinaryWriter();
+
+    var sentinel = 123456789;
+
+    // Write varint fields of different sizes.
+    writer.writeInt32(1, sentinel);
+    writer.writeInt32(1, 1);
+    writer.writeInt32(1, 1000);
+    writer.writeInt32(1, 1000000);
+    writer.writeInt32(1, 1000000000);
+
+    // Write fixed 64-bit encoded fields.
+    writer.writeInt32(2, sentinel);
+    writer.writeDouble(2, 1);
+    writer.writeFixed64(2, 1);
+    writer.writeSfixed64(2, 1);
+
+    // Write fixed 32-bit encoded fields.
+    writer.writeInt32(3, sentinel);
+    writer.writeFloat(3, 1);
+    writer.writeFixed32(3, 1);
+    writer.writeSfixed32(3, 1);
+
+    // Write delimited fields.
+    writer.writeInt32(4, sentinel);
+    writer.writeBytes(4, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
+    writer.writeString(4, 'The quick brown fox jumps over the lazy dog');
+
+    // Write a group with a nested group inside. We use the internal
+    // .rawWriteVarint() to ensure the tested wire data is what we want,
+    // independently of any serialization logic.
+    writer.writeInt32(5, sentinel);
+    // Start group, field 5.
+    writer.rawWriteVarint(
+        (5 << 3) + jspb.BinaryConstants.WireType.START_GROUP);
+    // Varint, field 42.
+    writer.rawWriteVarint(
+        (42 << 3) + jspb.BinaryConstants.WireType.VARINT);
+    // Varint data.
+    writer.rawWriteVarint(42);
+    // Start group, field 6.
+    writer.rawWriteVarint(
+        (6 << 3) + jspb.BinaryConstants.WireType.START_GROUP);
+    // Varint, field 84.
+    writer.rawWriteVarint(
+        (84 << 3) + jspb.BinaryConstants.WireType.VARINT);
+    writer.rawWriteVarint(42);
+    // End group, field 6.
+    writer.rawWriteVarint(
+        (6 << 3) + jspb.BinaryConstants.WireType.END_GROUP);
+    // End group, field 5.
+    writer.rawWriteVarint(
+        (5 << 3) + jspb.BinaryConstants.WireType.END_GROUP);
+
+    // Write final sentinel.
+    writer.writeInt32(6, sentinel);
+
+    var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
+
+    function skip(field, count) {
+      for (var i = 0; i < count; i++) {
+        reader.nextField();
+        if (field != reader.getFieldNumber()) throw 'fail!';
+        reader.skipField();
+      }
+    }
+
+    reader.nextField();
+    assertEquals(1, reader.getFieldNumber());
+    assertEquals(sentinel, reader.readInt32());
+    skip(1, 4);
+
+    reader.nextField();
+    assertEquals(2, reader.getFieldNumber());
+    assertEquals(sentinel, reader.readInt32());
+    skip(2, 3);
+
+    reader.nextField();
+    assertEquals(3, reader.getFieldNumber());
+    assertEquals(sentinel, reader.readInt32());
+    skip(3, 3);
+
+    reader.nextField();
+    assertEquals(4, reader.getFieldNumber());
+    assertEquals(sentinel, reader.readInt32());
+    skip(4, 2);
+
+    reader.nextField();
+    assertEquals(5, reader.getFieldNumber());
+    assertEquals(sentinel, reader.readInt32());
+    skip(5, 1);
+
+    reader.nextField();
+    assertEquals(6, reader.getFieldNumber());
+    assertEquals(sentinel, reader.readInt32());
+  });
+
+
+  /**
+   * Tests packed fields.
+   */
+  it('testPackedFields', function() {
+    var writer = new jspb.BinaryWriter();
+
+    var sentinel = 123456789;
+
+    var unsignedData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+    var signedData = [-1, 2, -3, 4, -5, 6, -7, 8, -9, 10];
+    var floatData = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.10];
+    var doubleData = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.10];
+    var boolData = [true, false, true, true, false, false, true, false];
+
+    for (var i = 0; i < floatData.length; i++) {
+      floatData[i] = truncate(floatData[i]);
+    }
+
+    writer.writeInt32(1, sentinel);
+
+    writer.writePackedInt32(2, signedData);
+    writer.writePackedInt64(2, signedData);
+    writer.writePackedUint32(2, unsignedData);
+    writer.writePackedUint64(2, unsignedData);
+    writer.writePackedSint32(2, signedData);
+    writer.writePackedSint64(2, signedData);
+    writer.writePackedFixed32(2, unsignedData);
+    writer.writePackedFixed64(2, unsignedData);
+    writer.writePackedSfixed32(2, signedData);
+    writer.writePackedSfixed64(2, signedData);
+    writer.writePackedFloat(2, floatData);
+    writer.writePackedDouble(2, doubleData);
+    writer.writePackedBool(2, boolData);
+    writer.writePackedEnum(2, unsignedData);
+
+    writer.writeInt32(3, sentinel);
+
+    var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
+
+    reader.nextField();
+    assertEquals(sentinel, reader.readInt32());
+
+    reader.nextField();
+    assertElementsEquals(reader.readPackedInt32(), signedData);
+
+    reader.nextField();
+    assertElementsEquals(reader.readPackedInt64(), signedData);
+
+    reader.nextField();
+    assertElementsEquals(reader.readPackedUint32(), unsignedData);
+
+    reader.nextField();
+    assertElementsEquals(reader.readPackedUint64(), unsignedData);
+
+    reader.nextField();
+    assertElementsEquals(reader.readPackedSint32(), signedData);
+
+    reader.nextField();
+    assertElementsEquals(reader.readPackedSint64(), signedData);
+
+    reader.nextField();
+    assertElementsEquals(reader.readPackedFixed32(), unsignedData);
+
+    reader.nextField();
+    assertElementsEquals(reader.readPackedFixed64(), unsignedData);
+
+    reader.nextField();
+    assertElementsEquals(reader.readPackedSfixed32(), signedData);
+
+    reader.nextField();
+    assertElementsEquals(reader.readPackedSfixed64(), signedData);
+
+    reader.nextField();
+    assertElementsEquals(reader.readPackedFloat(), floatData);
+
+    reader.nextField();
+    assertElementsEquals(reader.readPackedDouble(), doubleData);
+
+    reader.nextField();
+    assertElementsEquals(reader.readPackedBool(), boolData);
+
+    reader.nextField();
+    assertElementsEquals(reader.readPackedEnum(), unsignedData);
+
+    reader.nextField();
+    assertEquals(sentinel, reader.readInt32());
+  });
+
+
+  /**
+   * Byte blobs inside nested messages should always have their byte offset set
+   * relative to the start of the outermost blob, not the start of their parent
+   * blob.
+   */
+  it('testNestedBlobs', function() {
+    // Create a proto consisting of two nested messages, with the inner one
+    // containing a blob of bytes.
+
+    var fieldTag = (1 << 3) | jspb.BinaryConstants.WireType.DELIMITED;
+    var blob = [1, 2, 3, 4, 5];
+    var writer = new jspb.BinaryWriter();
+    var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
+
+    writer.writeMessage(1, dummyMessage, function() {
+      writer.writeMessage(1, dummyMessage, function() {
+        writer.writeBytes(1, blob);
+      });
+    });
+
+    // Peel off the outer two message layers. Each layer should have two bytes
+    // of overhead, one for the field tag and one for the length of the inner
+    // blob.
+
+    var decoder1 = new jspb.BinaryDecoder(writer.getResultBuffer());
+    assertEquals(fieldTag, decoder1.readUnsignedVarint32());
+    assertEquals(blob.length + 4, decoder1.readUnsignedVarint32());
+
+    var decoder2 = new jspb.BinaryDecoder(decoder1.readBytes(blob.length + 4));
+    assertEquals(fieldTag, decoder2.readUnsignedVarint32());
+    assertEquals(blob.length + 2, decoder2.readUnsignedVarint32());
+
+    assertEquals(fieldTag, decoder2.readUnsignedVarint32());
+    assertEquals(blob.length, decoder2.readUnsignedVarint32());
+    var bytes = decoder2.readBytes(blob.length);
+
+    assertElementsEquals(bytes, blob);
+  });
+
+
+  /**
+   * Tests read callbacks.
+   */
+  it('testReadCallbacks', function() {
+    var writer = new jspb.BinaryWriter();
+    var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
+
+    // Add an int, a submessage, and another int.
+    writer.writeInt32(1, 100);
+
+    writer.writeMessage(2, dummyMessage, function() {
+      writer.writeInt32(3, 300);
+      writer.writeInt32(4, 400);
+      writer.writeInt32(5, 500);
+    });
+
+    writer.writeInt32(7, 700);
+
+    // Create the reader and register a custom read callback.
+    var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
+
+    /**
+     * @param {!jspb.BinaryReader} reader
+     * @return {*}
+     */
+    function readCallback(reader) {
+      reader.nextField();
+      assertEquals(3, reader.getFieldNumber());
+      assertEquals(300, reader.readInt32());
+
+      reader.nextField();
+      assertEquals(4, reader.getFieldNumber());
+      assertEquals(400, reader.readInt32());
+
+      reader.nextField();
+      assertEquals(5, reader.getFieldNumber());
+      assertEquals(500, reader.readInt32());
+
+      assertEquals(false, reader.nextField());
+    };
+
+    reader.registerReadCallback('readCallback', readCallback);
+
+    // Read the container message.
+    reader.nextField();
+    assertEquals(1, reader.getFieldNumber());
+    assertEquals(100, reader.readInt32());
+
+    reader.nextField();
+    assertEquals(2, reader.getFieldNumber());
+    reader.readMessage(dummyMessage, function() {
+      // Decode the embedded message using the registered callback.
+      reader.runReadCallback('readCallback');
+    });
+
+    reader.nextField();
+    assertEquals(7, reader.getFieldNumber());
+    assertEquals(700, reader.readInt32());
+
+    assertEquals(false, reader.nextField());
+  });
+});
diff --git a/js/binary/utils.js b/js/binary/utils.js
new file mode 100644
index 0000000..9260038
--- /dev/null
+++ b/js/binary/utils.js
@@ -0,0 +1,979 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/**
+ * @fileoverview This file contains helper code used by jspb.BinaryReader
+ * and BinaryWriter.
+ *
+ * @author aappleby@google.com (Austin Appleby)
+ */
+
+goog.provide('jspb.utils');
+
+goog.require('goog.asserts');
+goog.require('goog.crypt.base64');
+goog.require('goog.string');
+goog.require('jspb.BinaryConstants');
+
+
+/**
+ * Javascript can't natively handle 64-bit data types, so to manipulate them we
+ * have to split them into two 32-bit halves and do the math manually.
+ *
+ * Instead of instantiating and passing small structures around to do this, we
+ * instead just use two global temporary values. This one stores the low 32
+ * bits of a split value - for example, if the original value was a 64-bit
+ * integer, this temporary value will contain the low 32 bits of that integer.
+ * If the original value was a double, this temporary value will contain the
+ * low 32 bits of the binary representation of that double, etcetera.
+ * @type {number}
+ */
+jspb.utils.split64Low = 0;
+
+
+/**
+ * And correspondingly, this temporary variable will contain the high 32 bits
+ * of whatever value was split.
+ * @type {number}
+ */
+jspb.utils.split64High = 0;
+
+
+/**
+ * Splits an unsigned Javascript integer into two 32-bit halves and stores it
+ * in the temp values above.
+ * @param {number} value The number to split.
+ */
+jspb.utils.splitUint64 = function(value) {
+  // Extract low 32 bits and high 32 bits as unsigned integers.
+  var lowBits = value >>> 0;
+  var highBits = Math.floor((value - lowBits) /
+                            jspb.BinaryConstants.TWO_TO_32) >>> 0;
+
+  jspb.utils.split64Low = lowBits;
+  jspb.utils.split64High = highBits;
+};
+
+
+/**
+ * Splits a signed Javascript integer into two 32-bit halves and stores it in
+ * the temp values above.
+ * @param {number} value The number to split.
+ */
+jspb.utils.splitInt64 = function(value) {
+  // Convert to sign-magnitude representation.
+  var sign = (value < 0);
+  value = Math.abs(value);
+
+  // Extract low 32 bits and high 32 bits as unsigned integers.
+  var lowBits = value >>> 0;
+  var highBits = Math.floor((value - lowBits) /
+                            jspb.BinaryConstants.TWO_TO_32);
+  highBits = highBits >>> 0;
+
+  // Perform two's complement conversion if the sign bit was set.
+  if (sign) {
+    highBits = ~highBits >>> 0;
+    lowBits = ~lowBits >>> 0;
+    lowBits += 1;
+    if (lowBits > 0xFFFFFFFF) {
+      lowBits = 0;
+      highBits++;
+      if (highBits > 0xFFFFFFFF) highBits = 0;
+    }
+  }
+
+  jspb.utils.split64Low = lowBits;
+  jspb.utils.split64High = highBits;
+};
+
+
+/**
+ * Convers a signed Javascript integer into zigzag format, splits it into two
+ * 32-bit halves, and stores it in the temp values above.
+ * @param {number} value The number to split.
+ */
+jspb.utils.splitZigzag64 = function(value) {
+  // Convert to sign-magnitude and scale by 2 before we split the value.
+  var sign = (value < 0);
+  value = Math.abs(value) * 2;
+
+  jspb.utils.splitUint64(value);
+  var lowBits = jspb.utils.split64Low;
+  var highBits = jspb.utils.split64High;
+
+  // If the value is negative, subtract 1 from the split representation so we
+  // don't lose the sign bit due to precision issues.
+  if (sign) {
+    if (lowBits == 0) {
+      if (highBits == 0) {
+        lowBits = 0xFFFFFFFF;
+        highBits = 0xFFFFFFFF;
+      } else {
+        highBits--;
+        lowBits = 0xFFFFFFFF;
+      }
+    } else {
+      lowBits--;
+    }
+  }
+
+  jspb.utils.split64Low = lowBits;
+  jspb.utils.split64High = highBits;
+};
+
+
+/**
+ * Converts a floating-point number into 32-bit IEEE representation and stores
+ * it in the temp values above.
+ * @param {number} value
+ */
+jspb.utils.splitFloat32 = function(value) {
+  var sign = (value < 0) ? 1 : 0;
+  value = sign ? -value : value;
+  var exp;
+  var mant;
+
+  // Handle zeros.
+  if (value === 0) {
+    if ((1 / value) > 0) {
+      // Positive zero.
+      jspb.utils.split64High = 0;
+      jspb.utils.split64Low = 0x00000000;
+    } else {
+      // Negative zero.
+      jspb.utils.split64High = 0;
+      jspb.utils.split64Low = 0x80000000;
+    }
+    return;
+  }
+
+  // Handle nans.
+  if (isNaN(value)) {
+    jspb.utils.split64High = 0;
+    jspb.utils.split64Low = 0x7FFFFFFF;
+    return;
+  }
+
+  // Handle infinities.
+  if (value > jspb.BinaryConstants.FLOAT32_MAX) {
+    jspb.utils.split64High = 0;
+    jspb.utils.split64Low = ((sign << 31) | (0x7F800000)) >>> 0;
+    return;
+  }
+
+  // Handle denormals.
+  if (value < jspb.BinaryConstants.FLOAT32_MIN) {
+    // Number is a denormal.
+    mant = Math.round(value / Math.pow(2, -149));
+    jspb.utils.split64High = 0;
+    jspb.utils.split64Low = ((sign << 31) | mant) >>> 0;
+    return;
+  }
+
+  exp = Math.floor(Math.log(value) / Math.LN2);
+  mant = value * Math.pow(2, -exp);
+  mant = Math.round(mant * jspb.BinaryConstants.TWO_TO_23) & 0x7FFFFF;
+
+  jspb.utils.split64High = 0;
+  jspb.utils.split64Low = ((sign << 31) | ((exp + 127) << 23) | mant) >>> 0;
+};
+
+
+/**
+ * Converts a floating-point number into 64-bit IEEE representation and stores
+ * it in the temp values above.
+ * @param {number} value
+ */
+jspb.utils.splitFloat64 = function(value) {
+  var sign = (value < 0) ? 1 : 0;
+  value = sign ? -value : value;
+
+  // Handle zeros.
+  if (value === 0) {
+    if ((1 / value) > 0) {
+      // Positive zero.
+      jspb.utils.split64High = 0x00000000;
+      jspb.utils.split64Low = 0x00000000;
+    } else {
+      // Negative zero.
+      jspb.utils.split64High = 0x80000000;
+      jspb.utils.split64Low = 0x00000000;
+    }
+    return;
+  }
+
+  // Handle nans.
+  if (isNaN(value)) {
+    jspb.utils.split64High = 0x7FFFFFFF;
+    jspb.utils.split64Low = 0xFFFFFFFF;
+    return;
+  }
+
+  // Handle infinities.
+  if (value > jspb.BinaryConstants.FLOAT64_MAX) {
+    jspb.utils.split64High = ((sign << 31) | (0x7FF00000)) >>> 0;
+    jspb.utils.split64Low = 0;
+    return;
+  }
+
+  // Handle denormals.
+  if (value < jspb.BinaryConstants.FLOAT64_MIN) {
+    // Number is a denormal.
+    var mant = value / Math.pow(2, -1074);
+    var mantHigh = (mant / jspb.BinaryConstants.TWO_TO_32);
+    jspb.utils.split64High = ((sign << 31) | mantHigh) >>> 0;
+    jspb.utils.split64Low = (mant >>> 0);
+    return;
+  }
+
+  var exp = Math.floor(Math.log(value) / Math.LN2);
+  if (exp == 1024) exp = 1023;
+  var mant = value * Math.pow(2, -exp);
+
+  var mantHigh = (mant * jspb.BinaryConstants.TWO_TO_20) & 0xFFFFF;
+  var mantLow = (mant * jspb.BinaryConstants.TWO_TO_52) >>> 0;
+
+  jspb.utils.split64High =
+      ((sign << 31) | ((exp + 1023) << 20) | mantHigh) >>> 0;
+  jspb.utils.split64Low = mantLow;
+};
+
+
+/**
+ * Converts an 8-character hash string into two 32-bit numbers and stores them
+ * in the temp values above.
+ * @param {string} hash
+ */
+jspb.utils.splitHash64 = function(hash) {
+  var a = hash.charCodeAt(0);
+  var b = hash.charCodeAt(1);
+  var c = hash.charCodeAt(2);
+  var d = hash.charCodeAt(3);
+  var e = hash.charCodeAt(4);
+  var f = hash.charCodeAt(5);
+  var g = hash.charCodeAt(6);
+  var h = hash.charCodeAt(7);
+
+  jspb.utils.split64Low = (a + (b << 8) + (c << 16) + (d << 24)) >>> 0;
+  jspb.utils.split64High = (e + (f << 8) + (g << 16) + (h << 24)) >>> 0;
+};
+
+
+/**
+ * Joins two 32-bit values into a 64-bit unsigned integer. Precision will be
+ * lost if the result is greater than 2^52.
+ * @param {number} bitsLow
+ * @param {number} bitsHigh
+ * @return {number}
+ */
+jspb.utils.joinUint64 = function(bitsLow, bitsHigh) {
+  return bitsHigh * jspb.BinaryConstants.TWO_TO_32 + bitsLow;
+};
+
+
+/**
+ * Joins two 32-bit values into a 64-bit signed integer. Precision will be lost
+ * if the result is greater than 2^52.
+ * @param {number} bitsLow
+ * @param {number} bitsHigh
+ * @return {number}
+ */
+jspb.utils.joinInt64 = function(bitsLow, bitsHigh) {
+  // If the high bit is set, do a manual two's complement conversion.
+  var sign = (bitsHigh & 0x80000000);
+  if (sign) {
+    bitsLow = (~bitsLow + 1) >>> 0;
+    bitsHigh = ~bitsHigh >>> 0;
+    if (bitsLow == 0) {
+      bitsHigh = (bitsHigh + 1) >>> 0;
+    }
+  }
+
+  var result = jspb.utils.joinUint64(bitsLow, bitsHigh);
+  return sign ? -result : result;
+};
+
+
+/**
+ * Joins two 32-bit values into a 64-bit unsigned integer and applies zigzag
+ * decoding. Precision will be lost if the result is greater than 2^52.
+ * @param {number} bitsLow
+ * @param {number} bitsHigh
+ * @return {number}
+ */
+jspb.utils.joinZigzag64 = function(bitsLow, bitsHigh) {
+  // Extract the sign bit and shift right by one.
+  var sign = bitsLow & 1;
+  bitsLow = ((bitsLow >>> 1) | (bitsHigh << 31)) >>> 0;
+  bitsHigh = bitsHigh >>> 1;
+
+  // Increment the split value if the sign bit was set.
+  if (sign) {
+    bitsLow = (bitsLow + 1) >>> 0;
+    if (bitsLow == 0) {
+      bitsHigh = (bitsHigh + 1) >>> 0;
+    }
+  }
+
+  var result = jspb.utils.joinUint64(bitsLow, bitsHigh);
+  return sign ? -result : result;
+};
+
+
+/**
+ * Joins two 32-bit values into a 32-bit IEEE floating point number and
+ * converts it back into a Javascript number.
+ * @param {number} bitsLow The low 32 bits of the binary number;
+ * @param {number} bitsHigh The high 32 bits of the binary number.
+ * @return {number}
+ */
+jspb.utils.joinFloat32 = function(bitsLow, bitsHigh) {
+  var sign = ((bitsLow >> 31) * 2 + 1);
+  var exp = (bitsLow >>> 23) & 0xFF;
+  var mant = bitsLow & 0x7FFFFF;
+
+  if (exp == 0xFF) {
+    if (mant) {
+      return NaN;
+    } else {
+      return sign * Infinity;
+    }
+  }
+
+  if (exp == 0) {
+    // Denormal.
+    return sign * Math.pow(2, -149) * mant;
+  } else {
+    return sign * Math.pow(2, exp - 150) *
+           (mant + Math.pow(2, 23));
+  }
+};
+
+
+/**
+ * Joins two 32-bit values into a 64-bit IEEE floating point number and
+ * converts it back into a Javascript number.
+ * @param {number} bitsLow The low 32 bits of the binary number;
+ * @param {number} bitsHigh The high 32 bits of the binary number.
+ * @return {number}
+ */
+jspb.utils.joinFloat64 = function(bitsLow, bitsHigh) {
+  var sign = ((bitsHigh >> 31) * 2 + 1);
+  var exp = (bitsHigh >>> 20) & 0x7FF;
+  var mant = jspb.BinaryConstants.TWO_TO_32 * (bitsHigh & 0xFFFFF) + bitsLow;
+
+  if (exp == 0x7FF) {
+    if (mant) {
+      return NaN;
+    } else {
+      return sign * Infinity;
+    }
+  }
+
+  if (exp == 0) {
+    // Denormal.
+    return sign * Math.pow(2, -1074) * mant;
+  } else {
+    return sign * Math.pow(2, exp - 1075) *
+           (mant + jspb.BinaryConstants.TWO_TO_52);
+  }
+};
+
+
+/**
+ * Joins two 32-bit values into an 8-character hash string.
+ * @param {number} bitsLow
+ * @param {number} bitsHigh
+ * @return {string}
+ */
+jspb.utils.joinHash64 = function(bitsLow, bitsHigh) {
+  var a = (bitsLow >>> 0) & 0xFF;
+  var b = (bitsLow >>> 8) & 0xFF;
+  var c = (bitsLow >>> 16) & 0xFF;
+  var d = (bitsLow >>> 24) & 0xFF;
+  var e = (bitsHigh >>> 0) & 0xFF;
+  var f = (bitsHigh >>> 8) & 0xFF;
+  var g = (bitsHigh >>> 16) & 0xFF;
+  var h = (bitsHigh >>> 24) & 0xFF;
+
+  return String.fromCharCode(a, b, c, d, e, f, g, h);
+};
+
+
+/**
+ * Individual digits for number->string conversion.
+ * @const {!Array.<number>}
+ */
+jspb.utils.DIGITS = [
+  '0', '1', '2', '3', '4', '5', '6', '7',
+  '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+];
+
+
+/**
+ * Losslessly converts a 64-bit unsigned integer in 32:32 split representation
+ * into a decimal string.
+ * @param {number} bitsLow The low 32 bits of the binary number;
+ * @param {number} bitsHigh The high 32 bits of the binary number.
+ * @return {string} The binary number represented as a string.
+ */
+jspb.utils.joinUnsignedDecimalString = function(bitsLow, bitsHigh) {
+  // Skip the expensive conversion if the number is small enough to use the
+  // built-in conversions.
+  if (bitsHigh <= 0x1FFFFF) {
+    return '' + (jspb.BinaryConstants.TWO_TO_32 * bitsHigh + bitsLow);
+  }
+
+  // What this code is doing is essentially converting the input number from
+  // base-2 to base-1e7, which allows us to represent the 64-bit range with
+  // only 3 (very large) digits. Those digits are then trivial to convert to
+  // a base-10 string.
+
+  // The magic numbers used here are -
+  // 2^24 = 16777216 = (1,6777216) in base-1e7.
+  // 2^48 = 281474976710656 = (2,8147497,6710656) in base-1e7.
+
+  // Split 32:32 representation into 16:24:24 representation so our
+  // intermediate digits don't overflow.
+  var low = bitsLow & 0xFFFFFF;
+  var mid = (((bitsLow >>> 24) | (bitsHigh << 8)) >>> 0) & 0xFFFFFF;
+  var high = (bitsHigh >> 16) & 0xFFFF;
+
+  // Assemble our three base-1e7 digits, ignoring carries. The maximum
+  // value in a digit at this step is representable as a 48-bit integer, which
+  // can be stored in a 64-bit floating point number.
+  var digitA = low + (mid * 6777216) + (high * 6710656);
+  var digitB = mid + (high * 8147497);
+  var digitC = (high * 2);
+
+  // Apply carries from A to B and from B to C.
+  var base = 10000000;
+  if (digitA >= base) {
+    digitB += Math.floor(digitA / base);
+    digitA %= base;
+  }
+
+  if (digitB >= base) {
+    digitC += Math.floor(digitB / base);
+    digitB %= base;
+  }
+
+  // Convert base-1e7 digits to base-10, omitting leading zeroes.
+  var table = jspb.utils.DIGITS;
+  var start = false;
+  var result = '';
+
+  function emit(digit) {
+    var temp = base;
+    for (var i = 0; i < 7; i++) {
+      temp /= 10;
+      var decimalDigit = ((digit / temp) % 10) >>> 0;
+      if ((decimalDigit == 0) && !start) continue;
+      start = true;
+      result += table[decimalDigit];
+    }
+  }
+
+  if (digitC || start) emit(digitC);
+  if (digitB || start) emit(digitB);
+  if (digitA || start) emit(digitA);
+
+  return result;
+};
+
+
+/**
+ * Losslessly converts a 64-bit signed integer in 32:32 split representation
+ * into a decimal string.
+ * @param {number} bitsLow The low 32 bits of the binary number;
+ * @param {number} bitsHigh The high 32 bits of the binary number.
+ * @return {string} The binary number represented as a string.
+ */
+jspb.utils.joinSignedDecimalString = function(bitsLow, bitsHigh) {
+  // If we're treating the input as a signed value and the high bit is set, do
+  // a manual two's complement conversion before the decimal conversion.
+  var negative = (bitsHigh & 0x80000000);
+  if (negative) {
+    bitsLow = (~bitsLow + 1) >>> 0;
+    var carry = (bitsLow == 0) ? 1 : 0;
+    bitsHigh = (~bitsHigh + carry) >>> 0;
+  }
+
+  var result = jspb.utils.joinUnsignedDecimalString(bitsLow, bitsHigh);
+  return negative ? '-' + result : result;
+};
+
+
+/**
+ * Convert an 8-character hash string representing either a signed or unsigned
+ * 64-bit integer into its decimal representation without losing accuracy.
+ * @param {string} hash The hash string to convert.
+ * @param {boolean} signed True if we should treat the hash string as encoding
+ *     a signed integer.
+ * @return {string}
+ */
+jspb.utils.hash64ToDecimalString = function(hash, signed) {
+  jspb.utils.splitHash64(hash);
+  var bitsLow = jspb.utils.split64Low;
+  var bitsHigh = jspb.utils.split64High;
+  return signed ?
+      jspb.utils.joinSignedDecimalString(bitsLow, bitsHigh) :
+      jspb.utils.joinUnsignedDecimalString(bitsLow, bitsHigh);
+};
+
+
+/**
+ * Converts an array of 8-character hash strings into their decimal
+ * representations.
+ * @param {!Array.<string>} hashes The array of hash strings to convert.
+ * @param {boolean} signed True if we should treat the hash string as encoding
+ *     a signed integer.
+ * @return {!Array.<string>}
+ */
+jspb.utils.hash64ArrayToDecimalStrings = function(hashes, signed) {
+  var result = new Array(hashes.length);
+  for (var i = 0; i < hashes.length; i++) {
+    result[i] = jspb.utils.hash64ToDecimalString(hashes[i], signed);
+  }
+  return result;
+};
+
+
+/**
+ * Converts an 8-character hash string into its hexadecimal representation.
+ * @param {string} hash
+ * @return {string}
+ */
+jspb.utils.hash64ToHexString = function(hash) {
+  var temp = new Array(18);
+  temp[0] = '0';
+  temp[1] = 'x';
+
+  for (var i = 0; i < 8; i++) {
+    var c = hash.charCodeAt(7 - i);
+    temp[i * 2 + 2] = jspb.utils.DIGITS[c >> 4];
+    temp[i * 2 + 3] = jspb.utils.DIGITS[c & 0xF];
+  }
+
+  var result = temp.join('');
+  return result;
+};
+
+
+/**
+ * Converts a '0x<16 digits>' hex string into its hash string representation.
+ * @param {string} hex
+ * @return {string}
+ */
+jspb.utils.hexStringToHash64 = function(hex) {
+  hex = hex.toLowerCase();
+  goog.asserts.assert(hex.length == 18);
+  goog.asserts.assert(hex[0] == '0');
+  goog.asserts.assert(hex[1] == 'x');
+
+  var result = '';
+  for (var i = 0; i < 8; i++) {
+    var hi = jspb.utils.DIGITS.indexOf(hex[i * 2 + 2]);
+    var lo = jspb.utils.DIGITS.indexOf(hex[i * 2 + 3]);
+    result = String.fromCharCode(hi * 16 + lo) + result;
+  }
+
+  return result;
+};
+
+
+/**
+ * Convert an 8-character hash string representing either a signed or unsigned
+ * 64-bit integer into a Javascript number. Will lose accuracy if the result is
+ * larger than 2^52.
+ * @param {string} hash The hash string to convert.
+ * @param {boolean} signed True if the has should be interpreted as a signed
+ *     number.
+ * @return {number}
+ */
+jspb.utils.hash64ToNumber = function(hash, signed) {
+  jspb.utils.splitHash64(hash);
+  var bitsLow = jspb.utils.split64Low;
+  var bitsHigh = jspb.utils.split64High;
+  return signed ? jspb.utils.joinInt64(bitsLow, bitsHigh) :
+                  jspb.utils.joinUint64(bitsLow, bitsHigh);
+};
+
+
+/**
+ * Convert a Javascript number into an 8-character hash string. Will lose
+ * precision if the value is non-integral or greater than 2^64.
+ * @param {number} value The integer to convert.
+ * @return {string}
+ */
+jspb.utils.numberToHash64 = function(value) {
+  jspb.utils.splitInt64(value);
+  return jspb.utils.joinHash64(jspb.utils.split64Low,
+                                  jspb.utils.split64High);
+};
+
+
+/**
+ * Counts the number of contiguous varints in a buffer.
+ * @param {!Uint8Array} buffer The buffer to scan.
+ * @param {number} start The starting point in the buffer to scan.
+ * @param {number} end The end point in the buffer to scan.
+ * @return {number} The number of varints in the buffer.
+ */
+jspb.utils.countVarints = function(buffer, start, end) {
+  // Count how many high bits of each byte were set in the buffer.
+  var count = 0;
+  for (var i = start; i < end; i++) {
+    count += buffer[i] >> 7;
+  }
+
+  // The number of varints in the buffer equals the size of the buffer minus
+  // the number of non-terminal bytes in the buffer (those with the high bit
+  // set).
+  return (end - start) - count;
+};
+
+
+/**
+ * Counts the number of contiguous varint fields with the given field number in
+ * the buffer.
+ * @param {!Uint8Array} buffer The buffer to scan.
+ * @param {number} start The starting point in the buffer to scan.
+ * @param {number} end The end point in the buffer to scan.
+ * @param {number} field The field number to count.
+ * @return {number} The number of matching fields in the buffer.
+ */
+jspb.utils.countVarintFields = function(buffer, start, end, field) {
+  var count = 0;
+  var cursor = start;
+  var tag = field * 8 + jspb.BinaryConstants.WireType.VARINT;
+
+  if (tag < 128) {
+    // Single-byte field tag, we can use a slightly quicker count.
+    while (cursor < end) {
+      // Skip the field tag, or exit if we find a non-matching tag.
+      if (buffer[cursor++] != tag) return count;
+
+      // Field tag matches, we've found a valid field.
+      count++;
+
+      // Skip the varint.
+      while (1) {
+        var x = buffer[cursor++];
+        if ((x & 0x80) == 0) break;
+      }
+    }
+  } else {
+    while (cursor < end) {
+      // Skip the field tag, or exit if we find a non-matching tag.
+      var temp = tag;
+      while (temp > 128) {
+        if (buffer[cursor] != ((temp & 0x7F) | 0x80)) return count;
+        cursor++;
+        temp >>= 7;
+      }
+      if (buffer[cursor++] != temp) return count;
+
+      // Field tag matches, we've found a valid field.
+      count++;
+
+      // Skip the varint.
+      while (1) {
+        var x = buffer[cursor++];
+        if ((x & 0x80) == 0) break;
+      }
+    }
+  }
+  return count;
+};
+
+
+/**
+ * Counts the number of contiguous fixed32 fields with the given tag in the
+ * buffer.
+ * @param {!Uint8Array} buffer The buffer to scan.
+ * @param {number} start The starting point in the buffer to scan.
+ * @param {number} end The end point in the buffer to scan.
+ * @param {number} tag The tag value to count.
+ * @param {number} stride The number of bytes to skip per field.
+ * @return {number} The number of fields with a matching tag in the buffer.
+ * @private
+ */
+jspb.utils.countFixedFields_ =
+    function(buffer, start, end, tag, stride) {
+  var count = 0;
+  var cursor = start;
+
+  if (tag < 128) {
+    // Single-byte field tag, we can use a slightly quicker count.
+    while (cursor < end) {
+      // Skip the field tag, or exit if we find a non-matching tag.
+      if (buffer[cursor++] != tag) return count;
+
+      // Field tag matches, we've found a valid field.
+      count++;
+
+      // Skip the value.
+      cursor += stride;
+    }
+  } else {
+    while (cursor < end) {
+      // Skip the field tag, or exit if we find a non-matching tag.
+      var temp = tag;
+      while (temp > 128) {
+        if (buffer[cursor++] != ((temp & 0x7F) | 0x80)) return count;
+        temp >>= 7;
+      }
+      if (buffer[cursor++] != temp) return count;
+
+      // Field tag matches, we've found a valid field.
+      count++;
+
+      // Skip the value.
+      cursor += stride;
+    }
+  }
+  return count;
+};
+
+
+/**
+ * Counts the number of contiguous fixed32 fields with the given field number
+ * in the buffer.
+ * @param {!Uint8Array} buffer The buffer to scan.
+ * @param {number} start The starting point in the buffer to scan.
+ * @param {number} end The end point in the buffer to scan.
+ * @param {number} field The field number to count.
+ * @return {number} The number of matching fields in the buffer.
+ */
+jspb.utils.countFixed32Fields = function(buffer, start, end, field) {
+  var tag = field * 8 + jspb.BinaryConstants.WireType.FIXED32;
+  return jspb.utils.countFixedFields_(buffer, start, end, tag, 4);
+};
+
+
+/**
+ * Counts the number of contiguous fixed64 fields with the given field number
+ * in the buffer.
+ * @param {!Uint8Array} buffer The buffer to scan.
+ * @param {number} start The starting point in the buffer to scan.
+ * @param {number} end The end point in the buffer to scan.
+ * @param {number} field The field number to count
+ * @return {number} The number of matching fields in the buffer.
+ */
+jspb.utils.countFixed64Fields = function(buffer, start, end, field) {
+  var tag = field * 8 + jspb.BinaryConstants.WireType.FIXED64;
+  return jspb.utils.countFixedFields_(buffer, start, end, tag, 8);
+};
+
+
+/**
+ * Counts the number of contiguous delimited fields with the given field number
+ * in the buffer.
+ * @param {!Uint8Array} buffer The buffer to scan.
+ * @param {number} start The starting point in the buffer to scan.
+ * @param {number} end The end point in the buffer to scan.
+ * @param {number} field The field number to count.
+ * @return {number} The number of matching fields in the buffer.
+ */
+jspb.utils.countDelimitedFields = function(buffer, start, end, field) {
+  var count = 0;
+  var cursor = start;
+  var tag = field * 8 + jspb.BinaryConstants.WireType.DELIMITED;
+
+  while (cursor < end) {
+    // Skip the field tag, or exit if we find a non-matching tag.
+    var temp = tag;
+    while (temp > 128) {
+      if (buffer[cursor++] != ((temp & 0x7F) | 0x80)) return count;
+      temp >>= 7;
+    }
+    if (buffer[cursor++] != temp) return count;
+
+    // Field tag matches, we've found a valid field.
+    count++;
+
+    // Decode the length prefix.
+    var length = 0;
+    var shift = 1;
+    while (1) {
+      temp = buffer[cursor++];
+      length += (temp & 0x7f) * shift;
+      shift *= 128;
+      if ((temp & 0x80) == 0) break;
+    }
+
+    // Advance the cursor past the blob.
+    cursor += length;
+  }
+  return count;
+};
+
+
+/**
+ * Clones a scalar field. Pulling this out to a helper method saves us a few
+ * bytes of generated code.
+ * @param {Array} array
+ * @return {Array}
+ */
+jspb.utils.cloneRepeatedScalarField = function(array) {
+  return array ? array.slice() : null;
+};
+
+
+/**
+ * Clones an array of messages using the provided cloner function.
+ * @param {Array.<jspb.BinaryMessage>} messages
+ * @param {jspb.ClonerFunction} cloner
+ * @return {Array.<jspb.BinaryMessage>}
+ */
+jspb.utils.cloneRepeatedMessageField = function(messages, cloner) {
+  if (messages === null) return null;
+  var result = [];
+  for (var i = 0; i < messages.length; i++) {
+    result.push(cloner(messages[i]));
+  }
+  return result;
+};
+
+
+/**
+ * Clones an array of byte blobs.
+ * @param {Array.<Uint8Array>} blobs
+ * @return {Array.<Uint8Array>}
+ */
+jspb.utils.cloneRepeatedBlobField = function(blobs) {
+  if (blobs === null) return null;
+  var result = [];
+  for (var i = 0; i < blobs.length; i++) {
+    result.push(new Uint8Array(blobs[i]));
+  }
+  return result;
+};
+
+
+/**
+ * String-ify bytes for text format. Should be optimized away in non-debug.
+ * The returned string uses \xXX escapes for all values and is itself quoted.
+ * [1, 31] serializes to '"\x01\x1f"'.
+ * @param {jspb.ByteSource} byteSource The bytes to serialize.
+ * @param {boolean=} opt_stringIsRawBytes The string is interpreted as a series
+ * of raw bytes rather than base64 data.
+ * @return {string} Stringified bytes for text format.
+ */
+jspb.utils.debugBytesToTextFormat = function(byteSource,
+                                                opt_stringIsRawBytes) {
+  var s = '"';
+  if (byteSource) {
+    var bytes =
+        jspb.utils.byteSourceToUint8Array(byteSource, opt_stringIsRawBytes);
+    for (var i = 0; i < bytes.length; i++) {
+      s += '\\x';
+      if (bytes[i] < 16) s += '0';
+      s += bytes[i].toString(16);
+    }
+  }
+  return s + '"';
+};
+
+
+/**
+ * String-ify a scalar for text format. Should be optimized away in non-debug.
+ * @param {string|number|boolean} scalar The scalar to stringify.
+ * @return {string} Stringified scalar for text format.
+ */
+jspb.utils.debugScalarToTextFormat = function(scalar) {
+  if (goog.isString(scalar)) {
+    return goog.string.quote(scalar);
+  } else {
+    return scalar.toString();
+  }
+};
+
+
+/**
+ * Utility function: convert a string with codepoints 0--255 inclusive to a
+ * Uint8Array. If any codepoints greater than 255 exist in the string, throws an
+ * exception.
+ * @param {string} str
+ * @return {!Uint8Array}
+ * @private
+ */
+jspb.utils.stringToByteArray_ = function(str) {
+  var arr = new Uint8Array(str.length);
+  for (var i = 0; i < str.length; i++) {
+    var codepoint = str.charCodeAt(i);
+    if (codepoint > 255) {
+      throw new Error('Conversion error: string contains codepoint ' +
+                      'outside of byte range');
+    }
+    arr[i] = codepoint;
+  }
+  return arr;
+};
+
+
+/**
+ * Converts any type defined in jspb.ByteSource into a Uint8Array.
+ * @param {!jspb.ByteSource} data
+ * @param {boolean=} opt_stringIsRawBytes Interpret a string as a series of raw
+ * bytes (encoded as codepoints 0--255 inclusive) rather than base64 data
+ * (default behavior).
+ * @return {!Uint8Array}
+ * @suppress {invalidCasts}
+ */
+jspb.utils.byteSourceToUint8Array = function(data, opt_stringIsRawBytes) {
+  if (data.constructor === Uint8Array) {
+    return /** @type {!Uint8Array} */(data);
+  }
+
+  if (data.constructor === ArrayBuffer) {
+    data = /** @type {!ArrayBuffer} */(data);
+    return /** @type {!Uint8Array} */(new Uint8Array(data));
+  }
+
+  if (data.constructor === Array) {
+    data = /** @type {!Array.<number>} */(data);
+    return /** @type {!Uint8Array} */(new Uint8Array(data));
+  }
+
+  if (data.constructor === String) {
+    data = /** @type {string} */(data);
+    if (opt_stringIsRawBytes) {
+      return jspb.utils.stringToByteArray_(data);
+    } else {
+      return goog.crypt.base64.decodeStringToUint8Array(data);
+    }
+  }
+
+  goog.asserts.fail('Type not convertible to Uint8Array.');
+  return /** @type {!Uint8Array} */(new Uint8Array(0));
+};
diff --git a/js/binary/utils_test.js b/js/binary/utils_test.js
new file mode 100644
index 0000000..5c33079
--- /dev/null
+++ b/js/binary/utils_test.js
@@ -0,0 +1,632 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/**
+ * @fileoverview Test cases for jspb's helper functions.
+ *
+ * Test suite is written using Jasmine -- see http://jasmine.github.io/
+ *
+ * @author aappleby@google.com (Austin Appleby)
+ */
+
+goog.require('goog.crypt.base64');
+goog.require('goog.testing.asserts');
+goog.require('jspb.BinaryConstants');
+goog.require('jspb.BinaryWriter');
+goog.require('jspb.utils');
+
+
+/**
+ * @param {number} x
+ * @return {number}
+ */
+function truncate(x) {
+  var temp = new Float32Array(1);
+  temp[0] = x;
+  return temp[0];
+}
+
+
+/**
+ * Converts an 64-bit integer in split representation to a 64-bit hash string
+ * (8 bits encoded per character).
+ * @param {number} bitsLow The low 32 bits of the split 64-bit integer.
+ * @param {number} bitsHigh The high 32 bits of the split 64-bit integer.
+ * @return {string} The encoded hash string, 8 bits per character.
+ */
+function toHashString(bitsLow, bitsHigh) {
+  return String.fromCharCode((bitsLow >>> 0) & 0xFF,
+                             (bitsLow >>> 8) & 0xFF,
+                             (bitsLow >>> 16) & 0xFF,
+                             (bitsLow >>> 24) & 0xFF,
+                             (bitsHigh >>> 0) & 0xFF,
+                             (bitsHigh >>> 8) & 0xFF,
+                             (bitsHigh >>> 16) & 0xFF,
+                             (bitsHigh >>> 24) & 0xFF);
+}
+
+
+describe('binaryUtilsTest', function() {
+  /**
+   * Tests lossless binary-to-decimal conversion.
+   */
+  it('testDecimalConversion', function() {
+    // Check some magic numbers.
+    var result =
+        jspb.utils.joinUnsignedDecimalString(0x89e80001, 0x8ac72304);
+    assertEquals('10000000000000000001', result);
+
+    result = jspb.utils.joinUnsignedDecimalString(0xacd05f15, 0x1b69b4b);
+    assertEquals('123456789123456789', result);
+
+    result = jspb.utils.joinUnsignedDecimalString(0xeb1f0ad2, 0xab54a98c);
+    assertEquals('12345678901234567890', result);
+
+    result = jspb.utils.joinUnsignedDecimalString(0xe3b70cb1, 0x891087b8);
+    assertEquals('9876543210987654321', result);
+
+    // Check limits.
+    result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00000000);
+    assertEquals('0', result);
+
+    result = jspb.utils.joinUnsignedDecimalString(0xFFFFFFFF, 0xFFFFFFFF);
+    assertEquals('18446744073709551615', result);
+
+    // Check each bit of the low dword.
+    for (var i = 0; i < 32; i++) {
+      var low = (1 << i) >>> 0;
+      result = jspb.utils.joinUnsignedDecimalString(low, 0);
+      assertEquals('' + Math.pow(2, i), result);
+    }
+
+    // Check the first 20 bits of the high dword.
+    for (var i = 0; i < 20; i++) {
+      var high = (1 << i) >>> 0;
+      result = jspb.utils.joinUnsignedDecimalString(0, high);
+      assertEquals('' + Math.pow(2, 32 + i), result);
+    }
+
+    // V8's internal double-to-string conversion is inaccurate for values above
+    // 2^52, even if they're representable integers - check the rest of the bits
+    // manually against the correct string representations of 2^N.
+
+    result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00100000);
+    assertEquals('4503599627370496', result);
+
+    result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00200000);
+    assertEquals('9007199254740992', result);
+
+    result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00400000);
+    assertEquals('18014398509481984', result);
+
+    result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00800000);
+    assertEquals('36028797018963968', result);
+
+    result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x01000000);
+    assertEquals('72057594037927936', result);
+
+    result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x02000000);
+    assertEquals('144115188075855872', result);
+
+    result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x04000000);
+    assertEquals('288230376151711744', result);
+
+    result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x08000000);
+    assertEquals('576460752303423488', result);
+
+    result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x10000000);
+    assertEquals('1152921504606846976', result);
+
+    result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x20000000);
+    assertEquals('2305843009213693952', result);
+
+    result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x40000000);
+    assertEquals('4611686018427387904', result);
+
+    result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x80000000);
+    assertEquals('9223372036854775808', result);
+  });
+
+
+  /**
+   * Going from hash strings to decimal strings should also be lossless.
+   */
+  it('testHashToDecimalConversion', function() {
+    var result;
+    var convert = jspb.utils.hash64ToDecimalString;
+
+    result = convert(toHashString(0x00000000, 0x00000000), false);
+    assertEquals('0', result);
+
+    result = convert(toHashString(0x00000000, 0x00000000), true);
+    assertEquals('0', result);
+
+    result = convert(toHashString(0xFFFFFFFF, 0xFFFFFFFF), false);
+    assertEquals('18446744073709551615', result);
+
+    result = convert(toHashString(0xFFFFFFFF, 0xFFFFFFFF), true);
+    assertEquals('-1', result);
+
+    result = convert(toHashString(0x00000000, 0x80000000), false);
+    assertEquals('9223372036854775808', result);
+
+    result = convert(toHashString(0x00000000, 0x80000000), true);
+    assertEquals('-9223372036854775808', result);
+
+    result = convert(toHashString(0xacd05f15, 0x01b69b4b), false);
+    assertEquals('123456789123456789', result);
+
+    result = convert(toHashString(~0xacd05f15 + 1, ~0x01b69b4b), true);
+    assertEquals('-123456789123456789', result);
+
+    // And converting arrays of hashes should work the same way.
+    result = jspb.utils.hash64ArrayToDecimalStrings([
+      toHashString(0xFFFFFFFF, 0xFFFFFFFF),
+      toHashString(0x00000000, 0x80000000),
+      toHashString(0xacd05f15, 0x01b69b4b)], false);
+    assertEquals(3, result.length);
+    assertEquals('18446744073709551615', result[0]);
+    assertEquals('9223372036854775808', result[1]);
+    assertEquals('123456789123456789', result[2]);
+  });
+
+
+  /**
+   * Going from hash strings to hex strings should be lossless.
+   */
+  it('testHashToHexConversion', function() {
+    var result;
+    var convert = jspb.utils.hash64ToHexString;
+
+    result = convert(toHashString(0x00000000, 0x00000000));
+    assertEquals('0x0000000000000000', result);
+
+    result = convert(toHashString(0xFFFFFFFF, 0xFFFFFFFF));
+    assertEquals('0xffffffffffffffff', result);
+
+    result = convert(toHashString(0x12345678, 0x9ABCDEF0));
+    assertEquals('0x9abcdef012345678', result);
+  });
+
+
+  /**
+   * Going from hex strings to hash strings should be lossless.
+   */
+  it('testHexToHashConversion', function() {
+    var result;
+    var convert = jspb.utils.hexStringToHash64;
+
+    result = convert('0x0000000000000000');
+    assertEquals(String.fromCharCode.apply(null,
+        [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), result);
+
+    result = convert('0xffffffffffffffff');
+    assertEquals(String.fromCharCode.apply(null,
+        [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]), result);
+
+    // Hex string is big-endian, hash string is little-endian.
+    result = convert('0x123456789ABCDEF0');
+    assertEquals(String.fromCharCode.apply(null,
+        [0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]), result);
+
+    // Capitalization should not matter.
+    result = convert('0x0000abcdefABCDEF');
+    assertEquals(String.fromCharCode.apply(null,
+        [0xEF, 0xCD, 0xAB, 0xEF, 0xCD, 0xAB, 0x00, 0x00]), result);
+  });
+
+
+  /**
+   * Going from numbers to hash strings should be lossless for up to 53 bits of
+   * precision.
+   */
+  it('testNumberToHashConversion', function() {
+    var result;
+    var convert = jspb.utils.numberToHash64;
+
+    result = convert(0x0000000000000);
+    assertEquals('0x0000000000000000', jspb.utils.hash64ToHexString(result));
+
+    result = convert(0xFFFFFFFFFFFFF);
+    assertEquals('0x000fffffffffffff', jspb.utils.hash64ToHexString(result));
+
+    result = convert(0x123456789ABCD);
+    assertEquals('0x000123456789abcd', jspb.utils.hash64ToHexString(result));
+
+    result = convert(0xDCBA987654321);
+    assertEquals('0x000dcba987654321', jspb.utils.hash64ToHexString(result));
+
+    // 53 bits of precision should not be truncated.
+    result = convert(0x10000000000001);
+    assertEquals('0x0010000000000001', jspb.utils.hash64ToHexString(result));
+
+    // 54 bits of precision should be truncated.
+    result = convert(0x20000000000001);
+    assertNotEquals(
+        '0x0020000000000001', jspb.utils.hash64ToHexString(result));
+  });
+
+
+  /**
+   * Sanity check the behavior of Javascript's strings when doing funny things
+   * with unicode characters.
+   */
+  it('sanityCheckUnicodeStrings', function() {
+    var strings = new Array(65536);
+
+    // All possible unsigned 16-bit values should be storable in a string, they
+    // shouldn't do weird things with the length of the string, and they should
+    // come back out of the string unchanged.
+    for (var i = 0; i < 65536; i++) {
+      strings[i] = 'a' + String.fromCharCode(i) + 'a';
+      if (3 != strings[i].length) throw 'fail!';
+      if (i != strings[i].charCodeAt(1)) throw 'fail!';
+    }
+
+    // Each unicode character should compare equal to itself and not equal to a
+    // different unicode character.
+    for (var i = 0; i < 65536; i++) {
+      if (strings[i] != strings[i]) throw 'fail!';
+      if (strings[i] == strings[(i + 1) % 65536]) throw 'fail!';
+    }
+  });
+
+
+  /**
+   * Tests conversion from 32-bit floating point numbers to split64 numbers.
+   */
+  it('testFloat32ToSplit64', function() {
+    var f32_eps = jspb.BinaryConstants.FLOAT32_EPS;
+    var f32_min = jspb.BinaryConstants.FLOAT32_MIN;
+    var f32_max = jspb.BinaryConstants.FLOAT32_MAX;
+
+    // NaN.
+    jspb.utils.splitFloat32(NaN);
+    if (!isNaN(jspb.utils.joinFloat32(jspb.utils.split64Low,
+                                         jspb.utils.split64High))) {
+      throw 'fail!';
+    }
+
+    /**
+     * @param {number} x
+     * @param {number=} opt_bits
+     */
+    function test(x, opt_bits) {
+      jspb.utils.splitFloat32(x);
+      if (goog.isDef(opt_bits)) {
+        if (opt_bits != jspb.utils.split64Low) throw 'fail!';
+      }
+      if (truncate(x) != jspb.utils.joinFloat32(jspb.utils.split64Low,
+                                                   jspb.utils.split64High)) {
+        throw 'fail!';
+      }
+    }
+
+    // Positive and negative infinity.
+    test(Infinity, 0x7f800000);
+    test(-Infinity, 0xff800000);
+
+    // Positive and negative zero.
+    test(0, 0x00000000);
+    test(-0, 0x80000000);
+
+    // Positive and negative epsilon.
+    test(f32_eps, 0x00000001);
+    test(-f32_eps, 0x80000001);
+
+    // Positive and negative min.
+    test(f32_min, 0x00800000);
+    test(-f32_min, 0x80800000);
+
+    // Positive and negative max.
+    test(f32_max, 0x7F7FFFFF);
+    test(-f32_max, 0xFF7FFFFF);
+
+    // Various positive values.
+    var cursor = f32_eps * 10;
+    while (cursor != Infinity) {
+      test(cursor);
+      cursor *= 1.1;
+    }
+
+    // Various negative values.
+    cursor = -f32_eps * 10;
+    while (cursor != -Infinity) {
+      test(cursor);
+      cursor *= 1.1;
+    }
+  });
+
+
+  /**
+   * Tests conversion from 64-bit floating point numbers to split64 numbers.
+   */
+  it('testFloat64ToSplit64', function() {
+    var f64_eps = jspb.BinaryConstants.FLOAT64_EPS;
+    var f64_min = jspb.BinaryConstants.FLOAT64_MIN;
+    var f64_max = jspb.BinaryConstants.FLOAT64_MAX;
+
+    // NaN.
+    jspb.utils.splitFloat64(NaN);
+    if (!isNaN(jspb.utils.joinFloat64(jspb.utils.split64Low,
+                                         jspb.utils.split64High))) {
+      throw 'fail!';
+    }
+
+    /**
+     * @param {number} x
+     * @param {number=} opt_highBits
+     * @param {number=} opt_lowBits
+     */
+    function test(x, opt_highBits, opt_lowBits) {
+      jspb.utils.splitFloat64(x);
+      if (goog.isDef(opt_highBits)) {
+        if (opt_highBits != jspb.utils.split64High) throw 'fail!';
+      }
+      if (goog.isDef(opt_lowBits)) {
+        if (opt_lowBits != jspb.utils.split64Low) throw 'fail!';
+      }
+      if (x != jspb.utils.joinFloat64(jspb.utils.split64Low,
+                                         jspb.utils.split64High)) {
+        throw 'fail!';
+      }
+    }
+
+    // Positive and negative infinity.
+    test(Infinity, 0x7ff00000, 0x00000000);
+    test(-Infinity, 0xfff00000, 0x00000000);
+
+    // Positive and negative zero.
+    test(0, 0x00000000, 0x00000000);
+    test(-0, 0x80000000, 0x00000000);
+
+    // Positive and negative epsilon.
+    test(f64_eps, 0x00000000, 0x00000001);
+    test(-f64_eps, 0x80000000, 0x00000001);
+
+    // Positive and negative min.
+    test(f64_min, 0x00100000, 0x00000000);
+    test(-f64_min, 0x80100000, 0x00000000);
+
+    // Positive and negative max.
+    test(f64_max, 0x7FEFFFFF, 0xFFFFFFFF);
+    test(-f64_max, 0xFFEFFFFF, 0xFFFFFFFF);
+
+    // Various positive values.
+    var cursor = f64_eps * 10;
+    while (cursor != Infinity) {
+      test(cursor);
+      cursor *= 1.1;
+    }
+
+    // Various negative values.
+    cursor = -f64_eps * 10;
+    while (cursor != -Infinity) {
+      test(cursor);
+      cursor *= 1.1;
+    }
+  });
+
+
+  /**
+   * Tests counting packed varints.
+   */
+  it('testCountVarints', function() {
+    var writer = new jspb.BinaryWriter();
+
+    var count = 0;
+    for (var i = 1; i < 1000000000; i *= 1.1) {
+      writer.rawWriteVarint(Math.floor(i));
+      count++;
+    }
+
+    var buffer = new Uint8Array(writer.getResultBuffer());
+    assertEquals(count, jspb.utils.countVarints(buffer, 0, buffer.length));
+  });
+
+
+  /**
+   * Tests counting matching varint fields.
+   */
+  it('testCountVarintFields', function() {
+    var writer = new jspb.BinaryWriter();
+
+    var count = 0;
+    for (var i = 1; i < 1000000000; i *= 1.1) {
+      writer.writeUint64(1, Math.floor(i));
+      count++;
+    }
+    writer.writeString(2, 'terminator');
+
+    var buffer = new Uint8Array(writer.getResultBuffer());
+    assertEquals(count,
+        jspb.utils.countVarintFields(buffer, 0, buffer.length, 1));
+
+    writer = new jspb.BinaryWriter();
+
+    count = 0;
+    for (var i = 1; i < 1000000000; i *= 1.1) {
+      writer.writeUint64(123456789, Math.floor(i));
+      count++;
+    }
+    writer.writeString(2, 'terminator');
+
+    buffer = new Uint8Array(writer.getResultBuffer());
+    assertEquals(count,
+        jspb.utils.countVarintFields(buffer, 0, buffer.length, 123456789));
+  });
+
+
+  /**
+   * Tests counting matching fixed32 fields.
+   */
+  it('testCountFixed32Fields', function() {
+    var writer = new jspb.BinaryWriter();
+
+    var count = 0;
+    for (var i = 1; i < 1000000000; i *= 1.1) {
+      writer.writeFixed32(1, Math.floor(i));
+      count++;
+    }
+    writer.writeString(2, 'terminator');
+
+    var buffer = new Uint8Array(writer.getResultBuffer());
+    assertEquals(count,
+        jspb.utils.countFixed32Fields(buffer, 0, buffer.length, 1));
+
+    writer = new jspb.BinaryWriter();
+
+    count = 0;
+    for (var i = 1; i < 1000000000; i *= 1.1) {
+      writer.writeFixed32(123456789, Math.floor(i));
+      count++;
+    }
+    writer.writeString(2, 'terminator');
+
+    buffer = new Uint8Array(writer.getResultBuffer());
+    assertEquals(count,
+        jspb.utils.countFixed32Fields(buffer, 0, buffer.length, 123456789));
+  });
+
+
+  /**
+   * Tests counting matching fixed64 fields.
+   */
+  it('testCountFixed64Fields', function() {
+    var writer = new jspb.BinaryWriter();
+
+    var count = 0;
+    for (var i = 1; i < 1000000000; i *= 1.1) {
+      writer.writeDouble(1, i);
+      count++;
+    }
+    writer.writeString(2, 'terminator');
+
+    var buffer = new Uint8Array(writer.getResultBuffer());
+    assertEquals(count,
+        jspb.utils.countFixed64Fields(buffer, 0, buffer.length, 1));
+
+    writer = new jspb.BinaryWriter();
+
+    count = 0;
+    for (var i = 1; i < 1000000000; i *= 1.1) {
+      writer.writeDouble(123456789, i);
+      count++;
+    }
+    writer.writeString(2, 'terminator');
+
+    buffer = new Uint8Array(writer.getResultBuffer());
+    assertEquals(count,
+        jspb.utils.countFixed64Fields(buffer, 0, buffer.length, 123456789));
+  });
+
+
+  /**
+   * Tests counting matching delimited fields.
+   */
+  it('testCountDelimitedFields', function() {
+    var writer = new jspb.BinaryWriter();
+
+    var count = 0;
+    for (var i = 1; i < 1000; i *= 1.1) {
+      writer.writeBytes(1, [Math.floor(i)]);
+      count++;
+    }
+    writer.writeString(2, 'terminator');
+
+    var buffer = new Uint8Array(writer.getResultBuffer());
+    assertEquals(count,
+        jspb.utils.countDelimitedFields(buffer, 0, buffer.length, 1));
+
+    writer = new jspb.BinaryWriter();
+
+    count = 0;
+    for (var i = 1; i < 1000; i *= 1.1) {
+      writer.writeBytes(123456789, [Math.floor(i)]);
+      count++;
+    }
+    writer.writeString(2, 'terminator');
+
+    buffer = new Uint8Array(writer.getResultBuffer());
+    assertEquals(count,
+        jspb.utils.countDelimitedFields(buffer, 0, buffer.length, 123456789));
+  });
+
+
+  /**
+   * Tests byte format for debug strings.
+   */
+  it('testDebugBytesToTextFormat', function() {
+    assertEquals('""', jspb.utils.debugBytesToTextFormat(null));
+    assertEquals('"\\x00\\x10\\xff"',
+        jspb.utils.debugBytesToTextFormat([0, 16, 255]));
+  });
+
+
+  /**
+   * Tests converting byte blob sources into byte blobs.
+   */
+  it('testByteSourceToUint8Array', function() {
+    var convert = jspb.utils.byteSourceToUint8Array;
+
+    var sourceData = [];
+    for (var i = 0; i < 256; i++) {
+      sourceData.push(i);
+    }
+
+    var sourceBytes = new Uint8Array(sourceData);
+    var sourceBuffer = sourceBytes.buffer;
+    var sourceBase64 = goog.crypt.base64.encodeByteArray(sourceData);
+    var sourceString = String.fromCharCode.apply(null, sourceData);
+
+    function check(result) {
+      assertEquals(Uint8Array, result.constructor);
+      assertEquals(sourceData.length, result.length);
+      for (var i = 0; i < result.length; i++) {
+        assertEquals(sourceData[i], result[i]);
+      }
+    }
+
+    // Converting Uint8Arrays into Uint8Arrays should be a no-op.
+    assertEquals(sourceBytes, convert(sourceBytes));
+
+    // Converting Array.<numbers> into Uint8Arrays should work.
+    check(convert(sourceData));
+
+    // Converting ArrayBuffers into Uint8Arrays should work.
+    check(convert(sourceBuffer));
+
+    // Converting base64-encoded strings into Uint8Arrays should work.
+    check(convert(sourceBase64));
+
+    // Converting binary-data strings into Uint8Arrays should work.
+    check(convert(sourceString, /* opt_stringIsRawBytes = */ true));
+  });
+});
diff --git a/js/binary/writer.js b/js/binary/writer.js
new file mode 100644
index 0000000..a184945
--- /dev/null
+++ b/js/binary/writer.js
@@ -0,0 +1,2124 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/**
+ * @fileoverview This file contains utilities for encoding Javascript objects
+ * into binary, wire-format protocol buffers (in the form of Uint8Arrays) that
+ * a server can consume directly.
+ *
+ * jspb's BinaryWriter class defines methods for efficiently encoding
+ * Javascript objects into binary, wire-format protocol buffers and supports
+ * all the fundamental field types used in protocol buffers.
+ *
+ * Major caveat 1 - Users of this library _must_ keep their Javascript proto
+ * parsing code in sync with the original .proto file - presumably you'll be
+ * using the typed jspb code generator, but if you bypass that you'll need
+ * to keep things in sync by hand.
+ *
+ * Major caveat 2 - Javascript is unable to accurately represent integers
+ * larger than 2^53 due to its use of a double-precision floating point format
+ * for all numbers. BinaryWriter does not make any special effort to preserve
+ * precision for values above this limit - if you need to pass 64-bit integers
+ * (hash codes, for example) between the client and server without precision
+ * loss, do _not_ use this library.
+ *
+ * Major caveat 3 - This class uses typed arrays and must not be used on older
+ * browsers that do not support them.
+ *
+ * @author aappleby@google.com (Austin Appleby)
+ */
+
+goog.provide('jspb.BinaryWriter');
+
+goog.require('goog.asserts');
+goog.require('goog.crypt.base64');
+goog.require('jspb.BinaryConstants');
+goog.require('jspb.arith.Int64');
+goog.require('jspb.arith.UInt64');
+goog.require('jspb.utils');
+
+goog.forwardDeclare('jspb.Message');
+
+
+
+/**
+ * BinaryWriter implements encoders for all the wire types specified in
+ * https://developers.google.com/protocol-buffers/docs/encoding.
+ *
+ * @constructor
+ * @struct
+ */
+jspb.BinaryWriter = function() {
+  /**
+   * Blocks of serialized data that will be concatenated once all messages have
+   * been written.
+   * @private {!Array<!Uint8Array|!Array<number>>}
+   */
+  this.blocks_ = [];
+
+  /**
+   * Total number of bytes in the blocks_ array. Does _not_ include the temp
+   * buffer.
+   * @private {number}
+   */
+  this.totalLength_ = 0;
+
+  /**
+   * Temporary buffer holding a message that we're still serializing. When we
+   * get to a stopping point (either the start of a new submessage, or when we
+   * need to append a raw Uint8Array), the temp buffer will be added to the
+   * block array above and a new temp buffer will be created.
+   * @private {!Array.<number>}
+   */
+  this.temp_ = [];
+
+  /**
+   * A stack of bookmarks containing the parent blocks for each message started
+   * via beginSubMessage(), needed as bookkeeping for endSubMessage().
+   * TODO(aappleby): Deprecated, users should be calling writeMessage().
+   * @private {!Array.<!jspb.BinaryWriter.Bookmark_>}
+   */
+  this.bookmarks_ = [];
+};
+
+
+/**
+ * @typedef {{block: !Array.<number>, length: number}}
+ * @private
+ */
+jspb.BinaryWriter.Bookmark_;
+
+
+/**
+ * Saves the current temp buffer in the blocks_ array and starts a new one.
+ * @return {!Array.<number>} Returns a reference to the old temp buffer.
+ * @private
+ */
+jspb.BinaryWriter.prototype.saveTempBuffer_ = function() {
+  var oldTemp = this.temp_;
+  this.blocks_.push(this.temp_);
+  this.totalLength_ += this.temp_.length;
+  this.temp_ = [];
+  return oldTemp;
+};
+
+
+/**
+ * Append a typed array of bytes onto the buffer.
+ *
+ * @param {!Uint8Array} arr The byte array to append.
+ * @private
+ */
+jspb.BinaryWriter.prototype.appendUint8Array_ = function(arr) {
+  if (this.temp_.length) {
+    this.saveTempBuffer_();
+  }
+  this.blocks_.push(arr);
+  this.totalLength_ += arr.length;
+};
+
+
+/**
+ * Append an untyped array of bytes onto the buffer.
+ *
+ * @param {!Array.<number>} arr The byte array to append.
+ * @private
+ */
+jspb.BinaryWriter.prototype.appendArray_ = function(arr) {
+  if (this.temp_.length) {
+    this.saveTempBuffer_();
+  }
+  this.temp_ = arr;
+};
+
+
+/**
+ * Begins a length-delimited section by writing the field header to the current
+ * temp buffer and then saving it in the block array. Returns the saved block,
+ * which we will append the length to in endDelimited_ below.
+ * @param {number} field
+ * @return {!jspb.BinaryWriter.Bookmark_}
+ * @private
+ */
+jspb.BinaryWriter.prototype.beginDelimited_ = function(field) {
+  this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
+  return {block: this.saveTempBuffer_(), length: this.totalLength_};
+};
+
+
+/**
+ * Ends a length-delimited block by encoding the _change_ in length of the
+ * buffer to the parent block and adds the number of bytes needed to encode
+ * that length to the total byte length. Note that 'parentLength' _must_ be the
+ * total length _after_ the field header was written in beginDelimited_ above.
+ * @param {!jspb.BinaryWriter.Bookmark_} bookmark
+ * @private
+ */
+jspb.BinaryWriter.prototype.endDelimited_ = function(bookmark) {
+  var messageLength = this.totalLength_ + this.temp_.length - bookmark.length;
+  goog.asserts.assert(messageLength >= 0);
+
+  var bytes = 1;
+  while (messageLength > 127) {
+    bookmark.block.push((messageLength & 0x7f) | 0x80);
+    messageLength = messageLength >>> 7;
+    bytes++;
+  }
+
+  bookmark.block.push(messageLength);
+  this.totalLength_ += bytes;
+};
+
+
+/**
+ * Resets the writer, throwing away any accumulated buffers.
+ */
+jspb.BinaryWriter.prototype.reset = function() {
+  this.blocks_ = [];
+  this.temp_ = [];
+  this.totalLength_ = 0;
+  this.bookmarks_ = [];
+};
+
+
+/**
+ * Converts the encoded data into a Uint8Array.
+ * @return {!Uint8Array}
+ */
+jspb.BinaryWriter.prototype.getResultBuffer = function() {
+  goog.asserts.assert(this.bookmarks_.length == 0);
+
+  var flat = new Uint8Array(this.totalLength_ + this.temp_.length);
+
+  var blocks = this.blocks_;
+  var blockCount = blocks.length;
+  var offset = 0;
+
+  for (var i = 0; i < blockCount; i++) {
+    var block = blocks[i];
+    flat.set(block, offset);
+    offset += block.length;
+  }
+
+  flat.set(this.temp_, offset);
+  offset += this.temp_.length;
+
+  // Post condition: `flattened` must have had every byte written.
+  goog.asserts.assert(offset == flat.length);
+
+  // Replace our block list with the flattened block, which lets GC reclaim
+  // the temp blocks sooner.
+  this.blocks_ = [flat];
+  this.temp_ = [];
+
+  return flat;
+};
+
+
+/**
+ * Converts the encoded data into a bas64-encoded string.
+ * @return {string}
+ */
+jspb.BinaryWriter.prototype.getResultBase64String = function() {
+  return goog.crypt.base64.encodeByteArray(this.getResultBuffer());
+};
+
+
+/**
+ * Begins a new sub-message. The client must call endSubMessage() when they're
+ * done.
+ * TODO(aappleby): Deprecated. Move callers to writeMessage().
+ * @param {number} field The field number of the sub-message.
+ */
+jspb.BinaryWriter.prototype.beginSubMessage = function(field) {
+  this.bookmarks_.push(this.beginDelimited_(field));
+};
+
+
+/**
+ * Finishes a sub-message and packs it into the parent messages' buffer.
+ * TODO(aappleby): Deprecated. Move callers to writeMessage().
+ */
+jspb.BinaryWriter.prototype.endSubMessage = function() {
+  goog.asserts.assert(this.bookmarks_.length >= 0);
+  this.endDelimited_(this.bookmarks_.pop());
+};
+
+
+/**
+ * Encodes a 32-bit unsigned integer into its wire-format varint representation
+ * and stores it in the buffer.
+ * @param {number} value The integer to convert.
+ */
+jspb.BinaryWriter.prototype.rawWriteUnsignedVarint32 = function(value) {
+  goog.asserts.assert(value == Math.floor(value));
+
+  while (value > 127) {
+    this.temp_.push((value & 0x7f) | 0x80);
+    value = value >>> 7;
+  }
+
+  this.temp_.push(value);
+};
+
+
+/**
+ * Encodes a 32-bit signed integer into its wire-format varint representation
+ * and stores it in the buffer.
+ * @param {number} value The integer to convert.
+ */
+jspb.BinaryWriter.prototype.rawWriteSignedVarint32 = function(value) {
+  goog.asserts.assert(value == Math.floor(value));
+  if (value >= 0) {
+    this.rawWriteUnsignedVarint32(value);
+    return;
+  }
+
+  // Write nine bytes with a _signed_ right shift so we preserve the sign bit.
+  for (var i = 0; i < 9; i++) {
+    this.temp_.push((value & 0x7f) | 0x80);
+    value = value >> 7;
+  }
+
+  // The above loop writes out 63 bits, so the last byte is always the sign bit
+  // which is always set for negative numbers.
+  this.temp_.push(1);
+};
+
+
+/**
+ * Encodes an unsigned 64-bit integer in 32:32 split representation into its
+ * wire-format varint representation and stores it in the buffer.
+ * @param {number} lowBits The low 32 bits of the int.
+ * @param {number} highBits The high 32 bits of the int.
+ */
+jspb.BinaryWriter.prototype.rawWriteSplitVarint =
+    function(lowBits, highBits) {
+  // Break the binary representation into chunks of 7 bits, set the 8th bit
+  // in each chunk if it's not the final chunk, and append to the result.
+  while (highBits > 0 || lowBits > 127) {
+    this.temp_.push((lowBits & 0x7f) | 0x80);
+    lowBits = ((lowBits >>> 7) | (highBits << 25)) >>> 0;
+    highBits = highBits >>> 7;
+  }
+  this.temp_.push(lowBits);
+};
+
+
+/**
+ * Encodes a JavaScript integer into its wire-format varint representation and
+ * stores it in the buffer. Due to the way the varint encoding works this
+ * behaves correctly for both signed and unsigned integers, though integers
+ * that are not representable in 64 bits will still be truncated.
+ * @param {number} value The integer to convert.
+ */
+jspb.BinaryWriter.prototype.rawWriteVarint = function(value) {
+  goog.asserts.assert(value == Math.floor(value));
+  jspb.utils.splitInt64(value);
+  this.rawWriteSplitVarint(jspb.utils.split64Low,
+                           jspb.utils.split64High);
+};
+
+
+/**
+ * Encodes a jspb.arith.{Int64,UInt64} instance into its wire-format
+ * varint representation and stores it in the buffer. Due to the way the varint
+ * encoding works this behaves correctly for both signed and unsigned integers,
+ * though integers that are not representable in 64 bits will still be
+ * truncated.
+ * @param {jspb.arith.Int64|jspb.arith.UInt64} value
+ */
+jspb.BinaryWriter.prototype.rawWriteVarintFromNum = function(value) {
+  this.rawWriteSplitVarint(value.lo, value.hi);
+};
+
+
+/**
+ * Encodes a JavaScript integer into its wire-format, zigzag-encoded varint
+ * representation and stores it in the buffer.
+ * @param {number} value The integer to convert.
+ */
+jspb.BinaryWriter.prototype.rawWriteZigzagVarint32 = function(value) {
+  goog.asserts.assert(value == Math.floor(value));
+  this.rawWriteUnsignedVarint32(((value << 1) ^ (value >> 31)) >>> 0);
+};
+
+
+/**
+ * Encodes a JavaScript integer into its wire-format, zigzag-encoded varint
+ * representation and stores it in the buffer. Integers not representable in 64
+ * bits will be truncated.
+ * @param {number} value The integer to convert.
+ */
+jspb.BinaryWriter.prototype.rawWriteZigzagVarint = function(value) {
+  goog.asserts.assert(value == Math.floor(value));
+  jspb.utils.splitZigzag64(value);
+  this.rawWriteSplitVarint(jspb.utils.split64Low,
+                           jspb.utils.split64High);
+};
+
+
+/**
+ * Writes a raw 8-bit unsigned integer to the buffer. Numbers outside the range
+ * [0,2^8) will be truncated.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryWriter.prototype.rawWriteUint8 = function(value) {
+  goog.asserts.assert(value == Math.floor(value));
+  goog.asserts.assert((value >= 0) && (value < 256));
+  this.temp_.push((value >>> 0) & 0xFF);
+};
+
+
+/**
+ * Writes a raw 16-bit unsigned integer to the buffer. Numbers outside the
+ * range [0,2^16) will be truncated.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryWriter.prototype.rawWriteUint16 = function(value) {
+  goog.asserts.assert(value == Math.floor(value));
+  goog.asserts.assert((value >= 0) && (value < 65536));
+  this.temp_.push((value >>> 0) & 0xFF);
+  this.temp_.push((value >>> 8) & 0xFF);
+};
+
+
+/**
+ * Writes a raw 32-bit unsigned integer to the buffer. Numbers outside the
+ * range [0,2^32) will be truncated.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryWriter.prototype.rawWriteUint32 = function(value) {
+  goog.asserts.assert(value == Math.floor(value));
+  goog.asserts.assert((value >= 0) &&
+                      (value < jspb.BinaryConstants.TWO_TO_32));
+  this.temp_.push((value >>> 0) & 0xFF);
+  this.temp_.push((value >>> 8) & 0xFF);
+  this.temp_.push((value >>> 16) & 0xFF);
+  this.temp_.push((value >>> 24) & 0xFF);
+};
+
+
+/**
+ * Writes a raw 64-bit unsigned integer to the buffer. Numbers outside the
+ * range [0,2^64) will be truncated.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryWriter.prototype.rawWriteUint64 = function(value) {
+  goog.asserts.assert(value == Math.floor(value));
+  goog.asserts.assert((value >= 0) &&
+                      (value < jspb.BinaryConstants.TWO_TO_64));
+  jspb.utils.splitUint64(value);
+  this.rawWriteUint32(jspb.utils.split64Low);
+  this.rawWriteUint32(jspb.utils.split64High);
+};
+
+
+/**
+ * Writes a raw 8-bit integer to the buffer. Numbers outside the range
+ * [-2^7,2^7) will be truncated.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryWriter.prototype.rawWriteInt8 = function(value) {
+  goog.asserts.assert(value == Math.floor(value));
+  goog.asserts.assert((value >= -128) && (value < 128));
+  this.temp_.push((value >>> 0) & 0xFF);
+};
+
+
+/**
+ * Writes a raw 16-bit integer to the buffer. Numbers outside the range
+ * [-2^15,2^15) will be truncated.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryWriter.prototype.rawWriteInt16 = function(value) {
+  goog.asserts.assert(value == Math.floor(value));
+  goog.asserts.assert((value >= -32768) && (value < 32768));
+  this.temp_.push((value >>> 0) & 0xFF);
+  this.temp_.push((value >>> 8) & 0xFF);
+};
+
+
+/**
+ * Writes a raw 32-bit integer to the buffer. Numbers outside the range
+ * [-2^31,2^31) will be truncated.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryWriter.prototype.rawWriteInt32 = function(value) {
+  goog.asserts.assert(value == Math.floor(value));
+  goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) &&
+                      (value < jspb.BinaryConstants.TWO_TO_31));
+  this.temp_.push((value >>> 0) & 0xFF);
+  this.temp_.push((value >>> 8) & 0xFF);
+  this.temp_.push((value >>> 16) & 0xFF);
+  this.temp_.push((value >>> 24) & 0xFF);
+};
+
+
+/**
+ * Writes a raw 64-bit integer to the buffer. Numbers outside the range
+ * [-2^63,2^63) will be truncated.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryWriter.prototype.rawWriteInt64 = function(value) {
+  goog.asserts.assert(value == Math.floor(value));
+  goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) &&
+                      (value < jspb.BinaryConstants.TWO_TO_63));
+  jspb.utils.splitInt64(value);
+  this.rawWriteUint32(jspb.utils.split64Low);
+  this.rawWriteUint32(jspb.utils.split64High);
+};
+
+
+/**
+ * Writes a raw single-precision floating point value to the buffer. Numbers
+ * requiring more than 32 bits of precision will be truncated.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryWriter.prototype.rawWriteFloat = function(value) {
+  jspb.utils.splitFloat32(value);
+  this.rawWriteUint32(jspb.utils.split64Low);
+};
+
+
+/**
+ * Writes a raw double-precision floating point value to the buffer. As this is
+ * the native format used by JavaScript, no precision will be lost.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryWriter.prototype.rawWriteDouble = function(value) {
+  jspb.utils.splitFloat64(value);
+  this.rawWriteUint32(jspb.utils.split64Low);
+  this.rawWriteUint32(jspb.utils.split64High);
+};
+
+
+/**
+ * Writes a raw boolean value to the buffer as a varint.
+ * @param {boolean} value The value to write.
+ */
+jspb.BinaryWriter.prototype.rawWriteBool = function(value) {
+  goog.asserts.assert(goog.isBoolean(value));
+  this.temp_.push(~~value);
+};
+
+
+/**
+ * Writes an raw enum value to the buffer as a varint.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryWriter.prototype.rawWriteEnum = function(value) {
+  goog.asserts.assert(value == Math.floor(value));
+  goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) &&
+                      (value < jspb.BinaryConstants.TWO_TO_31));
+  this.rawWriteSignedVarint32(value);
+};
+
+
+/**
+ * Writes a raw string value to the buffer.
+ * @param {string} string The string to write.
+ */
+jspb.BinaryWriter.prototype.rawWriteUtf8String = function(string) {
+  for (var i = 0; i < string.length; i++) {
+    this.temp_.push(string.charCodeAt(i));
+  }
+};
+
+
+/**
+ * Writes an arbitrary raw byte array to the buffer.
+ * @param {!Uint8Array} bytes The array of bytes to write.
+ */
+jspb.BinaryWriter.prototype.rawWriteBytes = function(bytes) {
+  this.appendUint8Array_(bytes);
+};
+
+
+/**
+ * Writes an arbitrary raw byte array to the buffer.
+ * @param {!Uint8Array} bytes The array of bytes to write.
+ * @param {number} start The start of the range to write.
+ * @param {number} end The end of the range to write.
+ */
+jspb.BinaryWriter.prototype.rawWriteByteRange = function(bytes, start, end) {
+  this.appendUint8Array_(bytes.subarray(start, end));
+};
+
+
+/**
+ * Writes a 64-bit hash string (8 characters @ 8 bits of data each) to the
+ * buffer as a varint.
+ * @param {string} hash The hash to write.
+ */
+jspb.BinaryWriter.prototype.rawWriteVarintHash64 = function(hash) {
+  jspb.utils.splitHash64(hash);
+  this.rawWriteSplitVarint(jspb.utils.split64Low,
+                           jspb.utils.split64High);
+};
+
+
+/**
+ * Writes a 64-bit hash string (8 characters @ 8 bits of data each) to the
+ * buffer as a fixed64.
+ * @param {string} hash The hash to write.
+ */
+jspb.BinaryWriter.prototype.rawWriteFixedHash64 = function(hash) {
+  jspb.utils.splitHash64(hash);
+  this.rawWriteUint32(jspb.utils.split64Low);
+  this.rawWriteUint32(jspb.utils.split64High);
+};
+
+
+/**
+ * Encodes a (field number, wire type) tuple into a wire-format field header
+ * and stores it in the buffer as a varint.
+ * @param {number} field The field number.
+ * @param {number} wireType The wire-type of the field, as specified in the
+ *     protocol buffer documentation.
+ * @private
+ */
+jspb.BinaryWriter.prototype.rawWriteFieldHeader_ =
+    function(field, wireType) {
+  goog.asserts.assert(field >= 1 && field == Math.floor(field));
+  var x = field * 8 + wireType;
+  this.rawWriteUnsignedVarint32(x);
+};
+
+
+/**
+ * Writes a field of any valid scalar type to the binary stream.
+ * @param {jspb.BinaryConstants.FieldType} fieldType
+ * @param {number} field
+ * @param {jspb.AnyFieldType} value
+ */
+jspb.BinaryWriter.prototype.writeAny = function(fieldType, field, value) {
+  var fieldTypes = jspb.BinaryConstants.FieldType;
+  switch (fieldType) {
+    case fieldTypes.DOUBLE:
+      this.writeDouble(field, /** @type {number} */(value));
+      return;
+    case fieldTypes.FLOAT:
+      this.writeFloat(field, /** @type {number} */(value));
+      return;
+    case fieldTypes.INT64:
+      this.writeInt64(field, /** @type {number} */(value));
+      return;
+    case fieldTypes.UINT64:
+      this.writeUint64(field, /** @type {number} */(value));
+      return;
+    case fieldTypes.INT32:
+      this.writeInt32(field, /** @type {number} */(value));
+      return;
+    case fieldTypes.FIXED64:
+      this.writeFixed64(field, /** @type {number} */(value));
+      return;
+    case fieldTypes.FIXED32:
+      this.writeFixed32(field, /** @type {number} */(value));
+      return;
+    case fieldTypes.BOOL:
+      this.writeBool(field, /** @type {boolean} */(value));
+      return;
+    case fieldTypes.STRING:
+      this.writeString(field, /** @type {string} */(value));
+      return;
+    case fieldTypes.GROUP:
+      goog.asserts.fail('Group field type not supported in writeAny()');
+      return;
+    case fieldTypes.MESSAGE:
+      goog.asserts.fail('Message field type not supported in writeAny()');
+      return;
+    case fieldTypes.BYTES:
+      this.writeBytes(field, /** @type {?Uint8Array} */(value));
+      return;
+    case fieldTypes.UINT32:
+      this.writeUint32(field, /** @type {number} */(value));
+      return;
+    case fieldTypes.ENUM:
+      this.writeEnum(field, /** @type {number} */(value));
+      return;
+    case fieldTypes.SFIXED32:
+      this.writeSfixed32(field, /** @type {number} */(value));
+      return;
+    case fieldTypes.SFIXED64:
+      this.writeSfixed64(field, /** @type {number} */(value));
+      return;
+    case fieldTypes.SINT32:
+      this.writeSint32(field, /** @type {number} */(value));
+      return;
+    case fieldTypes.SINT64:
+      this.writeSint64(field, /** @type {number} */(value));
+      return;
+    case fieldTypes.FHASH64:
+      this.writeFixedHash64(field, /** @type {string} */(value));
+      return;
+    case fieldTypes.VHASH64:
+      this.writeVarintHash64(field, /** @type {string} */(value));
+      return;
+    default:
+      goog.asserts.fail('Invalid field type in writeAny()');
+      return;
+  }
+};
+
+
+/**
+ * Writes a varint field to the buffer without range checking.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writeUnsignedVarint32_ = function(field, value) {
+  if (value == null) return;
+  this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+  this.rawWriteSignedVarint32(value);
+};
+
+
+/**
+ * Writes a varint field to the buffer without range checking.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writeSignedVarint32_ = function(field, value) {
+  if (value == null) return;
+  this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+  this.rawWriteSignedVarint32(value);
+};
+
+
+/**
+ * Writes a varint field to the buffer without range checking.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writeVarint_ = function(field, value) {
+  if (value == null) return;
+  this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+  this.rawWriteVarint(value);
+};
+
+
+/**
+ * Writes a zigzag varint field to the buffer without range checking.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writeZigzagVarint32_ = function(field, value) {
+  if (value == null) return;
+  this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+  this.rawWriteZigzagVarint32(value);
+};
+
+
+/**
+ * Writes a zigzag varint field to the buffer without range checking.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writeZigzagVarint_ = function(field, value) {
+  if (value == null) return;
+  this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+  this.rawWriteZigzagVarint(value);
+};
+
+
+/**
+ * Writes an int32 field to the buffer. Numbers outside the range [-2^31,2^31)
+ * will be truncated.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeInt32 = function(field, value) {
+  if (value == null) return;
+  goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) &&
+                      (value < jspb.BinaryConstants.TWO_TO_31));
+  this.writeSignedVarint32_(field, value);
+};
+
+
+/**
+ * Writes an int32 field represented as a string to the buffer. Numbers outside
+ * the range [-2^31,2^31) will be truncated.
+ * @param {number} field The field number.
+ * @param {string?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeInt32String = function(field, value) {
+  if (value == null) return;
+  var intValue = /** {number} */ parseInt(value, 10);
+  goog.asserts.assert((intValue >= -jspb.BinaryConstants.TWO_TO_31) &&
+                      (intValue < jspb.BinaryConstants.TWO_TO_31));
+  this.writeSignedVarint32_(field, intValue);
+};
+
+
+/**
+ * Writes an int64 field to the buffer. Numbers outside the range [-2^63,2^63)
+ * will be truncated.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeInt64 = function(field, value) {
+  if (value == null) return;
+  goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) &&
+                      (value < jspb.BinaryConstants.TWO_TO_63));
+  this.writeVarint_(field, value);
+};
+
+
+/**
+ * Writes a int64 field (with value as a string) to the buffer.
+ * @param {number} field The field number.
+ * @param {string?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeInt64String = function(field, value) {
+  if (value == null) return;
+  var num = jspb.arith.Int64.fromString(value);
+  this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+  this.rawWriteVarintFromNum(num);
+};
+
+
+/**
+ * Writes a uint32 field to the buffer. Numbers outside the range [0,2^32)
+ * will be truncated.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeUint32 = function(field, value) {
+  if (value == null) return;
+  goog.asserts.assert((value >= 0) &&
+                      (value < jspb.BinaryConstants.TWO_TO_32));
+  this.writeUnsignedVarint32_(field, value);
+};
+
+
+/**
+ * Writes a uint32 field represented as a string to the buffer. Numbers outside
+ * the range [0,2^32) will be truncated.
+ * @param {number} field The field number.
+ * @param {string?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeUint32String = function(field, value) {
+  if (value == null) return;
+  var intValue = /** {number} */ parseInt(value, 10);
+  goog.asserts.assert((intValue >= 0) &&
+                      (intValue < jspb.BinaryConstants.TWO_TO_32));
+  this.writeUnsignedVarint32_(field, intValue);
+};
+
+
+/**
+ * Writes a uint64 field to the buffer. Numbers outside the range [0,2^64)
+ * will be truncated.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeUint64 = function(field, value) {
+  if (value == null) return;
+  goog.asserts.assert((value >= 0) &&
+                      (value < jspb.BinaryConstants.TWO_TO_64));
+  this.writeVarint_(field, value);
+};
+
+
+/**
+ * Writes a uint64 field (with value as a string) to the buffer.
+ * @param {number} field The field number.
+ * @param {string?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeUint64String = function(field, value) {
+  if (value == null) return;
+  var num = jspb.arith.UInt64.fromString(value);
+  this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+  this.rawWriteVarintFromNum(num);
+};
+
+
+/**
+ * Writes a sint32 field to the buffer. Numbers outside the range [-2^31,2^31)
+ * will be truncated.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeSint32 = function(field, value) {
+  if (value == null) return;
+  goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) &&
+                      (value < jspb.BinaryConstants.TWO_TO_31));
+  this.writeZigzagVarint32_(field, value);
+};
+
+
+/**
+ * Writes a sint64 field to the buffer. Numbers outside the range [-2^63,2^63)
+ * will be truncated.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeSint64 = function(field, value) {
+  if (value == null) return;
+  goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) &&
+                      (value < jspb.BinaryConstants.TWO_TO_63));
+  this.writeZigzagVarint_(field, value);
+};
+
+
+/**
+ * Writes a fixed32 field to the buffer. Numbers outside the range [0,2^32)
+ * will be truncated.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeFixed32 = function(field, value) {
+  if (value == null) return;
+  goog.asserts.assert((value >= 0) &&
+                      (value < jspb.BinaryConstants.TWO_TO_32));
+  this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED32);
+  this.rawWriteUint32(value);
+};
+
+
+/**
+ * Writes a fixed64 field to the buffer. Numbers outside the range [0,2^64)
+ * will be truncated.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeFixed64 = function(field, value) {
+  if (value == null) return;
+  goog.asserts.assert((value >= 0) &&
+                      (value < jspb.BinaryConstants.TWO_TO_64));
+  this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64);
+  this.rawWriteUint64(value);
+};
+
+
+/**
+ * Writes a sfixed32 field to the buffer. Numbers outside the range
+ * [-2^31,2^31) will be truncated.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeSfixed32 = function(field, value) {
+  if (value == null) return;
+  goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) &&
+                      (value < jspb.BinaryConstants.TWO_TO_31));
+  this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED32);
+  this.rawWriteInt32(value);
+};
+
+
+/**
+ * Writes a sfixed64 field to the buffer. Numbers outside the range
+ * [-2^63,2^63) will be truncated.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeSfixed64 = function(field, value) {
+  if (value == null) return;
+  goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) &&
+                      (value < jspb.BinaryConstants.TWO_TO_63));
+  this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64);
+  this.rawWriteInt64(value);
+};
+
+
+/**
+ * Writes a single-precision floating point field to the buffer. Numbers
+ * requiring more than 32 bits of precision will be truncated.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeFloat = function(field, value) {
+  if (value == null) return;
+  this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED32);
+  this.rawWriteFloat(value);
+};
+
+
+/**
+ * Writes a double-precision floating point field to the buffer. As this is the
+ * native format used by JavaScript, no precision will be lost.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeDouble = function(field, value) {
+  if (value == null) return;
+  this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64);
+  this.rawWriteDouble(value);
+};
+
+
+/**
+ * Writes a boolean field to the buffer.
+ * @param {number} field The field number.
+ * @param {boolean?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeBool = function(field, value) {
+  if (value == null) return;
+  goog.asserts.assert(goog.isBoolean(value));
+  this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+  this.temp_.push(~~value);
+};
+
+
+/**
+ * Writes an enum field to the buffer.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeEnum = function(field, value) {
+  if (value == null) return;
+  goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) &&
+                      (value < jspb.BinaryConstants.TWO_TO_31));
+  this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+  this.rawWriteSignedVarint32(value);
+};
+
+
+/**
+ * Writes a string field to the buffer.
+ * @param {number} field The field number.
+ * @param {string?} value The string to write.
+ */
+jspb.BinaryWriter.prototype.writeString = function(field, value) {
+  if (value == null) return;
+  this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
+
+  // Conversion loop swiped from goog.crypt.stringToUtf8ByteArray. Note that
+  // 'bytes' will be at least as long as 'value', but could be longer if we
+  // need to unpack unicode characters.
+  var bytes = [];
+  for (var i = 0; i < value.length; i++) {
+    var c = value.charCodeAt(i);
+    if (c < 128) {
+      bytes.push(c);
+    } else if (c < 2048) {
+      bytes.push((c >> 6) | 192);
+      bytes.push((c & 63) | 128);
+    } else {
+      bytes.push((c >> 12) | 224);
+      bytes.push(((c >> 6) & 63) | 128);
+      bytes.push((c & 63) | 128);
+    }
+  }
+
+  this.rawWriteUnsignedVarint32(bytes.length);
+  this.appendArray_(bytes);
+};
+
+
+/**
+ * Writes an arbitrary byte field to the buffer. Note - to match the behavior
+ * of the C++ implementation, empty byte arrays _are_ serialized.
+ *
+ * If 'value' is null, this method will try and copy the pre-serialized value
+ * in 'opt_buffer' if present.
+ *
+ * @param {number} field The field number.
+ * @param {jspb.ByteSource} value The array of bytes to write.
+ * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
+ * @param {?number=} opt_start The starting point in the above buffer.
+ * @param {?number=} opt_end The ending point in the above buffer.
+ * @param {boolean=} opt_stringIsRawBytes If `value` is a string, interpret it
+ * as a series of raw bytes (codepoints 0--255 inclusive) rather than base64
+ * data.
+ */
+jspb.BinaryWriter.prototype.writeBytes =
+    function(field, value, opt_buffer, opt_start, opt_end,
+             opt_stringIsRawBytes) {
+  if (value != null) {
+    this.rawWriteFieldHeader_(field,
+        jspb.BinaryConstants.WireType.DELIMITED);
+    this.rawWriteUnsignedVarint32(value.length);
+    this.rawWriteBytes(
+        jspb.utils.byteSourceToUint8Array(value, opt_stringIsRawBytes));
+  } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
+    this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+  }
+};
+
+
+/**
+ * Writes an arbitrary byte field to the buffer, with `opt_stringIsRawBytes`
+ * flag implicitly true.
+ * @param {number} field
+ * @param {jspb.ByteSource} value The array of bytes to write.
+ */
+jspb.BinaryWriter.prototype.writeBytesRawString = function(field, value) {
+  this.writeBytes(field, value, null, null, null, true);
+};
+
+
+/**
+ * Writes a message to the buffer.
+ *
+ * If 'value' is null, this method will try and copy the pre-serialized value
+ * in 'opt_buffer' if present.
+ *
+ * @template MessageType
+ * @param {number} field The field number.
+ * @param {?MessageType} value The message to write.
+ * @param {!jspb.WriterFunction} writerCallback Will be invoked with the value
+ *     to write and the writer to write it with.
+ * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
+ * @param {?number=} opt_start The starting point in the above buffer.
+ * @param {?number=} opt_end The ending point in the above buffer.
+ */
+jspb.BinaryWriter.prototype.writeMessage =
+    function(field, value, writerCallback, opt_buffer, opt_start, opt_end) {
+  if (value !== null) {
+    var bookmark = this.beginDelimited_(field);
+
+    writerCallback(value, this);
+
+    this.endDelimited_(bookmark);
+  } else if (opt_buffer && (opt_start != null) && (opt_end != null)) {
+    this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+  }
+};
+
+
+/**
+ * Writes a group message to the buffer.
+ *
+ * @template MessageType
+ * @param {number} field The field number.
+ * @param {?MessageType} value The message to write, wrapped with START_GROUP /
+ *     END_GROUP tags. Will be a no-op if 'value' is null.
+ * @param {!jspb.WriterFunction} writerCallback Will be invoked with the value
+ *     to write and the writer to write it with.
+ */
+jspb.BinaryWriter.prototype.writeGroup =
+    function(field, value, writerCallback) {
+  if (value) {
+    this.rawWriteFieldHeader_(
+        field, jspb.BinaryConstants.WireType.START_GROUP);
+    writerCallback(value, this);
+    this.rawWriteFieldHeader_(
+        field, jspb.BinaryConstants.WireType.END_GROUP);
+  }
+};
+
+
+/**
+ * Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to
+ * the buffer.
+ * @param {number} field The field number.
+ * @param {string?} value The hash string.
+ */
+jspb.BinaryWriter.prototype.writeFixedHash64 = function(field, value) {
+  if (value == null) return;
+  goog.asserts.assert(value.length == 8);
+  this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64);
+  this.rawWriteFixedHash64(value);
+};
+
+
+/**
+ * Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to
+ * the buffer.
+ * @param {number} field The field number.
+ * @param {string?} value The hash string.
+ */
+jspb.BinaryWriter.prototype.writeVarintHash64 = function(field, value) {
+  if (value == null) return;
+  goog.asserts.assert(value.length == 8);
+  this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+  this.rawWriteVarintHash64(value);
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a repeated varint field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writeRepeatedUnsignedVarint32_ =
+    function(field, value) {
+  if (value == null) return;
+  for (var i = 0; i < value.length; i++) {
+    this.writeUnsignedVarint32_(field, value[i]);
+  }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a repeated varint field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writeRepeatedSignedVarint32_ =
+    function(field, value) {
+  if (value == null) return;
+  for (var i = 0; i < value.length; i++) {
+    this.writeSignedVarint32_(field, value[i]);
+  }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a repeated varint field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writeRepeatedVarint_ = function(field, value) {
+  if (value == null) return;
+  for (var i = 0; i < value.length; i++) {
+    this.writeVarint_(field, value[i]);
+  }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a repeated zigzag field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writeRepeatedZigzag32_ = function(field, value) {
+  if (value == null) return;
+  for (var i = 0; i < value.length; i++) {
+    this.writeZigzagVarint32_(field, value[i]);
+  }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a repeated zigzag field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writeRepeatedZigzag_ = function(field, value) {
+  if (value == null) return;
+  for (var i = 0; i < value.length; i++) {
+    this.writeZigzagVarint_(field, value[i]);
+  }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a repeated 32-bit int field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedInt32 =
+    jspb.BinaryWriter.prototype.writeRepeatedSignedVarint32_;
+
+
+/**
+ * Writes an array of numbers formatted as strings to the buffer as a repeated
+ * 32-bit int field.
+ * @param {number} field The field number.
+ * @param {?Array.<string>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedInt32String =
+    function(field, value) {
+  if (value == null) return;
+  for (var i = 0; i < value.length; i++) {
+    this.writeInt32String(field, value[i]);
+  }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a repeated 64-bit int field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedInt64 =
+    jspb.BinaryWriter.prototype.writeRepeatedVarint_;
+
+
+/**
+ * Writes an array of numbers formatted as strings to the buffer as a repeated
+ * 64-bit int field.
+ * @param {number} field The field number.
+ * @param {?Array.<string>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedInt64String =
+    function(field, value) {
+  if (value == null) return;
+  for (var i = 0; i < value.length; i++) {
+    this.writeInt64String(field, value[i]);
+  }
+};
+
+
+/**
+ * Writes an array numbers to the buffer as a repeated unsigned 32-bit int
+ *     field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedUint32 =
+    jspb.BinaryWriter.prototype.writeRepeatedUnsignedVarint32_;
+
+
+/**
+ * Writes an array of numbers formatted as strings to the buffer as a repeated
+ * unsigned 32-bit int field.
+ * @param {number} field The field number.
+ * @param {?Array.<string>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedUint32String =
+    function(field, value) {
+  if (value == null) return;
+  for (var i = 0; i < value.length; i++) {
+    this.writeUint32String(field, value[i]);
+  }
+};
+
+
+/**
+ * Writes an array numbers to the buffer as a repeated unsigned 64-bit int
+ *     field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedUint64 =
+    jspb.BinaryWriter.prototype.writeRepeatedVarint_;
+
+
+/**
+ * Writes an array of numbers formatted as strings to the buffer as a repeated
+ * unsigned 64-bit int field.
+ * @param {number} field The field number.
+ * @param {?Array.<string>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedUint64String =
+    function(field, value) {
+  if (value == null) return;
+  for (var i = 0; i < value.length; i++) {
+    this.writeUint64String(field, value[i]);
+  }
+};
+
+
+/**
+ * Writes an array numbers to the buffer as a repeated signed 32-bit int field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedSint32 =
+    jspb.BinaryWriter.prototype.writeRepeatedZigzag32_;
+
+
+/**
+ * Writes an array numbers to the buffer as a repeated signed 64-bit int field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedSint64 =
+    jspb.BinaryWriter.prototype.writeRepeatedZigzag_;
+
+
+/**
+ * Writes an array of numbers to the buffer as a repeated fixed32 field. This
+ * works for both signed and unsigned fixed32s.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedFixed32 = function(field, value) {
+  if (value == null) return;
+  for (var i = 0; i < value.length; i++) {
+    this.writeFixed32(field, value[i]);
+  }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a repeated fixed64 field. This
+ * works for both signed and unsigned fixed64s.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedFixed64 = function(field, value) {
+  if (value == null) return;
+  for (var i = 0; i < value.length; i++) {
+    this.writeFixed64(field, value[i]);
+  }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a repeated sfixed32 field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedSfixed32 = function(field, value) {
+  if (value == null) return;
+  for (var i = 0; i < value.length; i++) {
+    this.writeSfixed32(field, value[i]);
+  }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a repeated sfixed64 field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedSfixed64 = function(field, value) {
+  if (value == null) return;
+  for (var i = 0; i < value.length; i++) {
+    this.writeSfixed64(field, value[i]);
+  }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a repeated float field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedFloat = function(field, value) {
+  if (value == null) return;
+  for (var i = 0; i < value.length; i++) {
+    this.writeFloat(field, value[i]);
+  }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a repeated double field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedDouble = function(field, value) {
+  if (value == null) return;
+  for (var i = 0; i < value.length; i++) {
+    this.writeDouble(field, value[i]);
+  }
+};
+
+
+/**
+ * Writes an array of booleans to the buffer as a repeated bool field.
+ * @param {number} field The field number.
+ * @param {?Array.<boolean>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedBool = function(field, value) {
+  if (value == null) return;
+  for (var i = 0; i < value.length; i++) {
+    this.writeBool(field, value[i]);
+  }
+};
+
+
+/**
+ * Writes an array of enums to the buffer as a repeated enum field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedEnum = function(field, value) {
+  if (value == null) return;
+  for (var i = 0; i < value.length; i++) {
+    this.writeEnum(field, value[i]);
+  }
+};
+
+
+/**
+ * Writes an array of strings to the buffer as a repeated string field.
+ * @param {number} field The field number.
+ * @param {?Array.<string>} value The array of strings to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedString = function(field, value) {
+  if (value == null) return;
+  for (var i = 0; i < value.length; i++) {
+    this.writeString(field, value[i]);
+  }
+};
+
+
+/**
+ * Writes an array of arbitrary byte fields to the buffer.
+ *
+ * If 'value' is null, this method will try and copy the pre-serialized value
+ * in 'opt_buffer' if present.
+ *
+ * @param {number} field The field number.
+ * @param {?Array.<!Uint8Array|string>} value
+ *     The arrays of arrays of bytes to write.
+ * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
+ * @param {?number=} opt_start The starting point in the above buffer.
+ * @param {?number=} opt_end The ending point in the above buffer.
+ * @param {boolean=} opt_stringIsRawBytes Any values that are strings are
+ * interpreted as raw bytes rather than base64 data.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedBytes =
+    function(field, value, opt_buffer, opt_start, opt_end,
+             opt_stringIsRawBytes) {
+  if (value != null) {
+    for (var i = 0; i < value.length; i++) {
+      this.writeBytes(field, value[i], null, null, null, opt_stringIsRawBytes);
+    }
+  } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
+    this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+  }
+};
+
+
+/**
+ * Writes an array of arbitrary byte fields to the buffer, with
+ * `opt_stringIsRawBytes` implicitly true.
+ * @param {number} field
+ * @param {?Array.<string>} value
+ */
+jspb.BinaryWriter.prototype.writeRepeatedBytesRawString =
+    function(field, value) {
+  this.writeRepeatedBytes(field, value, null, null, null, true);
+};
+
+
+/**
+ * Writes an array of messages to the buffer.
+ *
+ * If 'value' is null, this method will try and copy the pre-serialized value
+ * in 'opt_buffer' if present.
+ *
+ * @template MessageType
+ * @param {number} field The field number.
+ * @param {?Array.<!MessageType>} value The array of messages to
+ *    write.
+ * @param {!jspb.WriterFunction} writerCallback Will be invoked with the value
+ *     to write and the writer to write it with.
+ * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
+ * @param {?number=} opt_start The starting point in the above buffer.
+ * @param {?number=} opt_end The ending point in the above buffer.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedMessage =
+    function(field, value, writerCallback, opt_buffer, opt_start, opt_end) {
+  if (value) {
+    for (var i = 0; i < value.length; i++) {
+      var bookmark = this.beginDelimited_(field);
+
+      writerCallback(value[i], this);
+
+      this.endDelimited_(bookmark);
+    }
+  } else if (opt_buffer && (opt_start != null) && (opt_end != null)) {
+    this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+  }
+};
+
+
+/**
+ * Writes an array of group messages to the buffer.
+ *
+ * @template MessageType
+ * @param {number} field The field number.
+ * @param {?Array.<!MessageType>} value The array of messages to
+ *    write.
+ * @param {!jspb.WriterFunction} writerCallback Will be invoked with the value
+ *     to write and the writer to write it with.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedGroup =
+    function(field, value, writerCallback) {
+  if (value) {
+    for (var i = 0; i < value.length; i++) {
+      this.rawWriteFieldHeader_(
+          field, jspb.BinaryConstants.WireType.START_GROUP);
+      writerCallback(value[i], this);
+      this.rawWriteFieldHeader_(
+          field, jspb.BinaryConstants.WireType.END_GROUP);
+    }
+  }
+};
+
+
+/**
+ * Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to
+ * the buffer.
+ * @param {number} field The field number.
+ * @param {?Array.<string>} value The array of hashes to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedFixedHash64 =
+    function(field, value) {
+  if (value == null) return;
+  for (var i = 0; i < value.length; i++) {
+    this.writeFixedHash64(field, value[i]);
+  }
+};
+
+
+/**
+ * Writes a repeated 64-bit hash string field (8 characters @ 8 bits of data
+ * each) to the buffer.
+ * @param {number} field The field number.
+ * @param {?Array.<string>} value The array of hashes to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedVarintHash64 =
+    function(field, value) {
+  if (value == null) return;
+  for (var i = 0; i < value.length; i++) {
+    this.writeVarintHash64(field, value[i]);
+  }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a packed varint field.
+ *
+ * If 'value' is null, this method will try and copy the pre-serialized value
+ * in 'opt_buffer' if present.
+ *
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
+ * @param {?number=} opt_start The starting point in the above buffer.
+ * @param {?number=} opt_end The ending point in the above buffer.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writePackedUnsignedVarint32_ =
+    function(field, value, opt_buffer, opt_start, opt_end) {
+  if (value != null && value.length) {
+    var bookmark = this.beginDelimited_(field);
+    for (var i = 0; i < value.length; i++) {
+      this.rawWriteUnsignedVarint32(value[i]);
+    }
+    this.endDelimited_(bookmark);
+  } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
+    this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+  }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a packed varint field.
+ *
+ * If 'value' is null, this method will try and copy the pre-serialized value
+ * in 'opt_buffer' if present.
+ *
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
+ * @param {?number=} opt_start The starting point in the above buffer.
+ * @param {?number=} opt_end The ending point in the above buffer.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writePackedSignedVarint32_ =
+    function(field, value, opt_buffer, opt_start, opt_end) {
+  if (value != null && value.length) {
+    var bookmark = this.beginDelimited_(field);
+    for (var i = 0; i < value.length; i++) {
+      this.rawWriteSignedVarint32(value[i]);
+    }
+    this.endDelimited_(bookmark);
+  } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
+    this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+  }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a packed varint field.
+ *
+ * If 'value' is null, this method will try and copy the pre-serialized value
+ * in 'opt_buffer' if present.
+ *
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
+ * @param {?number=} opt_start The starting point in the above buffer.
+ * @param {?number=} opt_end The ending point in the above buffer.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writePackedVarint_ =
+    function(field, value, opt_buffer, opt_start, opt_end) {
+  if (value != null && value.length) {
+    var bookmark = this.beginDelimited_(field);
+    for (var i = 0; i < value.length; i++) {
+      this.rawWriteVarint(value[i]);
+    }
+    this.endDelimited_(bookmark);
+  } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
+    this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+  }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a packed zigzag field.
+ *
+ * If 'value' is null, this method will try and copy the pre-serialized value
+ * in 'opt_buffer' if present.
+ *
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
+ * @param {?number=} opt_start The starting point in the above buffer.
+ * @param {?number=} opt_end The ending point in the above buffer.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writePackedZigzag_ =
+    function(field, value, opt_buffer, opt_start, opt_end) {
+  if (value != null && value.length) {
+    var bookmark = this.beginDelimited_(field);
+    for (var i = 0; i < value.length; i++) {
+      this.rawWriteZigzagVarint(value[i]);
+    }
+    this.endDelimited_(bookmark);
+  } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
+    this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+  }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a packed 32-bit int field.
+ *
+ * If 'value' is null, this method will try and copy the pre-serialized value
+ * in 'opt_buffer' if present.
+ *
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
+ * @param {?number=} opt_start The starting point in the above buffer.
+ * @param {?number=} opt_end The ending point in the above buffer.
+ */
+jspb.BinaryWriter.prototype.writePackedInt32 =
+    jspb.BinaryWriter.prototype.writePackedSignedVarint32_;
+
+
+/**
+ * Writes an array of numbers represented as strings to the buffer as a packed
+ * 32-bit int field.
+ * @param {number} field
+ * @param {?Array.<string>} value
+ */
+jspb.BinaryWriter.prototype.writePackedInt32String = function(field, value) {
+  if (value == null || !value.length) return;
+  var bookmark = this.beginDelimited_(field);
+  for (var i = 0; i < value.length; i++) {
+    this.rawWriteSignedVarint32(parseInt(value[i], 10));
+  }
+  this.endDelimited_(bookmark);
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a packed 64-bit int field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
+ * @param {?number=} opt_start The starting point in the above buffer.
+ * @param {?number=} opt_end The ending point in the above buffer.
+ */
+jspb.BinaryWriter.prototype.writePackedInt64 =
+    jspb.BinaryWriter.prototype.writePackedVarint_;
+
+
+/**
+ * Writes an array of numbers represented as strings to the buffer as a packed
+ * 64-bit int field.
+ * @param {number} field
+ * @param {?Array.<string>} value
+ */
+jspb.BinaryWriter.prototype.writePackedInt64String =
+    function(field, value) {
+  if (value == null || !value.length) return;
+  var bookmark = this.beginDelimited_(field);
+  for (var i = 0; i < value.length; i++) {
+    var num = jspb.arith.Int64.fromString(value[i]);
+    this.rawWriteVarintFromNum(num);
+  }
+  this.endDelimited_(bookmark);
+};
+
+
+/**
+ * Writes an array numbers to the buffer as a packed unsigned 32-bit int field.
+ *
+ * If 'value' is null, this method will try and copy the pre-serialized value
+ * in 'opt_buffer' if present.
+ *
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
+ * @param {?number=} opt_start The starting point in the above buffer.
+ * @param {?number=} opt_end The ending point in the above buffer.
+ */
+jspb.BinaryWriter.prototype.writePackedUint32 =
+    jspb.BinaryWriter.prototype.writePackedUnsignedVarint32_;
+
+
+/**
+ * Writes an array of numbers represented as strings to the buffer as a packed
+ * unsigned 32-bit int field.
+ * @param {number} field
+ * @param {?Array.<string>} value
+ */
+jspb.BinaryWriter.prototype.writePackedUint32String =
+    function(field, value) {
+  if (value == null || !value.length) return;
+  var bookmark = this.beginDelimited_(field);
+  for (var i = 0; i < value.length; i++) {
+    this.rawWriteUnsignedVarint32(parseInt(value[i], 10));
+  }
+  this.endDelimited_(bookmark);
+};
+
+
+/**
+ * Writes an array numbers to the buffer as a packed unsigned 64-bit int field.
+ *
+ * If 'value' is null, this method will try and copy the pre-serialized value
+ * in 'opt_buffer' if present.
+ *
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
+ * @param {?number=} opt_start The starting point in the above buffer.
+ * @param {?number=} opt_end The ending point in the above buffer.
+ */
+jspb.BinaryWriter.prototype.writePackedUint64 =
+    jspb.BinaryWriter.prototype.writePackedVarint_;
+
+
+/**
+ * Writes an array of numbers represented as strings to the buffer as a packed
+ * unsigned 64-bit int field.
+ * @param {number} field
+ * @param {?Array.<string>} value
+ */
+jspb.BinaryWriter.prototype.writePackedUint64String =
+    function(field, value) {
+  if (value == null || !value.length) return;
+  var bookmark = this.beginDelimited_(field);
+  for (var i = 0; i < value.length; i++) {
+    var num = jspb.arith.UInt64.fromString(value[i]);
+    this.rawWriteVarintFromNum(num);
+  }
+  this.endDelimited_(bookmark);
+};
+
+
+/**
+ * Writes an array numbers to the buffer as a packed signed 32-bit int field.
+ *
+ * If 'value' is null, this method will try and copy the pre-serialized value
+ * in 'opt_buffer' if present.
+ *
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
+ * @param {?number=} opt_start The starting point in the above buffer.
+ * @param {?number=} opt_end The ending point in the above buffer.
+ */
+jspb.BinaryWriter.prototype.writePackedSint32 =
+    jspb.BinaryWriter.prototype.writePackedZigzag_;
+
+
+/**
+ * Writes an array numbers to the buffer as a packed signed 64-bit int field.
+ *
+ * If 'value' is null, this method will try and copy the pre-serialized value
+ * in 'opt_buffer' if present.
+ *
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
+ * @param {?number=} opt_start The starting point in the above buffer.
+ * @param {?number=} opt_end The ending point in the above buffer.
+ */
+jspb.BinaryWriter.prototype.writePackedSint64 =
+    jspb.BinaryWriter.prototype.writePackedZigzag_;
+
+
+/**
+ * Writes an array of numbers to the buffer as a packed fixed32 field.
+ *
+ * If 'value' is null, this method will try and copy the pre-serialized value
+ * in 'opt_buffer' if present.
+ *
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
+ * @param {?number=} opt_start The starting point in the above buffer.
+ * @param {?number=} opt_end The ending point in the above buffer.
+ */
+jspb.BinaryWriter.prototype.writePackedFixed32 =
+    function(field, value, opt_buffer, opt_start, opt_end) {
+  if (value != null && value.length) {
+    this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
+    this.rawWriteUnsignedVarint32(value.length * 4);
+    for (var i = 0; i < value.length; i++) {
+      this.rawWriteUint32(value[i]);
+    }
+  } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
+    this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+  }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a packed fixed64 field.
+ *
+ * If 'value' is null, this method will try and copy the pre-serialized value
+ * in 'opt_buffer' if present.
+ *
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
+ * @param {?number=} opt_start The starting point in the above buffer.
+ * @param {?number=} opt_end The ending point in the above buffer.
+ */
+jspb.BinaryWriter.prototype.writePackedFixed64 =
+    function(field, value, opt_buffer, opt_start, opt_end) {
+  if (value != null && value.length) {
+    this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
+    this.rawWriteUnsignedVarint32(value.length * 8);
+    for (var i = 0; i < value.length; i++) {
+      this.rawWriteUint64(value[i]);
+    }
+  } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
+    this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+  }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a packed sfixed32 field.
+ *
+ * If 'value' is null, this method will try and copy the pre-serialized value
+ * in 'opt_buffer' if present.
+ *
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
+ * @param {?number=} opt_start The starting point in the above buffer.
+ * @param {?number=} opt_end The ending point in the above buffer.
+ */
+jspb.BinaryWriter.prototype.writePackedSfixed32 =
+    function(field, value, opt_buffer, opt_start, opt_end) {
+  if (value != null && value.length) {
+    this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
+    this.rawWriteUnsignedVarint32(value.length * 4);
+    for (var i = 0; i < value.length; i++) {
+      this.rawWriteInt32(value[i]);
+    }
+  } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
+    this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+  }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a packed sfixed64 field.
+ *
+ * If 'value' is null, this method will try and copy the pre-serialized value
+ * in 'opt_buffer' if present.
+ *
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
+ * @param {?number=} opt_start The starting point in the above buffer.
+ * @param {?number=} opt_end The ending point in the above buffer.
+ */
+jspb.BinaryWriter.prototype.writePackedSfixed64 =
+    function(field, value, opt_buffer, opt_start, opt_end) {
+  if (value != null) {
+    this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
+    this.rawWriteUnsignedVarint32(value.length * 8);
+    for (var i = 0; i < value.length; i++) {
+      this.rawWriteInt64(value[i]);
+    }
+  } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
+    this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+  }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a packed float field.
+ *
+ * If 'value' is null, this method will try and copy the pre-serialized value
+ * in 'opt_buffer' if present.
+ *
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
+ * @param {?number=} opt_start The starting point in the above buffer.
+ * @param {?number=} opt_end The ending point in the above buffer.
+ */
+jspb.BinaryWriter.prototype.writePackedFloat =
+    function(field, value, opt_buffer, opt_start, opt_end) {
+  if (value != null && value.length) {
+    this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
+    this.rawWriteUnsignedVarint32(value.length * 4);
+    for (var i = 0; i < value.length; i++) {
+      this.rawWriteFloat(value[i]);
+    }
+  } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
+    this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+  }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a packed double field.
+ *
+ * If 'value' is null, this method will try and copy the pre-serialized value
+ * in 'opt_buffer' if present.
+ *
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
+ * @param {?number=} opt_start The starting point in the above buffer.
+ * @param {?number=} opt_end The ending point in the above buffer.
+ */
+jspb.BinaryWriter.prototype.writePackedDouble =
+    function(field, value, opt_buffer, opt_start, opt_end) {
+  if (value != null && value.length) {
+    this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
+    this.rawWriteUnsignedVarint32(value.length * 8);
+    for (var i = 0; i < value.length; i++) {
+      this.rawWriteDouble(value[i]);
+    }
+  } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
+    this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+  }
+};
+
+
+/**
+ * Writes an array of booleans to the buffer as a packed bool field.
+ *
+ * If 'value' is null, this method will try and copy the pre-serialized value
+ * in 'opt_buffer' if present.
+ *
+ * @param {number} field The field number.
+ * @param {?Array.<boolean>} value The array of ints to write.
+ * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
+ * @param {?number=} opt_start The starting point in the above buffer.
+ * @param {?number=} opt_end The ending point in the above buffer.
+ */
+jspb.BinaryWriter.prototype.writePackedBool =
+    function(field, value, opt_buffer, opt_start, opt_end) {
+  if (value != null && value.length) {
+    this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
+    this.rawWriteUnsignedVarint32(value.length);
+    for (var i = 0; i < value.length; i++) {
+      this.rawWriteBool(value[i]);
+    }
+  } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
+    this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+  }
+};
+
+
+/**
+ * Writes an array of enums to the buffer as a packed enum field.
+ *
+ * If 'value' is null, this method will try and copy the pre-serialized value
+ * in 'opt_buffer' if present.
+ *
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
+ * @param {?number=} opt_start The starting point in the above buffer.
+ * @param {?number=} opt_end The ending point in the above buffer.
+ */
+jspb.BinaryWriter.prototype.writePackedEnum =
+    function(field, value, opt_buffer, opt_start, opt_end) {
+  if (value != null && value.length) {
+    var bookmark = this.beginDelimited_(field);
+    for (var i = 0; i < value.length; i++) {
+      this.rawWriteEnum(value[i]);
+    }
+    this.endDelimited_(bookmark);
+  } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
+    this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+  }
+};
+
+
+/**
+ * Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to
+ * the buffer.
+ *
+ * If 'value' is null, this method will try and copy the pre-serialized value
+ * in 'opt_buffer' if present.
+ *
+ * @param {number} field The field number.
+ * @param {?Array.<string>} value The array of hashes to write.
+ * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
+ * @param {?number=} opt_start The starting point in the above buffer.
+ * @param {?number=} opt_end The ending point in the above buffer.
+ */
+jspb.BinaryWriter.prototype.writePackedFixedHash64 =
+    function(field, value, opt_buffer, opt_start, opt_end) {
+  if (value != null && value.length) {
+    this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
+    this.rawWriteUnsignedVarint32(value.length * 8);
+    for (var i = 0; i < value.length; i++) {
+      this.rawWriteFixedHash64(value[i]);
+    }
+  } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
+    this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+  }
+};
+
+
+/**
+ * Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to
+ * the buffer.
+ *
+ * If 'value' is null, this method will try and copy the pre-serialized value
+ * in 'opt_buffer' if present.
+ *
+ * @param {number} field The field number.
+ * @param {?Array.<string>} value The array of hashes to write.
+ * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
+ * @param {?number=} opt_start The starting point in the above buffer.
+ * @param {?number=} opt_end The ending point in the above buffer.
+ */
+jspb.BinaryWriter.prototype.writePackedVarintHash64 =
+    function(field, value, opt_buffer, opt_start, opt_end) {
+  if (value != null && value.length) {
+    var bookmark = this.beginDelimited_(field);
+    for (var i = 0; i < value.length; i++) {
+      this.rawWriteVarintHash64(value[i]);
+    }
+    this.endDelimited_(bookmark);
+  } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
+    this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+  }
+};
diff --git a/js/binary/writer_test.js b/js/binary/writer_test.js
new file mode 100644
index 0000000..54d37a2
--- /dev/null
+++ b/js/binary/writer_test.js
@@ -0,0 +1,123 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/**
+ * @fileoverview Test cases for jspb's binary protocol buffer writer. In
+ * practice BinaryWriter is used to drive the Decoder and Reader test cases,
+ * so only writer-specific tests are here.
+ *
+ * Test suite is written using Jasmine -- see http://jasmine.github.io/
+ *
+ * @author aappleby@google.com (Austin Appleby)
+ */
+
+goog.require('goog.crypt');
+goog.require('goog.testing.asserts');
+goog.require('jspb.BinaryWriter');
+
+
+/**
+ * @param {function()} func This function should throw an error when run.
+ */
+function assertFails(func) {
+  var e = assertThrows(func);
+  console.log(e);
+  //assertNotNull(e.toString().match(/Error/));
+}
+
+
+describe('binaryWriterTest', function() {
+  /**
+   * Verifies that misuse of the writer class triggers assertions.
+   */
+  it('testWriteErrors', function() {
+    // Submessages with invalid field indices should assert.
+    var writer = new jspb.BinaryWriter();
+    var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
+
+    assertFails(function() {
+      writer.writeMessage(-1, dummyMessage, goog.nullFunction);
+    });
+
+    // Writing invalid field indices should assert.
+    writer = new jspb.BinaryWriter();
+    assertFails(function() {writer.writeUint64(-1, 1);});
+
+    // Writing out-of-range field values should assert.
+    writer = new jspb.BinaryWriter();
+
+    assertFails(function() {writer.writeInt32(1, -Infinity);});
+    assertFails(function() {writer.writeInt32(1, Infinity);});
+
+    assertFails(function() {writer.writeInt64(1, -Infinity);});
+    assertFails(function() {writer.writeInt64(1, Infinity);});
+
+    assertFails(function() {writer.writeUint32(1, -1);});
+    assertFails(function() {writer.writeUint32(1, Infinity);});
+
+    assertFails(function() {writer.writeUint64(1, -1);});
+    assertFails(function() {writer.writeUint64(1, Infinity);});
+
+    assertFails(function() {writer.writeSint32(1, -Infinity);});
+    assertFails(function() {writer.writeSint32(1, Infinity);});
+
+    assertFails(function() {writer.writeSint64(1, -Infinity);});
+    assertFails(function() {writer.writeSint64(1, Infinity);});
+
+    assertFails(function() {writer.writeFixed32(1, -1);});
+    assertFails(function() {writer.writeFixed32(1, Infinity);});
+
+    assertFails(function() {writer.writeFixed64(1, -1);});
+    assertFails(function() {writer.writeFixed64(1, Infinity);});
+
+    assertFails(function() {writer.writeSfixed32(1, -Infinity);});
+    assertFails(function() {writer.writeSfixed32(1, Infinity);});
+
+    assertFails(function() {writer.writeSfixed64(1, -Infinity);});
+    assertFails(function() {writer.writeSfixed64(1, Infinity);});
+  });
+
+
+  /**
+   * Basic test of retrieving the result as a Uint8Array buffer
+   */
+  it('testGetResultBuffer', function() {
+    var expected = '0864120b48656c6c6f20776f726c641a0301020320c801';
+
+    var writer = new jspb.BinaryWriter();
+    writer.writeUint32(1, 100);
+    writer.writeString(2, 'Hello world');
+    writer.writeBytes(3, new Uint8Array([1, 2, 3]));
+    writer.writeUint32(4, 200);
+
+    var buffer = writer.getResultBuffer();
+    assertEquals(expected, goog.crypt.byteArrayToHex(buffer));
+  });
+});
diff --git a/js/data.proto b/js/data.proto
new file mode 100644
index 0000000..74a8a99
--- /dev/null
+++ b/js/data.proto
@@ -0,0 +1,51 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: mwr@google.com (Mark Rawling)
+
+syntax = "proto2";
+
+option java_package = "com.google.apps.jspb.proto";
+option java_multiple_files = true;
+
+package jspb.test;
+
+// legacy data, must be nested
+message data {
+  message NestedData {
+    required string str = 1;
+  }
+}
+
+// new data, does not require nesting
+message UnnestedData {
+  required string str = 1;
+}
+
diff --git a/js/debug.js b/js/debug.js
new file mode 100644
index 0000000..4838911
--- /dev/null
+++ b/js/debug.js
@@ -0,0 +1,140 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/**
+ * @fileoverview Utilities to debug JSPB based proto objects.
+ */
+
+goog.provide('jspb.debug');
+
+goog.require('goog.array');
+goog.require('goog.asserts');
+goog.require('goog.object');
+goog.require('jspb.Message');
+
+
+/**
+ * Turns a proto into a human readable object that can i.e. be written to the
+ * console: {@code console.log(jspb.debug.dump(myProto))}.
+ * This function makes a best effort and may not work in all cases. It will not
+ * work in obfuscated and or optimized code.
+ * Use this in environments where {@see jspb.Message.prototype.toObject} is
+ * not available for code size reasons.
+ * @param {jspb.Message} message A jspb.Message.
+ * @return {Object}
+ */
+jspb.debug.dump = function(message) {
+  if (!goog.DEBUG) {
+    return null;
+  }
+  goog.asserts.assert(message instanceof jspb.Message,
+      'jspb.Message instance expected');
+  /** @type {Object} */
+  var object = message;
+  goog.asserts.assert(object['getExtension'],
+      'Only unobfuscated and unoptimized compilation modes supported.');
+  return /** @type {Object} */ (jspb.debug.dump_(message));
+};
+
+
+/**
+ * Recursively introspects a message and the values its getters return to
+ * make a best effort in creating a human readable representation of the
+ * message.
+ * @param {*} thing A jspb.Message, Array or primitive type to dump.
+ * @return {*}
+ * @private
+ */
+jspb.debug.dump_ = function(thing) {
+  var type = goog.typeOf(thing);
+  if (type == 'number' || type == 'string' || type == 'boolean' ||
+      type == 'null' || type == 'undefined') {
+    return thing;
+  }
+  if (type == 'array') {
+    goog.asserts.assertArray(thing);
+    return goog.array.map(thing, jspb.debug.dump_);
+  }
+  var message = thing;  // Copy because we don't want type inference on thing.
+  goog.asserts.assert(message instanceof jspb.Message,
+      'Only messages expected: ' + thing);
+  var ctor = message.constructor;
+  var messageName = ctor.name || ctor.displayName;
+  var object = {
+    '$name': messageName
+  };
+  for (var name in ctor.prototype) {
+    var match = /^get([A-Z]\w*)/.exec(name);
+    if (match && name != 'getExtension' &&
+        name != 'getJsPbMessageId') {
+      var val = thing[name]();
+      if (val != null) {
+        object[jspb.debug.formatFieldName_(match[1])] = jspb.debug.dump_(val);
+      }
+    }
+  }
+  if (COMPILED && thing['extensionObject_']) {
+    object['$extensions'] = 'Recursive dumping of extensions not supported ' +
+        'in compiled code. Switch to uncompiled or dump extension object ' +
+        'directly';
+    return object;
+  }
+  var extensionsObject;
+  for (var id in ctor['extensions']) {
+    if (/^\d+$/.test(id)) {
+      var ext = ctor['extensions'][id];
+      var extVal = thing.getExtension(ext);
+      var fieldName = goog.object.getKeys(ext.fieldName)[0];
+      if (extVal != null) {
+        if (!extensionsObject) {
+          extensionsObject = object['$extensions'] = {};
+        }
+        extensionsObject[jspb.debug.formatFieldName_(fieldName)] =
+            jspb.debug.dump_(extVal);
+      }
+    }
+  }
+  return object;
+};
+
+
+/**
+ * Formats a field name for output as camelCase.
+ *
+ * @param {string} name Name of the field.
+ * @return {string}
+ * @private
+ */
+jspb.debug.formatFieldName_ = function(name) {
+  // Name may be in TitleCase.
+  return name.replace(/^[A-Z]/, function(c) {
+    return c.toLowerCase();
+  });
+};
diff --git a/js/debug_test.js b/js/debug_test.js
new file mode 100644
index 0000000..615fc7c
--- /dev/null
+++ b/js/debug_test.js
@@ -0,0 +1,101 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+goog.setTestOnly();
+
+goog.require('goog.testing.asserts');
+goog.require('jspb.debug');
+goog.require('proto.jspb.test.HasExtensions');
+goog.require('proto.jspb.test.IsExtension');
+goog.require('proto.jspb.test.Simple1');
+
+
+
+describe('debugTest', function() {
+  it('testSimple1', function() {
+    if (COMPILED) {
+      return;
+    }
+    var message = new proto.jspb.test.Simple1();
+    message.setAString('foo');
+    assertObjectEquals({
+      $name: 'proto.jspb.test.Simple1',
+      'aString': 'foo',
+      'aRepeatedStringList': []
+    }, jspb.debug.dump(message));
+
+    message.setABoolean(true);
+    message.setARepeatedStringList(['1', '2']);
+
+    assertObjectEquals({
+      $name: 'proto.jspb.test.Simple1',
+      'aString': 'foo',
+      'aRepeatedStringList': ['1', '2'],
+      'aBoolean': true
+    }, jspb.debug.dump(message));
+
+    message.setAString(undefined);
+
+    assertObjectEquals({
+      $name: 'proto.jspb.test.Simple1',
+      'aRepeatedStringList': ['1', '2'],
+      'aBoolean': true
+    }, jspb.debug.dump(message));
+  });
+
+
+  it('testExtensions', function() {
+    if (COMPILED) {
+      return;
+    }
+    var extension = new proto.jspb.test.IsExtension();
+    extension.setExt1('ext1field');
+    var extendable = new proto.jspb.test.HasExtensions();
+    extendable.setStr1('v1');
+    extendable.setStr2('v2');
+    extendable.setStr3('v3');
+    extendable.setExtension(proto.jspb.test.IsExtension.extField, extension);
+
+    assertObjectEquals({
+      '$name': 'proto.jspb.test.HasExtensions',
+      'str1': 'v1',
+      'str2': 'v2',
+      'str3': 'v3',
+      '$extensions': {
+        'extField': {
+          '$name': 'proto.jspb.test.IsExtension',
+          'ext1': 'ext1field'
+        },
+        'repeatedSimpleList': []
+      }
+    }, jspb.debug.dump(extendable));
+  });
+
+});
diff --git a/js/gulpfile.js b/js/gulpfile.js
new file mode 100644
index 0000000..79095d6
--- /dev/null
+++ b/js/gulpfile.js
@@ -0,0 +1,29 @@
+var gulp = require('gulp');
+var exec = require('child_process').exec;
+
+gulp.task('genproto', function (cb) {
+  exec('../src/protoc --js_out=library=testproto_libs,binary:. -I ../src -I . *.proto ../src/google/protobuf/descriptor.proto',
+       function (err, stdout, stderr) {
+    console.log(stdout);
+    console.log(stderr);
+    cb(err);
+  });
+})
+
+gulp.task('deps', ['genproto'], function (cb) {
+  exec('./node_modules/google-closure-library/closure/bin/build/depswriter.py *.js binary/*.js > deps.js',
+       function (err, stdout, stderr) {
+    console.log(stdout);
+    console.log(stderr);
+    cb(err);
+  });
+})
+
+gulp.task('test', ['genproto', 'deps'], function (cb) {
+  exec('JASMINE_CONFIG_PATH=jasmine.json ./node_modules/.bin/jasmine',
+       function (err, stdout, stderr) {
+    console.log(stdout);
+    console.log(stderr);
+    cb(err);
+  });
+});
diff --git a/js/jasmine.json b/js/jasmine.json
new file mode 100644
index 0000000..f83c54c
--- /dev/null
+++ b/js/jasmine.json
@@ -0,0 +1,12 @@
+{
+    "spec_dir": "",
+    "spec_files": [
+        "*_test.js",
+        "binary/*_test.js"
+    ],
+    "helpers": [
+        "node_modules/google-closure-library/closure/goog/bootstrap/nodejs.js",
+        "node_loader.js",
+        "deps.js"
+    ]
+}
diff --git a/js/message.js b/js/message.js
new file mode 100644
index 0000000..cef9aef
--- /dev/null
+++ b/js/message.js
@@ -0,0 +1,1125 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/**
+ * @fileoverview Definition of jspb.Message.
+ *
+ * @author mwr@google.com (Mark Rawling)
+ */
+
+goog.provide('jspb.ExtensionFieldInfo');
+goog.provide('jspb.Message');
+
+goog.require('goog.array');
+goog.require('goog.asserts');
+goog.require('goog.json');
+goog.require('goog.object');
+
+// Not needed in compilation units that have no protos with xids.
+goog.forwardDeclare('xid.String');
+
+
+
+/**
+ * Stores information for a single extension field.
+ *
+ * For example, an extension field defined like so:
+ *
+ *     extend BaseMessage {
+ *       optional MyMessage my_field = 123;
+ *     }
+ *
+ * will result in an ExtensionFieldInfo object with these properties:
+ *
+ *     {
+ *       fieldIndex: 123,
+ *       fieldName: {my_field_renamed: 0},
+ *       ctor: proto.example.MyMessage,
+ *       toObjectFn: proto.example.MyMessage.toObject,
+ *       isRepeated: 0
+ *     }
+ *
+ * We include `toObjectFn` to allow the JSCompiler to perform dead-code removal
+ * on unused toObject() methods.
+ *
+ * If an extension field is primitive, ctor and toObjectFn will be null.
+ * isRepeated should be 0 or 1.
+ *
+ * binary{Reader,Writer}Fn and (if message type) binaryMessageSerializeFn are
+ * always provided. binaryReaderFn and binaryWriterFn are references to the
+ * appropriate methods on BinaryReader/BinaryWriter to read/write the value of
+ * this extension, and binaryMessageSerializeFn is a reference to the message
+ * class's .serializeBinary method, if available.
+ *
+ * @param {number} fieldNumber
+ * @param {Object} fieldName This has the extension field name as a property.
+ * @param {?function(new: jspb.Message, Array=)} ctor
+ * @param {?function((boolean|undefined),!jspb.Message):!Object} toObjectFn
+ * @param {number} isRepeated
+ * @param {?function(number,?)=} opt_binaryReaderFn
+ * @param {?function(number,?)|function(number,?,?,?,?,?)=} opt_binaryWriterFn
+ * @param {?function(?,?)=} opt_binaryMessageSerializeFn
+ * @param {?function(?,?)=} opt_binaryMessageDeserializeFn
+ * @param {?boolean=} opt_isPacked
+ * @constructor
+ * @struct
+ * @template T
+ */
+jspb.ExtensionFieldInfo = function(fieldNumber, fieldName, ctor, toObjectFn,
+    isRepeated, opt_binaryReaderFn, opt_binaryWriterFn,
+    opt_binaryMessageSerializeFn, opt_binaryMessageDeserializeFn,
+    opt_isPacked) {
+  /** @const */
+  this.fieldIndex = fieldNumber;
+  /** @const */
+  this.fieldName = fieldName;
+  /** @const */
+  this.ctor = ctor;
+  /** @const */
+  this.toObjectFn = toObjectFn;
+  /** @const */
+  this.binaryReaderFn = opt_binaryReaderFn;
+  /** @const */
+  this.binaryWriterFn = opt_binaryWriterFn;
+  /** @const */
+  this.binaryMessageSerializeFn = opt_binaryMessageSerializeFn;
+  /** @const */
+  this.binaryMessageDeserializeFn = opt_binaryMessageDeserializeFn;
+  /** @const */
+  this.isRepeated = isRepeated;
+  /** @const */
+  this.isPacked = opt_isPacked;
+};
+
+
+/**
+ * Base class for all JsPb messages.
+ * @constructor
+ * @struct
+ */
+jspb.Message = function() {
+};
+
+
+/**
+ * @define {boolean} Whether to generate toObject methods for objects. Turn
+ *     this off, if you do not want toObject to be ever used in your project.
+ *     When turning off this flag, consider adding a conformance test that bans
+ *     calling toObject. Enabling this will disable the JSCompiler's ability to
+ *     dead code eliminate fields used in protocol buffers that are never used
+ *     in an application.
+ */
+goog.define('jspb.Message.GENERATE_TO_OBJECT', true);
+
+
+/**
+ * @define {boolean} Whether to generate fromObject methods for objects. Turn
+ *     this off, if you do not want fromObject to be ever used in your project.
+ *     When turning off this flag, consider adding a conformance test that bans
+ *     calling fromObject. Enabling this might disable the JSCompiler's ability
+ *     to dead code eliminate fields used in protocol buffers that are never
+ *     used in an application.
+ *     NOTE: By default no protos actually have a fromObject method. You need to
+ *     add the jspb.generate_from_object options to the proto definition to
+ *     activate the feature.
+ *     By default this is enabled for test code only.
+ */
+goog.define('jspb.Message.GENERATE_FROM_OBJECT', !goog.DISALLOW_TEST_ONLY_CODE);
+
+
+/**
+ * @define {boolean} Turning on this flag does NOT change the behavior of JSPB
+ *     and only affects private internal state. It may, however, break some
+ *     tests that use naive deeply-equals algorithms, because using a proto
+ *     mutates its internal state.
+ *     Projects are advised to turn this flag always on.
+ */
+goog.define('jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS', COMPILED);
+// TODO(b/19419436) Turn this on by default.
+
+
+/**
+ * The internal data array.
+ * @type {!Array}
+ * @protected
+ */
+jspb.Message.prototype.array;
+
+
+/**
+ * Wrappers are the constructed instances of message-type fields. They are built
+ * on demand from the raw array data. Includes message fields, repeated message
+ * fields and extension message fields. Indexed by field number.
+ * @type {Object}
+ * @private
+ */
+jspb.Message.prototype.wrappers_;
+
+
+/**
+ * The object that contains extension fields, if any. This is an object that
+ * maps from a proto field number to the field's value.
+ * @type {Object}
+ * @private
+ */
+jspb.Message.prototype.extensionObject_;
+
+
+/**
+ * Non-extension fields with a field number at or above the pivot are
+ * stored in the extension object (in addition to all extension fields).
+ * @type {number}
+ * @private
+ */
+jspb.Message.prototype.pivot_;
+
+
+/**
+ * The JsPb message_id of this proto.
+ * @type {string|undefined} the message id or undefined if this message
+ *     has no id.
+ * @private
+ */
+jspb.Message.prototype.messageId_;
+
+
+/**
+ * The xid of this proto type (The same for all instances of a proto). Provides
+ * a way to identify a proto by stable obfuscated name.
+ * @see {xid}.
+ * Available if {@link jspb.generate_xid} is added as a Message option to
+ * a protocol buffer.
+ * @const {!xid.String|undefined} The xid or undefined if message is
+ *     annotated to generate the xid.
+ */
+jspb.Message.prototype.messageXid;
+
+
+
+/**
+ * Returns the JsPb message_id of this proto.
+ * @return {string|undefined} the message id or undefined if this message
+ *     has no id.
+ */
+jspb.Message.prototype.getJsPbMessageId = function() {
+  return this.messageId_;
+};
+
+
+/**
+ * An offset applied to lookups into this.array to account for the presence or
+ * absence of a messageId at position 0. For response messages, this will be 0.
+ * Otherwise, it will be -1 so that the first array position is not wasted.
+ * @type {number}
+ * @private
+ */
+jspb.Message.prototype.arrayIndexOffset_;
+
+
+/**
+ * Returns the index into msg.array at which the proto field with tag number
+ * fieldNumber will be located.
+ * @param {!jspb.Message} msg Message for which we're calculating an index.
+ * @param {number} fieldNumber The field number.
+ * @return {number} The index.
+ * @private
+ */
+jspb.Message.getIndex_ = function(msg, fieldNumber) {
+  return fieldNumber + msg.arrayIndexOffset_;
+};
+
+
+/**
+ * Initializes a JsPb Message.
+ * @param {!jspb.Message} msg The JsPb proto to modify.
+ * @param {Array|undefined} data An initial data array.
+ * @param {string|number} messageId For response messages, the message id or ''
+ *     if no message id is specified. For non-response messages, 0.
+ * @param {number} suggestedPivot The field number at which to start putting
+ *     fields into the extension object. This is only used if data does not
+ *     contain an extension object already. -1 if no extension object is
+ *     required for this message type.
+ * @param {Array<number>} repeatedFields The message's repeated fields.
+ * @param {Array<!Array<number>>=} opt_oneofFields The fields belonging to
+ *     each of the message's oneof unions.
+ * @protected
+ */
+jspb.Message.initialize = function(
+    msg, data, messageId, suggestedPivot, repeatedFields, opt_oneofFields) {
+  msg.wrappers_ = jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS ? null : {};
+  if (!data) {
+    data = messageId ? [messageId] : [];
+  }
+  msg.messageId_ = messageId ? String(messageId) : undefined;
+  // If the messageId is 0, this message is not a response message, so we shift
+  // array indices down by 1 so as not to waste the first position in the array,
+  // which would otherwise go unused.
+  msg.arrayIndexOffset_ = messageId === 0 ? -1 : 0;
+  msg.array = data;
+  jspb.Message.materializeExtensionObject_(msg, suggestedPivot);
+  if (repeatedFields) {
+    for (var i = 0; i < repeatedFields.length; i++) {
+      var fieldNumber = repeatedFields[i];
+      if (fieldNumber < msg.pivot_) {
+        var index = jspb.Message.getIndex_(msg, fieldNumber);
+        msg.array[index] = msg.array[index] ||
+            (jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS ?
+                jspb.Message.EMPTY_LIST_SENTINEL_ :
+                []);
+      } else {
+        msg.extensionObject_[fieldNumber] =
+            msg.extensionObject_[fieldNumber] ||
+            (jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS ?
+                jspb.Message.EMPTY_LIST_SENTINEL_ :
+                []);
+      }
+    }
+  }
+
+  if (opt_oneofFields && opt_oneofFields.length) {
+    // Compute the oneof case for each union. This ensures only one value is
+    // set in the union.
+    goog.array.forEach(
+        opt_oneofFields, goog.partial(jspb.Message.computeOneofCase, msg));
+  }
+};
+
+
+/**
+ * Used to mark empty repeated fields. Serializes to null when serialized
+ * to JSON.
+ * When reading a repeated field readers must check the return value against
+ * this value and return and replace it with a new empty array if it is
+ * present.
+ * @private @const {!Object}
+ */
+jspb.Message.EMPTY_LIST_SENTINEL_ = goog.DEBUG && Object.freeze ?
+    Object.freeze([]) :
+    [];
+
+
+/**
+ * Ensures that the array contains an extension object if necessary.
+ * If the array contains an extension object in its last position, then the
+ * object is kept in place and its position is used as the pivot.  If not, then
+ * create an extension object using suggestedPivot.  If suggestedPivot is -1,
+ * we don't have an extension object at all, in which case all fields are stored
+ * in the array.
+ * @param {!jspb.Message} msg The JsPb proto to modify.
+ * @param {number} suggestedPivot See description for initialize().
+ * @private
+ */
+jspb.Message.materializeExtensionObject_ = function(msg, suggestedPivot) {
+  if (msg.array.length) {
+    var foundIndex = msg.array.length - 1;
+    var obj = msg.array[foundIndex];
+    // Normal fields are never objects, so we can be sure that if we find an
+    // object here, then it's the extension object. However, we must ensure that
+    // the object is not an array, since arrays are valid field values.
+    // NOTE(lukestebbing): We avoid looking at .length to avoid a JIT bug
+    // in Safari on iOS 8. See the description of CL/86511464 for details.
+    if (obj && typeof obj == 'object' && !goog.isArray(obj)) {
+      msg.pivot_ = foundIndex - msg.arrayIndexOffset_;
+      msg.extensionObject_ = obj;
+      return;
+    }
+  }
+  // This complexity exists because we keep all extension fields in the
+  // extensionObject_ regardless of proto field number. Changing this would
+  // simplify the code here, but it would require changing the serialization
+  // format from the server, which is not backwards compatible.
+  // TODO(jshneier): Should we just treat extension fields the same as
+  // non-extension fields, and select whether they appear in the object or in
+  // the array purely based on tag number? This would allow simplifying all the
+  // get/setExtension logic, but it would require the breaking change described
+  // above.
+  if (suggestedPivot > -1) {
+    msg.pivot_ = suggestedPivot;
+    var pivotIndex = jspb.Message.getIndex_(msg, suggestedPivot);
+    if (!jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS) {
+      msg.extensionObject_ = msg.array[pivotIndex] = {};
+    } else {
+      // Initialize to null to avoid changing the shape of the proto when it
+      // gets eventually set.
+      msg.extensionObject_ = null;
+    }
+  } else {
+    msg.pivot_ = Number.MAX_VALUE;
+  }
+};
+
+
+/**
+ * Creates an empty extensionObject_ if non exists.
+ * @param {!jspb.Message} msg The JsPb proto to modify.
+ * @private
+ */
+jspb.Message.maybeInitEmptyExtensionObject_ = function(msg) {
+  var pivotIndex = jspb.Message.getIndex_(msg, msg.pivot_);
+  if (!msg.array[pivotIndex]) {
+    msg.extensionObject_ = msg.array[pivotIndex] = {};
+  }
+};
+
+
+/**
+ * Converts a JsPb repeated message field into an object list.
+ * @param {!Array<T>} field The repeated message field to be
+ *     converted.
+ * @param {?function(boolean=): Object|
+ *     function((boolean|undefined),T): Object} toObjectFn The toObject
+ *     function for this field.  We need to pass this for effective dead code
+ *     removal.
+ * @param {boolean=} opt_includeInstance Whether to include the JSPB instance
+ *     for transitional soy proto support: http://goto/soy-param-migration
+ * @return {!Array<Object>} An array of converted message objects.
+ * @template T
+ */
+jspb.Message.toObjectList = function(field, toObjectFn, opt_includeInstance) {
+  // Not using goog.array.map in the generated code to keep it small.
+  // And not using it here to avoid a function call.
+  var result = [];
+  for (var i = 0; i < field.length; i++) {
+    result[i] = toObjectFn.call(field[i], opt_includeInstance,
+      /** @type {!jspb.Message} */ (field[i]));
+  }
+  return result;
+};
+
+
+/**
+ * Adds a proto's extension data to a Soy rendering object.
+ * @param {!jspb.Message} proto The proto whose extensions to convert.
+ * @param {!Object} obj The Soy object to add converted extension data to.
+ * @param {!Object} extensions The proto class' registered extensions.
+ * @param {function(jspb.ExtensionFieldInfo) : *} getExtensionFn The proto
+ *     class' getExtension function. Passed for effective dead code removal.
+ * @param {boolean=} opt_includeInstance Whether to include the JSPB instance
+ *     for transitional soy proto support: http://goto/soy-param-migration
+ */
+jspb.Message.toObjectExtension = function(proto, obj, extensions,
+    getExtensionFn, opt_includeInstance) {
+  for (var fieldNumber in extensions) {
+    var fieldInfo = extensions[fieldNumber];
+    var value = getExtensionFn.call(proto, fieldInfo);
+    if (value) {
+      for (var name in fieldInfo.fieldName) {
+        if (fieldInfo.fieldName.hasOwnProperty(name)) {
+          break; // the compiled field name
+        }
+      }
+      if (!fieldInfo.toObjectFn) {
+        obj[name] = value;
+      } else {
+        if (fieldInfo.isRepeated) {
+          obj[name] = jspb.Message.toObjectList(
+              /** @type {!Array<jspb.Message>} */ (value),
+              fieldInfo.toObjectFn, opt_includeInstance);
+        } else {
+          obj[name] = fieldInfo.toObjectFn(opt_includeInstance, value);
+        }
+      }
+    }
+  }
+};
+
+
+/**
+ * Writes a proto's extension data to a binary-format output stream.
+ * @param {!jspb.Message} proto The proto whose extensions to convert.
+ * @param {*} writer The binary-format writer to write to.
+ * @param {!Object} extensions The proto class' registered extensions.
+ * @param {function(jspb.ExtensionFieldInfo) : *} getExtensionFn The proto
+ *     class' getExtension function. Passed for effective dead code removal.
+ */
+jspb.Message.serializeBinaryExtensions = function(proto, writer, extensions,
+    getExtensionFn) {
+  for (var fieldNumber in extensions) {
+    var fieldInfo = extensions[fieldNumber];
+    // The old codegen doesn't add the extra fields to ExtensionFieldInfo, so we
+    // need to gracefully error-out here rather than produce a null dereference
+    // below.
+    if (!fieldInfo.binaryWriterFn) {
+      throw new Error('Message extension present that was generated ' +
+                      'without binary serialization support');
+    }
+    var value = getExtensionFn.call(proto, fieldInfo);
+    if (value) {
+      if (fieldInfo.ctor) {  // is this a message type?
+        // If the message type of the extension was generated without binary
+        // support, there may not be a binary message serializer function, and
+        // we can't know when we codegen the extending message that the extended
+        // message may require binary support, so we can *only* catch this error
+        // here, at runtime (and this decoupled codegen is the whole point of
+        // extensions!).
+        if (fieldInfo.binaryMessageSerializeFn) {
+          fieldInfo.binaryWriterFn.call(writer, fieldInfo.fieldIndex,
+              value, fieldInfo.binaryMessageSerializeFn);
+        } else {
+          throw new Error('Message extension present holding submessage ' +
+                          'without binary support enabled, and message is ' +
+                          'being serialized to binary format');
+        }
+      } else {
+        fieldInfo.binaryWriterFn.call(writer, fieldInfo.fieldIndex, value);
+      }
+    }
+  }
+};
+
+
+/**
+ * Reads an extension field from the given reader and, if a valid extension,
+ * sets the extension value.
+ * @param {!jspb.Message} msg A jspb proto.
+ * @param {{skipField:function(),getFieldNumber:function():number}} reader
+ * @param {!Object} extensions The extensions object.
+ * @param {function(jspb.ExtensionFieldInfo)} getExtensionFn
+ * @param {function(jspb.ExtensionFieldInfo, ?)} setExtensionFn
+ */
+jspb.Message.readBinaryExtension = function(msg, reader, extensions,
+    getExtensionFn, setExtensionFn) {
+  var fieldInfo = extensions[reader.getFieldNumber()];
+  if (!fieldInfo) {
+    reader.skipField();
+    return;
+  }
+  if (!fieldInfo.binaryReaderFn) {
+    throw new Error('Deserializing extension whose generated code does not ' +
+                    'support binary format');
+  }
+
+  var value;
+  if (fieldInfo.ctor) {
+    // Message type.
+    value = new fieldInfo.ctor();
+    fieldInfo.binaryReaderFn.call(
+        reader, value, fieldInfo.binaryMessageDeserializeFn);
+  } else {
+    // All other types.
+    value = fieldInfo.binaryReaderFn.call(reader);
+  }
+
+  if (fieldInfo.isRepeated && !fieldInfo.isPacked) {
+    var currentList = getExtensionFn.call(msg, fieldInfo);
+    if (!currentList) {
+      setExtensionFn.call(msg, fieldInfo, [value]);
+    } else {
+      currentList.push(value);
+    }
+  } else {
+    setExtensionFn.call(msg, fieldInfo, value);
+  }
+};
+
+
+/**
+ * Gets the value of a non-extension field.
+ * @param {!jspb.Message} msg A jspb proto.
+ * @param {number} fieldNumber The field number.
+ * @return {string|number|boolean|Uint8Array|Array|null|undefined}
+ * The field's value.
+ * @protected
+ */
+jspb.Message.getField = function(msg, fieldNumber) {
+  if (fieldNumber < msg.pivot_) {
+    var index = jspb.Message.getIndex_(msg, fieldNumber);
+    var val = msg.array[index];
+    if (val === jspb.Message.EMPTY_LIST_SENTINEL_) {
+      return msg.array[index] = [];
+    }
+    return val;
+  } else {
+    var val = msg.extensionObject_[fieldNumber];
+    if (val === jspb.Message.EMPTY_LIST_SENTINEL_) {
+      return msg.extensionObject_[fieldNumber] = [];
+    }
+    return val;
+  }
+};
+
+
+/**
+ * Gets the value of a non-extension primitive field, with proto3 (non-nullable
+ * primitives) semantics. Returns `defaultValue` if the field is not otherwise
+ * set.
+ * @template T
+ * @param {!jspb.Message} msg A jspb proto.
+ * @param {number} fieldNumber The field number.
+ * @param {T} defaultValue The default value.
+ * @return {T} The field's value.
+ * @protected
+ */
+jspb.Message.getFieldProto3 = function(msg, fieldNumber, defaultValue) {
+  var value = jspb.Message.getField(msg, fieldNumber);
+  if (value == null) {
+    return defaultValue;
+  } else {
+    return value;
+  }
+};
+
+
+/**
+ * Sets the value of a non-extension field.
+ * @param {!jspb.Message} msg A jspb proto.
+ * @param {number} fieldNumber The field number.
+ * @param {string|number|boolean|Uint8Array|Array|undefined} value New value
+ * @protected
+ */
+jspb.Message.setField = function(msg, fieldNumber, value) {
+  if (fieldNumber < msg.pivot_) {
+    msg.array[jspb.Message.getIndex_(msg, fieldNumber)] = value;
+  } else {
+    msg.extensionObject_[fieldNumber] = value;
+  }
+};
+
+
+/**
+ * Sets the value of a field in a oneof union and clears all other fields in
+ * the union.
+ * @param {!jspb.Message} msg A jspb proto.
+ * @param {number} fieldNumber The field number.
+ * @param {!Array<number>} oneof The fields belonging to the union.
+ * @param {string|number|boolean|Uint8Array|Array|undefined} value New value
+ * @protected
+ */
+jspb.Message.setOneofField = function(msg, fieldNumber, oneof, value) {
+  var currentCase = jspb.Message.computeOneofCase(msg, oneof);
+  if (currentCase && currentCase !== fieldNumber && value !== undefined) {
+    if (msg.wrappers_ && currentCase in msg.wrappers_) {
+      msg.wrappers_[currentCase] = undefined;
+    }
+    jspb.Message.setField(msg, currentCase, undefined);
+  }
+  jspb.Message.setField(msg, fieldNumber, value);
+};
+
+
+/**
+ * Computes the selection in a oneof group for the given message, ensuring
+ * only one field is set in the process.
+ *
+ * According to the protobuf language guide (
+ * https://developers.google.com/protocol-buffers/docs/proto#oneof), "if the
+ * parser encounters multiple members of the same oneof on the wire, only the
+ * last member seen is used in the parsed message." Since JSPB serializes
+ * messages to a JSON array, the "last member seen" will always be the field
+ * with the greatest field number (directly corresponding to the greatest
+ * array index).
+ *
+ * @param {!jspb.Message} msg A jspb proto.
+ * @param {!Array<number>} oneof The field numbers belonging to the union.
+ * @return {number} The field number currently set in the union, or 0 if none.
+ * @protected
+ */
+jspb.Message.computeOneofCase = function(msg, oneof) {
+  var oneofField;
+  var oneofValue;
+
+  goog.array.forEach(oneof, function(fieldNumber) {
+    var value = jspb.Message.getField(msg, fieldNumber);
+    if (goog.isDefAndNotNull(value)) {
+      oneofField = fieldNumber;
+      oneofValue = value;
+      jspb.Message.setField(msg, fieldNumber, undefined);
+    }
+  });
+
+  if (oneofField) {
+    // NB: We know the value is unique, so we can call jspb.Message.setField
+    // directly instead of jpsb.Message.setOneofField. Also, setOneofField
+    // calls this function.
+    jspb.Message.setField(msg, oneofField, oneofValue);
+    return oneofField;
+  }
+
+  return 0;
+};
+
+
+/**
+ * Gets and wraps a proto field on access.
+ * @param {!jspb.Message} msg A jspb proto.
+ * @param {function(new:jspb.Message, Array)} ctor Constructor for the field.
+ * @param {number} fieldNumber The field number.
+ * @param {number=} opt_required True (1) if this is a required field.
+ * @return {jspb.Message} The field as a jspb proto.
+ * @protected
+ */
+jspb.Message.getWrapperField = function(msg, ctor, fieldNumber, opt_required) {
+  // TODO(mwr): Consider copying data and/or arrays.
+  if (!msg.wrappers_) {
+    msg.wrappers_ = {};
+  }
+  if (!msg.wrappers_[fieldNumber]) {
+    var data = /** @type {Array} */ (jspb.Message.getField(msg, fieldNumber));
+    if (opt_required || data) {
+      // TODO(mwr): Remove existence test for always valid default protos.
+      msg.wrappers_[fieldNumber] = new ctor(data);
+    }
+  }
+  return /** @type {jspb.Message} */ (msg.wrappers_[fieldNumber]);
+};
+
+
+/**
+ * Gets and wraps a repeated proto field on access.
+ * @param {!jspb.Message} msg A jspb proto.
+ * @param {function(new:jspb.Message, Array)} ctor Constructor for the field.
+ * @param {number} fieldNumber The field number.
+ * @return {Array<!jspb.Message>} The repeated field as an array of protos.
+ * @protected
+ */
+jspb.Message.getRepeatedWrapperField = function(msg, ctor, fieldNumber) {
+  if (!msg.wrappers_) {
+    msg.wrappers_ = {};
+  }
+  if (!msg.wrappers_[fieldNumber]) {
+    var data = jspb.Message.getField(msg, fieldNumber);
+    for (var wrappers = [], i = 0; i < data.length; i++) {
+      wrappers[i] = new ctor(data[i]);
+    }
+    msg.wrappers_[fieldNumber] = wrappers;
+  }
+  var val = msg.wrappers_[fieldNumber];
+  if (val == jspb.Message.EMPTY_LIST_SENTINEL_) {
+    val = msg.wrappers_[fieldNumber] = [];
+  }
+  return /** @type {Array<!jspb.Message>} */ (val);
+};
+
+
+/**
+ * Sets a proto field and syncs it to the backing array.
+ * @param {!jspb.Message} msg A jspb proto.
+ * @param {number} fieldNumber The field number.
+ * @param {jspb.Message|undefined} value A new value for this proto field.
+ * @protected
+ */
+jspb.Message.setWrapperField = function(msg, fieldNumber, value) {
+  if (!msg.wrappers_) {
+    msg.wrappers_ = {};
+  }
+  var data = value ? value.toArray() : value;
+  msg.wrappers_[fieldNumber] = value;
+  jspb.Message.setField(msg, fieldNumber, data);
+};
+
+
+/**
+ * Sets a proto field in a oneof union and syncs it to the backing array.
+ * @param {!jspb.Message} msg A jspb proto.
+ * @param {number} fieldNumber The field number.
+ * @param {!Array<number>} oneof The fields belonging to the union.
+ * @param {jspb.Message|undefined} value A new value for this proto field.
+ * @protected
+ */
+jspb.Message.setOneofWrapperField = function(msg, fieldNumber, oneof, value) {
+  if (!msg.wrappers_) {
+    msg.wrappers_ = {};
+  }
+  var data = value ? value.toArray() : value;
+  msg.wrappers_[fieldNumber] = value;
+  jspb.Message.setOneofField(msg, fieldNumber, oneof, data);
+};
+
+
+/**
+ * Sets a repeated proto field and syncs it to the backing array.
+ * @param {!jspb.Message} msg A jspb proto.
+ * @param {number} fieldNumber The field number.
+ * @param {Array<!jspb.Message>|undefined} value An array of protos.
+ * @protected
+ */
+jspb.Message.setRepeatedWrapperField = function(msg, fieldNumber, value) {
+  if (!msg.wrappers_) {
+    msg.wrappers_ = {};
+  }
+  value = value || [];
+  for (var data = [], i = 0; i < value.length; i++) {
+    data[i] = value[i].toArray();
+  }
+  msg.wrappers_[fieldNumber] = value;
+  jspb.Message.setField(msg, fieldNumber, data);
+};
+
+
+/**
+ * Converts a JsPb repeated message field into a map. The map will contain
+ * protos unless an optional toObject function is given, in which case it will
+ * contain objects suitable for Soy rendering.
+ * @param {!Array<T>} field The repeated message field to be
+ *     converted.
+ * @param {function() : string?} mapKeyGetterFn The function to get the key of
+ *     the map.
+ * @param {?function(boolean=): Object|
+ *     function((boolean|undefined),T): Object} opt_toObjectFn The
+ *     toObject function for this field. We need to pass this for effective
+ *     dead code removal.
+ * @param {boolean=} opt_includeInstance Whether to include the JSPB instance
+ *     for transitional soy proto support: http://goto/soy-param-migration
+ * @return {!Object.<string, Object>} A map of proto or Soy objects.
+ * @template T
+ */
+jspb.Message.toMap = function(
+    field, mapKeyGetterFn, opt_toObjectFn, opt_includeInstance) {
+  var result = {};
+  for (var i = 0; i < field.length; i++) {
+    result[mapKeyGetterFn.call(field[i])] = opt_toObjectFn ?
+        opt_toObjectFn.call(field[i], opt_includeInstance,
+            /** @type {!jspb.Message} */ (field[i])) : field[i];
+  }
+  return result;
+};
+
+
+/**
+ * Returns the internal array of this proto.
+ * <p>Note: If you use this array to construct a second proto, the content
+ * would then be partially shared between the two protos.
+ * @return {!Array} The proto represented as an array.
+ */
+jspb.Message.prototype.toArray = function() {
+  return this.array;
+};
+
+
+
+
+/**
+ * Creates a string representation of the internal data array of this proto.
+ * <p>NOTE: This string is *not* suitable for use in server requests.
+ * @return {string} A string representation of this proto.
+ * @override
+ */
+jspb.Message.prototype.toString = function() {
+  return this.array.toString();
+};
+
+
+/**
+ * Gets the value of the extension field from the extended object.
+ * @param {jspb.ExtensionFieldInfo.<T>} fieldInfo Specifies the field to get.
+ * @return {T} The value of the field.
+ * @template T
+ */
+jspb.Message.prototype.getExtension = function(fieldInfo) {
+  if (!this.extensionObject_) {
+    return undefined;
+  }
+  if (!this.wrappers_) {
+    this.wrappers_ = {};
+  }
+  var fieldNumber = fieldInfo.fieldIndex;
+  if (fieldInfo.isRepeated) {
+    if (fieldInfo.ctor) {
+      if (!this.wrappers_[fieldNumber]) {
+        this.wrappers_[fieldNumber] =
+            goog.array.map(this.extensionObject_[fieldNumber] || [],
+                function(arr) {
+                  return new fieldInfo.ctor(arr);
+                });
+      }
+      return this.wrappers_[fieldNumber];
+    } else {
+      return this.extensionObject_[fieldNumber];
+    }
+  } else {
+    if (fieldInfo.ctor) {
+      if (!this.wrappers_[fieldNumber] && this.extensionObject_[fieldNumber]) {
+        this.wrappers_[fieldNumber] = new fieldInfo.ctor(
+            /** @type {Array|undefined} */ (
+                this.extensionObject_[fieldNumber]));
+      }
+      return this.wrappers_[fieldNumber];
+    } else {
+      return this.extensionObject_[fieldNumber];
+    }
+  }
+};
+
+
+/**
+ * Sets the value of the extension field in the extended object.
+ * @param {jspb.ExtensionFieldInfo} fieldInfo Specifies the field to set.
+ * @param {jspb.Message|string|number|boolean|Array} value The value to set.
+ */
+jspb.Message.prototype.setExtension = function(fieldInfo, value) {
+  if (!this.wrappers_) {
+    this.wrappers_ = {};
+  }
+  jspb.Message.maybeInitEmptyExtensionObject_(this);
+  var fieldNumber = fieldInfo.fieldIndex;
+  if (fieldInfo.isRepeated) {
+    value = value || [];
+    if (fieldInfo.ctor) {
+      this.wrappers_[fieldNumber] = value;
+      this.extensionObject_[fieldNumber] = goog.array.map(
+          /** @type {Array<jspb.Message>} */ (value), function(msg) {
+        return msg.toArray();
+      });
+    } else {
+      this.extensionObject_[fieldNumber] = value;
+    }
+  } else {
+    if (fieldInfo.ctor) {
+      this.wrappers_[fieldNumber] = value;
+      this.extensionObject_[fieldNumber] = value ? value.toArray() : value;
+    } else {
+      this.extensionObject_[fieldNumber] = value;
+    }
+  }
+};
+
+
+/**
+ * Creates a difference object between two messages.
+ *
+ * The result will contain the top-level fields of m2 that differ from those of
+ * m1 at any level of nesting. No data is cloned, the result object will
+ * share its top-level elements with m2 (but not with m1).
+ *
+ * Note that repeated fields should not have null/undefined elements, but if
+ * they do, this operation will treat repeated fields of different length as
+ * the same if the only difference between them is due to trailing
+ * null/undefined values.
+ *
+ * @param {!jspb.Message} m1 The first message object.
+ * @param {!jspb.Message} m2 The second message object.
+ * @return {!jspb.Message} The difference returned as a proto message.
+ *     Note that the returned message may be missing required fields. This is
+ *     currently tolerated in Js, but would cause an error if you tried to
+ *     send such a proto to the server. You can access the raw difference
+ *     array with result.toArray().
+ * @throws {Error} If the messages are responses with different types.
+ */
+jspb.Message.difference = function(m1, m2) {
+  if (!(m1 instanceof m2.constructor)) {
+    throw new Error('Messages have different types.');
+  }
+  var arr1 = m1.toArray();
+  var arr2 = m2.toArray();
+  var res = [];
+  var start = 0;
+  var length = arr1.length > arr2.length ? arr1.length : arr2.length;
+  if (m1.getJsPbMessageId()) {
+    res[0] = m1.getJsPbMessageId();
+    start = 1;
+  }
+  for (var i = start; i < length; i++) {
+    if (!jspb.Message.compareFields(arr1[i], arr2[i])) {
+      res[i] = arr2[i];
+    }
+  }
+  return new m1.constructor(res);
+};
+
+
+/**
+ * Tests whether two messages are equal.
+ * @param {jspb.Message|undefined} m1 The first message object.
+ * @param {jspb.Message|undefined} m2 The second message object.
+ * @return {boolean} true if both messages are null/undefined, or if both are
+ *     of the same type and have the same field values.
+ */
+jspb.Message.equals = function(m1, m2) {
+  return m1 == m2 || (!!(m1 && m2) && (m1 instanceof m2.constructor) &&
+      jspb.Message.compareFields(m1.toArray(), m2.toArray()));
+};
+
+
+/**
+ * Compares two message fields recursively.
+ * @param {*} field1 The first field.
+ * @param {*} field2 The second field.
+ * @return {boolean} true if the fields are null/undefined, or otherwise equal.
+ */
+jspb.Message.compareFields = function(field1, field2) {
+  if (goog.isObject(field1) && goog.isObject(field2)) {
+    var keys = {}, name, extensionObject1, extensionObject2;
+    for (name in field1) {
+      field1.hasOwnProperty(name) && (keys[name] = 0);
+    }
+    for (name in field2) {
+      field2.hasOwnProperty(name) && (keys[name] = 0);
+    }
+    for (name in keys) {
+      var val1 = field1[name], val2 = field2[name];
+      if (goog.isObject(val1) && !goog.isArray(val1)) {
+        if (extensionObject1 !== undefined) {
+          throw new Error('invalid jspb state');
+        }
+        extensionObject1 = goog.object.isEmpty(val1) ? undefined : val1;
+        val1 = undefined;
+      }
+      if (goog.isObject(val2) && !goog.isArray(val2)) {
+        if (extensionObject2 !== undefined) {
+          throw new Error('invalid jspb state');
+        }
+        extensionObject2 = goog.object.isEmpty(val2) ? undefined : val2;
+        val2 = undefined;
+      }
+      if (!jspb.Message.compareFields(val1, val2)) {
+        return false;
+      }
+    }
+    if (extensionObject1 || extensionObject2) {
+      return jspb.Message.compareFields(extensionObject1, extensionObject2);
+    }
+    return true;
+  }
+  // Primitive fields, null and undefined compare as equal.
+  // This also forces booleans and 0/1 to compare as equal to ensure
+  // compatibility with the jspb serializer.
+  return field1 == field2;
+};
+
+
+/**
+ * Static clone function. NOTE: A type-safe method called "cloneMessage" exists
+ * on each generated JsPb class. Do not call this function directly.
+ * @param {!jspb.Message} msg A message to clone.
+ * @return {!jspb.Message} A deep clone of the given message.
+ */
+jspb.Message.clone = function(msg) {
+  // Although we could include the wrappers, we leave them out here.
+  return jspb.Message.cloneMessage(msg);
+};
+
+
+/**
+ * @param {!jspb.Message} msg A message to clone.
+ * @return {!jspb.Message} A deep clone of the given message.
+ * @protected
+ */
+jspb.Message.cloneMessage = function(msg) {
+  // Although we could include the wrappers, we leave them out here.
+  return new msg.constructor(jspb.Message.clone_(msg.toArray()));
+};
+
+
+/**
+ * Takes 2 messages of the same type and copies the contents of the first
+ * message into the second. After this the 2 messages will equals in terms of
+ * value semantics but share no state. All data in the destination message will
+ * be overridden.
+ *
+ * @param {MESSAGE} fromMessage Message that will be copied into toMessage.
+ * @param {MESSAGE} toMessage Message which will receive a copy of fromMessage
+ *     as its contents.
+ * @template MESSAGE
+ */
+jspb.Message.copyInto = function(fromMessage, toMessage) {
+  goog.asserts.assertInstanceof(fromMessage, jspb.Message);
+  goog.asserts.assertInstanceof(toMessage, jspb.Message);
+  goog.asserts.assert(fromMessage.constructor == toMessage.constructor,
+      'Copy source and target message should have the same type.');
+  var copyOfFrom = jspb.Message.clone(fromMessage);
+
+  var to = toMessage.toArray();
+  var from = copyOfFrom.toArray();
+
+  // Empty destination in case it has more values at the end of the array.
+  to.length = 0;
+  // and then copy everything from the new to the existing message.
+  for (var i = 0; i < from.length; i++) {
+    to[i] = from[i];
+  }
+
+  // This is either null or empty for a fresh copy.
+  toMessage.wrappers_ = copyOfFrom.wrappers_;
+  // Just a reference into the shared array.
+  toMessage.extensionObject_ = copyOfFrom.extensionObject_;
+};
+
+
+/**
+ * Helper for cloning an internal JsPb object.
+ * @param {!Object} obj A JsPb object, eg, a field, to be cloned.
+ * @return {!Object} A clone of the input object.
+ * @private
+ */
+jspb.Message.clone_ = function(obj) {
+  var o;
+  if (goog.isArray(obj)) {
+    // Allocate array of correct size.
+    var clonedArray = new Array(obj.length);
+    // Use array iteration where possible because it is faster than for-in.
+    for (var i = 0; i < obj.length; i++) {
+      if ((o = obj[i]) != null) {
+        clonedArray[i] = typeof o == 'object' ? jspb.Message.clone_(o) : o;
+      }
+    }
+    return clonedArray;
+  }
+  var clone = {};
+  for (var key in obj) {
+    if ((o = obj[key]) != null) {
+      clone[key] = typeof o == 'object' ? jspb.Message.clone_(o) : o;
+    }
+  }
+  return clone;
+};
+
+
+/**
+ * Registers a JsPb message type id with its constructor.
+ * @param {string} id The id for this type of message.
+ * @param {Function} constructor The message constructor.
+ */
+jspb.Message.registerMessageType = function(id, constructor) {
+  jspb.Message.registry_[id] = constructor;
+  // This is needed so we can later access messageId directly on the contructor,
+  // otherwise it is not available due to 'property collapsing' by the compiler.
+  constructor.messageId = id;
+};
+
+
+/**
+ * The registry of message ids to message constructors.
+ * @private
+ */
+jspb.Message.registry_ = {};
+
+
+/**
+ * The extensions registered on MessageSet. This is a map of extension
+ * field number to field info object. This should be considered as a
+ * private API.
+ *
+ * This is similar to [jspb class name].extensions object for
+ * non-MessageSet. We special case MessageSet so that we do not need
+ * to goog.require MessageSet from classes that extends MessageSet.
+ *
+ * @type {!Object.<number, jspb.ExtensionFieldInfo>}
+ */
+jspb.Message.messageSetExtensions = {};
diff --git a/js/message_test.js b/js/message_test.js
new file mode 100644
index 0000000..971ea4f
--- /dev/null
+++ b/js/message_test.js
@@ -0,0 +1,974 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Test suite is written using Jasmine -- see http://jasmine.github.io/
+
+goog.setTestOnly();
+
+goog.require('goog.json');
+goog.require('goog.testing.asserts');
+goog.require('jspb.Message');
+goog.require('proto.jspb.exttest.beta.floatingStrField');
+goog.require('proto.jspb.exttest.floatingMsgField');
+goog.require('proto.jspb.exttest.floatingMsgFieldTwo');
+goog.require('proto.jspb.test.CloneExtension');
+goog.require('proto.jspb.test.Complex');
+goog.require('proto.jspb.test.DefaultValues');
+goog.require('proto.jspb.test.Empty');
+goog.require('proto.jspb.test.EnumContainer');
+goog.require('proto.jspb.test.ExtensionMessage');
+goog.require('proto.jspb.test.floatingMsgField');
+goog.require('proto.jspb.test.floatingStrField');
+goog.require('proto.jspb.test.HasExtensions');
+goog.require('proto.jspb.test.IndirectExtension');
+goog.require('proto.jspb.test.IsExtension');
+goog.require('proto.jspb.test.OptionalFields');
+goog.require('proto.jspb.test.OuterEnum');
+goog.require('proto.jspb.test.simple1');
+goog.require('proto.jspb.test.Simple1');
+goog.require('proto.jspb.test.Simple2');
+goog.require('proto.jspb.test.SpecialCases');
+goog.require('proto.jspb.test.TestClone');
+goog.require('proto.jspb.test.TestExtensionsMessage');
+goog.require('proto.jspb.test.TestGroup');
+goog.require('proto.jspb.test.TestGroup1');
+goog.require('proto.jspb.test.TestMessageWithOneof');
+goog.require('proto.jspb.test.TestReservedNames');
+goog.require('proto.jspb.test.TestReservedNamesExtension');
+
+
+
+
+describe('Message test suite', function() {
+  it('testEmptyProto', function() {
+    var empty1 = new proto.jspb.test.Empty([]);
+    var empty2 = new proto.jspb.test.Empty([]);
+    assertObjectEquals({}, empty1.toObject());
+    assertObjectEquals('Message should not be corrupted:', empty2, empty1);
+  });
+
+  it('testTopLevelEnum', function() {
+    var response = new proto.jspb.test.EnumContainer([]);
+    response.setOuterEnum(proto.jspb.test.OuterEnum.FOO);
+    assertEquals(proto.jspb.test.OuterEnum.FOO, response.getOuterEnum());
+  });
+
+  it('testByteStrings', function() {
+    var data = new proto.jspb.test.DefaultValues([]);
+    data.setBytesField('some_bytes');
+    assertEquals('some_bytes', data.getBytesField());
+  });
+
+  it('testComplexConversion', function() {
+    var data1 = ['a',,, [, 11], [[, 22], [, 33]],, ['s1', 's2'],, 1];
+    var data2 = ['a',,, [, 11], [[, 22], [, 33]],, ['s1', 's2'],, 1];
+    var foo = new proto.jspb.test.Complex(data1);
+    var bar = new proto.jspb.test.Complex(data2);
+    var result = foo.toObject();
+    assertObjectEquals({
+      aString: 'a',
+      anOutOfOrderBool: 1,
+      aNestedMessage: {
+        anInt: 11
+      },
+      aRepeatedMessageList: [{anInt: 22}, {anInt: 33}],
+      aRepeatedStringList: ['s1', 's2']
+    }, result);
+
+    // Now test with the jspb instances included.
+    result = foo.toObject(true /* opt_includeInstance */);
+    assertObjectEquals({
+      aString: 'a',
+      anOutOfOrderBool: 1,
+      aNestedMessage: {
+        anInt: 11,
+        $jspbMessageInstance: foo.getANestedMessage()
+      },
+      aRepeatedMessageList: [
+        {anInt: 22, $jspbMessageInstance: foo.getARepeatedMessageList()[0]},
+        {anInt: 33, $jspbMessageInstance: foo.getARepeatedMessageList()[1]}
+      ],
+      aRepeatedStringList: ['s1', 's2'],
+      $jspbMessageInstance: foo
+    }, result);
+
+  });
+
+  it('testMissingFields', function() {
+    var foo = new proto.jspb.test.Complex([
+        undefined, undefined, undefined, [],
+        undefined, undefined, undefined, undefined]);
+    var bar = new proto.jspb.test.Complex([
+        undefined, undefined, undefined, [],
+        undefined, undefined, undefined, undefined]);
+    var result = foo.toObject();
+    assertObjectEquals({
+      aString: undefined,
+      anOutOfOrderBool: undefined,
+      aNestedMessage: {
+        anInt: undefined
+      },
+      // Note: JsPb converts undefined repeated fields to empty arrays.
+      aRepeatedMessageList: [],
+      aRepeatedStringList: []
+    }, result);
+
+  });
+
+  it('testSpecialCases', function() {
+    // Note: Some property names are reserved in JavaScript.
+    // These names are converted to the Js property named pb_<reserved_name>.
+    var special =
+        new proto.jspb.test.SpecialCases(['normal', 'default', 'function',
+        'var']);
+    var result = special.toObject();
+    assertObjectEquals({
+      normal: 'normal',
+      pb_default: 'default',
+      pb_function: 'function',
+      pb_var: 'var'
+    }, result);
+  });
+
+  it('testDefaultValues', function() {
+    var defaultString = "default<>\'\"abc";
+    var response = new proto.jspb.test.DefaultValues();
+
+    // Test toObject
+    var expectedObject = {
+      stringField: defaultString,
+      boolField: true,
+      intField: 11,
+      enumField: 13,
+      emptyField: '',
+      bytesField: 'bW9v'
+    };
+    assertObjectEquals(expectedObject, response.toObject());
+
+
+    // Test getters
+    response = new proto.jspb.test.DefaultValues();
+    assertEquals(defaultString, response.getStringField());
+    assertEquals(true, response.getBoolField());
+    assertEquals(11, response.getIntField());
+    assertEquals(13, response.getEnumField());
+    assertEquals('', response.getEmptyField());
+    assertEquals('bW9v', response.getBytesField());
+
+    function makeDefault(values) {
+      return new proto.jspb.test.DefaultValues(values);
+    }
+
+    // Test with undefined values,
+    // Use push to workaround IE treating undefined array elements as holes.
+    response = makeDefault([undefined, undefined, undefined, undefined]);
+    assertEquals(defaultString, response.getStringField());
+    assertEquals(true, response.getBoolField());
+    assertEquals(11, response.getIntField());
+    assertEquals(13, response.getEnumField());
+
+    // Test with null values, as would be returned by a JSON serializer.
+    response = makeDefault([null, null, null, null]);
+    assertEquals(defaultString, response.getStringField());
+    assertEquals(true, response.getBoolField());
+    assertEquals(11, response.getIntField());
+    assertEquals(13, response.getEnumField());
+
+    // Test with false-like values.
+    response = makeDefault(['', false, 0, 0]);
+    assertEquals('', response.getStringField());
+    assertEquals(false, response.getBoolField());
+    assertEquals(true, response.getIntField() == 0);
+    assertEquals(true, response.getEnumField() == 0);
+
+    // Test that clearing the values reverts them to the default state.
+    response = makeDefault(['blah', false, 111, 77]);
+    response.clearStringField(); response.clearBoolField();
+    response.clearIntField(); response.clearEnumField();
+    assertEquals(defaultString, response.getStringField());
+    assertEquals(true, response.getBoolField());
+    assertEquals(11, response.getIntField());
+    assertEquals(13, response.getEnumField());
+
+    // Test that setFoo(null) clears the values.
+    response = makeDefault(['blah', false, 111, 77]);
+    response.setStringField(null); response.setBoolField(null);
+    response.setIntField(undefined); response.setEnumField(undefined);
+    assertEquals(defaultString, response.getStringField());
+    assertEquals(true, response.getBoolField());
+    assertEquals(11, response.getIntField());
+    assertEquals(13, response.getEnumField());
+  });
+
+  it('testMessageRegistration', function() {
+    // goog.require(SomeResponse) will include its library, which will in
+    // turn add SomeResponse to the message registry.
+    assertEquals(jspb.Message.registry_['res'], proto.jspb.test.SomeResponse);
+  });
+
+  it('testClearFields', function() {
+    // We don't set 'proper' defaults, rather, bools, strings,
+    // etc, are cleared to undefined or null and take on the Javascript
+    // meaning for that value. Repeated fields are set to [] when cleared.
+    var data = ['str', true, [11], [[22], [33]], ['s1', 's2']];
+    var foo = new proto.jspb.test.OptionalFields(data);
+    foo.clearAString();
+    foo.clearABool();
+    foo.clearANestedMessage();
+    foo.clearARepeatedMessageList();
+    foo.clearARepeatedStringList();
+    assertUndefined(foo.getAString());
+    assertUndefined(foo.getABool());
+    assertUndefined(foo.getANestedMessage());
+    assertObjectEquals([], foo.getARepeatedMessageList());
+    assertObjectEquals([], foo.getARepeatedStringList());
+    // NOTE: We want the missing fields in 'expected' to be undefined,
+    // but we actually get a sparse array instead. We could use something
+    // like [1,undefined,2] to avoid this, except that this is still
+    // sparse on IE. No comment...
+    var expected = [,,, [], []];
+    expected[0] = expected[1] = expected[2] = undefined;
+    assertObjectEquals(expected, foo.toArray());
+
+    // Test set(null). We could deprecated this in favor of clear(), but
+    // it's also convenient to have.
+    data = ['str', true, [11], [[22], [33]], ['s1', 's2']];
+    foo = new proto.jspb.test.OptionalFields(data);
+    foo.setAString(null);
+    foo.setABool(null);
+    foo.setANestedMessage(null);
+    foo.setARepeatedMessageList(null);
+    foo.setARepeatedStringList(null);
+    assertNull(foo.getAString());
+    assertNull(foo.getABool());
+    assertNull(foo.getANestedMessage());
+    assertObjectEquals([], foo.getARepeatedMessageList());
+    assertObjectEquals([], foo.getARepeatedStringList());
+    assertObjectEquals([null, null, null, [], []], foo.toArray());
+
+    // Test set(undefined). Again, not something we really need, and not
+    // supported directly by our typing, but it should 'do the right thing'.
+    data = ['str', true, [11], [[22], [33]], ['s1', 's2']];
+    foo = new proto.jspb.test.OptionalFields(data);
+    foo.setAString(undefined);
+    foo.setABool(undefined);
+    foo.setANestedMessage(undefined);
+    foo.setARepeatedMessageList(undefined);
+    foo.setARepeatedStringList(undefined);
+    assertUndefined(foo.getAString());
+    assertUndefined(foo.getABool());
+    assertUndefined(foo.getANestedMessage());
+    assertObjectEquals([], foo.getARepeatedMessageList());
+    assertObjectEquals([], foo.getARepeatedStringList());
+    expected = [,,, [], []];
+    expected[0] = expected[1] = expected[2] = undefined;
+    assertObjectEquals(expected, foo.toArray());
+  });
+
+  it('testDifferenceRawObject', function() {
+    var p1 = new proto.jspb.test.HasExtensions(['hi', 'diff', {}]);
+    var p2 = new proto.jspb.test.HasExtensions(['hi', 'what',
+                                               {1000: 'unique'}]);
+    var diff = /** @type {proto.jspb.test.HasExtensions} */
+        (jspb.Message.difference(p1, p2));
+    assertUndefined(diff.getStr1());
+    assertEquals('what', diff.getStr2());
+    assertUndefined(diff.getStr3());
+    assertEquals('unique', diff.extensionObject_[1000]);
+  });
+
+  it('testEqualsSimple', function() {
+    var s1 = new proto.jspb.test.Simple1(['hi']);
+    assertTrue(jspb.Message.equals(s1, new proto.jspb.test.Simple1(['hi'])));
+    assertFalse(jspb.Message.equals(s1, new proto.jspb.test.Simple1(['bye'])));
+    var s1b = new proto.jspb.test.Simple1(['hi', ['hello']]);
+    assertTrue(jspb.Message.equals(s1b,
+        new proto.jspb.test.Simple1(['hi', ['hello']])));
+    assertTrue(jspb.Message.equals(s1b,
+        new proto.jspb.test.Simple1(['hi', ['hello', undefined,
+                                            undefined, undefined]])));
+    assertFalse(jspb.Message.equals(s1b,
+        new proto.jspb.test.Simple1(['no', ['hello']])));
+    // Test with messages of different types
+    var s2 = new proto.jspb.test.Simple2(['hi']);
+    assertFalse(jspb.Message.equals(s1, s2));
+  });
+
+  it('testEquals_softComparison', function() {
+    var s1 = new proto.jspb.test.Simple1(['hi', [], null]);
+    assertTrue(jspb.Message.equals(s1,
+        new proto.jspb.test.Simple1(['hi', []])));
+
+    var s1b = new proto.jspb.test.Simple1(['hi', [], true]);
+    assertTrue(jspb.Message.equals(s1b,
+        new proto.jspb.test.Simple1(['hi', [], 1])));
+  });
+
+  it('testEqualsComplex', function() {
+    var data1 = ['a',,, [, 11], [[, 22], [, 33]],, ['s1', 's2'],, 1];
+    var data2 = ['a',,, [, 11], [[, 22], [, 34]],, ['s1', 's2'],, 1];
+    var data3 = ['a',,, [, 11], [[, 22]],, ['s1', 's2'],, 1];
+    var data4 = ['hi'];
+    var c1a = new proto.jspb.test.Complex(data1);
+    var c1b = new proto.jspb.test.Complex(data1);
+    var c2 = new proto.jspb.test.Complex(data2);
+    var c3 = new proto.jspb.test.Complex(data3);
+    var s1 = new proto.jspb.test.Simple1(data4);
+
+    assertTrue(jspb.Message.equals(c1a, c1b));
+    assertFalse(jspb.Message.equals(c1a, c2));
+    assertFalse(jspb.Message.equals(c2, c3));
+    assertFalse(jspb.Message.equals(c1a, s1));
+  });
+
+  it('testEqualsExtensionsConstructed', function() {
+    assertTrue(jspb.Message.equals(
+        new proto.jspb.test.HasExtensions([]),
+        new proto.jspb.test.HasExtensions([{}])
+    ));
+    assertTrue(jspb.Message.equals(
+        new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]),
+        new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}])
+    ));
+    assertFalse(jspb.Message.equals(
+        new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]),
+        new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'b'}]}])
+    ));
+    assertTrue(jspb.Message.equals(
+        new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}]),
+        new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}])
+    ));
+    assertTrue(jspb.Message.equals(
+        new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}]),
+        new proto.jspb.test.HasExtensions([,,, {100: [{200: 'a'}]}])
+    ));
+    assertTrue(jspb.Message.equals(
+        new proto.jspb.test.HasExtensions([,,, {100: [{200: 'a'}]}]),
+        new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}])
+    ));
+    assertTrue(jspb.Message.equals(
+        new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]),
+        new proto.jspb.test.HasExtensions(['hi',,, {100: [{200: 'a'}]}])
+    ));
+    assertTrue(jspb.Message.equals(
+        new proto.jspb.test.HasExtensions(['hi',,, {100: [{200: 'a'}]}]),
+        new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}])
+    ));
+  });
+
+  it('testEqualsExtensionsUnconstructed', function() {
+    assertTrue(jspb.Message.compareFields([], [{}]));
+    assertTrue(jspb.Message.compareFields([,,, {}], []));
+    assertTrue(jspb.Message.compareFields([,,, {}], [,, {}]));
+    assertTrue(jspb.Message.compareFields(
+        ['hi', {100: [{200: 'a'}]}], ['hi', {100: [{200: 'a'}]}]));
+    assertFalse(jspb.Message.compareFields(
+        ['hi', {100: [{200: 'a'}]}], ['hi', {100: [{200: 'b'}]}]));
+    assertTrue(jspb.Message.compareFields(
+        [{100: [{200: 'a'}]}], [{100: [{200: 'a'}]}]));
+    assertTrue(jspb.Message.compareFields(
+        [{100: [{200: 'a'}]}], [,,, {100: [{200: 'a'}]}]));
+    assertTrue(jspb.Message.compareFields(
+        [,,, {100: [{200: 'a'}]}], [{100: [{200: 'a'}]}]));
+    assertTrue(jspb.Message.compareFields(
+        ['hi', {100: [{200: 'a'}]}], ['hi',,, {100: [{200: 'a'}]}]));
+    assertTrue(jspb.Message.compareFields(
+        ['hi',,, {100: [{200: 'a'}]}], ['hi', {100: [{200: 'a'}]}]));
+  });
+
+  it('testToMap', function() {
+    var p1 = new proto.jspb.test.Simple1(['k', ['v']]);
+    var p2 = new proto.jspb.test.Simple1(['k1', ['v1', 'v2']]);
+    var soymap = jspb.Message.toMap([p1, p2],
+        proto.jspb.test.Simple1.prototype.getAString,
+        proto.jspb.test.Simple1.prototype.toObject);
+    assertEquals('k', soymap['k'].aString);
+    assertArrayEquals(['v'], soymap['k'].aRepeatedStringList);
+    var protomap = jspb.Message.toMap([p1, p2],
+        proto.jspb.test.Simple1.prototype.getAString);
+    assertEquals('k', protomap['k'].getAString());
+    assertArrayEquals(['v'], protomap['k'].getARepeatedStringList());
+  });
+
+  it('testClone', function() {
+    var original = new proto.jspb.test.TestClone();
+    original.setStr('v1');
+    var simple1 = new proto.jspb.test.Simple1(['x1', ['y1', 'z1']]);
+    var simple2 = new proto.jspb.test.Simple1(['x2', ['y2', 'z2']]);
+    var simple3 = new proto.jspb.test.Simple1(['x3', ['y3', 'z3']]);
+    original.setSimple1(simple1);
+    original.setSimple2List([simple2, simple3]);
+    var extension = new proto.jspb.test.CloneExtension();
+    extension.setExt('e1');
+    original.setExtension(proto.jspb.test.IsExtension.extField, extension);
+    var clone = original.cloneMessage();
+    assertArrayEquals(['v1',, ['x1', ['y1', 'z1']],,
+      [['x2', ['y2', 'z2']], ['x3', ['y3', 'z3']]],,, { 100: [, 'e1'] }],
+        clone.toArray());
+    clone.setStr('v2');
+    var simple4 = new proto.jspb.test.Simple1(['a1', ['b1', 'c1']]);
+    var simple5 = new proto.jspb.test.Simple1(['a2', ['b2', 'c2']]);
+    var simple6 = new proto.jspb.test.Simple1(['a3', ['b3', 'c3']]);
+    clone.setSimple1(simple4);
+    clone.setSimple2List([simple5, simple6]);
+    var newExtension = new proto.jspb.test.CloneExtension();
+    newExtension.setExt('e2');
+    clone.setExtension(proto.jspb.test.CloneExtension.extField, newExtension);
+    assertArrayEquals(['v2',, ['a1', ['b1', 'c1']],,
+      [['a2', ['b2', 'c2']], ['a3', ['b3', 'c3']]],,, { 100: [, 'e2'] }],
+        clone.toArray());
+    assertArrayEquals(['v1',, ['x1', ['y1', 'z1']],,
+      [['x2', ['y2', 'z2']], ['x3', ['y3', 'z3']]],,, { 100: [, 'e1'] }],
+        original.toArray());
+  });
+
+  it('testCopyInto', function() {
+    var original = new proto.jspb.test.TestClone();
+    original.setStr('v1');
+    var dest = new proto.jspb.test.TestClone();
+    dest.setStr('override');
+    var simple1 = new proto.jspb.test.Simple1(['x1', ['y1', 'z1']]);
+    var simple2 = new proto.jspb.test.Simple1(['x2', ['y2', 'z2']]);
+    var simple3 = new proto.jspb.test.Simple1(['x3', ['y3', 'z3']]);
+    var destSimple1 = new proto.jspb.test.Simple1(['ox1', ['oy1', 'oz1']]);
+    var destSimple2 = new proto.jspb.test.Simple1(['ox2', ['oy2', 'oz2']]);
+    var destSimple3 = new proto.jspb.test.Simple1(['ox3', ['oy3', 'oz3']]);
+    original.setSimple1(simple1);
+    original.setSimple2List([simple2, simple3]);
+    dest.setSimple1(destSimple1);
+    dest.setSimple2List([destSimple2, destSimple3]);
+    var extension = new proto.jspb.test.CloneExtension();
+    extension.setExt('e1');
+    original.setExtension(proto.jspb.test.CloneExtension.extField, extension);
+
+    jspb.Message.copyInto(original, dest);
+    assertArrayEquals(original.toArray(), dest.toArray());
+    assertEquals('x1', dest.getSimple1().getAString());
+    assertEquals('e1',
+        dest.getExtension(proto.jspb.test.CloneExtension.extField).getExt());
+    dest.getSimple1().setAString('new value');
+    assertNotEquals(dest.getSimple1().getAString(),
+        original.getSimple1().getAString());
+    dest.getExtension(proto.jspb.test.CloneExtension.extField).
+        setExt('new value');
+    assertNotEquals(
+        dest.getExtension(proto.jspb.test.CloneExtension.extField).getExt(),
+        original.getExtension(
+            proto.jspb.test.CloneExtension.extField).getExt());
+  });
+
+  it('testCopyInto_notSameType', function() {
+    var a = new proto.jspb.test.TestClone();
+    var b = new proto.jspb.test.Simple1(['str', ['s1', 's2']]);
+
+    var e = assertThrows(function() {
+      jspb.Message.copyInto(a, b);
+    });
+    assertContains('should have the same type', e.message);
+  });
+
+  it('testExtensions', function() {
+    var extension1 = new proto.jspb.test.IsExtension(['ext1field']);
+    var extension2 = new proto.jspb.test.Simple1(['str', ['s1', 's2']]);
+    var extendable = new proto.jspb.test.HasExtensions(['v1', 'v2', 'v3']);
+    extendable.setExtension(proto.jspb.test.IsExtension.extField, extension1);
+    extendable.setExtension(proto.jspb.test.IndirectExtension.simple,
+                            extension2);
+    extendable.setExtension(proto.jspb.test.IndirectExtension.str, 'xyzzy');
+    extendable.setExtension(proto.jspb.test.IndirectExtension.repeatedStrList,
+        ['a', 'b']);
+    var s1 = new proto.jspb.test.Simple1(['foo', ['s1', 's2']]);
+    var s2 = new proto.jspb.test.Simple1(['bar', ['t1', 't2']]);
+    extendable.setExtension(
+        proto.jspb.test.IndirectExtension.repeatedSimpleList,
+        [s1, s2]);
+    assertObjectEquals(extension1,
+        extendable.getExtension(proto.jspb.test.IsExtension.extField));
+    assertObjectEquals(extension2,
+        extendable.getExtension(proto.jspb.test.IndirectExtension.simple));
+    assertObjectEquals('xyzzy',
+        extendable.getExtension(proto.jspb.test.IndirectExtension.str));
+    assertObjectEquals(['a', 'b'], extendable.getExtension(
+        proto.jspb.test.IndirectExtension.repeatedStrList));
+    assertObjectEquals([s1, s2], extendable.getExtension(
+        proto.jspb.test.IndirectExtension.repeatedSimpleList));
+    // Not supported yet, but it should work...
+    extendable.setExtension(proto.jspb.test.IndirectExtension.simple, null);
+    assertNull(
+        extendable.getExtension(proto.jspb.test.IndirectExtension.simple));
+    extendable.setExtension(proto.jspb.test.IndirectExtension.str, null);
+    assertNull(extendable.getExtension(proto.jspb.test.IndirectExtension.str));
+
+    // These assertions will only work properly in uncompiled mode.
+    // Extension fields defined on proto2 Descriptor messages are filtered out.
+
+    // TODO(haberman): codegen changes to properly ignore descriptor.proto
+    // extensions need to be merged from google3.
+    // assertUndefined(proto.jspb.test.IsExtension['simpleOption']);
+
+    // Extension fields with jspb.ignore = true are ignored.
+    assertUndefined(proto.jspb.test.IndirectExtension['ignored']);
+    assertUndefined(proto.jspb.test.HasExtensions['ignoredFloating']);
+  });
+
+  it('testFloatingExtensions', function() {
+    // From an autogenerated container.
+    var extendable = new proto.jspb.test.HasExtensions(['v1', 'v2', 'v3']);
+    var extension = new proto.jspb.test.Simple1(['foo', ['s1', 's2']]);
+    extendable.setExtension(proto.jspb.test.simple1, extension);
+    assertObjectEquals(extension,
+        extendable.getExtension(proto.jspb.test.simple1));
+
+    // From _lib mode.
+    extension = new proto.jspb.test.ExtensionMessage(['s1']);
+    extendable = new proto.jspb.test.TestExtensionsMessage([16]);
+    extendable.setExtension(proto.jspb.test.floatingMsgField, extension);
+    extendable.setExtension(proto.jspb.test.floatingStrField, 's2');
+    assertObjectEquals(extension,
+        extendable.getExtension(proto.jspb.test.floatingMsgField));
+    assertObjectEquals('s2',
+        extendable.getExtension(proto.jspb.test.floatingStrField));
+    assertNotUndefined(proto.jspb.exttest.floatingMsgField);
+    assertNotUndefined(proto.jspb.exttest.floatingMsgFieldTwo);
+    assertNotUndefined(proto.jspb.exttest.beta.floatingStrField);
+  });
+
+  it('testToObject_extendedObject', function() {
+    var extension1 = new proto.jspb.test.IsExtension(['ext1field']);
+    var extension2 = new proto.jspb.test.Simple1(['str', ['s1', 's2'], true]);
+    var extendable = new proto.jspb.test.HasExtensions(['v1', 'v2', 'v3']);
+    extendable.setExtension(proto.jspb.test.IsExtension.extField, extension1);
+    extendable.setExtension(proto.jspb.test.IndirectExtension.simple,
+                            extension2);
+    extendable.setExtension(proto.jspb.test.IndirectExtension.str, 'xyzzy');
+    extendable.setExtension(proto.jspb.test.IndirectExtension.repeatedStrList,
+        ['a', 'b']);
+    var s1 = new proto.jspb.test.Simple1(['foo', ['s1', 's2'], true]);
+    var s2 = new proto.jspb.test.Simple1(['bar', ['t1', 't2'], false]);
+    extendable.setExtension(
+        proto.jspb.test.IndirectExtension.repeatedSimpleList,
+        [s1, s2]);
+    assertObjectEquals({
+      str1: 'v1', str2: 'v2', str3: 'v3',
+      extField: { ext1: 'ext1field' },
+      simple: {
+        aString: 'str', aRepeatedStringList: ['s1', 's2'], aBoolean: true
+      },
+      str: 'xyzzy',
+      repeatedStrList: ['a', 'b'],
+      repeatedSimpleList: [
+        { aString: 'foo', aRepeatedStringList: ['s1', 's2'], aBoolean: true},
+        { aString: 'bar', aRepeatedStringList: ['t1', 't2'], aBoolean: false}
+      ]
+    }, extendable.toObject());
+
+    // Now, with instances included.
+    assertObjectEquals({
+      str1: 'v1', str2: 'v2', str3: 'v3',
+      extField: {
+        ext1: 'ext1field',
+        $jspbMessageInstance:
+            extendable.getExtension(proto.jspb.test.IsExtension.extField)
+      },
+      simple: {
+        aString: 'str',
+        aRepeatedStringList: ['s1', 's2'],
+        aBoolean: true,
+        $jspbMessageInstance:
+            extendable.getExtension(proto.jspb.test.IndirectExtension.simple)
+      },
+      str: 'xyzzy',
+      repeatedStrList: ['a', 'b'],
+      repeatedSimpleList: [{
+        aString: 'foo',
+        aRepeatedStringList: ['s1', 's2'],
+        aBoolean: true,
+        $jspbMessageInstance: s1
+      }, {
+        aString: 'bar',
+        aRepeatedStringList: ['t1', 't2'],
+        aBoolean: false,
+        $jspbMessageInstance: s2
+      }],
+      $jspbMessageInstance: extendable
+    }, extendable.toObject(true /* opt_includeInstance */));
+  });
+
+  it('testInitialization_emptyArray', function() {
+    var msg = new proto.jspb.test.HasExtensions([]);
+    if (jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS) {
+      assertArrayEquals([], msg.toArray());
+    } else {
+      // Extension object is created past all regular fields.
+      assertArrayEquals([,,, {}], msg.toArray());
+    }
+  });
+
+  it('testInitialization_justExtensionObject', function() {
+    var msg = new proto.jspb.test.Empty([{1: 'hi'}]);
+    // The extensionObject is not moved from its original location.
+    assertArrayEquals([{1: 'hi'}], msg.toArray());
+  });
+
+  it('testInitialization_incompleteList', function() {
+    var msg = new proto.jspb.test.Empty([1, {4: 'hi'}]);
+    // The extensionObject is not moved from its original location.
+    assertArrayEquals([1, {4: 'hi'}], msg.toArray());
+  });
+
+  it('testInitialization_forwardCompatible', function() {
+    var msg = new proto.jspb.test.Empty([1, 2, 3, {1: 'hi'}]);
+    assertArrayEquals([1, 2, 3, {1: 'hi'}], msg.toArray());
+  });
+
+  it('testExtendedMessageEnsureObject', function() {
+    var data = new proto.jspb.test.HasExtensions(['str1',
+        {'a_key': 'an_object'}]);
+    assertEquals('an_object', data.extensionObject_['a_key']);
+  });
+
+  it('testToObject_hasExtensionField', function() {
+    var data = new proto.jspb.test.HasExtensions(['str1', {100: ['ext1']}]);
+    var obj = data.toObject();
+    assertEquals('str1', obj.str1);
+    assertEquals('ext1', obj.extField.ext1);
+  });
+
+  it('testGetExtension', function() {
+    var data = new proto.jspb.test.HasExtensions(['str1', {100: ['ext1']}]);
+    assertEquals('str1', data.getStr1());
+    var extension = data.getExtension(proto.jspb.test.IsExtension.extField);
+    assertNotNull(extension);
+    assertEquals('ext1', extension.getExt1());
+  });
+
+  it('testSetExtension', function() {
+    var data = new proto.jspb.test.HasExtensions();
+    var extensionMessage = new proto.jspb.test.IsExtension(['is_extension']);
+    data.setExtension(proto.jspb.test.IsExtension.extField, extensionMessage);
+    var obj = data.toObject();
+    assertNotNull(
+        data.getExtension(proto.jspb.test.IsExtension.extField));
+    assertEquals('is_extension', obj.extField.ext1);
+  });
+
+  /**
+   * Note that group is long deprecated, we only support it because JsPb has
+   * a goal of being able to generate JS classes for all proto descriptors.
+   */
+  it('testGroups', function() {
+    var group = new proto.jspb.test.TestGroup();
+    var someGroup = new proto.jspb.test.TestGroup.RepeatedGroup();
+    someGroup.setId('g1');
+    someGroup.setSomeBoolList([true, false]);
+    group.setRepeatedGroupList([someGroup]);
+    var groups = group.getRepeatedGroupList();
+    assertEquals('g1', groups[0].getId());
+    assertObjectEquals([true, false], groups[0].getSomeBoolList());
+    assertObjectEquals({id: 'g1', someBoolList: [true, false]},
+        groups[0].toObject());
+    assertObjectEquals({
+      repeatedGroupList: [{id: 'g1', someBoolList: [true, false]}],
+      requiredGroup: {id: undefined},
+      optionalGroup: undefined,
+      requiredSimple: {aRepeatedStringList: [], aString: undefined},
+      optionalSimple: undefined,
+      id: undefined
+    }, group.toObject());
+    var group1 = new proto.jspb.test.TestGroup1();
+    group1.setGroup(someGroup);
+    assertEquals(someGroup, group1.getGroup());
+  });
+
+  it('testNonExtensionFieldsAfterExtensionRange', function() {
+    var data = [{'1': 'a_string'}];
+    var message = new proto.jspb.test.Complex(data);
+    assertArrayEquals([], message.getARepeatedStringList());
+  });
+
+  it('testReservedGetterNames', function() {
+    var message = new proto.jspb.test.TestReservedNames();
+    message.setExtension$(11);
+    message.setExtension(proto.jspb.test.TestReservedNamesExtension.foo, 12);
+    assertEquals(11, message.getExtension$());
+    assertEquals(12, message.getExtension(
+        proto.jspb.test.TestReservedNamesExtension.foo));
+    assertObjectEquals({extension: 11, foo: 12}, message.toObject());
+  });
+
+  it('testInitializeMessageWithUnsetOneof', function() {
+    var message = new proto.jspb.test.TestMessageWithOneof([]);
+    assertEquals(
+        proto.jspb.test.TestMessageWithOneof.PartialOneofCase.
+            PARTIAL_ONEOF_NOT_SET,
+        message.getPartialOneofCase());
+    assertEquals(
+        proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase.
+            RECURSIVE_ONEOF_NOT_SET,
+        message.getRecursiveOneofCase());
+  });
+
+  it('testInitializeMessageWithSingleValueSetInOneof', function() {
+    var message = new proto.jspb.test.TestMessageWithOneof([,, 'x']);
+
+    assertEquals('x', message.getPone());
+    assertUndefined(message.getPthree());
+    assertEquals(
+        proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PONE,
+        message.getPartialOneofCase());
+  });
+
+  it('testKeepsLastWireValueSetInUnion_multipleValues', function() {
+    var message = new proto.jspb.test.TestMessageWithOneof([,, 'x',, 'y']);
+
+    assertUndefined('x', message.getPone());
+    assertEquals('y', message.getPthree());
+    assertEquals(
+        proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PTHREE,
+        message.getPartialOneofCase());
+  });
+
+  it('testSettingOneofFieldClearsOthers', function() {
+    var message = new proto.jspb.test.TestMessageWithOneof;
+    assertUndefined(message.getPone());
+    assertUndefined(message.getPthree());
+
+    message.setPone('hi');
+    assertEquals('hi', message.getPone());
+    assertUndefined(message.getPthree());
+
+    message.setPthree('bye');
+    assertUndefined(message.getPone());
+    assertEquals('bye', message.getPthree());
+  });
+
+  it('testSettingOneofFieldDoesNotClearFieldsFromOtherUnions', function() {
+    var other = new proto.jspb.test.TestMessageWithOneof;
+    var message = new proto.jspb.test.TestMessageWithOneof;
+    assertUndefined(message.getPone());
+    assertUndefined(message.getPthree());
+    assertUndefined(message.getRone());
+
+    message.setPone('hi');
+    message.setRone(other);
+    assertEquals('hi', message.getPone());
+    assertUndefined(message.getPthree());
+    assertEquals(other, message.getRone());
+
+    message.setPthree('bye');
+    assertUndefined(message.getPone());
+    assertEquals('bye', message.getPthree());
+    assertEquals(other, message.getRone());
+  });
+
+  it('testUnsetsOneofCaseWhenFieldIsCleared', function() {
+    var message = new proto.jspb.test.TestMessageWithOneof;
+    assertEquals(
+        proto.jspb.test.TestMessageWithOneof.PartialOneofCase.
+            PARTIAL_ONEOF_NOT_SET,
+        message.getPartialOneofCase());
+
+    message.setPone('hi');
+    assertEquals(
+        proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PONE,
+        message.getPartialOneofCase());
+
+    message.clearPone();
+    assertEquals(
+        proto.jspb.test.TestMessageWithOneof.PartialOneofCase.
+            PARTIAL_ONEOF_NOT_SET,
+        message.getPartialOneofCase());
+  });
+
+  it('testMessageWithDefaultOneofValues', function() {
+    var message = new proto.jspb.test.TestMessageWithOneof;
+    assertEquals(1234, message.getAone());
+    assertUndefined(message.getAtwo());
+    assertEquals(
+        proto.jspb.test.TestMessageWithOneof.DefaultOneofACase
+            .DEFAULT_ONEOF_A_NOT_SET,
+        message.getDefaultOneofACase());
+
+    message.setAone(567);
+    assertEquals(567, message.getAone());
+    assertUndefined(message.getAtwo());
+    assertEquals(
+        proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.AONE,
+        message.getDefaultOneofACase());
+
+    message.setAtwo(890);
+    assertEquals(1234, message.getAone());
+    assertEquals(890, message.getAtwo());
+    assertEquals(
+        proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.ATWO,
+        message.getDefaultOneofACase());
+
+    message.clearAtwo();
+    assertEquals(1234, message.getAone());
+    assertUndefined(message.getAtwo());
+    assertEquals(
+        proto.jspb.test.TestMessageWithOneof.DefaultOneofACase
+            .DEFAULT_ONEOF_A_NOT_SET,
+        message.getDefaultOneofACase());
+  });
+
+  it('testMessageWithDefaultOneofValues_defaultNotOnFirstField', function() {
+    var message = new proto.jspb.test.TestMessageWithOneof;
+    assertUndefined(message.getBone());
+    assertEquals(1234, message.getBtwo());
+    assertEquals(
+        proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase
+            .DEFAULT_ONEOF_B_NOT_SET,
+        message.getDefaultOneofBCase());
+
+    message.setBone(2);
+    assertEquals(2, message.getBone());
+    assertEquals(1234, message.getBtwo());
+    assertEquals(
+        proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BONE,
+        message.getDefaultOneofBCase());
+
+    message.setBtwo(3);
+    assertUndefined(message.getBone());
+    assertEquals(3, message.getBtwo());
+    assertEquals(
+        proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO,
+        message.getDefaultOneofBCase());
+
+    message.clearBtwo();
+    assertUndefined(message.getBone());
+    assertEquals(1234, message.getBtwo());
+    assertEquals(
+        proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase
+            .DEFAULT_ONEOF_B_NOT_SET,
+        message.getDefaultOneofBCase());
+  });
+
+  it('testInitializeMessageWithOneofDefaults', function() {
+    var message =
+        new proto.jspb.test.TestMessageWithOneof(new Array(9).concat(567));
+    assertEquals(567, message.getAone());
+    assertUndefined(message.getAtwo());
+    assertEquals(
+        proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.AONE,
+        message.getDefaultOneofACase());
+
+    message =
+        new proto.jspb.test.TestMessageWithOneof(new Array(10).concat(890));
+    assertEquals(1234, message.getAone());
+    assertEquals(890, message.getAtwo());
+    assertEquals(
+        proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.ATWO,
+        message.getDefaultOneofACase());
+
+    message =
+        new proto.jspb.test.TestMessageWithOneof(new Array(9).concat(567,890));
+    assertEquals(1234, message.getAone());
+    assertEquals(890, message.getAtwo());
+    assertEquals(
+        proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.ATWO,
+        message.getDefaultOneofACase());
+  });
+
+  it('testInitializeMessageWithOneofDefaults_defaultNotSetOnFirstField',
+      function() {
+        var message;
+
+        message =
+            new proto.jspb.test.TestMessageWithOneof(new Array(11).concat(567));
+        assertEquals(567, message.getBone());
+        assertEquals(1234, message.getBtwo());
+        assertEquals(
+            proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BONE,
+            message.getDefaultOneofBCase());
+
+        message =
+            new proto.jspb.test.TestMessageWithOneof(new Array(12).concat(890));
+        assertUndefined(message.getBone());
+        assertEquals(890, message.getBtwo());
+        assertEquals(
+            proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO,
+            message.getDefaultOneofBCase());
+
+        message = new proto.jspb.test.TestMessageWithOneof(
+            new Array(11).concat(567,890));
+        assertUndefined(message.getBone());
+        assertEquals(890, message.getBtwo());
+        assertEquals(
+            proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO,
+            message.getDefaultOneofBCase());
+      });
+
+  it('testOneofContainingAnotherMessage', function() {
+    var message = new proto.jspb.test.TestMessageWithOneof;
+    assertEquals(
+        proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase.
+            RECURSIVE_ONEOF_NOT_SET,
+        message.getRecursiveOneofCase());
+
+    var other = new proto.jspb.test.TestMessageWithOneof;
+    message.setRone(other);
+    assertEquals(other, message.getRone());
+    assertUndefined(message.getRtwo());
+    assertEquals(
+        proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase.RONE,
+        message.getRecursiveOneofCase());
+
+    message.setRtwo('hi');
+    assertUndefined(message.getRone());
+    assertEquals('hi', message.getRtwo());
+    assertEquals(
+        proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase.RTWO,
+        message.getRecursiveOneofCase());
+  });
+
+  it('testQueryingOneofCaseEnsuresOnlyOneFieldIsSetInUnderlyingArray',
+     function() {
+    var message = new proto.jspb.test.TestMessageWithOneof;
+    message.setPone('x');
+    assertEquals('x', message.getPone());
+    assertUndefined(message.getPthree());
+    assertEquals(
+        proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PONE,
+        message.getPartialOneofCase());
+
+    var array = message.toArray();
+    assertEquals('x', array[2]);
+    assertUndefined(array[4]);
+    array[4] = 'y';
+
+    assertEquals(
+        proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PTHREE,
+        message.getPartialOneofCase());
+    assertUndefined(array[2]);
+    assertEquals('y', array[4]);
+  });
+
+});
diff --git a/js/node_loader.js b/js/node_loader.js
new file mode 100644
index 0000000..79211ad
--- /dev/null
+++ b/js/node_loader.js
@@ -0,0 +1,49 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/**
+ * @fileoverview Loader that handles goog.require() for Node.JS.
+ */
+
+var oldLoader = goog.global.CLOSURE_IMPORT_SCRIPT;
+
+goog.global.CLOSURE_IMPORT_SCRIPT = function(src, opt_sourceText) {
+  if (opt_sourceText === undefined) {
+    try {
+      // Load from the current directory.
+      require("./" + src);
+      return true;
+    } catch (e) {
+      // Fall back to the Closure loader.
+    }
+  }
+
+  return oldLoader(src, opt_sourceText);
+};
diff --git a/js/package.json b/js/package.json
new file mode 100644
index 0000000..be93286
--- /dev/null
+++ b/js/package.json
@@ -0,0 +1,21 @@
+{
+  "name": "google-protobuf",
+  "version": "3.0.0-alpha.5",
+  "description": "Protocol Buffers for JavaScript",
+  "main": "debug.js",
+  "dependencies": {
+    "google-closure-library": "~20160125.0.0",
+    "gulp": "~3.9.0",
+    "jasmine": "~2.4.1"
+  },
+  "devDependencies": {},
+  "scripts": {
+    "test": "./node_modules/gulp/bin/gulp.js test"
+  },
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/google/protobuf/tree/master/js"
+  },
+  "author": "",
+  "license": "Apache-2.0"
+}
diff --git a/js/proto3_test.js b/js/proto3_test.js
new file mode 100644
index 0000000..8102bab
--- /dev/null
+++ b/js/proto3_test.js
@@ -0,0 +1,279 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+goog.require('goog.testing.asserts');
+goog.require('proto.jspb.test.ForeignMessage');
+goog.require('proto.jspb.test.Proto3Enum');
+goog.require('proto.jspb.test.TestProto3');
+
+/**
+ * Helper: compare a bytes field to a string with codepoints 0--255.
+ * @param {Uint8Array|string} arr
+ * @param {string} str
+ * @return {boolean}
+ */
+function bytesCompare(arr, str) {
+  if (arr.length != str.length) {
+    return false;
+  }
+  if (typeof arr == 'string') {
+    for (var i = 0; i < arr.length; i++) {
+      if (arr.charCodeAt(i) != str.charCodeAt(i)) {
+        return false;
+      }
+    }
+    return true;
+  } else {
+    for (var i = 0; i < arr.length; i++) {
+      if (arr[i] != str.charCodeAt(i)) {
+        return false;
+      }
+    }
+    return true;
+  }
+}
+
+
+describe('proto3Test', function() {
+  /**
+   * Test defaults for proto3 message fields.
+   */
+  it('testProto3FieldDefaults', function() {
+    var msg = new proto.jspb.test.TestProto3();
+
+    assertEquals(msg.getOptionalInt32(), 0);
+    assertEquals(msg.getOptionalInt64(), 0);
+    assertEquals(msg.getOptionalUint32(), 0);
+    assertEquals(msg.getOptionalUint64(), 0);
+    assertEquals(msg.getOptionalSint32(), 0);
+    assertEquals(msg.getOptionalSint64(), 0);
+    assertEquals(msg.getOptionalFixed32(), 0);
+    assertEquals(msg.getOptionalFixed64(), 0);
+    assertEquals(msg.getOptionalSfixed32(), 0);
+    assertEquals(msg.getOptionalSfixed64(), 0);
+    assertEquals(msg.getOptionalFloat(), 0);
+    assertEquals(msg.getOptionalDouble(), 0);
+    assertEquals(msg.getOptionalString(), '');
+
+    // If/when we change bytes fields to return Uint8Array, we'll want to switch
+    // to this assertion instead:
+    //assertEquals(msg.getOptionalBytes() instanceof Uint8Array, true);
+    assertEquals(typeof msg.getOptionalBytes(), 'string');
+
+    assertEquals(msg.getOptionalBytes().length, 0);
+    assertEquals(msg.getOptionalForeignEnum(), proto.jspb.test.Proto3Enum.PROTO3_FOO);
+    assertEquals(msg.getOptionalForeignMessage(), undefined);
+    assertEquals(msg.getOptionalForeignMessage(), undefined);
+
+    assertEquals(msg.getRepeatedInt32List().length, 0);
+    assertEquals(msg.getRepeatedInt64List().length, 0);
+    assertEquals(msg.getRepeatedUint32List().length, 0);
+    assertEquals(msg.getRepeatedUint64List().length, 0);
+    assertEquals(msg.getRepeatedSint32List().length, 0);
+    assertEquals(msg.getRepeatedSint64List().length, 0);
+    assertEquals(msg.getRepeatedFixed32List().length, 0);
+    assertEquals(msg.getRepeatedFixed64List().length, 0);
+    assertEquals(msg.getRepeatedSfixed32List().length, 0);
+    assertEquals(msg.getRepeatedSfixed64List().length, 0);
+    assertEquals(msg.getRepeatedFloatList().length, 0);
+    assertEquals(msg.getRepeatedDoubleList().length, 0);
+    assertEquals(msg.getRepeatedStringList().length, 0);
+    assertEquals(msg.getRepeatedBytesList().length, 0);
+    assertEquals(msg.getRepeatedForeignEnumList().length, 0);
+    assertEquals(msg.getRepeatedForeignMessageList().length, 0);
+
+  });
+
+
+  /**
+   * Test that all fields can be set and read via a serialization roundtrip.
+   */
+  it('testProto3FieldSetGet', function() {
+    var msg = new proto.jspb.test.TestProto3();
+
+    msg.setOptionalInt32(-42);
+    msg.setOptionalInt64(-0x7fffffff00000000);
+    msg.setOptionalUint32(0x80000000);
+    msg.setOptionalUint64(0xf000000000000000);
+    msg.setOptionalSint32(-100);
+    msg.setOptionalSint64(-0x8000000000000000);
+    msg.setOptionalFixed32(1234);
+    msg.setOptionalFixed64(0x1234567800000000);
+    msg.setOptionalSfixed32(-1234);
+    msg.setOptionalSfixed64(-0x1234567800000000);
+    msg.setOptionalFloat(1.5);
+    msg.setOptionalDouble(-1.5);
+    msg.setOptionalBool(true);
+    msg.setOptionalString('hello world');
+    msg.setOptionalBytes('bytes');
+    var submsg = new proto.jspb.test.ForeignMessage();
+    submsg.setC(16);
+    msg.setOptionalForeignMessage(submsg);
+    msg.setOptionalForeignEnum(proto.jspb.test.Proto3Enum.PROTO3_BAR);
+
+    msg.setRepeatedInt32List([-42]);
+    msg.setRepeatedInt64List([-0x7fffffff00000000]);
+    msg.setRepeatedUint32List([0x80000000]);
+    msg.setRepeatedUint64List([0xf000000000000000]);
+    msg.setRepeatedSint32List([-100]);
+    msg.setRepeatedSint64List([-0x8000000000000000]);
+    msg.setRepeatedFixed32List([1234]);
+    msg.setRepeatedFixed64List([0x1234567800000000]);
+    msg.setRepeatedSfixed32List([-1234]);
+    msg.setRepeatedSfixed64List([-0x1234567800000000]);
+    msg.setRepeatedFloatList([1.5]);
+    msg.setRepeatedDoubleList([-1.5]);
+    msg.setRepeatedBoolList([true]);
+    msg.setRepeatedStringList(['hello world']);
+    msg.setRepeatedBytesList(['bytes']);
+    submsg = new proto.jspb.test.ForeignMessage();
+    submsg.setC(1000);
+    msg.setRepeatedForeignMessageList([submsg]);
+    msg.setRepeatedForeignEnumList([proto.jspb.test.Proto3Enum.PROTO3_BAR]);
+
+    msg.setOneofString('asdf');
+
+    var serialized = msg.serializeBinary();
+    msg = proto.jspb.test.TestProto3.deserializeBinary(serialized);
+
+    assertEquals(msg.getOptionalInt32(), -42);
+    assertEquals(msg.getOptionalInt64(), -0x7fffffff00000000);
+    assertEquals(msg.getOptionalUint32(), 0x80000000);
+    assertEquals(msg.getOptionalUint64(), 0xf000000000000000);
+    assertEquals(msg.getOptionalSint32(), -100);
+    assertEquals(msg.getOptionalSint64(), -0x8000000000000000);
+    assertEquals(msg.getOptionalFixed32(), 1234);
+    assertEquals(msg.getOptionalFixed64(), 0x1234567800000000);
+    assertEquals(msg.getOptionalSfixed32(), -1234);
+    assertEquals(msg.getOptionalSfixed64(), -0x1234567800000000);
+    assertEquals(msg.getOptionalFloat(), 1.5);
+    assertEquals(msg.getOptionalDouble(), -1.5);
+    assertEquals(msg.getOptionalBool(), true);
+    assertEquals(msg.getOptionalString(), 'hello world');
+    assertEquals(true, bytesCompare(msg.getOptionalBytes(), 'bytes'));
+    assertEquals(msg.getOptionalForeignMessage().getC(), 16);
+    assertEquals(msg.getOptionalForeignEnum(),
+        proto.jspb.test.Proto3Enum.PROTO3_BAR);
+
+    assertElementsEquals(msg.getRepeatedInt32List(), [-42]);
+    assertElementsEquals(msg.getRepeatedInt64List(), [-0x7fffffff00000000]);
+    assertElementsEquals(msg.getRepeatedUint32List(), [0x80000000]);
+    assertElementsEquals(msg.getRepeatedUint64List(), [0xf000000000000000]);
+    assertElementsEquals(msg.getRepeatedSint32List(), [-100]);
+    assertElementsEquals(msg.getRepeatedSint64List(), [-0x8000000000000000]);
+    assertElementsEquals(msg.getRepeatedFixed32List(), [1234]);
+    assertElementsEquals(msg.getRepeatedFixed64List(), [0x1234567800000000]);
+    assertElementsEquals(msg.getRepeatedSfixed32List(), [-1234]);
+    assertElementsEquals(msg.getRepeatedSfixed64List(), [-0x1234567800000000]);
+    assertElementsEquals(msg.getRepeatedFloatList(), [1.5]);
+    assertElementsEquals(msg.getRepeatedDoubleList(), [-1.5]);
+    assertElementsEquals(msg.getRepeatedBoolList(), [true]);
+    assertElementsEquals(msg.getRepeatedStringList(), ['hello world']);
+    assertEquals(msg.getRepeatedBytesList().length, 1);
+    assertEquals(true, bytesCompare(msg.getRepeatedBytesList()[0], 'bytes'));
+    assertEquals(msg.getRepeatedForeignMessageList().length, 1);
+    assertEquals(msg.getRepeatedForeignMessageList()[0].getC(), 1000);
+    assertElementsEquals(msg.getRepeatedForeignEnumList(),
+        [proto.jspb.test.Proto3Enum.PROTO3_BAR]);
+
+    assertEquals(msg.getOneofString(), 'asdf');
+  });
+
+
+  /**
+   * Test that oneofs continue to have a notion of field presence.
+   */
+  it('testOneofs', function() {
+    var msg = new proto.jspb.test.TestProto3();
+
+    assertEquals(msg.getOneofUint32(), undefined);
+    assertEquals(msg.getOneofForeignMessage(), undefined);
+    assertEquals(msg.getOneofString(), undefined);
+    assertEquals(msg.getOneofBytes(), undefined);
+
+    msg.setOneofUint32(42);
+    assertEquals(msg.getOneofUint32(), 42);
+    assertEquals(msg.getOneofForeignMessage(), undefined);
+    assertEquals(msg.getOneofString(), undefined);
+    assertEquals(msg.getOneofBytes(), undefined);
+
+
+    var submsg = new proto.jspb.test.ForeignMessage();
+    msg.setOneofForeignMessage(submsg);
+    assertEquals(msg.getOneofUint32(), undefined);
+    assertEquals(msg.getOneofForeignMessage(), submsg);
+    assertEquals(msg.getOneofString(), undefined);
+    assertEquals(msg.getOneofBytes(), undefined);
+
+    msg.setOneofString('hello');
+    assertEquals(msg.getOneofUint32(), undefined);
+    assertEquals(msg.getOneofForeignMessage(), undefined);
+    assertEquals(msg.getOneofString(), 'hello');
+    assertEquals(msg.getOneofBytes(), undefined);
+
+    msg.setOneofBytes('\u00FF\u00FF');
+    assertEquals(msg.getOneofUint32(), undefined);
+    assertEquals(msg.getOneofForeignMessage(), undefined);
+    assertEquals(msg.getOneofString(), undefined);
+    assertEquals(msg.getOneofBytes(), '\u00FF\u00FF');
+  });
+
+
+  /**
+   * Test that "default"-valued primitive fields are not emitted on the wire.
+   */
+  it('testNoSerializeDefaults', function() {
+    var msg = new proto.jspb.test.TestProto3();
+
+    // Set each primitive to a non-default value, then back to its default, to
+    // ensure that the serialization is actually checking the value and not just
+    // whether it has ever been set.
+    msg.setOptionalInt32(42);
+    msg.setOptionalInt32(0);
+    msg.setOptionalDouble(3.14);
+    msg.setOptionalDouble(0.0);
+    msg.setOptionalBool(true);
+    msg.setOptionalBool(false);
+    msg.setOptionalString('hello world');
+    msg.setOptionalString('');
+    msg.setOptionalBytes('\u00FF\u00FF');
+    msg.setOptionalBytes('');
+    msg.setOptionalForeignMessage(new proto.jspb.test.ForeignMessage());
+    msg.setOptionalForeignMessage(null);
+    msg.setOptionalForeignEnum(proto.jspb.test.Proto3Enum.PROTO3_BAR);
+    msg.setOptionalForeignEnum(proto.jspb.test.Proto3Enum.PROTO3_FOO);
+    msg.setOneofUint32(32);
+    msg.setOneofUint32(null);
+
+
+    var serialized = msg.serializeBinary();
+    assertEquals(0, serialized.length);
+  });
+});
diff --git a/js/proto3_test.proto b/js/proto3_test.proto
new file mode 100644
index 0000000..acb6716
--- /dev/null
+++ b/js/proto3_test.proto
@@ -0,0 +1,89 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto3";
+
+import "testbinary.proto";
+
+package jspb.test;
+
+message TestProto3 {
+     int32 optional_int32    =  1;
+     int64 optional_int64    =  2;
+    uint32 optional_uint32   =  3;
+    uint64 optional_uint64   =  4;
+    sint32 optional_sint32   =  5;
+    sint64 optional_sint64   =  6;
+   fixed32 optional_fixed32  =  7;
+   fixed64 optional_fixed64  =  8;
+  sfixed32 optional_sfixed32 =  9;
+  sfixed64 optional_sfixed64 = 10;
+     float optional_float    = 11;
+    double optional_double   = 12;
+      bool optional_bool     = 13;
+    string optional_string   = 14;
+     bytes optional_bytes    = 15;
+
+  ForeignMessage optional_foreign_message = 19;
+  Proto3Enum     optional_foreign_enum    = 22;
+
+  repeated    int32 repeated_int32    = 31;
+  repeated    int64 repeated_int64    = 32;
+  repeated   uint32 repeated_uint32   = 33;
+  repeated   uint64 repeated_uint64   = 34;
+  repeated   sint32 repeated_sint32   = 35;
+  repeated   sint64 repeated_sint64   = 36;
+  repeated  fixed32 repeated_fixed32  = 37;
+  repeated  fixed64 repeated_fixed64  = 38;
+  repeated sfixed32 repeated_sfixed32 = 39;
+  repeated sfixed64 repeated_sfixed64 = 40;
+  repeated    float repeated_float    = 41;
+  repeated   double repeated_double   = 42;
+  repeated     bool repeated_bool     = 43;
+  repeated   string repeated_string   = 44;
+  repeated    bytes repeated_bytes    = 45;
+
+  repeated ForeignMessage repeated_foreign_message = 49;
+  repeated Proto3Enum     repeated_foreign_enum    = 52;
+
+
+  oneof oneof_field {
+    uint32 oneof_uint32 = 111;
+    ForeignMessage oneof_foreign_message = 112;
+    string oneof_string = 113;
+    bytes oneof_bytes = 114;
+  }
+}
+
+enum Proto3Enum {
+  PROTO3_FOO = 0;
+  PROTO3_BAR = 1;
+  PROTO3_BAZ = 2;
+}
diff --git a/js/test.proto b/js/test.proto
new file mode 100644
index 0000000..5f9078e
--- /dev/null
+++ b/js/test.proto
@@ -0,0 +1,212 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: mwr@google.com (Mark Rawling)
+
+syntax = "proto2";
+
+option java_package = "com.google.apps.jspb.proto";
+option java_multiple_files = true;
+
+import "google/protobuf/descriptor.proto";
+
+package jspb.test;
+
+message Empty {
+}
+
+enum OuterEnum {
+  FOO = 1;
+  BAR = 2;
+}
+
+message EnumContainer {
+  optional OuterEnum outer_enum = 1;
+}
+
+message Simple1 {
+  required string a_string = 1;
+  repeated string a_repeated_string = 2;
+  optional bool a_boolean = 3;
+}
+
+// A message that differs from Simple1 only by name
+message Simple2 {
+  required string a_string = 1;
+  repeated string a_repeated_string = 2;
+}
+
+message SpecialCases {
+  required string normal = 1;
+  // Examples of Js reserved names that are converted to pb_<name>.
+  required string default = 2;
+  required string function = 3;
+  required string var = 4;
+}
+
+message OptionalFields {
+  message Nested {
+    optional int32 an_int = 1;
+  }
+  optional string a_string = 1;
+  required bool a_bool = 2;
+  optional Nested a_nested_message = 3;
+  repeated Nested a_repeated_message = 4;
+  repeated string a_repeated_string = 5;
+}
+
+message HasExtensions {
+  optional string str1 = 1;
+  optional string str2 = 2;
+  optional string str3 = 3;
+  extensions 10 to max;
+}
+
+message Complex {
+  message Nested {
+    required int32 an_int = 2;
+  }
+  required string a_string = 1;
+  required bool an_out_of_order_bool = 9;
+  optional Nested a_nested_message = 4;
+  repeated Nested a_repeated_message = 5;
+  repeated string a_repeated_string = 7;
+}
+
+message IsExtension {
+  extend HasExtensions {
+    optional IsExtension ext_field = 100;
+  }
+  optional string ext1 = 1;
+
+  // Extensions of proto2 Descriptor messages will be ignored.
+  extend google.protobuf.EnumOptions {
+    optional string simple_option = 42113038;
+  }
+}
+
+message IndirectExtension {
+  extend HasExtensions {
+    optional Simple1 simple = 101;
+    optional string str = 102;
+    repeated string repeated_str = 103;
+    repeated Simple1 repeated_simple = 104;
+  }
+}
+
+extend HasExtensions {
+  optional Simple1 simple1 = 105;
+}
+
+message DefaultValues {
+  enum Enum {
+    E1 = 13;
+    E2 = 77;
+  }
+  optional string string_field = 1 [default="default<>\'\"abc"];
+  optional bool bool_field = 2 [default=true];
+  optional int64 int_field = 3 [default=11];
+  optional Enum enum_field = 4 [default=E1];
+  optional string empty_field = 6 [default=""];
+  optional bytes bytes_field = 8 [default="moo"]; // Base64 encoding is "bW9v"
+}
+
+message TestClone {
+  optional string str = 1;
+  optional Simple1 simple1 = 3;
+  repeated Simple1 simple2 = 5;
+  optional string unused = 7;
+  extensions 10 to max;
+}
+
+message CloneExtension {
+  extend TestClone {
+    optional CloneExtension ext_field = 100;
+  }
+  optional string ext = 2;
+}
+
+message TestGroup {
+  repeated group RepeatedGroup = 1 {
+    required string id = 1;
+    repeated bool some_bool = 2;
+  }
+  required group RequiredGroup = 2 {
+    required string id = 1;
+  }
+  optional group OptionalGroup = 3 {
+    required string id = 1;
+  }
+  optional string id = 4;
+  required Simple2 required_simple = 5;
+  optional Simple2 optional_simple = 6;
+}
+
+message TestGroup1 {
+  optional TestGroup.RepeatedGroup group = 1;
+}
+
+message TestReservedNames {
+  optional int32 extension = 1;
+  extensions 10 to max;
+}
+
+message TestReservedNamesExtension {
+  extend TestReservedNames {
+    optional int32 foo = 10;
+  }
+}
+
+message TestMessageWithOneof {
+
+  oneof partial_oneof {
+    string pone = 3;
+    string pthree = 5;
+  }
+
+  oneof recursive_oneof {
+    TestMessageWithOneof rone = 6;
+    string rtwo = 7;
+  }
+
+  optional bool normal_field = 8;
+  repeated string repeated_field = 9;
+
+  oneof default_oneof_a {
+    int32 aone = 10 [default = 1234];
+    int32 atwo = 11;
+  }
+
+  oneof default_oneof_b {
+    int32 bone = 12;
+    int32 btwo = 13 [default = 1234];
+  }
+}
+
diff --git a/js/test2.proto b/js/test2.proto
new file mode 100644
index 0000000..44e55ef
--- /dev/null
+++ b/js/test2.proto
@@ -0,0 +1,54 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto2";
+
+option java_package = "com.google.apps.jspb.proto";
+option java_multiple_files = true;
+
+package jspb.test;
+
+message TestExtensionsMessage {
+  optional int32 intfield = 1;
+  extensions 100 to max;
+}
+
+message ExtensionMessage {
+  extend TestExtensionsMessage {
+    optional ExtensionMessage ext_field = 100;
+  }
+  optional string ext1 = 1;
+}
+
+// Floating extensions are only supported when generating a _lib.js library.
+extend TestExtensionsMessage {
+  optional ExtensionMessage floating_msg_field = 101;
+  optional string floating_str_field = 102;
+}
diff --git a/js/test3.proto b/js/test3.proto
new file mode 100644
index 0000000..940a552
--- /dev/null
+++ b/js/test3.proto
@@ -0,0 +1,53 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto2";
+
+option java_package = "com.google.apps.jspb.proto";
+option java_multiple_files = true;
+
+package jspb.exttest;
+
+message TestExtensionsMessage {
+  optional int32 intfield = 1;
+  extensions 100 to max;
+}
+
+message ExtensionMessage {
+  extend TestExtensionsMessage {
+    optional ExtensionMessage ext_field = 100;
+  }
+  optional string ext1 = 1;
+}
+
+extend TestExtensionsMessage {
+  optional ExtensionMessage floating_msg_field = 101;
+  optional string floating_str_field = 102;
+}
diff --git a/js/test4.proto b/js/test4.proto
new file mode 100644
index 0000000..cf2451e
--- /dev/null
+++ b/js/test4.proto
@@ -0,0 +1,42 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto2";
+
+option java_package = "com.google.apps.jspb.proto";
+option java_multiple_files = true;
+
+package jspb.exttest;
+
+import "test3.proto";
+
+extend TestExtensionsMessage {
+  optional ExtensionMessage floating_msg_field_two = 103;
+}
diff --git a/js/test5.proto b/js/test5.proto
new file mode 100644
index 0000000..3497951
--- /dev/null
+++ b/js/test5.proto
@@ -0,0 +1,44 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto2";
+
+option java_package = "com.google.apps.jspb.proto";
+option java_multiple_files = true;
+
+package jspb.exttest.beta;
+
+message TestBetaExtensionsMessage {
+  extensions 100 to max;
+}
+
+extend TestBetaExtensionsMessage {
+  optional string floating_str_field = 101;
+}
diff --git a/js/test_bootstrap.js b/js/test_bootstrap.js
new file mode 100644
index 0000000..9d00a1c
--- /dev/null
+++ b/js/test_bootstrap.js
@@ -0,0 +1,41 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/**
+ * @fileoverview Sets flags for uncompiled JSUnit tests.
+ */
+
+/**
+ * Set uncompiled flags.
+ */
+var CLOSURE_DEFINES = {
+    // Enable the fromObject method on the message class.
+    'jspb.Message.GENERATE_FROM_OBJECT': true
+};
diff --git a/js/testbinary.proto b/js/testbinary.proto
new file mode 100644
index 0000000..60c7019
--- /dev/null
+++ b/js/testbinary.proto
@@ -0,0 +1,185 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// LINT: ALLOW_GROUPS
+
+syntax = "proto2";
+
+
+package jspb.test;
+
+// These types are borrowed from `unittest.proto` in the protobuf tree. We want
+// to ensure that the binary-format support will handle all field types
+// properly.
+message TestAllTypes {
+  optional    int32 optional_int32    =  1;
+  optional    int64 optional_int64    =  2;
+  optional   uint32 optional_uint32   =  3;
+  optional   uint64 optional_uint64   =  4;
+  optional   sint32 optional_sint32   =  5;
+  optional   sint64 optional_sint64   =  6;
+  optional  fixed32 optional_fixed32  =  7;
+  optional  fixed64 optional_fixed64  =  8;
+  optional sfixed32 optional_sfixed32 =  9;
+  optional sfixed64 optional_sfixed64 = 10;
+  optional    float optional_float    = 11;
+  optional   double optional_double   = 12;
+  optional     bool optional_bool     = 13;
+  optional   string optional_string   = 14;
+  optional    bytes optional_bytes    = 15;
+  optional group OptionalGroup = 16 {
+    optional int32 a = 17;
+  }
+
+  optional ForeignMessage                       optional_foreign_message = 19;
+  optional ForeignEnum                          optional_foreign_enum    = 22;
+
+  // Repeated
+  repeated    int32 repeated_int32    = 31;
+  repeated    int64 repeated_int64    = 32;
+  repeated   uint32 repeated_uint32   = 33;
+  repeated   uint64 repeated_uint64   = 34;
+  repeated   sint32 repeated_sint32   = 35;
+  repeated   sint64 repeated_sint64   = 36;
+  repeated  fixed32 repeated_fixed32  = 37;
+  repeated  fixed64 repeated_fixed64  = 38;
+  repeated sfixed32 repeated_sfixed32 = 39;
+  repeated sfixed64 repeated_sfixed64 = 40;
+  repeated    float repeated_float    = 41;
+  repeated   double repeated_double   = 42;
+  repeated     bool repeated_bool     = 43;
+  repeated   string repeated_string   = 44;
+  repeated    bytes repeated_bytes    = 45;
+
+  repeated group RepeatedGroup = 46 {
+    optional int32 a = 47;
+  }
+
+  repeated ForeignMessage                       repeated_foreign_message = 49;
+  repeated ForeignEnum                          repeated_foreign_enum    = 52;
+
+  // Packed repeated
+  repeated    int32 packed_repeated_int32    = 61 [packed=true];
+  repeated    int64 packed_repeated_int64    = 62 [packed=true];
+  repeated   uint32 packed_repeated_uint32   = 63 [packed=true];
+  repeated   uint64 packed_repeated_uint64   = 64 [packed=true];
+  repeated   sint32 packed_repeated_sint32   = 65 [packed=true];
+  repeated   sint64 packed_repeated_sint64   = 66 [packed=true];
+  repeated  fixed32 packed_repeated_fixed32  = 67 [packed=true];
+  repeated  fixed64 packed_repeated_fixed64  = 68 [packed=true];
+  repeated sfixed32 packed_repeated_sfixed32 = 69 [packed=true];
+  repeated sfixed64 packed_repeated_sfixed64 = 70 [packed=true];
+  repeated    float packed_repeated_float    = 71 [packed=true];
+  repeated   double packed_repeated_double   = 72 [packed=true];
+  repeated     bool packed_repeated_bool     = 73 [packed=true];
+
+  oneof oneof_field {
+    uint32 oneof_uint32 = 111;
+    ForeignMessage oneof_foreign_message = 112;
+    string oneof_string = 113;
+    bytes oneof_bytes = 114;
+  }
+
+}
+
+message ForeignMessage {
+  optional int32 c = 1;
+}
+
+enum ForeignEnum {
+  FOREIGN_FOO = 4;
+  FOREIGN_BAR = 5;
+  FOREIGN_BAZ = 6;
+}
+
+message TestExtendable {
+  extensions 1 to max;
+}
+
+message ExtendsWithMessage {
+  extend TestExtendable {
+    optional ExtendsWithMessage optional_extension = 19;
+    repeated ExtendsWithMessage repeated_extension = 49;
+  }
+  optional int32 foo = 1;
+}
+
+extend TestExtendable {
+  optional    int32 extend_optional_int32    =  1;
+  optional    int64 extend_optional_int64    =  2;
+  optional   uint32 extend_optional_uint32   =  3;
+  optional   uint64 extend_optional_uint64   =  4;
+  optional   sint32 extend_optional_sint32   =  5;
+  optional   sint64 extend_optional_sint64   =  6;
+  optional  fixed32 extend_optional_fixed32  =  7;
+  optional  fixed64 extend_optional_fixed64  =  8;
+  optional sfixed32 extend_optional_sfixed32 =  9;
+  optional sfixed64 extend_optional_sfixed64 = 10;
+  optional    float extend_optional_float    = 11;
+  optional   double extend_optional_double   = 12;
+  optional     bool extend_optional_bool     = 13;
+  optional   string extend_optional_string   = 14;
+  optional    bytes extend_optional_bytes    = 15;
+  optional ForeignEnum extend_optional_foreign_enum    = 22;
+
+  repeated    int32 extend_repeated_int32    = 31;
+  repeated    int64 extend_repeated_int64    = 32;
+  repeated   uint32 extend_repeated_uint32   = 33;
+  repeated   uint64 extend_repeated_uint64   = 34;
+  repeated   sint32 extend_repeated_sint32   = 35;
+  repeated   sint64 extend_repeated_sint64   = 36;
+  repeated  fixed32 extend_repeated_fixed32  = 37;
+  repeated  fixed64 extend_repeated_fixed64  = 38;
+  repeated sfixed32 extend_repeated_sfixed32 = 39;
+  repeated sfixed64 extend_repeated_sfixed64 = 40;
+  repeated    float extend_repeated_float    = 41;
+  repeated   double extend_repeated_double   = 42;
+  repeated     bool extend_repeated_bool     = 43;
+  repeated   string extend_repeated_string   = 44;
+  repeated    bytes extend_repeated_bytes    = 45;
+  repeated ForeignEnum extend_repeated_foreign_enum    = 52;
+
+  repeated    int32 extend_packed_repeated_int32    = 61 [packed=true];
+  repeated    int64 extend_packed_repeated_int64    = 62 [packed=true];
+  repeated   uint32 extend_packed_repeated_uint32   = 63 [packed=true];
+  repeated   uint64 extend_packed_repeated_uint64   = 64 [packed=true];
+  repeated   sint32 extend_packed_repeated_sint32   = 65 [packed=true];
+  repeated   sint64 extend_packed_repeated_sint64   = 66 [packed=true];
+  repeated  fixed32 extend_packed_repeated_fixed32  = 67 [packed=true];
+  repeated  fixed64 extend_packed_repeated_fixed64  = 68 [packed=true];
+  repeated sfixed32 extend_packed_repeated_sfixed32 = 69 [packed=true];
+  repeated sfixed64 extend_packed_repeated_sfixed64 = 70 [packed=true];
+  repeated    float extend_packed_repeated_float    = 71 [packed=true];
+  repeated   double extend_packed_repeated_double   = 72 [packed=true];
+  repeated     bool extend_packed_repeated_bool     = 73 [packed=true];
+  repeated ForeignEnum extend_packed_repeated_foreign_enum    = 82
+      [packed=true];
+
+}
diff --git a/js/testempty.proto b/js/testempty.proto
new file mode 100644
index 0000000..960bce4
--- /dev/null
+++ b/js/testempty.proto
@@ -0,0 +1,34 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto2";
+
+package javatests.com.google.apps.jspb;
+
