diff --git a/generate_descriptor_proto.sh b/generate_descriptor_proto.sh
index 53e88e67fae735900df8c58ac488e47f5110c02f..5587db0c2ca4fe97d79be23a0682225af90286be 100755
--- a/generate_descriptor_proto.sh
+++ b/generate_descriptor_proto.sh
@@ -6,14 +6,6 @@
 # will fail if these files do not match what the protocol compiler would
 # generate.
 
-# Note that this will always need to be run once after running
-# extract_from_google3.sh.  That script initially copies descriptor.pb.{h,cc}
-# over from the google3 code and fixes it up to compile outside of google3, but
-# it cannot fix the encoded descriptor embedded in descriptor.pb.cc.  So, once
-# the protocol compiler has been built with the slightly-broken
-# descriptor.pb.cc, the files must be regenerated and the compiler must be
-# built again.
-
 if test ! -e src/google/protobuf/stubs/common.h; then
   cat >&2 << __EOF__
 Could not find source code.  Make sure you are running this script from the
diff --git a/python/google/protobuf/internal/reflection_test.py b/python/google/protobuf/internal/reflection_test.py
index 5947f97a88d0083c4a1cbd1557a25bd98d298007..5577781993692af1e1df591badb5640fb6ef39fa 100755
--- a/python/google/protobuf/internal/reflection_test.py
+++ b/python/google/protobuf/internal/reflection_test.py
@@ -656,9 +656,172 @@ class RefectionTest(unittest.TestCase):
     self.assertRaises(KeyError, extendee_proto.HasExtension,
                       unittest_pb2.repeated_string_extension)
 
-  def testCopyFrom(self):
-    # TODO(robinson): Implement.
-    pass
+  def testMergeFromSingularField(self):
+    # Test merge with just a singular field.
+    proto1 = unittest_pb2.TestAllTypes()
+    proto1.optional_int32 = 1
+
+    proto2 = unittest_pb2.TestAllTypes()
+    # This shouldn't get overwritten.
+    proto2.optional_string = 'value'
+
+    proto2.MergeFrom(proto1)
+    self.assertEqual(1, proto2.optional_int32)
+    self.assertEqual('value', proto2.optional_string)
+
+  def testMergeFromRepeatedField(self):
+    # Test merge with just a repeated field.
+    proto1 = unittest_pb2.TestAllTypes()
+    proto1.repeated_int32.append(1)
+    proto1.repeated_int32.append(2)
+
+    proto2 = unittest_pb2.TestAllTypes()
+    proto2.repeated_int32.append(0)
+    proto2.MergeFrom(proto1)
+
+    self.assertEqual(0, proto2.repeated_int32[0])
+    self.assertEqual(1, proto2.repeated_int32[1])
+    self.assertEqual(2, proto2.repeated_int32[2])
+
+  def testMergeFromOptionalGroup(self):
+    # Test merge with an optional group.
+    proto1 = unittest_pb2.TestAllTypes()
+    proto1.optionalgroup.a = 12
+    proto2 = unittest_pb2.TestAllTypes()
+    proto2.MergeFrom(proto1)
+    self.assertEqual(12, proto2.optionalgroup.a)
+
+  def testMergeFromRepeatedNestedMessage(self):
+    # Test merge with a repeated nested message.
+    proto1 = unittest_pb2.TestAllTypes()
+    m = proto1.repeated_nested_message.add()
+    m.bb = 123
+    m = proto1.repeated_nested_message.add()
+    m.bb = 321
+
+    proto2 = unittest_pb2.TestAllTypes()
+    m = proto2.repeated_nested_message.add()
+    m.bb = 999
+    proto2.MergeFrom(proto1)
+    self.assertEqual(999, proto2.repeated_nested_message[0].bb)
+    self.assertEqual(123, proto2.repeated_nested_message[1].bb)
+    self.assertEqual(321, proto2.repeated_nested_message[2].bb)
+
+  def testMergeFromAllFields(self):
+    # With all fields set.
+    proto1 = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(proto1)
+    proto2 = unittest_pb2.TestAllTypes()
+    proto2.MergeFrom(proto1)
+
+    # Messages should be equal.
+    self.assertEqual(proto2, proto1)
+
+    # Serialized string should be equal too.
+    string1 = proto1.SerializeToString()
+    string2 = proto2.SerializeToString()
+    self.assertEqual(string1, string2)
+
+  def testMergeFromExtensionsSingular(self):
+    proto1 = unittest_pb2.TestAllExtensions()
+    proto1.Extensions[unittest_pb2.optional_int32_extension] = 1
+
+    proto2 = unittest_pb2.TestAllExtensions()
+    proto2.MergeFrom(proto1)
+    self.assertEqual(
+        1, proto2.Extensions[unittest_pb2.optional_int32_extension])
+
+  def testMergeFromExtensionsRepeated(self):
+    proto1 = unittest_pb2.TestAllExtensions()
+    proto1.Extensions[unittest_pb2.repeated_int32_extension].append(1)
+    proto1.Extensions[unittest_pb2.repeated_int32_extension].append(2)
+
+    proto2 = unittest_pb2.TestAllExtensions()
+    proto2.Extensions[unittest_pb2.repeated_int32_extension].append(0)
+    proto2.MergeFrom(proto1)
+    self.assertEqual(
+        3, len(proto2.Extensions[unittest_pb2.repeated_int32_extension]))
+    self.assertEqual(
+        0, proto2.Extensions[unittest_pb2.repeated_int32_extension][0])
+    self.assertEqual(
+        1, proto2.Extensions[unittest_pb2.repeated_int32_extension][1])
+    self.assertEqual(
+        2, proto2.Extensions[unittest_pb2.repeated_int32_extension][2])
+
+  def testMergeFromExtensionsNestedMessage(self):
+    proto1 = unittest_pb2.TestAllExtensions()
+    ext1 = proto1.Extensions[
+        unittest_pb2.repeated_nested_message_extension]
+    m = ext1.add()
+    m.bb = 222
+    m = ext1.add()
+    m.bb = 333
+
+    proto2 = unittest_pb2.TestAllExtensions()
+    ext2 = proto2.Extensions[
+        unittest_pb2.repeated_nested_message_extension]
+    m = ext2.add()
+    m.bb = 111
+
+    proto2.MergeFrom(proto1)
+    ext2 = proto2.Extensions[
+        unittest_pb2.repeated_nested_message_extension]
+    self.assertEqual(3, len(ext2))
+    self.assertEqual(111, ext2[0].bb)
+    self.assertEqual(222, ext2[1].bb)
+    self.assertEqual(333, ext2[2].bb)
+
+  def testCopyFromSingularField(self):
+    # Test copy with just a singular field.
+    proto1 = unittest_pb2.TestAllTypes()
+    proto1.optional_int32 = 1
+    proto1.optional_string = 'important-text'
+
+    proto2 = unittest_pb2.TestAllTypes()
+    proto2.optional_string = 'value'
+
+    proto2.CopyFrom(proto1)
+    self.assertEqual(1, proto2.optional_int32)
+    self.assertEqual('important-text', proto2.optional_string)
+
+  def testCopyFromRepeatedField(self):
+    # Test copy with a repeated field.
+    proto1 = unittest_pb2.TestAllTypes()
+    proto1.repeated_int32.append(1)
+    proto1.repeated_int32.append(2)
+
+    proto2 = unittest_pb2.TestAllTypes()
+    proto2.repeated_int32.append(0)
+    proto2.CopyFrom(proto1)
+
+    self.assertEqual(1, proto2.repeated_int32[0])
+    self.assertEqual(2, proto2.repeated_int32[1])
+
+  def testCopyFromAllFields(self):
+    # With all fields set.
+    proto1 = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(proto1)
+    proto2 = unittest_pb2.TestAllTypes()
+    proto2.CopyFrom(proto1)
+
+    # Messages should be equal.
+    self.assertEqual(proto2, proto1)
+
+    # Serialized string should be equal too.
+    string1 = proto1.SerializeToString()
+    string2 = proto2.SerializeToString()
+    self.assertEqual(string1, string2)
+
+  def testCopyFromSelf(self):
+    proto1 = unittest_pb2.TestAllTypes()
+    proto1.repeated_int32.append(1)
+    proto1.optional_int32 = 2
+    proto1.optional_string = 'important-text'
+
+    proto1.CopyFrom(proto1)
+    self.assertEqual(1, proto1.repeated_int32[0])
+    self.assertEqual(2, proto1.optional_int32)
+    self.assertEqual('important-text', proto1.optional_string)
 
   def testClear(self):
     proto = unittest_pb2.TestAllTypes()
@@ -1256,6 +1419,57 @@ class SerializationTest(unittest.TestCase):
     # Parsing this message should succeed.
     proto2.MergeFromString(serialized)
 
+  def _CheckRaises(self, exc_class, callable_obj, exception):
+    """This method checks if the excpetion type and message are as expected."""
+    try:
+      callable_obj()
+    except exc_class, ex:
+      # Check if the exception message is the right one.
+      self.assertEqual(exception, str(ex))
+      return
+    else:
+      raise self.failureException('%s not raised' % str(exc_class))
+
+  def testSerializeUninitialized(self):
+    proto = unittest_pb2.TestRequired()
+    self._CheckRaises(
+        message.EncodeError,
+        proto.SerializeToString,
+        'Required field protobuf_unittest.TestRequired.a is not set.')
+    # Shouldn't raise exceptions.
+    partial = proto.SerializePartialToString()
+
+    proto.a = 1
+    self._CheckRaises(
+        message.EncodeError,
+        proto.SerializeToString,
+        'Required field protobuf_unittest.TestRequired.b is not set.')
+    # Shouldn't raise exceptions.
+    partial = proto.SerializePartialToString()
+
+    proto.b = 2
+    self._CheckRaises(
+        message.EncodeError,
+        proto.SerializeToString,
+        'Required field protobuf_unittest.TestRequired.c is not set.')
+    # Shouldn't raise exceptions.
+    partial = proto.SerializePartialToString()
+
+    proto.c = 3
+    serialized = proto.SerializeToString()
+    # Shouldn't raise exceptions.
+    partial = proto.SerializePartialToString()
+
+    proto2 = unittest_pb2.TestRequired()
+    proto2.MergeFromString(serialized)
+    self.assertEqual(1, proto2.a)
+    self.assertEqual(2, proto2.b)
+    self.assertEqual(3, proto2.c)
+    proto2.ParseFromString(partial)
+    self.assertEqual(1, proto2.a)
+    self.assertEqual(2, proto2.b)
+    self.assertEqual(3, proto2.c)
+
 
 class OptionsTest(unittest.TestCase):
 
diff --git a/python/google/protobuf/message.py b/python/google/protobuf/message.py
index 9b48f889900a3ecf63f69c9d07f7e926e0030c06..593f6a630207971d4c15c69eed7da426f66ded3f 100755
--- a/python/google/protobuf/message.py
+++ b/python/google/protobuf/message.py
@@ -65,15 +65,43 @@ class Message(object):
     return text_format.MessageToString(self)
 
   def MergeFrom(self, other_msg):
+    """Merges the contents of the specified message into current message.
+
+    This method merges the contents of the specified message into the current
+    message. Singular fields that are set in the specified message overwrite
+    the corresponding fields in the current message. Repeated fields are
+    appended. Singular sub-messages and groups are recursively merged.
+
+    Args:
+      other_msg: Message to merge into the current message.
+    """
     raise NotImplementedError
 
   def CopyFrom(self, other_msg):
-    raise NotImplementedError
+    """Copies the content of the specified message into the current message.
+
+    The method clears the current message and then merges the specified
+    message using MergeFrom.
+
+    Args:
+      other_msg: Message to copy into the current one.
+    """
+    if self == other_msg:
+      return
+    self.Clear()
+    self.MergeFrom(other_msg)
 
   def Clear(self):
+    """Clears all data that was set in the message."""
     raise NotImplementedError
 
   def IsInitialized(self):
+    """Checks if the message is initialized.
+
+    Returns:
+      The method returns True if the message is initialized (i.e. all of its
+      required fields are set).
+    """
     raise NotImplementedError
 
   # TODO(robinson): MergeFromString() should probably return None and be
@@ -118,6 +146,26 @@ class Message(object):
     self.MergeFromString(serialized)
 
   def SerializeToString(self):
+    """Serializes the protocol message to a binary string.
+
+    Returns:
+      A binary string representation of the message if all of the required
+      fields in the message are set (i.e. the message is initialized).
+
+    Raises:
+      message.EncodeError if the message isn't initialized.
+    """
+    raise NotImplementedError
+
+  def SerializePartialToString(self):
+    """Serializes the protocol message to a binary string.
+
+    This method is similar to SerializeToString but doesn't check if the
+    message is initialized.
+
+    Returns:
+      A string representation of the partial message.
+    """
     raise NotImplementedError
 
   # TODO(robinson): Decide whether we like these better
diff --git a/python/google/protobuf/reflection.py b/python/google/protobuf/reflection.py
index 75202c4e30d33ad2f1473dd6a410a2c3d073b877..ef054466467e5b8f03f14ac641aa127cc23c2dc1 100755
--- a/python/google/protobuf/reflection.py
+++ b/python/google/protobuf/reflection.py
@@ -43,6 +43,7 @@ import weakref
 from google.protobuf.internal import decoder
 from google.protobuf.internal import encoder
 from google.protobuf.internal import message_listener as message_listener_mod
+from google.protobuf.internal import type_checkers
 from google.protobuf.internal import wire_format
 from google.protobuf import descriptor as descriptor_mod
 from google.protobuf import message as message_mod
@@ -261,8 +262,8 @@ def _DefaultValueForField(message, field):
       # been set.  (Depends on order in which we initialize the classes).
       return _RepeatedCompositeFieldContainer(listener, field.message_type)
     else:
-      return _RepeatedScalarFieldContainer(listener,
-                                           _VALUE_CHECKERS[field.cpp_type])
+      return _RepeatedScalarFieldContainer(
+          listener, type_checkers.VALUE_CHECKERS[field.cpp_type])
 
   if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
     assert field.default_value is None
@@ -370,7 +371,7 @@ def _AddPropertiesForNonRepeatedScalarField(field, cls):
   python_field_name = _ValueFieldName(proto_field_name)
   has_field_name = _HasFieldName(proto_field_name)
   property_name = _PropertyName(proto_field_name)
-  type_checker = _VALUE_CHECKERS[field.cpp_type]
+  type_checker = type_checkers.VALUE_CHECKERS[field.cpp_type]
 
   def getter(self):
     return getattr(self, python_field_name)
@@ -614,7 +615,7 @@ def _BytesForNonRepeatedElement(value, field_number, field_type):
       within FieldDescriptor.
   """
   try:
-    fn = _TYPE_TO_BYTE_SIZE_FN[field_type]
+    fn = type_checkers.TYPE_TO_BYTE_SIZE_FN[field_type]
     return fn(field_number, value)
   except KeyError:
     raise message_mod.EncodeError('Unrecognized field type: %d' % field_type)
@@ -707,7 +708,7 @@ def _SerializeValueToEncoder(value, field_number, field_descriptor, encoder):
     return
 
   try:
-    method = _TYPE_TO_SERIALIZE_METHOD[field_descriptor.type]
+    method = type_checkers.TYPE_TO_SERIALIZE_METHOD[field_descriptor.type]
     method(encoder, field_number, value)
   except KeyError:
     raise message_mod.EncodeError('Unrecognized field type: %d' %
@@ -748,15 +749,24 @@ def _ImergeSorted(*streams):
 
 def _AddSerializeToStringMethod(message_descriptor, cls):
   """Helper for _AddMessageMethods()."""
-  Encoder = encoder.Encoder
 
   def SerializeToString(self):
+    # Check if the message has all of its required fields set.
+    errors = []
+    if not _InternalIsInitialized(self, errors):
+      raise message_mod.EncodeError('\n'.join(errors))
+    return self.SerializePartialToString()
+  cls.SerializeToString = SerializeToString
+
+
+def _AddSerializePartialToStringMethod(message_descriptor, cls):
+  """Helper for _AddMessageMethods()."""
+  Encoder = encoder.Encoder
+
+  def SerializePartialToString(self):
     encoder = Encoder()
     # We need to serialize all extension and non-extension fields
     # together, in sorted order by field number.
-
-    # Step 3: Iterate over all extension and non-extension fields, sorted
-    # in order of tag number, and serialize each one to the wire.
     for field_descriptor, field_value in self.ListFields():
       if field_descriptor.label == _FieldDescriptor.LABEL_REPEATED:
         repeated_value = field_value
@@ -766,13 +776,13 @@ def _AddSerializeToStringMethod(message_descriptor, cls):
         _SerializeValueToEncoder(element, field_descriptor.number,
                                  field_descriptor, encoder)
     return encoder.ToString()
-  cls.SerializeToString = SerializeToString
+  cls.SerializePartialToString = SerializePartialToString
 
 
 def _WireTypeForFieldType(field_type):
   """Given a field type, returns the expected wire type."""
   try:
-    return _FIELD_TYPE_TO_WIRE_TYPE[field_type]
+    return type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_type]
   except KeyError:
     raise message_mod.DecodeError('Unknown field type: %d' % field_type)
 
@@ -804,7 +814,7 @@ def _DeserializeScalarFromDecoder(field_type, decoder):
   be a scalar (non-group, non-message) FieldDescriptor.FIELD_* constant.
   """
   try:
-    method = _TYPE_TO_DESERIALIZE_METHOD[field_type]
+    method = type_checkers.TYPE_TO_DESERIALIZE_METHOD[field_type]
     return method(decoder)
   except KeyError:
     raise message_mod.DecodeError('Unrecognized field type: %d' % field_type)
@@ -1034,12 +1044,13 @@ def _HasFieldOrExtension(message, field_or_extension):
     return message.HasField(field_or_extension.name)
 
 
-def _IsFieldOrExtensionInitialized(message, field):
+def _IsFieldOrExtensionInitialized(message, field, errors=None):
   """Checks if a message field or extension is initialized.
 
   Args:
     message: The message which contains the field or extension.
     field: Field or extension to check. This must be a FieldDescriptor instance.
+    errors: Errors will be appended to it, if set to a meaningful value.
 
   Returns:
     True if the field/extension can be considered initialized.
@@ -1047,6 +1058,8 @@ def _IsFieldOrExtensionInitialized(message, field):
   # If the field is required and is not set, it isn't initialized.
   if field.label == _FieldDescriptor.LABEL_REQUIRED:
     if not _HasFieldOrExtension(message, field):
+      if errors is not None:
+        errors.append('Required field %s is not set.' % field.full_name)
       return False
 
   # If the field is optional and is not set, or if it
@@ -1062,7 +1075,27 @@ def _IsFieldOrExtensionInitialized(message, field):
   # If all submessages in this field are initialized, the field is
   # considered initialized.
   for message in messages:
-    if not message.IsInitialized():
+    if not _InternalIsInitialized(message, errors):
+      return False
+  return True
+
+
+def _InternalIsInitialized(message, errors=None):
+  """Checks if all required fields of a message are set.
+
+  Args:
+    message: The message to check.
+    errors: If set, initialization errors will be appended to it.
+
+  Returns:
+    True iff the specified message has all required fields set.
+  """
+  fields_and_extensions = []
+  fields_and_extensions.extend(message.DESCRIPTOR.fields)
+  fields_and_extensions.extend(
+      [extension[0] for extension in message.Extensions._ListSetExtensions()])
+  for field_or_extension in fields_and_extensions:
+    if not _IsFieldOrExtensionInitialized(message, field_or_extension, errors):
       return False
   return True
 
@@ -1082,25 +1115,54 @@ def _AddMergeFromStringMethod(message_descriptor, cls):
   cls.MergeFromString = MergeFromString
 
 
-def _AddIsInitializedMethod(message_descriptor, cls):
+def _AddIsInitializedMethod(cls):
   """Adds the IsInitialized method to the protocol message class."""
-  def IsInitialized(self):
-    fields_and_extensions = []
-    fields_and_extensions.extend(message_descriptor.fields)
-    fields_and_extensions.extend(
-        self.Extensions._AllExtensionsByNumber().values())
-    for field_or_extension in fields_and_extensions:
-      if not _IsFieldOrExtensionInitialized(self, field_or_extension):
-        return False
-    return True
-  cls.IsInitialized = IsInitialized
+  cls.IsInitialized = _InternalIsInitialized
 
 
-def _AddMessageMethods(message_descriptor, cls):
-  """Adds implementations of all Message methods to cls."""
+def _MergeFieldOrExtension(destination_msg, field, value):
+  """Merges a specified message field into another message."""
+  property_name = _PropertyName(field.name)
+  is_extension = field.is_extension
 
-  # TODO(robinson): Add support for remaining Message methods.
+  if not is_extension:
+    destination = getattr(destination_msg, property_name)
+  elif (field.label == _FieldDescriptor.LABEL_REPEATED or
+        field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE):
+    destination = destination_msg.Extensions[field]
 
+  # Case 1 - a composite field.
+  if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+    if field.label == _FieldDescriptor.LABEL_REPEATED:
+      for v in value:
+        destination.add().MergeFrom(v)
+    else:
+      destination.MergeFrom(value)
+    return
+
+  # Case 2 - a repeated field.
+  if field.label == _FieldDescriptor.LABEL_REPEATED:
+    for v in value:
+      destination.append(v)
+    return
+
+  # Case 3 - a singular field.
+  if is_extension:
+    destination_msg.Extensions[field] = value
+  else:
+    setattr(destination_msg, property_name, value)
+
+
+def _AddMergeFromMethod(cls):
+  def MergeFrom(self, msg):
+    assert msg is not self
+    for field in msg.ListFields():
+      _MergeFieldOrExtension(self, field[0], field[1])
+  cls.MergeFrom = MergeFrom
+
+
+def _AddMessageMethods(message_descriptor, cls):
+  """Adds implementations of all Message methods to cls."""
   _AddListFieldsMethod(message_descriptor, cls)
   _AddHasFieldMethod(cls)
   _AddClearFieldMethod(cls)
@@ -1111,8 +1173,10 @@ def _AddMessageMethods(message_descriptor, cls):
   _AddSetListenerMethod(cls)
   _AddByteSizeMethod(message_descriptor, cls)
   _AddSerializeToStringMethod(message_descriptor, cls)
+  _AddSerializePartialToStringMethod(message_descriptor, cls)
   _AddMergeFromStringMethod(message_descriptor, cls)
-  _AddIsInitializedMethod(message_descriptor, cls)
+  _AddIsInitializedMethod(cls)
+  _AddMergeFromMethod(cls)
 
 
 def _AddPrivateHelperMethods(cls):
@@ -1440,7 +1504,7 @@ class _ExtensionDict(object):
         and field.cpp_type != _FieldDescriptor.CPPTYPE_MESSAGE):
       # It's slightly wasteful to lookup the type checker each time,
       # but we expect this to be a vanishingly uncommon case anyway.
-      type_checker = _VALUE_CHECKERS[field.cpp_type]
+      type_checker = type_checkers.VALUE_CHECKERS[field.cpp_type]
       type_checker.CheckValue(value)
       self._values[handle_id] = value
       self._has_bits[handle_id] = True
@@ -1561,174 +1625,3 @@ class _ExtensionDict(object):
     # be careful when we move away from having _known_extensions as a
     # deep-copied member of this object.
     return dict((f.number, f) for f in self._known_extensions.itervalues())
-
-
-# None of the typecheckers below make any attempt to guard against people
-# subclassing builtin types and doing weird things.  We're not trying to
-# protect against malicious clients here, just people accidentally shooting
-# themselves in the foot in obvious ways.
-
-class _TypeChecker(object):
-
-  """Type checker used to catch type errors as early as possible
-  when the client is setting scalar fields in protocol messages.
-  """
-
-  def __init__(self, *acceptable_types):
-    self._acceptable_types = acceptable_types
-
-  def CheckValue(self, proposed_value):
-    if not isinstance(proposed_value, self._acceptable_types):
-      message = ('%.1024r has type %s, but expected one of: %s' %
-                 (proposed_value, type(proposed_value), self._acceptable_types))
-      raise TypeError(message)
-
-
-# _IntValueChecker and its subclasses perform integer type-checks
-# and bounds-checks.
-class _IntValueChecker(object):
-
-  """Checker used for integer fields.  Performs type-check and range check."""
-
-  def CheckValue(self, proposed_value):
-    if not isinstance(proposed_value, (int, long)):
-      message = ('%.1024r has type %s, but expected one of: %s' %
-                 (proposed_value, type(proposed_value), (int, long)))
-      raise TypeError(message)
-    if not self._MIN <= proposed_value <= self._MAX:
-      raise ValueError('Value out of range: %d' % proposed_value)
-
-class _Int32ValueChecker(_IntValueChecker):
-  # We're sure to use ints instead of longs here since comparison may be more
-  # efficient.
-  _MIN = -2147483648
-  _MAX = 2147483647
-
-class _Uint32ValueChecker(_IntValueChecker):
-  _MIN = 0
-  _MAX = (1 << 32) - 1
-
-class _Int64ValueChecker(_IntValueChecker):
-  _MIN = -(1 << 63)
-  _MAX = (1 << 63) - 1
-
-class _Uint64ValueChecker(_IntValueChecker):
-  _MIN = 0
-  _MAX = (1 << 64) - 1
-
-
-# Type-checkers for all scalar CPPTYPEs.
-_VALUE_CHECKERS = {
-    _FieldDescriptor.CPPTYPE_INT32: _Int32ValueChecker(),
-    _FieldDescriptor.CPPTYPE_INT64: _Int64ValueChecker(),
-    _FieldDescriptor.CPPTYPE_UINT32: _Uint32ValueChecker(),
-    _FieldDescriptor.CPPTYPE_UINT64: _Uint64ValueChecker(),
-    _FieldDescriptor.CPPTYPE_DOUBLE: _TypeChecker(
-        float, int, long),
-    _FieldDescriptor.CPPTYPE_FLOAT: _TypeChecker(
-        float, int, long),
-    _FieldDescriptor.CPPTYPE_BOOL: _TypeChecker(bool, int),
-    _FieldDescriptor.CPPTYPE_ENUM: _Int32ValueChecker(),
-    _FieldDescriptor.CPPTYPE_STRING: _TypeChecker(str),
-    }
-
-
-# Map from field type to a function F, such that F(field_num, value)
-# gives the total byte size for a value of the given type.  This
-# byte size includes tag information and any other additional space
-# associated with serializing "value".
-_TYPE_TO_BYTE_SIZE_FN = {
-    _FieldDescriptor.TYPE_DOUBLE: wire_format.DoubleByteSize,
-    _FieldDescriptor.TYPE_FLOAT: wire_format.FloatByteSize,
-    _FieldDescriptor.TYPE_INT64: wire_format.Int64ByteSize,
-    _FieldDescriptor.TYPE_UINT64: wire_format.UInt64ByteSize,
-    _FieldDescriptor.TYPE_INT32: wire_format.Int32ByteSize,
-    _FieldDescriptor.TYPE_FIXED64: wire_format.Fixed64ByteSize,
-    _FieldDescriptor.TYPE_FIXED32: wire_format.Fixed32ByteSize,
-    _FieldDescriptor.TYPE_BOOL: wire_format.BoolByteSize,
-    _FieldDescriptor.TYPE_STRING: wire_format.StringByteSize,
-    _FieldDescriptor.TYPE_GROUP: wire_format.GroupByteSize,
-    _FieldDescriptor.TYPE_MESSAGE: wire_format.MessageByteSize,
-    _FieldDescriptor.TYPE_BYTES: wire_format.BytesByteSize,
-    _FieldDescriptor.TYPE_UINT32: wire_format.UInt32ByteSize,
-    _FieldDescriptor.TYPE_ENUM: wire_format.EnumByteSize,
-    _FieldDescriptor.TYPE_SFIXED32: wire_format.SFixed32ByteSize,
-    _FieldDescriptor.TYPE_SFIXED64: wire_format.SFixed64ByteSize,
-    _FieldDescriptor.TYPE_SINT32: wire_format.SInt32ByteSize,
-    _FieldDescriptor.TYPE_SINT64: wire_format.SInt64ByteSize
-    }
-
-# Maps from field type to an unbound Encoder method F, such that
-# F(encoder, field_number, value) will append the serialization
-# of a value of this type to the encoder.
-_Encoder = encoder.Encoder
-_TYPE_TO_SERIALIZE_METHOD = {
-    _FieldDescriptor.TYPE_DOUBLE: _Encoder.AppendDouble,
-    _FieldDescriptor.TYPE_FLOAT: _Encoder.AppendFloat,
-    _FieldDescriptor.TYPE_INT64: _Encoder.AppendInt64,
-    _FieldDescriptor.TYPE_UINT64: _Encoder.AppendUInt64,
-    _FieldDescriptor.TYPE_INT32: _Encoder.AppendInt32,
-    _FieldDescriptor.TYPE_FIXED64: _Encoder.AppendFixed64,
-    _FieldDescriptor.TYPE_FIXED32: _Encoder.AppendFixed32,
-    _FieldDescriptor.TYPE_BOOL: _Encoder.AppendBool,
-    _FieldDescriptor.TYPE_STRING: _Encoder.AppendString,
-    _FieldDescriptor.TYPE_GROUP: _Encoder.AppendGroup,
-    _FieldDescriptor.TYPE_MESSAGE: _Encoder.AppendMessage,
-    _FieldDescriptor.TYPE_BYTES: _Encoder.AppendBytes,
-    _FieldDescriptor.TYPE_UINT32: _Encoder.AppendUInt32,
-    _FieldDescriptor.TYPE_ENUM: _Encoder.AppendEnum,
-    _FieldDescriptor.TYPE_SFIXED32: _Encoder.AppendSFixed32,
-    _FieldDescriptor.TYPE_SFIXED64: _Encoder.AppendSFixed64,
-    _FieldDescriptor.TYPE_SINT32: _Encoder.AppendSInt32,
-    _FieldDescriptor.TYPE_SINT64: _Encoder.AppendSInt64,
-    }
-
-# Maps from field type to expected wiretype.
-_FIELD_TYPE_TO_WIRE_TYPE = {
-    _FieldDescriptor.TYPE_DOUBLE: wire_format.WIRETYPE_FIXED64,
-    _FieldDescriptor.TYPE_FLOAT: wire_format.WIRETYPE_FIXED32,
-    _FieldDescriptor.TYPE_INT64: wire_format.WIRETYPE_VARINT,
-    _FieldDescriptor.TYPE_UINT64: wire_format.WIRETYPE_VARINT,
-    _FieldDescriptor.TYPE_INT32: wire_format.WIRETYPE_VARINT,
-    _FieldDescriptor.TYPE_FIXED64: wire_format.WIRETYPE_FIXED64,
-    _FieldDescriptor.TYPE_FIXED32: wire_format.WIRETYPE_FIXED32,
-    _FieldDescriptor.TYPE_BOOL: wire_format.WIRETYPE_VARINT,
-    _FieldDescriptor.TYPE_STRING:
-      wire_format.WIRETYPE_LENGTH_DELIMITED,
-    _FieldDescriptor.TYPE_GROUP: wire_format.WIRETYPE_START_GROUP,
-    _FieldDescriptor.TYPE_MESSAGE:
-      wire_format.WIRETYPE_LENGTH_DELIMITED,
-    _FieldDescriptor.TYPE_BYTES:
-      wire_format.WIRETYPE_LENGTH_DELIMITED,
-    _FieldDescriptor.TYPE_UINT32: wire_format.WIRETYPE_VARINT,
-    _FieldDescriptor.TYPE_ENUM: wire_format.WIRETYPE_VARINT,
-    _FieldDescriptor.TYPE_SFIXED32: wire_format.WIRETYPE_FIXED32,
-    _FieldDescriptor.TYPE_SFIXED64: wire_format.WIRETYPE_FIXED64,
-    _FieldDescriptor.TYPE_SINT32: wire_format.WIRETYPE_VARINT,
-    _FieldDescriptor.TYPE_SINT64: wire_format.WIRETYPE_VARINT,
-    }
-
-# Maps from field type to an unbound Decoder method F,
-# such that F(decoder) will read a field of the requested type.
-#
-# Note that Message and Group are intentionally missing here.
-# They're handled by _RecursivelyMerge().
-_Decoder = decoder.Decoder
-_TYPE_TO_DESERIALIZE_METHOD = {
-    _FieldDescriptor.TYPE_DOUBLE: _Decoder.ReadDouble,
-    _FieldDescriptor.TYPE_FLOAT: _Decoder.ReadFloat,
-    _FieldDescriptor.TYPE_INT64: _Decoder.ReadInt64,
-    _FieldDescriptor.TYPE_UINT64: _Decoder.ReadUInt64,
-    _FieldDescriptor.TYPE_INT32: _Decoder.ReadInt32,
-    _FieldDescriptor.TYPE_FIXED64: _Decoder.ReadFixed64,
-    _FieldDescriptor.TYPE_FIXED32: _Decoder.ReadFixed32,
-    _FieldDescriptor.TYPE_BOOL: _Decoder.ReadBool,
-    _FieldDescriptor.TYPE_STRING: _Decoder.ReadString,
-    _FieldDescriptor.TYPE_BYTES: _Decoder.ReadBytes,
-    _FieldDescriptor.TYPE_UINT32: _Decoder.ReadUInt32,
-    _FieldDescriptor.TYPE_ENUM: _Decoder.ReadEnum,
-    _FieldDescriptor.TYPE_SFIXED32: _Decoder.ReadSFixed32,
-    _FieldDescriptor.TYPE_SFIXED64: _Decoder.ReadSFixed64,
-    _FieldDescriptor.TYPE_SINT32: _Decoder.ReadSInt32,
-    _FieldDescriptor.TYPE_SINT64: _Decoder.ReadSInt64,
-    }
diff --git a/python/google/protobuf/service.py b/python/google/protobuf/service.py
index 461031b708b5ca45c6731f3e9bcf7d9102d4dfeb..5d3439576a61376a9872dd30bb4bb31204eda6e7 100755
--- a/python/google/protobuf/service.py
+++ b/python/google/protobuf/service.py
@@ -85,18 +85,14 @@ class Service(object):
 
 class RpcController(object):
 
-  """Abstract interface for an RPC channel.
-
-  An RpcChannel represents a communication line to a service which can be used
-  to call that service's methods.  The service may be running on another
-  machine. Normally, you should not use an RpcChannel directly, but instead
-  construct a stub {@link Service} wrapping it.  Example:
+  """An RpcController mediates a single method call.
 
-  Example:
-    RpcChannel channel = rpcImpl.Channel("remotehost.example.com:1234")
-    RpcController controller = rpcImpl.Controller()
-    MyService service = MyService_Stub(channel)
-    service.MyMethod(controller, request, callback)
+  The primary purpose of the controller is to provide a way to manipulate
+  settings specific to the RPC implementation and to find out about RPC-level
+  errors. The methods provided by the RpcController interface are intended
+  to be a "least common denominator" set of features which we expect all
+  implementations to support.  Specific implementations may provide more
+  advanced features (e.g. deadline propagation).
   """
 
   # Client-side methods below
@@ -172,14 +168,18 @@ class RpcController(object):
 
 class RpcChannel(object):
 
-  """An RpcController mediates a single method call.
+  """Abstract interface for an RPC channel.
 
-  The primary purpose of the controller is to provide a way to manipulate
-  settings specific to the RPC implementation and to find out about RPC-level
-  errors. The methods provided by the RpcController interface are intended
-  to be a "least common denominator" set of features which we expect all
-  implementations to support.  Specific implementations may provide more
-  advanced features (e.g. deadline propagation).
+  An RpcChannel represents a communication line to a service which can be used
+  to call that service's methods.  The service may be running on another
+  machine. Normally, you should not use an RpcChannel directly, but instead
+  construct a stub {@link Service} wrapping it.  Example:
+
+  Example:
+    RpcChannel channel = rpcImpl.Channel("remotehost.example.com:1234")
+    RpcController controller = rpcImpl.Controller()
+    MyService service = MyService_Stub(channel)
+    service.MyMethod(controller, request, callback)
   """
 
   def CallMethod(self, method_descriptor, rpc_controller,
diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc
index 8f559f55f1c9ae7d69e14dc91b75af36535fa892..d58fc3b85e5e10d0983babcf9cab96aac402dad1 100644
--- a/src/google/protobuf/compiler/command_line_interface.cc
+++ b/src/google/protobuf/compiler/command_line_interface.cc
@@ -35,6 +35,8 @@
 #include <google/protobuf/compiler/importer.h>
 #include <google/protobuf/compiler/code_generator.h>
 #include <google/protobuf/descriptor.h>
+#include <google/protobuf/text_format.h>
+#include <google/protobuf/dynamic_message.h>
 #include <google/protobuf/io/zero_copy_stream_impl.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/strutil.h>
@@ -52,6 +54,12 @@ namespace compiler {
 #ifndef F_OK
 #define F_OK 00  // not defined by MSVC for whatever reason
 #endif
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
 #endif
 
 #ifndef O_BINARY
@@ -82,10 +90,31 @@ static bool IsWindowsAbsolutePath(const string& text) {
 #endif
 }
 
+void SetFdToTextMode(int fd) {
+#ifdef _WIN32
+  if (_setmode(fd, _O_TEXT) == -1) {
+    // This should never happen, I think.
+    GOOGLE_LOG(WARNING) << "_setmode(" << fd << ", _O_TEXT): " << strerror(errno);
+  }
+#endif
+  // (Text and binary are the same on non-Windows platforms.)
+}
+
+void SetFdToBinaryMode(int fd) {
+#ifdef _WIN32
+  if (_setmode(fd, _O_BINARY) == -1) {
+    // This should never happen, I think.
+    GOOGLE_LOG(WARNING) << "_setmode(" << fd << ", _O_BINARY): " << strerror(errno);
+  }
+#endif
+  // (Text and binary are the same on non-Windows platforms.)
+}
+
 }  // namespace
 
 // A MultiFileErrorCollector that prints errors to stderr.
-class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector {
+class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector,
+                                           public io::ErrorCollector {
  public:
   ErrorPrinter() {}
   ~ErrorPrinter() {}
@@ -101,6 +130,11 @@ class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector {
     }
     cerr << ": " << message << endl;
   }
+
+  // implements io::ErrorCollector -----------------------------------
+  void AddError(int line, int column, const string& message) {
+    AddError("input", line, column, message);
+  }
 };
 
 // -------------------------------------------------------------------
@@ -243,7 +277,9 @@ CommandLineInterface::ErrorReportingFileOutput::~ErrorReportingFileOutput() {
 // ===================================================================
 
 CommandLineInterface::CommandLineInterface()
-  : disallow_services_(false),
+  : mode_(MODE_COMPILE),
+    imports_in_descriptor_set_(false),
+    disallow_services_(false),
     inputs_are_proto_path_relative_(false) {}
 CommandLineInterface::~CommandLineInterface() {}
 
@@ -258,7 +294,7 @@ void CommandLineInterface::RegisterGenerator(const string& flag_name,
 
 int CommandLineInterface::Run(int argc, const char* const argv[]) {
   Clear();
-  if (!ParseArguments(argc, argv)) return -1;
+  if (!ParseArguments(argc, argv)) return 1;
 
   // Set up the source tree.
   DiskSourceTree source_tree;
@@ -269,32 +305,61 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) {
   // Map input files to virtual paths if necessary.
   if (!inputs_are_proto_path_relative_) {
     if (!MakeInputsBeProtoPathRelative(&source_tree)) {
-      return -1;
+      return 1;
     }
   }
 
   // Allocate the Importer.
   ErrorPrinter error_collector;
-  DescriptorPool pool;
   Importer importer(&source_tree, &error_collector);
 
+  vector<const FileDescriptor*> parsed_files;
+
   // Parse each file and generate output.
   for (int i = 0; i < input_files_.size(); i++) {
     // Import the file.
     const FileDescriptor* parsed_file = importer.Import(input_files_[i]);
-    if (parsed_file == NULL) return -1;
+    if (parsed_file == NULL) return 1;
+    parsed_files.push_back(parsed_file);
 
     // Enforce --disallow_services.
     if (disallow_services_ && parsed_file->service_count() > 0) {
       cerr << parsed_file->name() << ": This file contains services, but "
               "--disallow_services was used." << endl;
-      return -1;
+      return 1;
     }
 
-    // Generate output files.
-    for (int i = 0; i < output_directives_.size(); i++) {
-      if (!GenerateOutput(parsed_file, output_directives_[i])) {
-        return -1;
+    if (mode_ == MODE_COMPILE) {
+      // Generate output files.
+      for (int i = 0; i < output_directives_.size(); i++) {
+        if (!GenerateOutput(parsed_file, output_directives_[i])) {
+          return 1;
+        }
+      }
+    }
+  }
+
+  if (!descriptor_set_name_.empty()) {
+    if (!WriteDescriptorSet(parsed_files)) {
+      return 1;
+    }
+  }
+
+  if (mode_ == MODE_ENCODE || mode_ == MODE_DECODE) {
+    if (codec_type_.empty()) {
+      // HACK:  Define an EmptyMessage type to use for decoding.
+      DescriptorPool pool;
+      FileDescriptorProto file;
+      file.set_name("empty_message.proto");
+      file.add_message_type()->set_name("EmptyMessage");
+      GOOGLE_CHECK(pool.BuildFile(file) != NULL);
+      codec_type_ = "EmptyMessage";
+      if (!EncodeOrDecode(&pool)) {
+        return 1;
+      }
+    } else {
+      if (!EncodeOrDecode(importer.pool())) {
+        return 1;
       }
     }
   }
@@ -303,9 +368,18 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) {
 }
 
 void CommandLineInterface::Clear() {
+  // Clear all members that are set by Run().  Note that we must not clear
+  // members which are set by other methods before Run() is called.
+  executable_name_.clear();
   proto_path_.clear();
   input_files_.clear();
   output_directives_.clear();
+  codec_type_.clear();
+  descriptor_set_name_.clear();
+
+  mode_ = MODE_COMPILE;
+  imports_in_descriptor_set_ = false;
+  disallow_services_ = false;
 }
 
 bool CommandLineInterface::MakeInputsBeProtoPathRelative(
@@ -351,9 +425,12 @@ bool CommandLineInterface::ParseArguments(int argc, const char* const argv[]) {
     string name, value;
 
     if (ParseArgument(argv[i], &name, &value)) {
-      // Retured true => Use the next argument as the flag value.
+      // Returned true => Use the next argument as the flag value.
       if (i + 1 == argc || argv[i+1][0] == '-') {
         cerr << "Missing value for flag: " << name << endl;
+        if (name == "--decode") {
+          cerr << "To decode an unknown message, use --decode_raw." << endl;
+        }
         return false;
       } else {
         ++i;
@@ -370,14 +447,23 @@ bool CommandLineInterface::ParseArguments(int argc, const char* const argv[]) {
   }
 
   // Check some errror cases.
-  if (input_files_.empty()) {
+  bool decoding_raw = (mode_ == MODE_DECODE) && codec_type_.empty();
+  if (decoding_raw && !input_files_.empty()) {
+    cerr << "When using --decode_raw, no input files should be given." << endl;
+    return false;
+  } else if (!decoding_raw && input_files_.empty()) {
     cerr << "Missing input file." << endl;
     return false;
   }
-  if (output_directives_.empty()) {
+  if (mode_ == MODE_COMPILE && output_directives_.empty() &&
+      descriptor_set_name_.empty()) {
     cerr << "Missing output directives." << endl;
     return false;
   }
+  if (imports_in_descriptor_set_ && descriptor_set_name_.empty()) {
+    cerr << "--include_imports only makes sense when combined with "
+            "--descriptor_set_name." << endl;
+  }
 
   return true;
 }
@@ -428,7 +514,9 @@ bool CommandLineInterface::ParseArgument(const char* arg,
 
   if (*name == "-h" || *name == "--help" ||
       *name == "--disallow_services" ||
-      *name == "--version") {
+      *name == "--include_imports" ||
+      *name == "--version" ||
+      *name == "--decode_raw") {
     // HACK:  These are the only flags that don't take a value.
     //   They probably should not be hard-coded like this but for now it's
     //   not worth doing better.
@@ -487,6 +575,29 @@ bool CommandLineInterface::InterpretArgument(const string& name,
       proto_path_.push_back(make_pair(virtual_path, disk_path));
     }
 
+  } else if (name == "-o" || name == "--descriptor_set_out") {
+    if (!descriptor_set_name_.empty()) {
+      cerr << name << " may only be passed once." << endl;
+      return false;
+    }
+    if (value.empty()) {
+      cerr << name << " requires a non-empty value." << endl;
+      return false;
+    }
+    if (mode_ != MODE_COMPILE) {
+      cerr << "Cannot use --encode or --decode and generate descriptors at the "
+              "same time." << endl;
+      return false;
+    }
+    descriptor_set_name_ = value;
+
+  } else if (name == "--include_imports") {
+    if (imports_in_descriptor_set_) {
+      cerr << name << " may only be passed once." << endl;
+      return false;
+    }
+    imports_in_descriptor_set_ = true;
+
   } else if (name == "-h" || name == "--help") {
     PrintHelpText();
     return false;  // Exit without running compiler.
@@ -503,6 +614,33 @@ bool CommandLineInterface::InterpretArgument(const string& name,
   } else if (name == "--disallow_services") {
     disallow_services_ = true;
 
+  } else if (name == "--encode" || name == "--decode" ||
+             name == "--decode_raw") {
+    if (mode_ != MODE_COMPILE) {
+      cerr << "Only one of --encode and --decode can be specified." << endl;
+      return false;
+    }
+    if (!output_directives_.empty() || !descriptor_set_name_.empty()) {
+      cerr << "Cannot use " << name
+           << " and generate code or descriptors at the same time." << endl;
+      return false;
+    }
+
+    mode_ = (name == "--encode") ? MODE_ENCODE : MODE_DECODE;
+
+    if (value.empty() && name != "--decode_raw") {
+      cerr << "Type name for " << name << " cannot be blank." << endl;
+      if (name == "--decode") {
+        cerr << "To decode an unknown message, use --decode_raw." << endl;
+      }
+      return false;
+    } else if (!value.empty() && name == "--decode_raw") {
+      cerr << "--decode_raw does not take a parameter." << endl;
+      return false;
+    }
+
+    codec_type_ = value;
+
   } else {
     // Some other flag.  Look it up in the generators list.
     GeneratorMap::const_iterator iter = generators_.find(name);
@@ -512,6 +650,12 @@ bool CommandLineInterface::InterpretArgument(const string& name,
     }
 
     // It's an output flag.  Add it to the output directives.
+    if (mode_ != MODE_COMPILE) {
+      cerr << "Cannot use --encode or --decode and generate code at the "
+              "same time." << endl;
+      return false;
+    }
+
     OutputDirective directive;
     directive.name = name;
     directive.generator = iter->second.generator;
@@ -536,14 +680,33 @@ bool CommandLineInterface::InterpretArgument(const string& name,
 void CommandLineInterface::PrintHelpText() {
   // Sorry for indentation here; line wrapping would be uglier.
   cerr <<
-"Usage: " << executable_name_ << " [OPTION] PROTO_FILE\n"
-"Parse PROTO_FILE and generate output based on the options given:\n"
+"Usage: " << executable_name_ << " [OPTION] PROTO_FILES\n"
+"Parse PROTO_FILES and generate output based on the options given:\n"
 "  -IPATH, --proto_path=PATH   Specify the directory in which to search for\n"
 "                              imports.  May be specified multiple times;\n"
 "                              directories will be searched in order.  If not\n"
 "                              given, the current working directory is used.\n"
 "  --version                   Show version info and exit.\n"
-"  -h, --help                  Show this text and exit." << endl;
+"  -h, --help                  Show this text and exit.\n"
+"  --encode=MESSAGE_TYPE       Read a text-format message of the given type\n"
+"                              from standard input and write it in binary\n"
+"                              to standard output.  The message type must\n"
+"                              be defined in PROTO_FILES or their imports.\n"
+"  --decode=MESSAGE_TYPE       Read a binary message of the given type from\n"
+"                              standard input and write it in text format\n"
+"                              to standard output.  The message type must\n"
+"                              be defined in PROTO_FILES or their imports.\n"
+"  --decode_raw                Read an arbitrary protocol message from\n"
+"                              standard input and write the raw tag/value\n"
+"                              pairs in text format to standard output.  No\n"
+"                              PROTO_FILES should be given when using this\n"
+"                              flag.\n"
+"  -oFILE,                     Writes a FileDescriptorSet (a protocol buffer,\n"
+"    --descriptor_set_out=FILE defined in descriptor.proto) containing all of\n"
+"                              the input files to FILE.\n"
+"  --include_imports           When using --descriptor_set_out, also include\n"
+"                              all dependencies of the input files in the\n"
+"                              set, so that the set is self-contained." << endl;
 
   for (GeneratorMap::iterator iter = generators_.begin();
        iter != generators_.end(); ++iter) {
@@ -584,6 +747,116 @@ bool CommandLineInterface::GenerateOutput(
   return true;
 }
 
+bool CommandLineInterface::EncodeOrDecode(const DescriptorPool* pool) {
+  // Look up the type.
+  const Descriptor* type = pool->FindMessageTypeByName(codec_type_);
+  if (type == NULL) {
+    cerr << "Type not defined: " << codec_type_ << endl;
+    return false;
+  }
+
+  DynamicMessageFactory dynamic_factory(pool);
+  scoped_ptr<Message> message(dynamic_factory.GetPrototype(type)->New());
+
+  if (mode_ == MODE_ENCODE) {
+    SetFdToTextMode(STDIN_FILENO);
+    SetFdToBinaryMode(STDOUT_FILENO);
+  } else {
+    SetFdToBinaryMode(STDIN_FILENO);
+    SetFdToTextMode(STDOUT_FILENO);
+  }
+
+  io::FileInputStream in(STDIN_FILENO);
+  io::FileOutputStream out(STDOUT_FILENO);
+
+  if (mode_ == MODE_ENCODE) {
+    // Input is text.
+    ErrorPrinter error_collector;
+    TextFormat::Parser parser;
+    parser.RecordErrorsTo(&error_collector);
+    parser.AllowPartialMessage(true);
+
+    if (!parser.Parse(&in, message.get())) {
+      cerr << "Failed to parse input." << endl;
+      return false;
+    }
+  } else {
+    // Input is binary.
+    if (!message->ParsePartialFromZeroCopyStream(&in)) {
+      cerr << "Failed to parse input." << endl;
+      return false;
+    }
+  }
+
+  if (!message->IsInitialized()) {
+    cerr << "warning:  Input message is missing required fields:  "
+         << message->InitializationErrorString() << endl;
+  }
+
+  if (mode_ == MODE_ENCODE) {
+    // Output is binary.
+    if (!message->SerializePartialToZeroCopyStream(&out)) {
+      cerr << "output: I/O error." << endl;
+      return false;
+    }
+  } else {
+    // Output is text.
+    if (!TextFormat::Print(*message, &out)) {
+      cerr << "output: I/O error." << endl;
+      return false;
+    }
+  }
+
+  return true;
+}
+
+bool CommandLineInterface::WriteDescriptorSet(
+    const vector<const FileDescriptor*> parsed_files) {
+  FileDescriptorSet file_set;
+  set<const FileDescriptor*> already_added;
+  vector<const FileDescriptor*> to_add(parsed_files);
+
+  while (!to_add.empty()) {
+    const FileDescriptor* file = to_add.back();
+    to_add.pop_back();
+    if (already_added.insert(file).second) {
+      // This file was not already in the set.
+      file->CopyTo(file_set.add_file());
+
+      if (imports_in_descriptor_set_) {
+        // Add all of this file's dependencies.
+        for (int i = 0; i < file->dependency_count(); i++) {
+          to_add.push_back(file->dependency(i));
+        }
+      }
+    }
+  }
+
+  int fd;
+  do {
+    fd = open(descriptor_set_name_.c_str(),
+              O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
+  } while (fd < 0 && errno == EINTR);
+
+  if (fd < 0) {
+    perror(descriptor_set_name_.c_str());
+    return false;
+  }
+
+  io::FileOutputStream out(fd);
+  if (!file_set.SerializeToZeroCopyStream(&out)) {
+    cerr << descriptor_set_name_ << ": " << strerror(out.GetErrno()) << endl;
+    out.Close();
+    return false;
+  }
+  if (!out.Close()) {
+    cerr << descriptor_set_name_ << ": " << strerror(out.GetErrno()) << endl;
+    return false;
+  }
+
+  return true;
+}
+
 
 }  // namespace compiler
 }  // namespace protobuf
diff --git a/src/google/protobuf/compiler/command_line_interface.h b/src/google/protobuf/compiler/command_line_interface.h
index d3cae75e0c83dd08982260b4136a92e451eb2ac6..9185e47aef79a77d668b0ce76254a697ff22d581 100644
--- a/src/google/protobuf/compiler/command_line_interface.h
+++ b/src/google/protobuf/compiler/command_line_interface.h
@@ -35,6 +35,7 @@ namespace google {
 namespace protobuf {
 
 class FileDescriptor;        // descriptor.h
+class DescriptorPool;        // descriptor.h
 
 namespace compiler {
 
@@ -164,6 +165,12 @@ class LIBPROTOC_EXPORT CommandLineInterface {
   bool GenerateOutput(const FileDescriptor* proto_file,
                       const OutputDirective& output_directive);
 
+  // Implements --encode and --decode.
+  bool EncodeOrDecode(const DescriptorPool* pool);
+
+  // Implements the --descriptor_set_out option.
+  bool WriteDescriptorSet(const vector<const FileDescriptor*> parsed_files);
+
   // -----------------------------------------------------------------
 
   // The name of the executable as invoked (i.e. argv[0]).
@@ -181,6 +188,14 @@ class LIBPROTOC_EXPORT CommandLineInterface {
   GeneratorMap generators_;
 
   // Stuff parsed from command line.
+  enum Mode {
+    MODE_COMPILE,  // Normal mode:  parse .proto files and compile them.
+    MODE_ENCODE,   // --encode:  read text from stdin, write binary to stdout.
+    MODE_DECODE    // --decode:  read binary from stdin, write text to stdout.
+  };
+
+  Mode mode_;
+
   vector<pair<string, string> > proto_path_;  // Search path for proto files.
   vector<string> input_files_;                // Names of the input proto files.
 
@@ -194,6 +209,19 @@ class LIBPROTOC_EXPORT CommandLineInterface {
   };
   vector<OutputDirective> output_directives_;
 
+  // When using --encode or --decode, this names the type we are encoding or
+  // decoding.  (Empty string indicates --decode_raw.)
+  string codec_type_;
+
+  // If --descriptor_set_out was given, this is the filename to which the
+  // FileDescriptorSet should be written.  Otherwise, empty.
+  string descriptor_set_name_;
+
+  // True if --include_imports was given, meaning that we should
+  // write all transitive dependencies to the DescriptorSet.  Otherwise, only
+  // the .proto files listed on the command-line are added.
+  bool imports_in_descriptor_set_;
+
   // Was the --disallow_services flag used?
   bool disallow_services_;
 
diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc
index 09644466dfd5316f2d8ea047290d497bd98cdc49..d67cbe0d4cf820c74875f5306ace202c2d72e206 100644
--- a/src/google/protobuf/compiler/command_line_interface_unittest.cc
+++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc
@@ -18,13 +18,23 @@
 //  Based on original Protocol Buffers design by
 //  Sanjay Ghemawat, Jeff Dean, and others.
 
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifdef _MSC_VER
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
 #include <vector>
 
+#include <google/protobuf/descriptor.pb.h>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/io/zero_copy_stream.h>
 #include <google/protobuf/compiler/command_line_interface.h>
 #include <google/protobuf/compiler/code_generator.h>
 #include <google/protobuf/io/printer.h>
+#include <google/protobuf/unittest.pb.h>
 #include <google/protobuf/testing/file.h>
 #include <google/protobuf/stubs/strutil.h>
 
@@ -35,6 +45,15 @@ namespace google {
 namespace protobuf {
 namespace compiler {
 
+#if defined(_WIN32)
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
+#endif
+
 namespace {
 
 class CommandLineInterfaceTest : public testing::Test {
@@ -110,6 +129,9 @@ class CommandLineInterfaceTest : public testing::Test {
                        const string& message_name,
                        const string& output_file);
 
+  void ReadDescriptorSet(const string& filename,
+                         FileDescriptorSet* descriptor_set);
+
  private:
   // The object we are testing.
   CommandLineInterface cli_;
@@ -333,6 +355,18 @@ void CommandLineInterfaceTest::ExpectGenerated(
     << "Output file did not have expected contents: " + output_file;
 }
 
+void CommandLineInterfaceTest::ReadDescriptorSet(
+    const string& filename, FileDescriptorSet* descriptor_set) {
+  string path = temp_directory_ + "/" + filename;
+  string file_contents;
+  if (!File::ReadFileToString(path, &file_contents)) {
+    FAIL() << "File not found: " << path;
+  }
+  if (!descriptor_set->ParseFromString(file_contents)) {
+    FAIL() << "Could not parse file contents: " << path;
+  }
+}
+
 // ===================================================================
 
 CommandLineInterfaceTest::MockCodeGenerator::MockCodeGenerator(
@@ -665,6 +699,57 @@ TEST_F(CommandLineInterfaceTest, CwdRelativeInputs) {
   ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test");
 }
 
+TEST_F(CommandLineInterfaceTest, WriteDescriptorSet) {
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+  CreateTempFile("bar.proto",
+    "syntax = \"proto2\";\n"
+    "import \"foo.proto\";\n"
+    "message Bar {\n"
+    "  optional Foo foo = 1;\n"
+    "}\n");
+
+  Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set "
+      "--proto_path=$tmpdir bar.proto");
+
+  ExpectNoErrors();
+
+  FileDescriptorSet descriptor_set;
+  ReadDescriptorSet("descriptor_set", &descriptor_set);
+  if (HasFatalFailure()) return;
+  ASSERT_EQ(1, descriptor_set.file_size());
+  EXPECT_EQ("bar.proto", descriptor_set.file(0).name());
+}
+
+TEST_F(CommandLineInterfaceTest, WriteTransitiveDescriptorSet) {
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+  CreateTempFile("bar.proto",
+    "syntax = \"proto2\";\n"
+    "import \"foo.proto\";\n"
+    "message Bar {\n"
+    "  optional Foo foo = 1;\n"
+    "}\n");
+
+  Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set "
+      "--include_imports --proto_path=$tmpdir bar.proto");
+
+  ExpectNoErrors();
+
+  FileDescriptorSet descriptor_set;
+  ReadDescriptorSet("descriptor_set", &descriptor_set);
+  if (HasFatalFailure()) return;
+  ASSERT_EQ(2, descriptor_set.file_size());
+  if (descriptor_set.file(0).name() == "bar.proto") {
+    swap(descriptor_set.mutable_file()->mutable_data()[0],
+         descriptor_set.mutable_file()->mutable_data()[1]);
+  }
+  EXPECT_EQ("foo.proto", descriptor_set.file(0).name());
+  EXPECT_EQ("bar.proto", descriptor_set.file(1).name());
+}
+
 // -------------------------------------------------------------------
 
 TEST_F(CommandLineInterfaceTest, ParseErrors) {
@@ -954,14 +1039,14 @@ TEST_F(CommandLineInterfaceTest, HelpText) {
 TEST_F(CommandLineInterfaceTest, ParseSingleCharacterFlag) {
   // Test that a single-character flag works.
 
-  RegisterGenerator("test_generator", "-o",
+  RegisterGenerator("test_generator", "-t",
                     "output.test", "Test output.");
 
   CreateTempFile("foo.proto",
     "syntax = \"proto2\";\n"
     "message Foo {}\n");
 
-  Run("protocol_compiler -o$tmpdir "
+  Run("protocol_compiler -t$tmpdir "
       "--proto_path=$tmpdir foo.proto");
 
   ExpectNoErrors();
@@ -989,14 +1074,14 @@ TEST_F(CommandLineInterfaceTest, ParseSingleCharacterSpaceDelimitedValue) {
   // Test that separating the flag value with a space works for
   // single-character flags.
 
-  RegisterGenerator("test_generator", "-o",
+  RegisterGenerator("test_generator", "-t",
                     "output.test", "Test output.");
 
   CreateTempFile("foo.proto",
     "syntax = \"proto2\";\n"
     "message Foo {}\n");
 
-  Run("protocol_compiler -o $tmpdir "
+  Run("protocol_compiler -t $tmpdir "
       "--proto_path=$tmpdir foo.proto");
 
   ExpectNoErrors();
@@ -1026,6 +1111,166 @@ TEST_F(CommandLineInterfaceTest, MissingValueAtEndError) {
   ExpectErrorText("Missing value for flag: --test_out\n");
 }
 
+// ===================================================================
+
+// Test for --encode and --decode.  Note that it would be easier to do this
+// test as a shell script, but we'd like to be able to run the test on
+// platforms that don't have a Bourne-compatible shell available (especially
+// Windows/MSVC).
+class EncodeDecodeTest : public testing::Test {
+ protected:
+  virtual void SetUp() {
+    duped_stdin_ = dup(STDIN_FILENO);
+  }
+
+  virtual void TearDown() {
+    dup2(duped_stdin_, STDIN_FILENO);
+    close(duped_stdin_);
+  }
+
+  void RedirectStdinFromText(const string& input) {
+    string filename = TestTempDir() + "/test_stdin";
+    File::WriteStringToFileOrDie(input, filename);
+    GOOGLE_CHECK(RedirectStdinFromFile(filename));
+  }
+
+  bool RedirectStdinFromFile(const string& filename) {
+    int fd = open(filename.c_str(), O_RDONLY);
+    if (fd < 0) return false;
+    dup2(fd, STDIN_FILENO);
+    close(fd);
+    return true;
+  }
+
+  // Remove '\r' characters from text.
+  string StripCR(const string& text) {
+    string result;
+
+    for (int i = 0; i < text.size(); i++) {
+      if (text[i] != '\r') {
+        result.push_back(text[i]);
+      }
+    }
+
+    return result;
+  }
+
+  enum Type { TEXT, BINARY };
+  enum ReturnCode { SUCCESS, ERROR };
+
+  bool Run(const string& command) {
+    vector<string> args;
+    args.push_back("protoc");
+    SplitStringUsing(command, " ", &args);
+    args.push_back("--proto_path=" + TestSourceDir());
+
+    scoped_array<const char*> argv(new const char*[args.size()]);
+    for (int i = 0; i < args.size(); i++) {
+      argv[i] = args[i].c_str();
+    }
+
+    CommandLineInterface cli;
+    cli.SetInputsAreProtoPathRelative(true);
+
+    CaptureTestStdout();
+    CaptureTestStderr();
+
+    int result = cli.Run(args.size(), argv.get());
+
+    captured_stdout_ = GetCapturedTestStdout();
+    captured_stderr_ = GetCapturedTestStderr();
+
+    return result == 0;
+  }
+
+  void ExpectStdoutMatchesBinaryFile(const string& filename) {
+    string expected_output;
+    ASSERT_TRUE(File::ReadFileToString(filename, &expected_output));
+
+    // Don't use EXPECT_EQ because we don't want to print raw binary data to
+    // stdout on failure.
+    EXPECT_TRUE(captured_stdout_ == expected_output);
+  }
+
+  void ExpectStdoutMatchesTextFile(const string& filename) {
+    string expected_output;
+    ASSERT_TRUE(File::ReadFileToString(filename, &expected_output));
+
+    ExpectStdoutMatchesText(expected_output);
+  }
+
+  void ExpectStdoutMatchesText(const string& expected_text) {
+    EXPECT_EQ(StripCR(expected_text), StripCR(captured_stdout_));
+  }
+
+  void ExpectStderrMatchesText(const string& expected_text) {
+    EXPECT_EQ(StripCR(expected_text), StripCR(captured_stderr_));
+  }
+
+ private:
+  int duped_stdin_;
+  string captured_stdout_;
+  string captured_stderr_;
+};
+
+TEST_F(EncodeDecodeTest, Encode) {
+  RedirectStdinFromFile(TestSourceDir() +
+    "/google/protobuf/testdata/text_format_unittest_data.txt");
+  EXPECT_TRUE(Run("google/protobuf/unittest.proto "
+                  "--encode=protobuf_unittest.TestAllTypes"));
+  ExpectStdoutMatchesBinaryFile(TestSourceDir() +
+    "/google/protobuf/testdata/golden_message");
+  ExpectStderrMatchesText("");
+}
+
+TEST_F(EncodeDecodeTest, Decode) {
+  RedirectStdinFromFile(TestSourceDir() +
+    "/google/protobuf/testdata/golden_message");
+  EXPECT_TRUE(Run("google/protobuf/unittest.proto "
+                  "--decode=protobuf_unittest.TestAllTypes"));
+  ExpectStdoutMatchesTextFile(TestSourceDir() +
+    "/google/protobuf/testdata/text_format_unittest_data.txt");
+  ExpectStderrMatchesText("");
+}
+
+TEST_F(EncodeDecodeTest, Partial) {
+  RedirectStdinFromText("");
+  EXPECT_TRUE(Run("google/protobuf/unittest.proto "
+                  "--encode=protobuf_unittest.TestRequired"));
+  ExpectStdoutMatchesText("");
+  ExpectStderrMatchesText(
+    "warning:  Input message is missing required fields:  a, b, c\n");
+}
+
+TEST_F(EncodeDecodeTest, DecodeRaw) {
+  protobuf_unittest::TestAllTypes message;
+  message.set_optional_int32(123);
+  message.set_optional_string("foo");
+  string data;
+  message.SerializeToString(&data);
+
+  RedirectStdinFromText(data);
+  EXPECT_TRUE(Run("--decode_raw"));
+  ExpectStdoutMatchesText("1: 123\n"
+                          "14: \"foo\"\n");
+  ExpectStderrMatchesText("");
+}
+
+TEST_F(EncodeDecodeTest, UnknownType) {
+  EXPECT_FALSE(Run("google/protobuf/unittest.proto "
+                   "--encode=NoSuchType"));
+  ExpectStdoutMatchesText("");
+  ExpectStderrMatchesText("Type not defined: NoSuchType\n");
+}
+
+TEST_F(EncodeDecodeTest, ProtoParseError) {
+  EXPECT_FALSE(Run("google/protobuf/no_such_file.proto "
+                   "--encode=NoSuchType"));
+  ExpectStdoutMatchesText("");
+  ExpectStderrMatchesText(
+    "google/protobuf/no_such_file.proto: File not found.\n");
+}
+
 }  // anonymous namespace
 
 }  // namespace compiler
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc
index aea3a4b2fca3127e956340e068ce28d2a1421555..f88d63fce5122dbd89e35cbdcac0e9d69bc2478b 100644
--- a/src/google/protobuf/compiler/cpp/cpp_file.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_file.cc
@@ -128,7 +128,14 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
   // Open namespace.
   GenerateNamespaceOpeners(printer);
 
-  printer->Print("\n");
+  // Forward-declare the BuildDescriptors function, so that we can declare it
+  // to be a friend of each class.
+  printer->Print(
+    "\n"
+    "// Internal implementation detail -- do not call this.\n"
+    "void $builddescriptorsname$();\n"
+    "\n",
+    "builddescriptorsname", GlobalBuildDescriptorsName(file_->name()));
 
   // Generate forward declarations of classes.
   for (int i = 0; i < file_->message_type_count(); i++) {
@@ -302,6 +309,9 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
   // time, because every message has a statically-initialized default instance,
   // and the constructor for a message class accesses its descriptor.  See the
   // constructor and the descriptor() method of message classes.
+  //
+  // We also construct the reflection object for each class inside
+  // BuildDescriptors().
   printer->Print(
     "\n"
     "void $builddescriptorsname$() {\n"
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
index 21de816c5580dcd8b8c5e711b6425b2b7f48719c..6a49f815197d090d3e1861e61088be6df1a81646 100644
--- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
@@ -188,7 +188,7 @@ string FilenameIdentifier(const string& filename) {
 
 // Return the name of the BuildDescriptors() function for a given file.
 string GlobalBuildDescriptorsName(const string& filename) {
-  return "proto_BuildDescriptors_" + FilenameIdentifier(filename);
+  return "protobuf_BuildDesc_" + FilenameIdentifier(filename);
 }
 
 }  // namespace cpp
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc
index 002b0ad299b1c9095d7b6d21d94ef53379a9fa27..afd99314ee5036e67b03e3c3339e502a3d69eb75 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -374,6 +374,8 @@ GenerateClassDefinition(io::Printer* printer) {
   } else {
     vars["dllexport"] = dllexport_decl_ + " ";
   }
+  vars["builddescriptorsname"] =
+    GlobalBuildDescriptorsName(descriptor_->file()->name());
 
   printer->Print(vars,
     "class $dllexport$$classname$ : public ::google::protobuf::Message {\n"
@@ -396,11 +398,11 @@ GenerateClassDefinition(io::Printer* printer) {
     "}\n"
     "\n"
     "inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {\n"
-    "  return _reflection_.unknown_fields();\n"
+    "  return _unknown_fields_;\n"
     "}\n"
     "\n"
     "inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {\n"
-    "  return _reflection_.mutable_unknown_fields();\n"
+    "  return &_unknown_fields_;\n"
     "}\n"
     "\n"
     "static const ::google::protobuf::Descriptor* descriptor();\n"
@@ -432,8 +434,7 @@ GenerateClassDefinition(io::Printer* printer) {
     "public:\n"
     "\n"
     "const ::google::protobuf::Descriptor* GetDescriptor() const;\n"
-    "const ::google::protobuf::Message::Reflection* GetReflection() const;\n"
-    "::google::protobuf::Message::Reflection* GetReflection();\n"
+    "const ::google::protobuf::Reflection* GetReflection() const;\n"
     "\n"
     "// nested types ----------------------------------------------------\n"
     "\n");
@@ -481,7 +482,7 @@ GenerateClassDefinition(io::Printer* printer) {
 
   // TODO(kenton):  Make _cached_size_ an atomic<int> when C++ supports it.
   printer->Print(
-    "::google::protobuf::internal::GeneratedMessageReflection _reflection_;\n"
+    "::google::protobuf::UnknownFieldSet _unknown_fields_;\n"
     "mutable int _cached_size_;\n"
     "\n");
   for (int i = 0; i < descriptor_->field_count(); i++) {
@@ -491,7 +492,7 @@ GenerateClassDefinition(io::Printer* printer) {
 
   // Generate offsets and _has_bits_ boilerplate.
   printer->Print(vars,
-    "\n"
+    "friend void $builddescriptorsname$();\n"
     "static const $classname$ default_instance_;\n");
 
   if (descriptor_->field_count() > 0) {
@@ -540,8 +541,11 @@ GenerateInlineMethods(io::Printer* printer) {
 
 void MessageGenerator::
 GenerateDescriptorDeclarations(io::Printer* printer) {
-  printer->Print("const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n",
-                 "name", classname_);
+  printer->Print(
+    "const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n"
+    "const ::google::protobuf::internal::GeneratedMessageReflection*\n"
+    "  $name$_reflection_ = NULL;\n",
+    "name", classname_);
 
   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
     nested_generators_[i]->GenerateDescriptorDeclarations(printer);
@@ -562,6 +566,7 @@ GenerateDescriptorInitializer(io::Printer* printer, int index) {
   vars["classname"] = classname_;
   vars["index"] = SimpleItoa(index);
 
+  // Obtain the descriptor from the parent's descriptor.
   if (descriptor_->containing_type() == NULL) {
     printer->Print(vars,
       "$classname$_descriptor_ = file->message_type($index$);\n");
@@ -572,6 +577,29 @@ GenerateDescriptorInitializer(io::Printer* printer, int index) {
         "$parent$_descriptor_->nested_type($index$);\n");
   }
 
+  // Construct the reflection object.
+  printer->Print(vars,
+    "$classname$_reflection_ =\n"
+    "  new ::google::protobuf::internal::GeneratedMessageReflection(\n"
+    "    $classname$_descriptor_,\n"
+    "    &$classname$::default_instance(),\n"
+    "    $classname$::_offsets_,\n"
+    "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, _has_bits_[0]),\n"
+    "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
+      "$classname$, _unknown_fields_),\n");
+  if (descriptor_->extension_range_count() > 0) {
+    printer->Print(vars,
+      "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
+        "$classname$, _extensions_),\n");
+  } else {
+    // No extensions.
+    printer->Print(vars,
+      "    -1,\n");
+  }
+  printer->Print(vars,
+    "    ::google::protobuf::DescriptorPool::generated_pool());\n");
+
+  // Handle nested types.
   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
     nested_generators_[i]->GenerateDescriptorInitializer(printer, i);
   }
@@ -650,15 +678,13 @@ GenerateClassMethods(io::Printer* printer) {
     "  return descriptor();\n"
     "}\n"
     "\n"
-    "const ::google::protobuf::Message::Reflection*\n"
-    "$classname$::GetReflection() const {\n"
-    "  return &_reflection_;\n"
-    "}\n"
-    "\n"
-    "::google::protobuf::Message::Reflection* $classname$::GetReflection() {\n"
-    "  return &_reflection_;\n"
+    "const ::google::protobuf::Reflection* $classname$::GetReflection() const {\n"
+    "  if ($classname$_reflection_ == NULL) $builddescriptorsname$();\n"
+    "  return $classname$_reflection_;\n"
     "}\n",
-    "classname", classname_);
+    "classname", classname_,
+    "builddescriptorsname",
+      GlobalBuildDescriptorsName(descriptor_->file()->name()));
 }
 
 void MessageGenerator::
@@ -686,20 +712,16 @@ GenerateInitializerList(io::Printer* printer) {
   printer->Indent();
   printer->Indent();
 
-  bool has_extensions = descriptor_->extension_range_count() > 0;
-  if (has_extensions) {
+  if (descriptor_->extension_range_count() > 0) {
     printer->Print(
-      "_extensions_(descriptor(),\n"
+      "_extensions_(&$classname$_descriptor_,\n"
       "             ::google::protobuf::DescriptorPool::generated_pool(),\n"
-      "             ::google::protobuf::MessageFactory::generated_factory()),\n");
+      "             ::google::protobuf::MessageFactory::generated_factory()),\n",
+      "classname", classname_);
   }
 
   printer->Print(
-    "_reflection_(descriptor(),\n"
-    "             this, &default_instance_,\n"
-    "             _offsets_, _has_bits_, $extensions$),\n"
-    "_cached_size_(0)",
-    "extensions", has_extensions ? "&_extensions_" : "NULL");
+    "_cached_size_(0)");
 
   // Write the initializers for each field.
   for (int i = 0; i < descriptor_->field_count(); i++) {
@@ -904,8 +926,7 @@ GenerateMergeFrom(io::Printer* printer) {
       "  ::google::protobuf::internal::dynamic_cast_if_available<const $classname$*>(\n"
       "    &from);\n"
       "if (source == NULL) {\n"
-      "  ::google::protobuf::internal::ReflectionOps::Merge(\n"
-      "    descriptor(), *from.GetReflection(), &_reflection_);\n"
+      "  ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n"
       "} else {\n"
       "  MergeFrom(*source);\n"
       "}\n",
@@ -1028,7 +1049,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
       "bool $classname$::MergePartialFromCodedStream(\n"
       "    ::google::protobuf::io::CodedInputStream* input) {\n"
       "  return ::google::protobuf::internal::WireFormat::ParseAndMergePartial(\n"
-      "    descriptor(), input, &_reflection_);\n"
+      "    input, this);\n"
       "}\n",
       "classname", classname_);
     return;
@@ -1157,7 +1178,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
       }
     }
     printer->Print(") {\n"
-      "  DO_(_extensions_.ParseField(tag, input, &_reflection_));\n"
+      "  DO_(_extensions_.ParseField(tag, input, this));\n"
       "  continue;\n"
       "}\n");
   }
@@ -1214,7 +1235,7 @@ void MessageGenerator::GenerateSerializeOneExtensionRange(
   printer->Print(vars,
     "// Extension range [$start$, $end$)\n"
     "DO_(_extensions_.SerializeWithCachedSizes(\n"
-    "    $start$, $end$, &_reflection_, output));\n\n");
+    "    $start$, $end$, *this, output));\n\n");
 }
 
 void MessageGenerator::
@@ -1341,7 +1362,7 @@ GenerateByteSize(io::Printer* printer) {
 
   if (descriptor_->extension_range_count() > 0) {
     printer->Print(
-      "total_size += _extensions_.ByteSize(&_reflection_);\n"
+      "total_size += _extensions_.ByteSize(*this);\n"
       "\n");
   }
 
diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
index 561a5ad1d55180e978f194c0d2ccfde3e75ff498..010843cf3d68dcf6da66289139951a53063dc39f 100644
--- a/src/google/protobuf/compiler/cpp/cpp_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
@@ -268,7 +268,7 @@ TEST(GeneratedMessageTest, DynamicMessageCopyFrom) {
 
   TestUtil::ReflectionTester reflection_tester(
     unittest::TestAllTypes::descriptor());
-  reflection_tester.SetAllFieldsViaReflection(message1->GetReflection());
+  reflection_tester.SetAllFieldsViaReflection(message1.get());
 
   message2.CopyFrom(*message1);
 
diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc
index 3b73530be957e3037f2a57128f37b1689808cbb1..7a148c5a70751844386299ab37f15e0a37c70692 100644
--- a/src/google/protobuf/compiler/parser.cc
+++ b/src/google/protobuf/compiler/parser.cc
@@ -604,7 +604,7 @@ bool Parser::ParseDefaultAssignment(FieldDescriptorProto* field) {
 }
 
 bool Parser::ParseOptionAssignment(Message* options) {
-  Message::Reflection* reflection = options->GetReflection();
+  const Reflection* reflection = options->GetReflection();
   const Descriptor* descriptor = options->GetDescriptor();
 
   // Parse name.
@@ -623,7 +623,7 @@ bool Parser::ParseOptionAssignment(Message* options) {
     AddError(line, column, "Not implemented: repeated options.");
     return false;
   }
-  if (reflection->HasField(field)) {
+  if (reflection->HasField(*options, field)) {
     AddError(line, column, "Option \"" + name + "\" was already set.");
     return false;
   }
@@ -638,7 +638,7 @@ bool Parser::ParseOptionAssignment(Message* options) {
 
     // This field is a message/group.  The user must identify a field within
     // it to set.
-    return ParseOptionAssignment(reflection->MutableMessage(field));
+    return ParseOptionAssignment(reflection->MutableMessage(options, field));
   }
 
   DO(Consume("="));
@@ -651,7 +651,7 @@ bool Parser::ParseOptionAssignment(Message* options) {
       uint64 max_value = kint32max;
       if (is_negative) ++max_value;
       DO(ConsumeInteger64(max_value, &value, "Expected integer."));
-      reflection->SetInt32(field, is_negative ? -value : value);
+      reflection->SetInt32(options, field, is_negative ? -value : value);
       break;
     }
 
@@ -661,21 +661,21 @@ bool Parser::ParseOptionAssignment(Message* options) {
       uint64 max_value = kint64max;
       if (is_negative) ++max_value;
       DO(ConsumeInteger64(max_value, &value, "Expected integer."));
-      reflection->SetInt64(field, is_negative ? -value : value);
+      reflection->SetInt64(options, field, is_negative ? -value : value);
       break;
     }
 
     case FieldDescriptor::CPPTYPE_UINT32: {
       uint64 value;
       DO(ConsumeInteger64(kuint32max, &value, "Expected integer."));
-      reflection->SetUInt32(field, value);
+      reflection->SetUInt32(options, field, value);
       break;
     }
 
     case FieldDescriptor::CPPTYPE_UINT64: {
       uint64 value;
       DO(ConsumeInteger64(kuint64max, &value, "Expected integer."));
-      reflection->SetUInt64(field, value);
+      reflection->SetUInt64(options, field, value);
       break;
     }
 
@@ -683,7 +683,7 @@ bool Parser::ParseOptionAssignment(Message* options) {
       double value;
       bool is_negative = TryConsume("-");
       DO(ConsumeNumber(&value, "Expected number."));
-      reflection->SetDouble(field, is_negative ? -value : value);
+      reflection->SetDouble(options, field, is_negative ? -value : value);
       break;
     }
 
@@ -691,15 +691,15 @@ bool Parser::ParseOptionAssignment(Message* options) {
       double value;
       bool is_negative = TryConsume("-");
       DO(ConsumeNumber(&value, "Expected number."));
-      reflection->SetFloat(field, is_negative ? -value : value);
+      reflection->SetFloat(options, field, is_negative ? -value : value);
       break;
     }
 
     case FieldDescriptor::CPPTYPE_BOOL:
       if (TryConsume("true")) {
-        reflection->SetBool(field, true);
+        reflection->SetBool(options, field, true);
       } else if (TryConsume("false")) {
-        reflection->SetBool(field, false);
+        reflection->SetBool(options, field, false);
       } else {
         AddError("Expected \"true\" or \"false\".");
         return false;
@@ -719,14 +719,14 @@ bool Parser::ParseOptionAssignment(Message* options) {
           "named \"" + value_name + "\".");
         return false;
       }
-      reflection->SetEnum(field, value);
+      reflection->SetEnum(options, field, value);
       break;
     }
 
     case FieldDescriptor::CPPTYPE_STRING: {
       string value;
       DO(ConsumeString(&value, "Expected string."));
-      reflection->SetString(field, value);
+      reflection->SetString(options, field, value);
       break;
     }
 
diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc
index 4485fd43f1117d77f178ef28bf39cd48ecf09c8e..8b8085658803e16cbce0cbfb28ffc807814c10f5 100644
--- a/src/google/protobuf/descriptor.cc
+++ b/src/google/protobuf/descriptor.cc
@@ -1232,9 +1232,9 @@ namespace {
 // Used by each of the option formatters.
 bool RetrieveOptions(const Message &options, vector<string> *option_entries) {
   option_entries->clear();
-  const Message::Reflection *reflection = options.GetReflection();
+  const Reflection* reflection = options.GetReflection();
   vector<const FieldDescriptor*> fields;
-  reflection->ListFields(&fields);
+  reflection->ListFields(options, &fields);
   for (int i = 0; i < fields.size(); i++) {
     // Doesn't make sense to have message type fields here
     if (fields[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
@@ -1243,7 +1243,7 @@ bool RetrieveOptions(const Message &options, vector<string> *option_entries) {
     int count = 1;
     bool repeated = false;
     if (fields[i]->is_repeated()) {
-      count = reflection->FieldSize(fields[i]);
+      count = reflection->FieldSize(options, fields[i]);
       repeated = true;
     }
     for (int j = 0; j < count; j++) {
diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h
index 4203f4969ee4b4b0b8cbc0b5b94dd70cf1d098f4..5f3fa0a21d8d3b247e54a35f9f5003ede52b3966 100644
--- a/src/google/protobuf/descriptor.h
+++ b/src/google/protobuf/descriptor.h
@@ -232,9 +232,9 @@ class LIBPROTOBUF_EXPORT Descriptor {
 //   call Descriptor::FindExtensionByName() or
 //   FileDescriptor::FindExtensionByName().
 // - Given a DescriptorPool, call DescriptorPool::FindExtensionByNumber().
-// - Given a Message::Reflection for a message object, call
-//   Message::Reflection::FindKnownExtensionByName() or
-//   Message::Reflection::FindKnownExtensionByNumber().
+// - Given a Reflection for a message object, call
+//   Reflection::FindKnownExtensionByName() or
+//   Reflection::FindKnownExtensionByNumber().
 // Use DescriptorPool to construct your own descriptors.
 class LIBPROTOBUF_EXPORT FieldDescriptor {
  public:
diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc
index 836d141e52f2ea1ea864265d4e064bdaea07e9a1..a37731d6b91c8fd34e2c6c7d34bca3e0c30e8276 100644
--- a/src/google/protobuf/descriptor.pb.cc
+++ b/src/google/protobuf/descriptor.pb.cc
@@ -11,30 +11,63 @@ namespace protobuf {
 
 namespace {
 
+const ::google::protobuf::Descriptor* FileDescriptorSet_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  FileDescriptorSet_reflection_ = NULL;
 const ::google::protobuf::Descriptor* FileDescriptorProto_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  FileDescriptorProto_reflection_ = NULL;
 const ::google::protobuf::Descriptor* DescriptorProto_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  DescriptorProto_reflection_ = NULL;
 const ::google::protobuf::Descriptor* DescriptorProto_ExtensionRange_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  DescriptorProto_ExtensionRange_reflection_ = NULL;
 const ::google::protobuf::Descriptor* FieldDescriptorProto_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  FieldDescriptorProto_reflection_ = NULL;
 const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor_ = NULL;
 const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor_ = NULL;
 const ::google::protobuf::Descriptor* EnumDescriptorProto_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  EnumDescriptorProto_reflection_ = NULL;
 const ::google::protobuf::Descriptor* EnumValueDescriptorProto_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  EnumValueDescriptorProto_reflection_ = NULL;
 const ::google::protobuf::Descriptor* ServiceDescriptorProto_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  ServiceDescriptorProto_reflection_ = NULL;
 const ::google::protobuf::Descriptor* MethodDescriptorProto_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  MethodDescriptorProto_reflection_ = NULL;
 const ::google::protobuf::Descriptor* FileOptions_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  FileOptions_reflection_ = NULL;
 const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor_ = NULL;
 const ::google::protobuf::Descriptor* MessageOptions_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  MessageOptions_reflection_ = NULL;
 const ::google::protobuf::Descriptor* FieldOptions_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  FieldOptions_reflection_ = NULL;
 const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor_ = NULL;
 const ::google::protobuf::Descriptor* EnumOptions_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  EnumOptions_reflection_ = NULL;
 const ::google::protobuf::Descriptor* EnumValueOptions_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  EnumValueOptions_reflection_ = NULL;
 const ::google::protobuf::Descriptor* ServiceOptions_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  ServiceOptions_reflection_ = NULL;
 const ::google::protobuf::Descriptor* MethodOptions_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  MethodOptions_reflection_ = NULL;
 
 }  // namespace
 
 
-void proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto() {
+void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto() {
   static bool already_here = false;
   if (already_here) return;
   already_here = true;
@@ -44,116 +77,265 @@ void proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto() {
 
   const ::google::protobuf::FileDescriptor* file = pool->InternalBuildGeneratedFile(
     "\n google/protobuf/descriptor.proto\022\017goog"
-    "le.protobuf\"\334\002\n\023FileDescriptorProto\022\014\n\004n"
-    "ame\030\001 \001(\t\022\017\n\007package\030\002 \001(\t\022\022\n\ndependency"
-    "\030\003 \003(\t\0226\n\014message_type\030\004 \003(\0132 .google.pr"
-    "otobuf.DescriptorProto\0227\n\tenum_type\030\005 \003("
-    "\0132$.google.protobuf.EnumDescriptorProto\022"
-    "8\n\007service\030\006 \003(\0132\'.google.protobuf.Servi"
-    "ceDescriptorProto\0228\n\textension\030\007 \003(\0132%.g"
-    "oogle.protobuf.FieldDescriptorProto\022-\n\007o"
-    "ptions\030\010 \001(\0132\034.google.protobuf.FileOptio"
-    "ns\"\251\003\n\017DescriptorProto\022\014\n\004name\030\001 \001(\t\0224\n\005"
-    "field\030\002 \003(\0132%.google.protobuf.FieldDescr"
-    "iptorProto\0228\n\textension\030\006 \003(\0132%.google.p"
-    "rotobuf.FieldDescriptorProto\0225\n\013nested_t"
-    "ype\030\003 \003(\0132 .google.protobuf.DescriptorPr"
-    "oto\0227\n\tenum_type\030\004 \003(\0132$.google.protobuf"
-    ".EnumDescriptorProto\022H\n\017extension_range\030"
-    "\005 \003(\0132/.google.protobuf.DescriptorProto."
-    "ExtensionRange\0220\n\007options\030\007 \001(\0132\037.google"
-    ".protobuf.MessageOptions\032,\n\016ExtensionRan"
-    "ge\022\r\n\005start\030\001 \001(\005\022\013\n\003end\030\002 \001(\005\"\224\005\n\024Field"
-    "DescriptorProto\022\014\n\004name\030\001 \001(\t\022\016\n\006number\030"
-    "\003 \001(\005\022:\n\005label\030\004 \001(\0162+.google.protobuf.F"
-    "ieldDescriptorProto.Label\0228\n\004type\030\005 \001(\0162"
-    "*.google.protobuf.FieldDescriptorProto.T"
-    "ype\022\021\n\ttype_name\030\006 \001(\t\022\020\n\010extendee\030\002 \001(\t"
-    "\022\025\n\rdefault_value\030\007 \001(\t\022.\n\007options\030\010 \001(\013"
-    "2\035.google.protobuf.FieldOptions\"\266\002\n\004Type"
-    "\022\017\n\013TYPE_DOUBLE\020\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTYP"
-    "E_INT64\020\003\022\017\n\013TYPE_UINT64\020\004\022\016\n\nTYPE_INT32"
-    "\020\005\022\020\n\014TYPE_FIXED64\020\006\022\020\n\014TYPE_FIXED32\020\007\022\r"
-    "\n\tTYPE_BOOL\020\010\022\017\n\013TYPE_STRING\020\t\022\016\n\nTYPE_G"
-    "ROUP\020\n\022\020\n\014TYPE_MESSAGE\020\013\022\016\n\nTYPE_BYTES\020\014"
-    "\022\017\n\013TYPE_UINT32\020\r\022\r\n\tTYPE_ENUM\020\016\022\021\n\rTYPE"
-    "_SFIXED32\020\017\022\021\n\rTYPE_SFIXED64\020\020\022\017\n\013TYPE_S"
-    "INT32\020\021\022\017\n\013TYPE_SINT64\020\022\"C\n\005Label\022\022\n\016LAB"
-    "EL_OPTIONAL\020\001\022\022\n\016LABEL_REQUIRED\020\002\022\022\n\016LAB"
-    "EL_REPEATED\020\003\"\214\001\n\023EnumDescriptorProto\022\014\n"
-    "\004name\030\001 \001(\t\0228\n\005value\030\002 \003(\0132).google.prot"
-    "obuf.EnumValueDescriptorProto\022-\n\007options"
-    "\030\003 \001(\0132\034.google.protobuf.EnumOptions\"l\n\030"
-    "EnumValueDescriptorProto\022\014\n\004name\030\001 \001(\t\022\016"
-    "\n\006number\030\002 \001(\005\0222\n\007options\030\003 \001(\0132!.google"
-    ".protobuf.EnumValueOptions\"\220\001\n\026ServiceDe"
-    "scriptorProto\022\014\n\004name\030\001 \001(\t\0226\n\006method\030\002 "
-    "\003(\0132&.google.protobuf.MethodDescriptorPr"
-    "oto\0220\n\007options\030\003 \001(\0132\037.google.protobuf.S"
-    "erviceOptions\"\177\n\025MethodDescriptorProto\022\014"
-    "\n\004name\030\001 \001(\t\022\022\n\ninput_type\030\002 \001(\t\022\023\n\013outp"
-    "ut_type\030\003 \001(\t\022/\n\007options\030\004 \001(\0132\036.google."
-    "protobuf.MethodOptions\"\333\001\n\013FileOptions\022\024"
-    "\n\014java_package\030\001 \001(\t\022\034\n\024java_outer_class"
-    "name\030\010 \001(\t\022\"\n\023java_multiple_files\030\n \001(\010:"
-    "\005false\022J\n\014optimize_for\030\t \001(\0162).google.pr"
-    "otobuf.FileOptions.OptimizeMode:\tCODE_SI"
-    "ZE\"(\n\014OptimizeMode\022\t\n\005SPEED\020\001\022\r\n\tCODE_SI"
-    "ZE\020\002\"8\n\016MessageOptions\022&\n\027message_set_wi"
-    "re_format\030\001 \001(\010:\005false\"\205\001\n\014FieldOptions\022"
-    "2\n\005ctype\030\001 \001(\0162#.google.protobuf.FieldOp"
-    "tions.CType\022\034\n\024experimental_map_key\030\t \001("
-    "\t\"#\n\005CType\022\010\n\004CORD\020\001\022\020\n\014STRING_PIECE\020\002\"\r"
-    "\n\013EnumOptions\"\022\n\020EnumValueOptions\"\020\n\016Ser"
-    "viceOptions\"\017\n\rMethodOptionsB)\n\023com.goog"
-    "le.protobufB\020DescriptorProtosH\001", 2551);
-  FileDescriptorProto_descriptor_ = file->message_type(0);
+    "le.protobuf\"G\n\021FileDescriptorSet\0222\n\004file"
+    "\030\001 \003(\0132$.google.protobuf.FileDescriptorP"
+    "roto\"\334\002\n\023FileDescriptorProto\022\014\n\004name\030\001 \001"
+    "(\t\022\017\n\007package\030\002 \001(\t\022\022\n\ndependency\030\003 \003(\t\022"
+    "6\n\014message_type\030\004 \003(\0132 .google.protobuf."
+    "DescriptorProto\0227\n\tenum_type\030\005 \003(\0132$.goo"
+    "gle.protobuf.EnumDescriptorProto\0228\n\007serv"
+    "ice\030\006 \003(\0132\'.google.protobuf.ServiceDescr"
+    "iptorProto\0228\n\textension\030\007 \003(\0132%.google.p"
+    "rotobuf.FieldDescriptorProto\022-\n\007options\030"
+    "\010 \001(\0132\034.google.protobuf.FileOptions\"\251\003\n\017"
+    "DescriptorProto\022\014\n\004name\030\001 \001(\t\0224\n\005field\030\002"
+    " \003(\0132%.google.protobuf.FieldDescriptorPr"
+    "oto\0228\n\textension\030\006 \003(\0132%.google.protobuf"
+    ".FieldDescriptorProto\0225\n\013nested_type\030\003 \003"
+    "(\0132 .google.protobuf.DescriptorProto\0227\n\t"
+    "enum_type\030\004 \003(\0132$.google.protobuf.EnumDe"
+    "scriptorProto\022H\n\017extension_range\030\005 \003(\0132/"
+    ".google.protobuf.DescriptorProto.Extensi"
+    "onRange\0220\n\007options\030\007 \001(\0132\037.google.protob"
+    "uf.MessageOptions\032,\n\016ExtensionRange\022\r\n\005s"
+    "tart\030\001 \001(\005\022\013\n\003end\030\002 \001(\005\"\224\005\n\024FieldDescrip"
+    "torProto\022\014\n\004name\030\001 \001(\t\022\016\n\006number\030\003 \001(\005\022:"
+    "\n\005label\030\004 \001(\0162+.google.protobuf.FieldDes"
+    "criptorProto.Label\0228\n\004type\030\005 \001(\0162*.googl"
+    "e.protobuf.FieldDescriptorProto.Type\022\021\n\t"
+    "type_name\030\006 \001(\t\022\020\n\010extendee\030\002 \001(\t\022\025\n\rdef"
+    "ault_value\030\007 \001(\t\022.\n\007options\030\010 \001(\0132\035.goog"
+    "le.protobuf.FieldOptions\"\266\002\n\004Type\022\017\n\013TYP"
+    "E_DOUBLE\020\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTYPE_INT64"
+    "\020\003\022\017\n\013TYPE_UINT64\020\004\022\016\n\nTYPE_INT32\020\005\022\020\n\014T"
+    "YPE_FIXED64\020\006\022\020\n\014TYPE_FIXED32\020\007\022\r\n\tTYPE_"
+    "BOOL\020\010\022\017\n\013TYPE_STRING\020\t\022\016\n\nTYPE_GROUP\020\n\022"
+    "\020\n\014TYPE_MESSAGE\020\013\022\016\n\nTYPE_BYTES\020\014\022\017\n\013TYP"
+    "E_UINT32\020\r\022\r\n\tTYPE_ENUM\020\016\022\021\n\rTYPE_SFIXED"
+    "32\020\017\022\021\n\rTYPE_SFIXED64\020\020\022\017\n\013TYPE_SINT32\020\021"
+    "\022\017\n\013TYPE_SINT64\020\022\"C\n\005Label\022\022\n\016LABEL_OPTI"
+    "ONAL\020\001\022\022\n\016LABEL_REQUIRED\020\002\022\022\n\016LABEL_REPE"
+    "ATED\020\003\"\214\001\n\023EnumDescriptorProto\022\014\n\004name\030\001"
+    " \001(\t\0228\n\005value\030\002 \003(\0132).google.protobuf.En"
+    "umValueDescriptorProto\022-\n\007options\030\003 \001(\0132"
+    "\034.google.protobuf.EnumOptions\"l\n\030EnumVal"
+    "ueDescriptorProto\022\014\n\004name\030\001 \001(\t\022\016\n\006numbe"
+    "r\030\002 \001(\005\0222\n\007options\030\003 \001(\0132!.google.protob"
+    "uf.EnumValueOptions\"\220\001\n\026ServiceDescripto"
+    "rProto\022\014\n\004name\030\001 \001(\t\0226\n\006method\030\002 \003(\0132&.g"
+    "oogle.protobuf.MethodDescriptorProto\0220\n\007"
+    "options\030\003 \001(\0132\037.google.protobuf.ServiceO"
+    "ptions\"\177\n\025MethodDescriptorProto\022\014\n\004name\030"
+    "\001 \001(\t\022\022\n\ninput_type\030\002 \001(\t\022\023\n\013output_type"
+    "\030\003 \001(\t\022/\n\007options\030\004 \001(\0132\036.google.protobu"
+    "f.MethodOptions\"\333\001\n\013FileOptions\022\024\n\014java_"
+    "package\030\001 \001(\t\022\034\n\024java_outer_classname\030\010 "
+    "\001(\t\022\"\n\023java_multiple_files\030\n \001(\010:\005false\022"
+    "J\n\014optimize_for\030\t \001(\0162).google.protobuf."
+    "FileOptions.OptimizeMode:\tCODE_SIZE\"(\n\014O"
+    "ptimizeMode\022\t\n\005SPEED\020\001\022\r\n\tCODE_SIZE\020\002\"8\n"
+    "\016MessageOptions\022&\n\027message_set_wire_form"
+    "at\030\001 \001(\010:\005false\"\205\001\n\014FieldOptions\0222\n\005ctyp"
+    "e\030\001 \001(\0162#.google.protobuf.FieldOptions.C"
+    "Type\022\034\n\024experimental_map_key\030\t \001(\t\"#\n\005CT"
+    "ype\022\010\n\004CORD\020\001\022\020\n\014STRING_PIECE\020\002\"\r\n\013EnumO"
+    "ptions\"\022\n\020EnumValueOptions\"\020\n\016ServiceOpt"
+    "ions\"\017\n\rMethodOptionsB)\n\023com.google.prot"
+    "obufB\020DescriptorProtosH\001", 2624);
+  FileDescriptorSet_descriptor_ = file->message_type(0);
+  FileDescriptorSet_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      FileDescriptorSet_descriptor_,
+      &FileDescriptorSet::default_instance(),
+      FileDescriptorSet::_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    FileDescriptorSet_descriptor_, &FileDescriptorSet::default_instance());
+  FileDescriptorProto_descriptor_ = file->message_type(1);
+  FileDescriptorProto_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      FileDescriptorProto_descriptor_,
+      &FileDescriptorProto::default_instance(),
+      FileDescriptorProto::_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool());
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
     FileDescriptorProto_descriptor_, &FileDescriptorProto::default_instance());
-  DescriptorProto_descriptor_ = file->message_type(1);
+  DescriptorProto_descriptor_ = file->message_type(2);
+  DescriptorProto_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      DescriptorProto_descriptor_,
+      &DescriptorProto::default_instance(),
+      DescriptorProto::_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool());
   DescriptorProto_ExtensionRange_descriptor_ = DescriptorProto_descriptor_->nested_type(0);
+  DescriptorProto_ExtensionRange_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      DescriptorProto_ExtensionRange_descriptor_,
+      &DescriptorProto_ExtensionRange::default_instance(),
+      DescriptorProto_ExtensionRange::_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool());
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
     DescriptorProto_ExtensionRange_descriptor_, &DescriptorProto_ExtensionRange::default_instance());
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
     DescriptorProto_descriptor_, &DescriptorProto::default_instance());
-  FieldDescriptorProto_descriptor_ = file->message_type(2);
+  FieldDescriptorProto_descriptor_ = file->message_type(3);
+  FieldDescriptorProto_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      FieldDescriptorProto_descriptor_,
+      &FieldDescriptorProto::default_instance(),
+      FieldDescriptorProto::_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool());
   FieldDescriptorProto_Type_descriptor_ = FieldDescriptorProto_descriptor_->enum_type(0);
   FieldDescriptorProto_Label_descriptor_ = FieldDescriptorProto_descriptor_->enum_type(1);
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
     FieldDescriptorProto_descriptor_, &FieldDescriptorProto::default_instance());
-  EnumDescriptorProto_descriptor_ = file->message_type(3);
+  EnumDescriptorProto_descriptor_ = file->message_type(4);
+  EnumDescriptorProto_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      EnumDescriptorProto_descriptor_,
+      &EnumDescriptorProto::default_instance(),
+      EnumDescriptorProto::_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool());
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
     EnumDescriptorProto_descriptor_, &EnumDescriptorProto::default_instance());
-  EnumValueDescriptorProto_descriptor_ = file->message_type(4);
+  EnumValueDescriptorProto_descriptor_ = file->message_type(5);
+  EnumValueDescriptorProto_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      EnumValueDescriptorProto_descriptor_,
+      &EnumValueDescriptorProto::default_instance(),
+      EnumValueDescriptorProto::_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool());
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
     EnumValueDescriptorProto_descriptor_, &EnumValueDescriptorProto::default_instance());
-  ServiceDescriptorProto_descriptor_ = file->message_type(5);
+  ServiceDescriptorProto_descriptor_ = file->message_type(6);
+  ServiceDescriptorProto_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      ServiceDescriptorProto_descriptor_,
+      &ServiceDescriptorProto::default_instance(),
+      ServiceDescriptorProto::_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool());
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
     ServiceDescriptorProto_descriptor_, &ServiceDescriptorProto::default_instance());
-  MethodDescriptorProto_descriptor_ = file->message_type(6);
+  MethodDescriptorProto_descriptor_ = file->message_type(7);
+  MethodDescriptorProto_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      MethodDescriptorProto_descriptor_,
+      &MethodDescriptorProto::default_instance(),
+      MethodDescriptorProto::_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool());
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
     MethodDescriptorProto_descriptor_, &MethodDescriptorProto::default_instance());
-  FileOptions_descriptor_ = file->message_type(7);
+  FileOptions_descriptor_ = file->message_type(8);
+  FileOptions_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      FileOptions_descriptor_,
+      &FileOptions::default_instance(),
+      FileOptions::_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool());
   FileOptions_OptimizeMode_descriptor_ = FileOptions_descriptor_->enum_type(0);
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
     FileOptions_descriptor_, &FileOptions::default_instance());
-  MessageOptions_descriptor_ = file->message_type(8);
+  MessageOptions_descriptor_ = file->message_type(9);
+  MessageOptions_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      MessageOptions_descriptor_,
+      &MessageOptions::default_instance(),
+      MessageOptions::_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool());
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
     MessageOptions_descriptor_, &MessageOptions::default_instance());
-  FieldOptions_descriptor_ = file->message_type(9);
+  FieldOptions_descriptor_ = file->message_type(10);
+  FieldOptions_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      FieldOptions_descriptor_,
+      &FieldOptions::default_instance(),
+      FieldOptions::_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool());
   FieldOptions_CType_descriptor_ = FieldOptions_descriptor_->enum_type(0);
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
     FieldOptions_descriptor_, &FieldOptions::default_instance());
-  EnumOptions_descriptor_ = file->message_type(10);
+  EnumOptions_descriptor_ = file->message_type(11);
+  EnumOptions_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      EnumOptions_descriptor_,
+      &EnumOptions::default_instance(),
+      EnumOptions::_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool());
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
     EnumOptions_descriptor_, &EnumOptions::default_instance());
-  EnumValueOptions_descriptor_ = file->message_type(11);
+  EnumValueOptions_descriptor_ = file->message_type(12);
+  EnumValueOptions_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      EnumValueOptions_descriptor_,
+      &EnumValueOptions::default_instance(),
+      EnumValueOptions::_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool());
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
     EnumValueOptions_descriptor_, &EnumValueOptions::default_instance());
-  ServiceOptions_descriptor_ = file->message_type(12);
+  ServiceOptions_descriptor_ = file->message_type(13);
+  ServiceOptions_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      ServiceOptions_descriptor_,
+      &ServiceOptions::default_instance(),
+      ServiceOptions::_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool());
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
     ServiceOptions_descriptor_, &ServiceOptions::default_instance());
-  MethodOptions_descriptor_ = file->message_type(13);
+  MethodOptions_descriptor_ = file->message_type(14);
+  MethodOptions_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      MethodOptions_descriptor_,
+      &MethodOptions::default_instance(),
+      MethodOptions::_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool());
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
     MethodOptions_descriptor_, &MethodOptions::default_instance());
 }
@@ -161,11 +343,169 @@ void proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto() {
 // Force BuildDescriptors() to be called at static initialization time.
 struct StaticDescriptorInitializer_google_2fprotobuf_2fdescriptor_2eproto {
   StaticDescriptorInitializer_google_2fprotobuf_2fdescriptor_2eproto() {
-    proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+    protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   }
 } static_descriptor_initializer_google_2fprotobuf_2fdescriptor_2eproto_;
 
 
+// ===================================================================
+
+const FileDescriptorSet FileDescriptorSet::default_instance_;
+
+
+const int FileDescriptorSet::_offsets_[1] = {
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, file_),
+};
+
+FileDescriptorSet::FileDescriptorSet()
+  : _cached_size_(0) {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  if (this == &default_instance_) {
+  }
+}
+
+FileDescriptorSet::FileDescriptorSet(const FileDescriptorSet& from)
+  : _cached_size_(0) {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  MergeFrom(from);
+}
+
+FileDescriptorSet::~FileDescriptorSet() {
+  if (this != &default_instance_) {
+  }
+}
+
+const ::google::protobuf::Descriptor* FileDescriptorSet::descriptor() {
+  if (FileDescriptorSet_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return FileDescriptorSet_descriptor_;
+}
+
+FileDescriptorSet* FileDescriptorSet::New() const {
+  return new FileDescriptorSet;
+}
+
+void FileDescriptorSet::Clear() {
+  file_.Clear();
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  mutable_unknown_fields()->Clear();
+}
+
+bool FileDescriptorSet::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+  ::google::protobuf::uint32 tag;
+  while ((tag = input->ReadTag()) != 0) {
+    switch (::google::protobuf::internal::WireFormat::GetTagFieldNumber(tag)) {
+      // repeated .google.protobuf.FileDescriptorProto file = 1;
+      case 1: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+       parse_file:
+        DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual(
+             input, add_file()));
+        if (input->ExpectTag(10)) goto parse_file;
+        if (input->ExpectAtEnd()) return true;
+        break;
+      }
+      
+      default: {
+      handle_uninterpreted:
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) {
+          return true;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+  return true;
+#undef DO_
+}
+
+bool FileDescriptorSet::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+  // repeated .google.protobuf.FileDescriptorProto file = 1;
+  for (int i = 0; i < file_.size(); i++) {
+    DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(1, this->file(i), output));
+  }
+  
+  if (!unknown_fields().empty()) {
+    DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output));
+  }
+  return true;
+#undef DO_
+}
+
+int FileDescriptorSet::ByteSize() const {
+  int total_size = 0;
+  
+  // repeated .google.protobuf.FileDescriptorProto file = 1;
+  total_size += 1 * file_size();
+  for (int i = 0; i < file_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
+        this->file(i));
+  }
+  
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  _cached_size_ = total_size;
+  return total_size;
+}
+
+void FileDescriptorSet::MergeFrom(const ::google::protobuf::Message& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  const FileDescriptorSet* source =
+    ::google::protobuf::internal::dynamic_cast_if_available<const FileDescriptorSet*>(
+      &from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void FileDescriptorSet::MergeFrom(const FileDescriptorSet& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  file_.MergeFrom(from.file_);
+  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void FileDescriptorSet::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void FileDescriptorSet::CopyFrom(const FileDescriptorSet& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool FileDescriptorSet::IsInitialized() const {
+  
+  return true;
+}
+
+const ::google::protobuf::Descriptor* FileDescriptorSet::GetDescriptor() const {
+  return descriptor();
+}
+
+const ::google::protobuf::Reflection* FileDescriptorSet::GetReflection() const {
+  if (FileDescriptorSet_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return FileDescriptorSet_reflection_;
+}
+
 // ===================================================================
 
 const FileDescriptorProto FileDescriptorProto::default_instance_;
@@ -190,10 +530,7 @@ const int FileDescriptorProto::_offsets_[8] = {
 };
 
 FileDescriptorProto::FileDescriptorProto()
-  : _reflection_(descriptor(),
-                 this, &default_instance_,
-                 _offsets_, _has_bits_, NULL),
-    _cached_size_(0),
+  : _cached_size_(0),
     name_(const_cast< ::std::string*>(&_default_name_)),
     package_(const_cast< ::std::string*>(&_default_package_)),
     options_(NULL) {
@@ -204,10 +541,7 @@ FileDescriptorProto::FileDescriptorProto()
 }
 
 FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto& from)
-  : _reflection_(descriptor(),
-                 this, &default_instance_,
-                 _offsets_, _has_bits_, NULL),
-    _cached_size_(0),
+  : _cached_size_(0),
     name_(const_cast< ::std::string*>(&_default_name_)),
     package_(const_cast< ::std::string*>(&_default_package_)),
     options_(NULL) {
@@ -228,7 +562,7 @@ FileDescriptorProto::~FileDescriptorProto() {
 }
 
 const ::google::protobuf::Descriptor* FileDescriptorProto::descriptor() {
-  if (FileDescriptorProto_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  if (FileDescriptorProto_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   return FileDescriptorProto_descriptor_;
 }
 
@@ -518,8 +852,7 @@ void FileDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
     ::google::protobuf::internal::dynamic_cast_if_available<const FileDescriptorProto*>(
       &from);
   if (source == NULL) {
-    ::google::protobuf::internal::ReflectionOps::Merge(
-      descriptor(), *from.GetReflection(), &_reflection_);
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
   } else {
     MergeFrom(*source);
   }
@@ -567,13 +900,9 @@ const ::google::protobuf::Descriptor* FileDescriptorProto::GetDescriptor() const
   return descriptor();
 }
 
-const ::google::protobuf::Message::Reflection*
-FileDescriptorProto::GetReflection() const {
-  return &_reflection_;
-}
-
-::google::protobuf::Message::Reflection* FileDescriptorProto::GetReflection() {
-  return &_reflection_;
+const ::google::protobuf::Reflection* FileDescriptorProto::GetReflection() const {
+  if (FileDescriptorProto_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return FileDescriptorProto_reflection_;
 }
 
 // ===================================================================
@@ -588,10 +917,7 @@ const int DescriptorProto_ExtensionRange::_offsets_[2] = {
 };
 
 DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange()
-  : _reflection_(descriptor(),
-                 this, &default_instance_,
-                 _offsets_, _has_bits_, NULL),
-    _cached_size_(0),
+  : _cached_size_(0),
     start_(0),
     end_(0) {
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
@@ -600,10 +926,7 @@ DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange()
 }
 
 DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from)
-  : _reflection_(descriptor(),
-                 this, &default_instance_,
-                 _offsets_, _has_bits_, NULL),
-    _cached_size_(0),
+  : _cached_size_(0),
     start_(0),
     end_(0) {
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
@@ -616,7 +939,7 @@ DescriptorProto_ExtensionRange::~DescriptorProto_ExtensionRange() {
 }
 
 const ::google::protobuf::Descriptor* DescriptorProto_ExtensionRange::descriptor() {
-  if (DescriptorProto_ExtensionRange_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  if (DescriptorProto_ExtensionRange_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   return DescriptorProto_ExtensionRange_descriptor_;
 }
 
@@ -737,8 +1060,7 @@ void DescriptorProto_ExtensionRange::MergeFrom(const ::google::protobuf::Message
     ::google::protobuf::internal::dynamic_cast_if_available<const DescriptorProto_ExtensionRange*>(
       &from);
   if (source == NULL) {
-    ::google::protobuf::internal::ReflectionOps::Merge(
-      descriptor(), *from.GetReflection(), &_reflection_);
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
   } else {
     MergeFrom(*source);
   }
@@ -778,13 +1100,9 @@ const ::google::protobuf::Descriptor* DescriptorProto_ExtensionRange::GetDescrip
   return descriptor();
 }
 
-const ::google::protobuf::Message::Reflection*
-DescriptorProto_ExtensionRange::GetReflection() const {
-  return &_reflection_;
-}
-
-::google::protobuf::Message::Reflection* DescriptorProto_ExtensionRange::GetReflection() {
-  return &_reflection_;
+const ::google::protobuf::Reflection* DescriptorProto_ExtensionRange::GetReflection() const {
+  if (DescriptorProto_ExtensionRange_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return DescriptorProto_ExtensionRange_reflection_;
 }
 
 // -------------------------------------------------------------------
@@ -809,10 +1127,7 @@ const int DescriptorProto::_offsets_[7] = {
 };
 
 DescriptorProto::DescriptorProto()
-  : _reflection_(descriptor(),
-                 this, &default_instance_,
-                 _offsets_, _has_bits_, NULL),
-    _cached_size_(0),
+  : _cached_size_(0),
     name_(const_cast< ::std::string*>(&_default_name_)),
     options_(NULL) {
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
@@ -822,10 +1137,7 @@ DescriptorProto::DescriptorProto()
 }
 
 DescriptorProto::DescriptorProto(const DescriptorProto& from)
-  : _reflection_(descriptor(),
-                 this, &default_instance_,
-                 _offsets_, _has_bits_, NULL),
-    _cached_size_(0),
+  : _cached_size_(0),
     name_(const_cast< ::std::string*>(&_default_name_)),
     options_(NULL) {
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
@@ -842,7 +1154,7 @@ DescriptorProto::~DescriptorProto() {
 }
 
 const ::google::protobuf::Descriptor* DescriptorProto::descriptor() {
-  if (DescriptorProto_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  if (DescriptorProto_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   return DescriptorProto_descriptor_;
 }
 
@@ -1105,8 +1417,7 @@ void DescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
     ::google::protobuf::internal::dynamic_cast_if_available<const DescriptorProto*>(
       &from);
   if (source == NULL) {
-    ::google::protobuf::internal::ReflectionOps::Merge(
-      descriptor(), *from.GetReflection(), &_reflection_);
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
   } else {
     MergeFrom(*source);
   }
@@ -1151,19 +1462,15 @@ const ::google::protobuf::Descriptor* DescriptorProto::GetDescriptor() const {
   return descriptor();
 }
 
-const ::google::protobuf::Message::Reflection*
-DescriptorProto::GetReflection() const {
-  return &_reflection_;
-}
-
-::google::protobuf::Message::Reflection* DescriptorProto::GetReflection() {
-  return &_reflection_;
+const ::google::protobuf::Reflection* DescriptorProto::GetReflection() const {
+  if (DescriptorProto_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return DescriptorProto_reflection_;
 }
 
 // ===================================================================
 
 const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor() {
-  if (FieldDescriptorProto_Type_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  if (FieldDescriptorProto_Type_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   return FieldDescriptorProto_Type_descriptor_;
 }
 bool FieldDescriptorProto_Type_IsValid(int value) {
@@ -1215,7 +1522,7 @@ const FieldDescriptorProto_Type FieldDescriptorProto::Type_MIN;
 const FieldDescriptorProto_Type FieldDescriptorProto::Type_MAX;
 #endif  // _MSC_VER
 const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor() {
-  if (FieldDescriptorProto_Label_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  if (FieldDescriptorProto_Label_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   return FieldDescriptorProto_Label_descriptor_;
 }
 bool FieldDescriptorProto_Label_IsValid(int value) {
@@ -1258,10 +1565,7 @@ const int FieldDescriptorProto::_offsets_[8] = {
 };
 
 FieldDescriptorProto::FieldDescriptorProto()
-  : _reflection_(descriptor(),
-                 this, &default_instance_,
-                 _offsets_, _has_bits_, NULL),
-    _cached_size_(0),
+  : _cached_size_(0),
     name_(const_cast< ::std::string*>(&_default_name_)),
     number_(0),
     label_(1),
@@ -1277,10 +1581,7 @@ FieldDescriptorProto::FieldDescriptorProto()
 }
 
 FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto& from)
-  : _reflection_(descriptor(),
-                 this, &default_instance_,
-                 _offsets_, _has_bits_, NULL),
-    _cached_size_(0),
+  : _cached_size_(0),
     name_(const_cast< ::std::string*>(&_default_name_)),
     number_(0),
     label_(1),
@@ -1312,7 +1613,7 @@ FieldDescriptorProto::~FieldDescriptorProto() {
 }
 
 const ::google::protobuf::Descriptor* FieldDescriptorProto::descriptor() {
-  if (FieldDescriptorProto_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  if (FieldDescriptorProto_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   return FieldDescriptorProto_descriptor_;
 }
 
@@ -1606,8 +1907,7 @@ void FieldDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
     ::google::protobuf::internal::dynamic_cast_if_available<const FieldDescriptorProto*>(
       &from);
   if (source == NULL) {
-    ::google::protobuf::internal::ReflectionOps::Merge(
-      descriptor(), *from.GetReflection(), &_reflection_);
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
   } else {
     MergeFrom(*source);
   }
@@ -1665,13 +1965,9 @@ const ::google::protobuf::Descriptor* FieldDescriptorProto::GetDescriptor() cons
   return descriptor();
 }
 
-const ::google::protobuf::Message::Reflection*
-FieldDescriptorProto::GetReflection() const {
-  return &_reflection_;
-}
-
-::google::protobuf::Message::Reflection* FieldDescriptorProto::GetReflection() {
-  return &_reflection_;
+const ::google::protobuf::Reflection* FieldDescriptorProto::GetReflection() const {
+  if (FieldDescriptorProto_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return FieldDescriptorProto_reflection_;
 }
 
 // ===================================================================
@@ -1688,10 +1984,7 @@ const int EnumDescriptorProto::_offsets_[3] = {
 };
 
 EnumDescriptorProto::EnumDescriptorProto()
-  : _reflection_(descriptor(),
-                 this, &default_instance_,
-                 _offsets_, _has_bits_, NULL),
-    _cached_size_(0),
+  : _cached_size_(0),
     name_(const_cast< ::std::string*>(&_default_name_)),
     options_(NULL) {
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
@@ -1701,10 +1994,7 @@ EnumDescriptorProto::EnumDescriptorProto()
 }
 
 EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto& from)
-  : _reflection_(descriptor(),
-                 this, &default_instance_,
-                 _offsets_, _has_bits_, NULL),
-    _cached_size_(0),
+  : _cached_size_(0),
     name_(const_cast< ::std::string*>(&_default_name_)),
     options_(NULL) {
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
@@ -1721,7 +2011,7 @@ EnumDescriptorProto::~EnumDescriptorProto() {
 }
 
 const ::google::protobuf::Descriptor* EnumDescriptorProto::descriptor() {
-  if (EnumDescriptorProto_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  if (EnumDescriptorProto_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   return EnumDescriptorProto_descriptor_;
 }
 
@@ -1872,8 +2162,7 @@ void EnumDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
     ::google::protobuf::internal::dynamic_cast_if_available<const EnumDescriptorProto*>(
       &from);
   if (source == NULL) {
-    ::google::protobuf::internal::ReflectionOps::Merge(
-      descriptor(), *from.GetReflection(), &_reflection_);
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
   } else {
     MergeFrom(*source);
   }
@@ -1914,13 +2203,9 @@ const ::google::protobuf::Descriptor* EnumDescriptorProto::GetDescriptor() const
   return descriptor();
 }
 
-const ::google::protobuf::Message::Reflection*
-EnumDescriptorProto::GetReflection() const {
-  return &_reflection_;
-}
-
-::google::protobuf::Message::Reflection* EnumDescriptorProto::GetReflection() {
-  return &_reflection_;
+const ::google::protobuf::Reflection* EnumDescriptorProto::GetReflection() const {
+  if (EnumDescriptorProto_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return EnumDescriptorProto_reflection_;
 }
 
 // ===================================================================
@@ -1937,10 +2222,7 @@ const int EnumValueDescriptorProto::_offsets_[3] = {
 };
 
 EnumValueDescriptorProto::EnumValueDescriptorProto()
-  : _reflection_(descriptor(),
-                 this, &default_instance_,
-                 _offsets_, _has_bits_, NULL),
-    _cached_size_(0),
+  : _cached_size_(0),
     name_(const_cast< ::std::string*>(&_default_name_)),
     number_(0),
     options_(NULL) {
@@ -1951,10 +2233,7 @@ EnumValueDescriptorProto::EnumValueDescriptorProto()
 }
 
 EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProto& from)
-  : _reflection_(descriptor(),
-                 this, &default_instance_,
-                 _offsets_, _has_bits_, NULL),
-    _cached_size_(0),
+  : _cached_size_(0),
     name_(const_cast< ::std::string*>(&_default_name_)),
     number_(0),
     options_(NULL) {
@@ -1972,7 +2251,7 @@ EnumValueDescriptorProto::~EnumValueDescriptorProto() {
 }
 
 const ::google::protobuf::Descriptor* EnumValueDescriptorProto::descriptor() {
-  if (EnumValueDescriptorProto_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  if (EnumValueDescriptorProto_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   return EnumValueDescriptorProto_descriptor_;
 }
 
@@ -2122,8 +2401,7 @@ void EnumValueDescriptorProto::MergeFrom(const ::google::protobuf::Message& from
     ::google::protobuf::internal::dynamic_cast_if_available<const EnumValueDescriptorProto*>(
       &from);
   if (source == NULL) {
-    ::google::protobuf::internal::ReflectionOps::Merge(
-      descriptor(), *from.GetReflection(), &_reflection_);
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
   } else {
     MergeFrom(*source);
   }
@@ -2166,13 +2444,9 @@ const ::google::protobuf::Descriptor* EnumValueDescriptorProto::GetDescriptor()
   return descriptor();
 }
 
-const ::google::protobuf::Message::Reflection*
-EnumValueDescriptorProto::GetReflection() const {
-  return &_reflection_;
-}
-
-::google::protobuf::Message::Reflection* EnumValueDescriptorProto::GetReflection() {
-  return &_reflection_;
+const ::google::protobuf::Reflection* EnumValueDescriptorProto::GetReflection() const {
+  if (EnumValueDescriptorProto_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return EnumValueDescriptorProto_reflection_;
 }
 
 // ===================================================================
@@ -2189,10 +2463,7 @@ const int ServiceDescriptorProto::_offsets_[3] = {
 };
 
 ServiceDescriptorProto::ServiceDescriptorProto()
-  : _reflection_(descriptor(),
-                 this, &default_instance_,
-                 _offsets_, _has_bits_, NULL),
-    _cached_size_(0),
+  : _cached_size_(0),
     name_(const_cast< ::std::string*>(&_default_name_)),
     options_(NULL) {
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
@@ -2202,10 +2473,7 @@ ServiceDescriptorProto::ServiceDescriptorProto()
 }
 
 ServiceDescriptorProto::ServiceDescriptorProto(const ServiceDescriptorProto& from)
-  : _reflection_(descriptor(),
-                 this, &default_instance_,
-                 _offsets_, _has_bits_, NULL),
-    _cached_size_(0),
+  : _cached_size_(0),
     name_(const_cast< ::std::string*>(&_default_name_)),
     options_(NULL) {
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
@@ -2222,7 +2490,7 @@ ServiceDescriptorProto::~ServiceDescriptorProto() {
 }
 
 const ::google::protobuf::Descriptor* ServiceDescriptorProto::descriptor() {
-  if (ServiceDescriptorProto_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  if (ServiceDescriptorProto_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   return ServiceDescriptorProto_descriptor_;
 }
 
@@ -2373,8 +2641,7 @@ void ServiceDescriptorProto::MergeFrom(const ::google::protobuf::Message& from)
     ::google::protobuf::internal::dynamic_cast_if_available<const ServiceDescriptorProto*>(
       &from);
   if (source == NULL) {
-    ::google::protobuf::internal::ReflectionOps::Merge(
-      descriptor(), *from.GetReflection(), &_reflection_);
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
   } else {
     MergeFrom(*source);
   }
@@ -2415,13 +2682,9 @@ const ::google::protobuf::Descriptor* ServiceDescriptorProto::GetDescriptor() co
   return descriptor();
 }
 
-const ::google::protobuf::Message::Reflection*
-ServiceDescriptorProto::GetReflection() const {
-  return &_reflection_;
-}
-
-::google::protobuf::Message::Reflection* ServiceDescriptorProto::GetReflection() {
-  return &_reflection_;
+const ::google::protobuf::Reflection* ServiceDescriptorProto::GetReflection() const {
+  if (ServiceDescriptorProto_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return ServiceDescriptorProto_reflection_;
 }
 
 // ===================================================================
@@ -2440,10 +2703,7 @@ const int MethodDescriptorProto::_offsets_[4] = {
 };
 
 MethodDescriptorProto::MethodDescriptorProto()
-  : _reflection_(descriptor(),
-                 this, &default_instance_,
-                 _offsets_, _has_bits_, NULL),
-    _cached_size_(0),
+  : _cached_size_(0),
     name_(const_cast< ::std::string*>(&_default_name_)),
     input_type_(const_cast< ::std::string*>(&_default_input_type_)),
     output_type_(const_cast< ::std::string*>(&_default_output_type_)),
@@ -2455,10 +2715,7 @@ MethodDescriptorProto::MethodDescriptorProto()
 }
 
 MethodDescriptorProto::MethodDescriptorProto(const MethodDescriptorProto& from)
-  : _reflection_(descriptor(),
-                 this, &default_instance_,
-                 _offsets_, _has_bits_, NULL),
-    _cached_size_(0),
+  : _cached_size_(0),
     name_(const_cast< ::std::string*>(&_default_name_)),
     input_type_(const_cast< ::std::string*>(&_default_input_type_)),
     output_type_(const_cast< ::std::string*>(&_default_output_type_)),
@@ -2483,7 +2740,7 @@ MethodDescriptorProto::~MethodDescriptorProto() {
 }
 
 const ::google::protobuf::Descriptor* MethodDescriptorProto::descriptor() {
-  if (MethodDescriptorProto_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  if (MethodDescriptorProto_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   return MethodDescriptorProto_descriptor_;
 }
 
@@ -2662,8 +2919,7 @@ void MethodDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
     ::google::protobuf::internal::dynamic_cast_if_available<const MethodDescriptorProto*>(
       &from);
   if (source == NULL) {
-    ::google::protobuf::internal::ReflectionOps::Merge(
-      descriptor(), *from.GetReflection(), &_reflection_);
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
   } else {
     MergeFrom(*source);
   }
@@ -2709,19 +2965,15 @@ const ::google::protobuf::Descriptor* MethodDescriptorProto::GetDescriptor() con
   return descriptor();
 }
 
-const ::google::protobuf::Message::Reflection*
-MethodDescriptorProto::GetReflection() const {
-  return &_reflection_;
-}
-
-::google::protobuf::Message::Reflection* MethodDescriptorProto::GetReflection() {
-  return &_reflection_;
+const ::google::protobuf::Reflection* MethodDescriptorProto::GetReflection() const {
+  if (MethodDescriptorProto_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return MethodDescriptorProto_reflection_;
 }
 
 // ===================================================================
 
 const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor() {
-  if (FileOptions_OptimizeMode_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  if (FileOptions_OptimizeMode_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   return FileOptions_OptimizeMode_descriptor_;
 }
 bool FileOptions_OptimizeMode_IsValid(int value) {
@@ -2754,10 +3006,7 @@ const int FileOptions::_offsets_[4] = {
 };
 
 FileOptions::FileOptions()
-  : _reflection_(descriptor(),
-                 this, &default_instance_,
-                 _offsets_, _has_bits_, NULL),
-    _cached_size_(0),
+  : _cached_size_(0),
     java_package_(const_cast< ::std::string*>(&_default_java_package_)),
     java_outer_classname_(const_cast< ::std::string*>(&_default_java_outer_classname_)),
     java_multiple_files_(false),
@@ -2768,10 +3017,7 @@ FileOptions::FileOptions()
 }
 
 FileOptions::FileOptions(const FileOptions& from)
-  : _reflection_(descriptor(),
-                 this, &default_instance_,
-                 _offsets_, _has_bits_, NULL),
-    _cached_size_(0),
+  : _cached_size_(0),
     java_package_(const_cast< ::std::string*>(&_default_java_package_)),
     java_outer_classname_(const_cast< ::std::string*>(&_default_java_outer_classname_)),
     java_multiple_files_(false),
@@ -2792,7 +3038,7 @@ FileOptions::~FileOptions() {
 }
 
 const ::google::protobuf::Descriptor* FileOptions::descriptor() {
-  if (FileOptions_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  if (FileOptions_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   return FileOptions_descriptor_;
 }
 
@@ -2970,8 +3216,7 @@ void FileOptions::MergeFrom(const ::google::protobuf::Message& from) {
     ::google::protobuf::internal::dynamic_cast_if_available<const FileOptions*>(
       &from);
   if (source == NULL) {
-    ::google::protobuf::internal::ReflectionOps::Merge(
-      descriptor(), *from.GetReflection(), &_reflection_);
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
   } else {
     MergeFrom(*source);
   }
@@ -3017,13 +3262,9 @@ const ::google::protobuf::Descriptor* FileOptions::GetDescriptor() const {
   return descriptor();
 }
 
-const ::google::protobuf::Message::Reflection*
-FileOptions::GetReflection() const {
-  return &_reflection_;
-}
-
-::google::protobuf::Message::Reflection* FileOptions::GetReflection() {
-  return &_reflection_;
+const ::google::protobuf::Reflection* FileOptions::GetReflection() const {
+  if (FileOptions_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return FileOptions_reflection_;
 }
 
 // ===================================================================
@@ -3036,10 +3277,7 @@ const int MessageOptions::_offsets_[1] = {
 };
 
 MessageOptions::MessageOptions()
-  : _reflection_(descriptor(),
-                 this, &default_instance_,
-                 _offsets_, _has_bits_, NULL),
-    _cached_size_(0),
+  : _cached_size_(0),
     message_set_wire_format_(false) {
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
   if (this == &default_instance_) {
@@ -3047,10 +3285,7 @@ MessageOptions::MessageOptions()
 }
 
 MessageOptions::MessageOptions(const MessageOptions& from)
-  : _reflection_(descriptor(),
-                 this, &default_instance_,
-                 _offsets_, _has_bits_, NULL),
-    _cached_size_(0),
+  : _cached_size_(0),
     message_set_wire_format_(false) {
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
   MergeFrom(from);
@@ -3062,7 +3297,7 @@ MessageOptions::~MessageOptions() {
 }
 
 const ::google::protobuf::Descriptor* MessageOptions::descriptor() {
-  if (MessageOptions_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  if (MessageOptions_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   return MessageOptions_descriptor_;
 }
 
@@ -3154,8 +3389,7 @@ void MessageOptions::MergeFrom(const ::google::protobuf::Message& from) {
     ::google::protobuf::internal::dynamic_cast_if_available<const MessageOptions*>(
       &from);
   if (source == NULL) {
-    ::google::protobuf::internal::ReflectionOps::Merge(
-      descriptor(), *from.GetReflection(), &_reflection_);
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
   } else {
     MergeFrom(*source);
   }
@@ -3192,19 +3426,15 @@ const ::google::protobuf::Descriptor* MessageOptions::GetDescriptor() const {
   return descriptor();
 }
 
-const ::google::protobuf::Message::Reflection*
-MessageOptions::GetReflection() const {
-  return &_reflection_;
-}
-
-::google::protobuf::Message::Reflection* MessageOptions::GetReflection() {
-  return &_reflection_;
+const ::google::protobuf::Reflection* MessageOptions::GetReflection() const {
+  if (MessageOptions_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return MessageOptions_reflection_;
 }
 
 // ===================================================================
 
 const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor() {
-  if (FieldOptions_CType_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  if (FieldOptions_CType_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   return FieldOptions_CType_descriptor_;
 }
 bool FieldOptions_CType_IsValid(int value) {
@@ -3233,10 +3463,7 @@ const int FieldOptions::_offsets_[2] = {
 };
 
 FieldOptions::FieldOptions()
-  : _reflection_(descriptor(),
-                 this, &default_instance_,
-                 _offsets_, _has_bits_, NULL),
-    _cached_size_(0),
+  : _cached_size_(0),
     ctype_(1),
     experimental_map_key_(const_cast< ::std::string*>(&_default_experimental_map_key_)) {
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
@@ -3245,10 +3472,7 @@ FieldOptions::FieldOptions()
 }
 
 FieldOptions::FieldOptions(const FieldOptions& from)
-  : _reflection_(descriptor(),
-                 this, &default_instance_,
-                 _offsets_, _has_bits_, NULL),
-    _cached_size_(0),
+  : _cached_size_(0),
     ctype_(1),
     experimental_map_key_(const_cast< ::std::string*>(&_default_experimental_map_key_)) {
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
@@ -3264,7 +3488,7 @@ FieldOptions::~FieldOptions() {
 }
 
 const ::google::protobuf::Descriptor* FieldOptions::descriptor() {
-  if (FieldOptions_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  if (FieldOptions_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   return FieldOptions_descriptor_;
 }
 
@@ -3389,8 +3613,7 @@ void FieldOptions::MergeFrom(const ::google::protobuf::Message& from) {
     ::google::protobuf::internal::dynamic_cast_if_available<const FieldOptions*>(
       &from);
   if (source == NULL) {
-    ::google::protobuf::internal::ReflectionOps::Merge(
-      descriptor(), *from.GetReflection(), &_reflection_);
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
   } else {
     MergeFrom(*source);
   }
@@ -3430,13 +3653,9 @@ const ::google::protobuf::Descriptor* FieldOptions::GetDescriptor() const {
   return descriptor();
 }
 
-const ::google::protobuf::Message::Reflection*
-FieldOptions::GetReflection() const {
-  return &_reflection_;
-}
-
-::google::protobuf::Message::Reflection* FieldOptions::GetReflection() {
-  return &_reflection_;
+const ::google::protobuf::Reflection* FieldOptions::GetReflection() const {
+  if (FieldOptions_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return FieldOptions_reflection_;
 }
 
 // ===================================================================
@@ -3447,20 +3666,14 @@ const int EnumOptions::_offsets_[1] = {
 };
 
 EnumOptions::EnumOptions()
-  : _reflection_(descriptor(),
-                 this, &default_instance_,
-                 _offsets_, _has_bits_, NULL),
-    _cached_size_(0) {
+  : _cached_size_(0) {
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
   if (this == &default_instance_) {
   }
 }
 
 EnumOptions::EnumOptions(const EnumOptions& from)
-  : _reflection_(descriptor(),
-                 this, &default_instance_,
-                 _offsets_, _has_bits_, NULL),
-    _cached_size_(0) {
+  : _cached_size_(0) {
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
   MergeFrom(from);
 }
@@ -3471,7 +3684,7 @@ EnumOptions::~EnumOptions() {
 }
 
 const ::google::protobuf::Descriptor* EnumOptions::descriptor() {
-  if (EnumOptions_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  if (EnumOptions_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   return EnumOptions_descriptor_;
 }
 
@@ -3553,13 +3766,9 @@ const ::google::protobuf::Descriptor* EnumOptions::GetDescriptor() const {
   return descriptor();
 }
 
-const ::google::protobuf::Message::Reflection*
-EnumOptions::GetReflection() const {
-  return &_reflection_;
-}
-
-::google::protobuf::Message::Reflection* EnumOptions::GetReflection() {
-  return &_reflection_;
+const ::google::protobuf::Reflection* EnumOptions::GetReflection() const {
+  if (EnumOptions_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return EnumOptions_reflection_;
 }
 
 // ===================================================================
@@ -3570,20 +3779,14 @@ const int EnumValueOptions::_offsets_[1] = {
 };
 
 EnumValueOptions::EnumValueOptions()
-  : _reflection_(descriptor(),
-                 this, &default_instance_,
-                 _offsets_, _has_bits_, NULL),
-    _cached_size_(0) {
+  : _cached_size_(0) {
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
   if (this == &default_instance_) {
   }
 }
 
 EnumValueOptions::EnumValueOptions(const EnumValueOptions& from)
-  : _reflection_(descriptor(),
-                 this, &default_instance_,
-                 _offsets_, _has_bits_, NULL),
-    _cached_size_(0) {
+  : _cached_size_(0) {
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
   MergeFrom(from);
 }
@@ -3594,7 +3797,7 @@ EnumValueOptions::~EnumValueOptions() {
 }
 
 const ::google::protobuf::Descriptor* EnumValueOptions::descriptor() {
-  if (EnumValueOptions_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  if (EnumValueOptions_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   return EnumValueOptions_descriptor_;
 }
 
@@ -3676,13 +3879,9 @@ const ::google::protobuf::Descriptor* EnumValueOptions::GetDescriptor() const {
   return descriptor();
 }
 
-const ::google::protobuf::Message::Reflection*
-EnumValueOptions::GetReflection() const {
-  return &_reflection_;
-}
-
-::google::protobuf::Message::Reflection* EnumValueOptions::GetReflection() {
-  return &_reflection_;
+const ::google::protobuf::Reflection* EnumValueOptions::GetReflection() const {
+  if (EnumValueOptions_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return EnumValueOptions_reflection_;
 }
 
 // ===================================================================
@@ -3693,20 +3892,14 @@ const int ServiceOptions::_offsets_[1] = {
 };
 
 ServiceOptions::ServiceOptions()
-  : _reflection_(descriptor(),
-                 this, &default_instance_,
-                 _offsets_, _has_bits_, NULL),
-    _cached_size_(0) {
+  : _cached_size_(0) {
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
   if (this == &default_instance_) {
   }
 }
 
 ServiceOptions::ServiceOptions(const ServiceOptions& from)
-  : _reflection_(descriptor(),
-                 this, &default_instance_,
-                 _offsets_, _has_bits_, NULL),
-    _cached_size_(0) {
+  : _cached_size_(0) {
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
   MergeFrom(from);
 }
@@ -3717,7 +3910,7 @@ ServiceOptions::~ServiceOptions() {
 }
 
 const ::google::protobuf::Descriptor* ServiceOptions::descriptor() {
-  if (ServiceOptions_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  if (ServiceOptions_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   return ServiceOptions_descriptor_;
 }
 
@@ -3799,13 +3992,9 @@ const ::google::protobuf::Descriptor* ServiceOptions::GetDescriptor() const {
   return descriptor();
 }
 
-const ::google::protobuf::Message::Reflection*
-ServiceOptions::GetReflection() const {
-  return &_reflection_;
-}
-
-::google::protobuf::Message::Reflection* ServiceOptions::GetReflection() {
-  return &_reflection_;
+const ::google::protobuf::Reflection* ServiceOptions::GetReflection() const {
+  if (ServiceOptions_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return ServiceOptions_reflection_;
 }
 
 // ===================================================================
@@ -3816,20 +4005,14 @@ const int MethodOptions::_offsets_[1] = {
 };
 
 MethodOptions::MethodOptions()
-  : _reflection_(descriptor(),
-                 this, &default_instance_,
-                 _offsets_, _has_bits_, NULL),
-    _cached_size_(0) {
+  : _cached_size_(0) {
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
   if (this == &default_instance_) {
   }
 }
 
 MethodOptions::MethodOptions(const MethodOptions& from)
-  : _reflection_(descriptor(),
-                 this, &default_instance_,
-                 _offsets_, _has_bits_, NULL),
-    _cached_size_(0) {
+  : _cached_size_(0) {
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
   MergeFrom(from);
 }
@@ -3840,7 +4023,7 @@ MethodOptions::~MethodOptions() {
 }
 
 const ::google::protobuf::Descriptor* MethodOptions::descriptor() {
-  if (MethodOptions_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  if (MethodOptions_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   return MethodOptions_descriptor_;
 }
 
@@ -3922,13 +4105,9 @@ const ::google::protobuf::Descriptor* MethodOptions::GetDescriptor() const {
   return descriptor();
 }
 
-const ::google::protobuf::Message::Reflection*
-MethodOptions::GetReflection() const {
-  return &_reflection_;
-}
-
-::google::protobuf::Message::Reflection* MethodOptions::GetReflection() {
-  return &_reflection_;
+const ::google::protobuf::Reflection* MethodOptions::GetReflection() const {
+  if (MethodOptions_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return MethodOptions_reflection_;
 }
 
 }  // namespace protobuf
diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h
index 892f92d0c5a3dd241ce88c9ffc3deddbc1f73f67..926e9bd0002409f59cf6535ed61a5bad91c27e65 100644
--- a/src/google/protobuf/descriptor.pb.h
+++ b/src/google/protobuf/descriptor.pb.h
@@ -7,7 +7,7 @@
 
 #include <google/protobuf/stubs/common.h>
 
-#if GOOGLE_PROTOBUF_VERSION < 2000000
+#if GOOGLE_PROTOBUF_VERSION < 2000001
 #error This file was generated by a newer version of protoc which is
 #error incompatible with your Protocol Buffer headers.  Please update
 #error your headers.
@@ -25,6 +25,10 @@
 namespace google {
 namespace protobuf {
 
+// Internal implementation detail -- do not call this.
+void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
+
+class FileDescriptorSet;
 class FileDescriptorProto;
 class DescriptorProto;
 class DescriptorProto_ExtensionRange;
@@ -96,6 +100,92 @@ const FieldOptions_CType FieldOptions_CType_CType_MAX = FieldOptions_CType_STRIN
 
 // ===================================================================
 
+class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message {
+ public:
+  FileDescriptorSet();
+  virtual ~FileDescriptorSet();
+  
+  FileDescriptorSet(const FileDescriptorSet& from);
+  
+  inline FileDescriptorSet& operator=(const FileDescriptorSet& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  
+  inline static const FileDescriptorSet& default_instance() {
+    return default_instance_;
+  }
+  
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _unknown_fields_;
+  }
+  
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return &_unknown_fields_;
+  }
+  
+  static const ::google::protobuf::Descriptor* descriptor();
+  
+  // implements Message ----------------------------------------------
+  
+  FileDescriptorSet* New() const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const FileDescriptorSet& from);
+  void MergeFrom(const FileDescriptorSet& from);
+  void Clear();
+  bool IsInitialized() const;
+  int ByteSize() const;
+  
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  bool SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SetCachedSize(int size) const { _cached_size_ = size; }
+  public:
+  
+  const ::google::protobuf::Descriptor* GetDescriptor() const;
+  const ::google::protobuf::Reflection* GetReflection() const;
+  
+  // nested types ----------------------------------------------------
+  
+  // accessors -------------------------------------------------------
+  
+  // repeated .google.protobuf.FileDescriptorProto file = 1;
+  inline int file_size() const;
+  inline void clear_file();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >& file() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >* mutable_file();
+  inline const ::google::protobuf::FileDescriptorProto& file(int index) const;
+  inline ::google::protobuf::FileDescriptorProto* mutable_file(int index);
+  inline ::google::protobuf::FileDescriptorProto* add_file();
+  
+ private:
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
+  mutable int _cached_size_;
+  
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > file_;
+  friend void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  static const FileDescriptorSet default_instance_;
+  static const int _offsets_[1];
+  
+  ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
+  
+  // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
+  inline bool _has_bit(int index) const {
+    return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
+  }
+  inline void _set_bit(int index) {
+    _has_bits_[index / 32] |= (1u << (index % 32));
+  }
+  inline void _clear_bit(int index) {
+    _has_bits_[index / 32] &= ~(1u << (index % 32));
+  }
+};
+// -------------------------------------------------------------------
+
 class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Message {
  public:
   FileDescriptorProto();
@@ -113,11 +203,11 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag
   }
   
   inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
-    return _reflection_.unknown_fields();
+    return _unknown_fields_;
   }
   
   inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
-    return _reflection_.mutable_unknown_fields();
+    return &_unknown_fields_;
   }
   
   static const ::google::protobuf::Descriptor* descriptor();
@@ -143,8 +233,7 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag
   public:
   
   const ::google::protobuf::Descriptor* GetDescriptor() const;
-  const ::google::protobuf::Message::Reflection* GetReflection() const;
-  ::google::protobuf::Message::Reflection* GetReflection();
+  const ::google::protobuf::Reflection* GetReflection() const;
   
   // nested types ----------------------------------------------------
   
@@ -222,7 +311,7 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag
   inline ::google::protobuf::FileOptions* mutable_options();
   
  private:
-  ::google::protobuf::internal::GeneratedMessageReflection _reflection_;
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
   mutable int _cached_size_;
   
   ::std::string* name_;
@@ -235,7 +324,7 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto > service_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_;
   ::google::protobuf::FileOptions* options_;
-  
+  friend void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   static const FileDescriptorProto default_instance_;
   static const int _offsets_[8];
   
@@ -271,11 +360,11 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::proto
   }
   
   inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
-    return _reflection_.unknown_fields();
+    return _unknown_fields_;
   }
   
   inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
-    return _reflection_.mutable_unknown_fields();
+    return &_unknown_fields_;
   }
   
   static const ::google::protobuf::Descriptor* descriptor();
@@ -301,8 +390,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::proto
   public:
   
   const ::google::protobuf::Descriptor* GetDescriptor() const;
-  const ::google::protobuf::Message::Reflection* GetReflection() const;
-  ::google::protobuf::Message::Reflection* GetReflection();
+  const ::google::protobuf::Reflection* GetReflection() const;
   
   // nested types ----------------------------------------------------
   
@@ -321,12 +409,12 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::proto
   inline void set_end(::google::protobuf::int32 value);
   
  private:
-  ::google::protobuf::internal::GeneratedMessageReflection _reflection_;
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
   mutable int _cached_size_;
   
   ::google::protobuf::int32 start_;
   ::google::protobuf::int32 end_;
-  
+  friend void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   static const DescriptorProto_ExtensionRange default_instance_;
   static const int _offsets_[2];
   
@@ -362,11 +450,11 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message {
   }
   
   inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
-    return _reflection_.unknown_fields();
+    return _unknown_fields_;
   }
   
   inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
-    return _reflection_.mutable_unknown_fields();
+    return &_unknown_fields_;
   }
   
   static const ::google::protobuf::Descriptor* descriptor();
@@ -392,8 +480,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message {
   public:
   
   const ::google::protobuf::Descriptor* GetDescriptor() const;
-  const ::google::protobuf::Message::Reflection* GetReflection() const;
-  ::google::protobuf::Message::Reflection* GetReflection();
+  const ::google::protobuf::Reflection* GetReflection() const;
   
   // nested types ----------------------------------------------------
   
@@ -461,7 +548,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message {
   inline ::google::protobuf::MessageOptions* mutable_options();
   
  private:
-  ::google::protobuf::internal::GeneratedMessageReflection _reflection_;
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
   mutable int _cached_size_;
   
   ::std::string* name_;
@@ -472,7 +559,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message {
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto > enum_type_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange > extension_range_;
   ::google::protobuf::MessageOptions* options_;
-  
+  friend void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   static const DescriptorProto default_instance_;
   static const int _offsets_[7];
   
@@ -508,11 +595,11 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa
   }
   
   inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
-    return _reflection_.unknown_fields();
+    return _unknown_fields_;
   }
   
   inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
-    return _reflection_.mutable_unknown_fields();
+    return &_unknown_fields_;
   }
   
   static const ::google::protobuf::Descriptor* descriptor();
@@ -538,8 +625,7 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa
   public:
   
   const ::google::protobuf::Descriptor* GetDescriptor() const;
-  const ::google::protobuf::Message::Reflection* GetReflection() const;
-  ::google::protobuf::Message::Reflection* GetReflection();
+  const ::google::protobuf::Reflection* GetReflection() const;
   
   // nested types ----------------------------------------------------
   
@@ -649,7 +735,7 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa
   inline ::google::protobuf::FieldOptions* mutable_options();
   
  private:
-  ::google::protobuf::internal::GeneratedMessageReflection _reflection_;
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
   mutable int _cached_size_;
   
   ::std::string* name_;
@@ -664,7 +750,7 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa
   ::std::string* default_value_;
   static const ::std::string _default_default_value_;
   ::google::protobuf::FieldOptions* options_;
-  
+  friend void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   static const FieldDescriptorProto default_instance_;
   static const int _offsets_[8];
   
@@ -700,11 +786,11 @@ class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Messag
   }
   
   inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
-    return _reflection_.unknown_fields();
+    return _unknown_fields_;
   }
   
   inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
-    return _reflection_.mutable_unknown_fields();
+    return &_unknown_fields_;
   }
   
   static const ::google::protobuf::Descriptor* descriptor();
@@ -730,8 +816,7 @@ class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Messag
   public:
   
   const ::google::protobuf::Descriptor* GetDescriptor() const;
-  const ::google::protobuf::Message::Reflection* GetReflection() const;
-  ::google::protobuf::Message::Reflection* GetReflection();
+  const ::google::protobuf::Reflection* GetReflection() const;
   
   // nested types ----------------------------------------------------
   
@@ -761,14 +846,14 @@ class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Messag
   inline ::google::protobuf::EnumOptions* mutable_options();
   
  private:
-  ::google::protobuf::internal::GeneratedMessageReflection _reflection_;
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
   mutable int _cached_size_;
   
   ::std::string* name_;
   static const ::std::string _default_name_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto > value_;
   ::google::protobuf::EnumOptions* options_;
-  
+  friend void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   static const EnumDescriptorProto default_instance_;
   static const int _offsets_[3];
   
@@ -804,11 +889,11 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::M
   }
   
   inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
-    return _reflection_.unknown_fields();
+    return _unknown_fields_;
   }
   
   inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
-    return _reflection_.mutable_unknown_fields();
+    return &_unknown_fields_;
   }
   
   static const ::google::protobuf::Descriptor* descriptor();
@@ -834,8 +919,7 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::M
   public:
   
   const ::google::protobuf::Descriptor* GetDescriptor() const;
-  const ::google::protobuf::Message::Reflection* GetReflection() const;
-  ::google::protobuf::Message::Reflection* GetReflection();
+  const ::google::protobuf::Reflection* GetReflection() const;
   
   // nested types ----------------------------------------------------
   
@@ -862,14 +946,14 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::M
   inline ::google::protobuf::EnumValueOptions* mutable_options();
   
  private:
-  ::google::protobuf::internal::GeneratedMessageReflection _reflection_;
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
   mutable int _cached_size_;
   
   ::std::string* name_;
   static const ::std::string _default_name_;
   ::google::protobuf::int32 number_;
   ::google::protobuf::EnumValueOptions* options_;
-  
+  friend void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   static const EnumValueDescriptorProto default_instance_;
   static const int _offsets_[3];
   
@@ -905,11 +989,11 @@ class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Mes
   }
   
   inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
-    return _reflection_.unknown_fields();
+    return _unknown_fields_;
   }
   
   inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
-    return _reflection_.mutable_unknown_fields();
+    return &_unknown_fields_;
   }
   
   static const ::google::protobuf::Descriptor* descriptor();
@@ -935,8 +1019,7 @@ class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Mes
   public:
   
   const ::google::protobuf::Descriptor* GetDescriptor() const;
-  const ::google::protobuf::Message::Reflection* GetReflection() const;
-  ::google::protobuf::Message::Reflection* GetReflection();
+  const ::google::protobuf::Reflection* GetReflection() const;
   
   // nested types ----------------------------------------------------
   
@@ -966,14 +1049,14 @@ class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Mes
   inline ::google::protobuf::ServiceOptions* mutable_options();
   
  private:
-  ::google::protobuf::internal::GeneratedMessageReflection _reflection_;
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
   mutable int _cached_size_;
   
   ::std::string* name_;
   static const ::std::string _default_name_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto > method_;
   ::google::protobuf::ServiceOptions* options_;
-  
+  friend void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   static const ServiceDescriptorProto default_instance_;
   static const int _offsets_[3];
   
@@ -1009,11 +1092,11 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess
   }
   
   inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
-    return _reflection_.unknown_fields();
+    return _unknown_fields_;
   }
   
   inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
-    return _reflection_.mutable_unknown_fields();
+    return &_unknown_fields_;
   }
   
   static const ::google::protobuf::Descriptor* descriptor();
@@ -1039,8 +1122,7 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess
   public:
   
   const ::google::protobuf::Descriptor* GetDescriptor() const;
-  const ::google::protobuf::Message::Reflection* GetReflection() const;
-  ::google::protobuf::Message::Reflection* GetReflection();
+  const ::google::protobuf::Reflection* GetReflection() const;
   
   // nested types ----------------------------------------------------
   
@@ -1077,7 +1159,7 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess
   inline ::google::protobuf::MethodOptions* mutable_options();
   
  private:
-  ::google::protobuf::internal::GeneratedMessageReflection _reflection_;
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
   mutable int _cached_size_;
   
   ::std::string* name_;
@@ -1087,7 +1169,7 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess
   ::std::string* output_type_;
   static const ::std::string _default_output_type_;
   ::google::protobuf::MethodOptions* options_;
-  
+  friend void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   static const MethodDescriptorProto default_instance_;
   static const int _offsets_[4];
   
@@ -1123,11 +1205,11 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
   }
   
   inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
-    return _reflection_.unknown_fields();
+    return _unknown_fields_;
   }
   
   inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
-    return _reflection_.mutable_unknown_fields();
+    return &_unknown_fields_;
   }
   
   static const ::google::protobuf::Descriptor* descriptor();
@@ -1153,8 +1235,7 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
   public:
   
   const ::google::protobuf::Descriptor* GetDescriptor() const;
-  const ::google::protobuf::Message::Reflection* GetReflection() const;
-  ::google::protobuf::Message::Reflection* GetReflection();
+  const ::google::protobuf::Reflection* GetReflection() const;
   
   // nested types ----------------------------------------------------
   
@@ -1204,7 +1285,7 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
   inline void set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value);
   
  private:
-  ::google::protobuf::internal::GeneratedMessageReflection _reflection_;
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
   mutable int _cached_size_;
   
   ::std::string* java_package_;
@@ -1213,7 +1294,7 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
   static const ::std::string _default_java_outer_classname_;
   bool java_multiple_files_;
   int optimize_for_;
-  
+  friend void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   static const FileOptions default_instance_;
   static const int _offsets_[4];
   
@@ -1249,11 +1330,11 @@ class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message {
   }
   
   inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
-    return _reflection_.unknown_fields();
+    return _unknown_fields_;
   }
   
   inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
-    return _reflection_.mutable_unknown_fields();
+    return &_unknown_fields_;
   }
   
   static const ::google::protobuf::Descriptor* descriptor();
@@ -1279,8 +1360,7 @@ class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message {
   public:
   
   const ::google::protobuf::Descriptor* GetDescriptor() const;
-  const ::google::protobuf::Message::Reflection* GetReflection() const;
-  ::google::protobuf::Message::Reflection* GetReflection();
+  const ::google::protobuf::Reflection* GetReflection() const;
   
   // nested types ----------------------------------------------------
   
@@ -1293,11 +1373,11 @@ class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message {
   inline void set_message_set_wire_format(bool value);
   
  private:
-  ::google::protobuf::internal::GeneratedMessageReflection _reflection_;
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
   mutable int _cached_size_;
   
   bool message_set_wire_format_;
-  
+  friend void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   static const MessageOptions default_instance_;
   static const int _offsets_[1];
   
@@ -1333,11 +1413,11 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message {
   }
   
   inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
-    return _reflection_.unknown_fields();
+    return _unknown_fields_;
   }
   
   inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
-    return _reflection_.mutable_unknown_fields();
+    return &_unknown_fields_;
   }
   
   static const ::google::protobuf::Descriptor* descriptor();
@@ -1363,8 +1443,7 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message {
   public:
   
   const ::google::protobuf::Descriptor* GetDescriptor() const;
-  const ::google::protobuf::Message::Reflection* GetReflection() const;
-  ::google::protobuf::Message::Reflection* GetReflection();
+  const ::google::protobuf::Reflection* GetReflection() const;
   
   // nested types ----------------------------------------------------
   
@@ -1400,13 +1479,13 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message {
   inline ::std::string* mutable_experimental_map_key();
   
  private:
-  ::google::protobuf::internal::GeneratedMessageReflection _reflection_;
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
   mutable int _cached_size_;
   
   int ctype_;
   ::std::string* experimental_map_key_;
   static const ::std::string _default_experimental_map_key_;
-  
+  friend void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   static const FieldOptions default_instance_;
   static const int _offsets_[2];
   
@@ -1442,11 +1521,11 @@ class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message {
   }
   
   inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
-    return _reflection_.unknown_fields();
+    return _unknown_fields_;
   }
   
   inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
-    return _reflection_.mutable_unknown_fields();
+    return &_unknown_fields_;
   }
   
   static const ::google::protobuf::Descriptor* descriptor();
@@ -1472,18 +1551,17 @@ class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message {
   public:
   
   const ::google::protobuf::Descriptor* GetDescriptor() const;
-  const ::google::protobuf::Message::Reflection* GetReflection() const;
-  ::google::protobuf::Message::Reflection* GetReflection();
+  const ::google::protobuf::Reflection* GetReflection() const;
   
   // nested types ----------------------------------------------------
   
   // accessors -------------------------------------------------------
   
  private:
-  ::google::protobuf::internal::GeneratedMessageReflection _reflection_;
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
   mutable int _cached_size_;
   
-  
+  friend void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   static const EnumOptions default_instance_;
   static const int _offsets_[1];
   
@@ -1519,11 +1597,11 @@ class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message {
   }
   
   inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
-    return _reflection_.unknown_fields();
+    return _unknown_fields_;
   }
   
   inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
-    return _reflection_.mutable_unknown_fields();
+    return &_unknown_fields_;
   }
   
   static const ::google::protobuf::Descriptor* descriptor();
@@ -1549,18 +1627,17 @@ class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message {
   public:
   
   const ::google::protobuf::Descriptor* GetDescriptor() const;
-  const ::google::protobuf::Message::Reflection* GetReflection() const;
-  ::google::protobuf::Message::Reflection* GetReflection();
+  const ::google::protobuf::Reflection* GetReflection() const;
   
   // nested types ----------------------------------------------------
   
   // accessors -------------------------------------------------------
   
  private:
-  ::google::protobuf::internal::GeneratedMessageReflection _reflection_;
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
   mutable int _cached_size_;
   
-  
+  friend void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   static const EnumValueOptions default_instance_;
   static const int _offsets_[1];
   
@@ -1596,11 +1673,11 @@ class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message {
   }
   
   inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
-    return _reflection_.unknown_fields();
+    return _unknown_fields_;
   }
   
   inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
-    return _reflection_.mutable_unknown_fields();
+    return &_unknown_fields_;
   }
   
   static const ::google::protobuf::Descriptor* descriptor();
@@ -1626,18 +1703,17 @@ class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message {
   public:
   
   const ::google::protobuf::Descriptor* GetDescriptor() const;
-  const ::google::protobuf::Message::Reflection* GetReflection() const;
-  ::google::protobuf::Message::Reflection* GetReflection();
+  const ::google::protobuf::Reflection* GetReflection() const;
   
   // nested types ----------------------------------------------------
   
   // accessors -------------------------------------------------------
   
  private:
-  ::google::protobuf::internal::GeneratedMessageReflection _reflection_;
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
   mutable int _cached_size_;
   
-  
+  friend void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   static const ServiceOptions default_instance_;
   static const int _offsets_[1];
   
@@ -1673,11 +1749,11 @@ class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message {
   }
   
   inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
-    return _reflection_.unknown_fields();
+    return _unknown_fields_;
   }
   
   inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
-    return _reflection_.mutable_unknown_fields();
+    return &_unknown_fields_;
   }
   
   static const ::google::protobuf::Descriptor* descriptor();
@@ -1703,18 +1779,17 @@ class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message {
   public:
   
   const ::google::protobuf::Descriptor* GetDescriptor() const;
-  const ::google::protobuf::Message::Reflection* GetReflection() const;
-  ::google::protobuf::Message::Reflection* GetReflection();
+  const ::google::protobuf::Reflection* GetReflection() const;
   
   // nested types ----------------------------------------------------
   
   // accessors -------------------------------------------------------
   
  private:
-  ::google::protobuf::internal::GeneratedMessageReflection _reflection_;
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
   mutable int _cached_size_;
   
-  
+  friend void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto();
   static const MethodOptions default_instance_;
   static const int _offsets_[1];
   
@@ -1739,6 +1814,35 @@ class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message {
 
 // ===================================================================
 
+// FileDescriptorSet
+
+// repeated .google.protobuf.FileDescriptorProto file = 1;
+inline int FileDescriptorSet::file_size() const {
+  return file_.size();
+}
+inline void FileDescriptorSet::clear_file() {
+  file_.Clear();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
+FileDescriptorSet::file() const {
+  return file_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
+FileDescriptorSet::mutable_file() {
+  return &file_;
+}
+inline const ::google::protobuf::FileDescriptorProto& FileDescriptorSet::file(int index) const {
+  return file_.Get(index);
+}
+inline ::google::protobuf::FileDescriptorProto* FileDescriptorSet::mutable_file(int index) {
+  return file_.Mutable(index);
+}
+inline ::google::protobuf::FileDescriptorProto* FileDescriptorSet::add_file() {
+  return file_.Add();
+}
+
+// -------------------------------------------------------------------
+
 // FileDescriptorProto
 
 // optional string name = 1;
diff --git a/src/google/protobuf/descriptor.proto b/src/google/protobuf/descriptor.proto
index 13d9478098cc04d0fafba9bebde3a4e216edfb52..6a8c0c266a903a82b6ff55f356c23034063a6fab 100644
--- a/src/google/protobuf/descriptor.proto
+++ b/src/google/protobuf/descriptor.proto
@@ -32,6 +32,12 @@ option java_outer_classname = "DescriptorProtos";
 // algorithms don't work during bootstrapping.
 option optimize_for = SPEED;
 
+// The protocol compiler can output a FileDescriptorSet containing the .proto
+// files it parses.
+message FileDescriptorSet {
+  repeated FileDescriptorProto file = 1;
+}
+
 // Describes a complete .proto file.
 message FileDescriptorProto {
   optional string name = 1;       // file name, relative to root of source tree
diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc
index 43e2451eae8dbb7aac0e4bf045bfec530ca1502c..c355bf5f0b1a593cb63eef86ea9683d8aefc73a2 100644
--- a/src/google/protobuf/dynamic_message.cc
+++ b/src/google/protobuf/dynamic_message.cc
@@ -23,7 +23,7 @@
 // Then, we use GeneratedMessageReflection to implement our reflection
 // interface.  All the other operations we need to implement (e.g.
 // parsing, copying, etc.) are already implemented in terms of
-// Message::Reflection, so the rest is easy.
+// Reflection, so the rest is easy.
 //
 // The up side of this strategy is that it's very efficient.  We don't
 // need to use hash_maps or generic representations of fields.  The
@@ -141,6 +141,14 @@ inline int DivideRoundingUp(int i, int j) {
   return (i + (j - 1)) / j;
 }
 
+static const int kSafeAlignment = sizeof(uint64);
+
+// Rounds the given byte offset up to the next offset aligned such that any
+// type may be stored at it.
+inline int AlignOffset(int offset) {
+  return DivideRoundingUp(offset, kSafeAlignment) * kSafeAlignment;
+}
+
 #define bitsizeof(T) (sizeof(T) * 8)
 
 }  // namespace
@@ -149,14 +157,29 @@ inline int DivideRoundingUp(int i, int j) {
 
 class DynamicMessage : public Message {
  public:
-  DynamicMessage(const Descriptor* descriptor,
-                 uint8* base, const uint8* prototype_base,
-                 int size, const int offsets[],
-                 const DescriptorPool* pool, DynamicMessageFactory* factory);
+  struct TypeInfo {
+    int size;
+    int has_bits_offset;
+    int unknown_fields_offset;
+    int extensions_offset;
+
+    // Not owned by the TypeInfo.
+    DynamicMessageFactory* factory;  // The factory that created this object.
+    const DescriptorPool* pool;      // The factory's DescriptorPool.
+    const Descriptor* type;          // Type of this DynamicMessage.
+
+    // Warning:  The order in which the following pointers are defined is
+    //   important (the prototype must be deleted *before* the offsets).
+    scoped_array<int> offsets;
+    scoped_ptr<const GeneratedMessageReflection> reflection;
+    scoped_ptr<const DynamicMessage> prototype;
+  };
+
+  DynamicMessage(const TypeInfo* type_info);
   ~DynamicMessage();
 
   // Called on the prototype after construction to initialize message fields.
-  void CrossLinkPrototypes(DynamicMessageFactory* factory);
+  void CrossLinkPrototypes();
 
   // implements Message ----------------------------------------------
 
@@ -167,47 +190,32 @@ class DynamicMessage : public Message {
 
   const Descriptor* GetDescriptor() const;
   const Reflection* GetReflection() const;
-  Reflection* GetReflection();
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessage);
 
-  inline bool is_prototype() { return base_ == prototype_base_; }
+  inline bool is_prototype() const {
+    return type_info_->prototype == this ||
+           // If type_info_->prototype is NULL, then we must be constructing
+           // the prototype now, which means we must be the prototype.
+           type_info_->prototype == NULL;
+  }
+
+  inline void* OffsetToPointer(int offset) {
+    return reinterpret_cast<uint8*>(this) + offset;
+  }
+  inline const void* OffsetToPointer(int offset) const {
+    return reinterpret_cast<const uint8*>(this) + offset;
+  }
 
-  const Descriptor* descriptor_;
-  const DescriptorPool* descriptor_pool_;
-  DynamicMessageFactory* factory_;
-  scoped_ptr<ExtensionSet> extensions_;
-  GeneratedMessageReflection reflection_;
-  uint8* base_;
-  const uint8* prototype_base_;
-  const int* offsets_;
-  int size_;
+  const TypeInfo* type_info_;
 
   // TODO(kenton):  Make this an atomic<int> when C++ supports it.
   mutable int cached_byte_size_;
 };
 
-DynamicMessage::DynamicMessage(const Descriptor* descriptor,
-                               uint8* base, const uint8* prototype_base,
-                               int size, const int offsets[],
-                               const DescriptorPool* pool,
-                               DynamicMessageFactory* factory)
-  : descriptor_(descriptor),
-    descriptor_pool_((pool == NULL) ? descriptor->file()->pool() : pool),
-    factory_(factory),
-    extensions_(descriptor->extension_range_count() > 0 ?
-                new ExtensionSet(descriptor, descriptor_pool_, factory_) :
-                NULL),
-    reflection_(descriptor, base, prototype_base, offsets,
-                // has_bits
-                reinterpret_cast<uint32*>(base + size) -
-                DivideRoundingUp(descriptor->field_count(), bitsizeof(uint32)),
-                extensions_.get()),
-    base_(base),
-    prototype_base_(prototype_base),
-    offsets_(offsets),
-    size_(size),
+DynamicMessage::DynamicMessage(const TypeInfo* type_info)
+  : type_info_(type_info),
     cached_byte_size_(0) {
   // We need to call constructors for various fields manually and set
   // default values where appropriate.  We use placement new to call
@@ -217,9 +225,19 @@ DynamicMessage::DynamicMessage(const Descriptor* descriptor,
   // any time you are trying to convert untyped memory to typed memory, though
   // in practice that's not strictly necessary for types that don't have a
   // constructor.)
+
+  const Descriptor* descriptor = type_info_->type;
+
+  new(OffsetToPointer(type_info_->unknown_fields_offset)) UnknownFieldSet;
+
+  if (type_info_->extensions_offset != -1) {
+    new(OffsetToPointer(type_info_->extensions_offset))
+      ExtensionSet(&type_info_->type, type_info_->pool, type_info_->factory);
+  }
+
   for (int i = 0; i < descriptor->field_count(); i++) {
     const FieldDescriptor* field = descriptor->field(i);
-    void* field_ptr = base + offsets[i];
+    void* field_ptr = OffsetToPointer(type_info_->offsets[i]);
     switch (field->cpp_type()) {
 #define HANDLE_TYPE(CPPTYPE, TYPE)                                           \
       case FieldDescriptor::CPPTYPE_##CPPTYPE:                               \
@@ -254,7 +272,8 @@ DynamicMessage::DynamicMessage(const Descriptor* descriptor,
             } else {
               string* default_value =
                 *reinterpret_cast<string* const*>(
-                  prototype_base + offsets[i]);
+                  type_info_->prototype->OffsetToPointer(
+                    type_info_->offsets[i]));
               new(field_ptr) string*(default_value);
             }
           } else {
@@ -272,7 +291,8 @@ DynamicMessage::DynamicMessage(const Descriptor* descriptor,
           } else {
             const RepeatedPtrField<Message>* prototype_field =
               reinterpret_cast<const RepeatedPtrField<Message>*>(
-                prototype_base + offsets[i]);
+                type_info_->prototype->OffsetToPointer(
+                  type_info_->offsets[i]));
             new(field_ptr) RepeatedPtrField<Message>(
               prototype_field->prototype());
           }
@@ -284,16 +304,25 @@ DynamicMessage::DynamicMessage(const Descriptor* descriptor,
 }
 
 DynamicMessage::~DynamicMessage() {
+  const Descriptor* descriptor = type_info_->type;
+
+  reinterpret_cast<UnknownFieldSet*>(
+    OffsetToPointer(type_info_->unknown_fields_offset))->~UnknownFieldSet();
+
+  if (type_info_->extensions_offset != -1) {
+    reinterpret_cast<ExtensionSet*>(
+      OffsetToPointer(type_info_->extensions_offset))->~ExtensionSet();
+  }
+
   // We need to manually run the destructors for repeated fields and strings,
   // just as we ran their constructors in the the DynamicMessage constructor.
   // Additionally, if any singular embedded messages have been allocated, we
   // need to delete them, UNLESS we are the prototype message of this type,
   // in which case any embedded messages are other prototypes and shouldn't
   // be touched.
-  const Descriptor* descriptor = GetDescriptor();
   for (int i = 0; i < descriptor->field_count(); i++) {
     const FieldDescriptor* field = descriptor->field(i);
-    void* field_ptr = base_ + offsets_[i];
+    void* field_ptr = OffsetToPointer(type_info_->offsets[i]);
 
     if (field->is_repeated()) {
       GenericRepeatedField* field =
@@ -313,26 +342,19 @@ DynamicMessage::~DynamicMessage() {
       }
     }
   }
-
-  // OK, now we can delete our base pointer.
-  operator delete(base_);
-
-  // When the prototype is deleted, we also want to free the offsets table.
-  // (The prototype is only deleted when the factory that created it is
-  // deleted.)
-  if (is_prototype()) {
-    delete [] offsets_;
-  }
 }
 
-void DynamicMessage::CrossLinkPrototypes(DynamicMessageFactory* factory) {
+void DynamicMessage::CrossLinkPrototypes() {
   // This should only be called on the prototype message.
   GOOGLE_CHECK(is_prototype());
 
+  DynamicMessageFactory* factory = type_info_->factory;
+  const Descriptor* descriptor = type_info_->type;
+
   // Cross-link default messages.
-  for (int i = 0; i < descriptor_->field_count(); i++) {
-    const FieldDescriptor* field = descriptor_->field(i);
-    void* field_ptr = base_ + offsets_[i];
+  for (int i = 0; i < descriptor->field_count(); i++) {
+    const FieldDescriptor* field = descriptor->field(i);
+    void* field_ptr = OffsetToPointer(type_info_->offsets[i]);
 
     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
       // For fields with message types, we need to cross-link with the
@@ -357,11 +379,9 @@ void DynamicMessage::CrossLinkPrototypes(DynamicMessageFactory* factory) {
 }
 
 Message* DynamicMessage::New() const {
-  uint8* new_base = reinterpret_cast<uint8*>(operator new(size_));
-  memset(new_base, 0, size_);
-
-  return new DynamicMessage(GetDescriptor(), new_base, prototype_base_,
-                            size_, offsets_, descriptor_pool_, factory_);
+  void* new_base = reinterpret_cast<uint8*>(operator new(type_info_->size));
+  memset(new_base, 0, type_info_->size);
+  return new(new_base) DynamicMessage(type_info_);
 }
 
 int DynamicMessage::GetCachedSize() const {
@@ -376,21 +396,17 @@ void DynamicMessage::SetCachedSize(int size) const {
 }
 
 const Descriptor* DynamicMessage::GetDescriptor() const {
-  return descriptor_;
-}
-
-const Message::Reflection* DynamicMessage::GetReflection() const {
-  return &reflection_;
+  return type_info_->type;
 }
 
-Message::Reflection* DynamicMessage::GetReflection() {
-  return &reflection_;
+const Reflection* DynamicMessage::GetReflection() const {
+  return type_info_->reflection.get();
 }
 
 // ===================================================================
 
 struct DynamicMessageFactory::PrototypeMap {
-  typedef hash_map<const Descriptor*, const Message*> Map;
+  typedef hash_map<const Descriptor*, const DynamicMessage::TypeInfo*> Map;
   Map map_;
 };
 
@@ -411,12 +427,19 @@ DynamicMessageFactory::~DynamicMessageFactory() {
 
 
 const Message* DynamicMessageFactory::GetPrototype(const Descriptor* type) {
-  const Message** target = &prototypes_->map_[type];
+  const DynamicMessage::TypeInfo** target = &prototypes_->map_[type];
   if (*target != NULL) {
     // Already exists.
-    return *target;
+    return (*target)->prototype.get();
   }
 
+  DynamicMessage::TypeInfo* type_info = new DynamicMessage::TypeInfo;
+  *target = type_info;
+
+  type_info->type = type;
+  type_info->pool = (pool_ == NULL) ? type->file()->pool() : pool_;
+  type_info->factory = this;
+
   // We need to construct all the structures passed to
   // GeneratedMessageReflection's constructor.  This includes:
   // - A block of memory that contains space for all the message's fields.
@@ -427,6 +450,7 @@ const Message* DynamicMessageFactory::GetPrototype(const Descriptor* type) {
 
   // Compute size and offsets.
   int* offsets = new int[type->field_count()];
+  type_info->offsets.reset(offsets);
 
   // Sort the fields of this message in descending order by size.  We
   // assume that if we then pack the fields tightly in this order, all fields
@@ -441,35 +465,68 @@ const Message* DynamicMessageFactory::GetPrototype(const Descriptor* type) {
               DescendingFieldSizeOrder());
 
   // Decide all field offsets by packing in order.
-  int current_offset = 0;
+  // We place the DynamicMessage object itself at the beginning of the allocated
+  // space.
+  int size = sizeof(DynamicMessage);
+  size = AlignOffset(size);
+
+  // Next the has_bits, which is an array of uint32s.
+  type_info->has_bits_offset = size;
+  int has_bits_array_size =
+    DivideRoundingUp(type->field_count(), bitsizeof(uint32));
+  size += has_bits_array_size * sizeof(uint32);
+  size = AlignOffset(size);
+
+  // The ExtensionSet, if any.
+  if (type->extension_range_count() > 0) {
+    type_info->extensions_offset = size;
+    size += sizeof(ExtensionSet);
+    size = AlignOffset(size);
+  } else {
+    // No extensions.
+    type_info->extensions_offset = -1;
+  }
 
+  // All the fields.  We don't need to align after each field because they are
+  // sorted in descending size order, and the size of a type is always a
+  // multiple of its alignment.
   for (int i = 0; i < type->field_count(); i++) {
-    offsets[ordered_fields[i]->index()] = current_offset;
-    current_offset += FieldSpaceUsed(ordered_fields[i]);
+    offsets[ordered_fields[i]->index()] = size;
+    size += FieldSpaceUsed(ordered_fields[i]);
   }
 
-  // Allocate space for all fields plus has_bits.  We'll stick has_bits on
-  // the end.
-  int size = current_offset +
-    DivideRoundingUp(type->field_count(), bitsizeof(uint32)) * sizeof(uint32);
-
-  // Round size up to the nearest 64-bit boundary just to make sure no
-  // clever allocators think that alignment is not necessary.  This also
-  // insures that has_bits is properly-aligned, since we'll always align
-  // has_bits with the end of the structure.
-  size = DivideRoundingUp(size, sizeof(uint64)) * sizeof(uint64);
-  uint8* base = reinterpret_cast<uint8*>(operator new(size));
-  memset(base, 0, size);
+  // Add the UnknownFieldSet to the end.
+  size = AlignOffset(size);
+  type_info->unknown_fields_offset = size;
+  size += sizeof(UnknownFieldSet);
 
-  // Construct message.
-  DynamicMessage* result =
-    new DynamicMessage(type, base, base, size, offsets, pool_, this);
-  *target = result;
-  result->CrossLinkPrototypes(this);
+  // Align the final size to make sure no clever allocators think that
+  // alignment is not necessary.
+  size = AlignOffset(size);
+  type_info->size = size;
 
-  return result;
+  // Allocate the prototype.
+  void* base = operator new(size);
+  memset(base, 0, size);
+  DynamicMessage* prototype = new(base) DynamicMessage(type_info);
+  type_info->prototype.reset(prototype);
+
+  // Construct the reflection object.
+  type_info->reflection.reset(
+    new GeneratedMessageReflection(
+      type_info->type,
+      type_info->prototype.get(),
+      type_info->offsets.get(),
+      type_info->has_bits_offset,
+      type_info->unknown_fields_offset,
+      type_info->extensions_offset,
+      type_info->pool));
+
+  // Cross link prototypes.
+  prototype->CrossLinkPrototypes();
+
+  return prototype;
 }
 
 }  // namespace protobuf
-
 }  // namespace google
diff --git a/src/google/protobuf/dynamic_message_unittest.cc b/src/google/protobuf/dynamic_message_unittest.cc
index 5afac1fce4459600409d0b1b7b580f32bb3d218c..f7ed51f434c641e24216c8ce7a00188cae2000d4 100644
--- a/src/google/protobuf/dynamic_message_unittest.cc
+++ b/src/google/protobuf/dynamic_message_unittest.cc
@@ -90,7 +90,7 @@ TEST_F(DynamicMessageTest, OnePrototype) {
 TEST_F(DynamicMessageTest, Defaults) {
   // Check that all default values are set correctly in the initial message.
   TestUtil::ReflectionTester reflection_tester(descriptor_);
-  reflection_tester.ExpectClearViaReflection(*prototype_->GetReflection());
+  reflection_tester.ExpectClearViaReflection(*prototype_);
 }
 
 TEST_F(DynamicMessageTest, IndependentOffsets) {
@@ -100,8 +100,8 @@ TEST_F(DynamicMessageTest, IndependentOffsets) {
   scoped_ptr<Message> message(prototype_->New());
   TestUtil::ReflectionTester reflection_tester(descriptor_);
 
-  reflection_tester.SetAllFieldsViaReflection(message->GetReflection());
-  reflection_tester.ExpectAllFieldsSetViaReflection(*message->GetReflection());
+  reflection_tester.SetAllFieldsViaReflection(message.get());
+  reflection_tester.ExpectAllFieldsSetViaReflection(*message);
 }
 
 TEST_F(DynamicMessageTest, Extensions) {
@@ -109,8 +109,8 @@ TEST_F(DynamicMessageTest, Extensions) {
   scoped_ptr<Message> message(extensions_prototype_->New());
   TestUtil::ReflectionTester reflection_tester(extensions_descriptor_);
 
-  reflection_tester.SetAllFieldsViaReflection(message->GetReflection());
-  reflection_tester.ExpectAllFieldsSetViaReflection(*message->GetReflection());
+  reflection_tester.SetAllFieldsViaReflection(message.get());
+  reflection_tester.ExpectAllFieldsSetViaReflection(*message);
 }
 
 }  // namespace protobuf
diff --git a/src/google/protobuf/extension_set.cc b/src/google/protobuf/extension_set.cc
index 154f06f81d087982456fce523456ea36952465c5..f679d7ae8ddef1e170b3a37a7c775d0d1e830174 100644
--- a/src/google/protobuf/extension_set.cc
+++ b/src/google/protobuf/extension_set.cc
@@ -34,42 +34,10 @@ namespace internal {
 // -------------------------------------------------------------------
 // Lookup functions
 
-const FieldDescriptor*
-ExtensionSet::FindKnownExtensionByName(const string& name) const {
-  const FieldDescriptor* result = descriptor_pool_->FindExtensionByName(name);
-  if (result != NULL && result->containing_type() == extendee_) {
-    return result;
-  }
-
-  if (extendee_->options().message_set_wire_format()) {
-    // MessageSet extensions may be identified by type name.
-    const Descriptor* type = descriptor_pool_->FindMessageTypeByName(name);
-    if (type != NULL) {
-      // Look for a matching extension in the foreign type's scope.
-      for (int i = 0; i < type->extension_count(); i++) {
-        const FieldDescriptor* extension = type->extension(i);
-        if (extension->containing_type() == extendee_ &&
-            extension->type() == FieldDescriptor::TYPE_MESSAGE &&
-            extension->is_optional() &&
-            extension->message_type() == type) {
-          // Found it.
-          return extension;
-        }
-      }
-    }
-  }
-
-  return NULL;
-}
-
-const FieldDescriptor*
-ExtensionSet::FindKnownExtensionByNumber(int number) const {
-  return descriptor_pool_->FindExtensionByNumber(extendee_, number);
-}
-
 const FieldDescriptor*
 ExtensionSet::FindKnownExtensionOrDie(int number) const {
-  const FieldDescriptor* descriptor = FindKnownExtensionByNumber(number);
+  const FieldDescriptor* descriptor =
+    descriptor_pool_->FindExtensionByNumber(*extendee_, number);
   if (descriptor == NULL) {
     // This extension doesn't exist, so we have to crash.  However, let's
     // try to provide an informative error message.
@@ -77,7 +45,7 @@ ExtensionSet::FindKnownExtensionOrDie(int number) const {
         message_factory_ == MessageFactory::generated_factory()) {
       // This is probably the ExtensionSet for a generated class.
       GOOGLE_LOG(FATAL) << ": No extension is registered for \""
-                 << extendee_->full_name() << "\" with number "
+                 << (*extendee_)->full_name() << "\" with number "
                  << number << ".  Perhaps you were trying to access it via "
                     "the Reflection interface, but you provided a "
                     "FieldDescriptor which did not come from a linked-in "
@@ -87,7 +55,7 @@ ExtensionSet::FindKnownExtensionOrDie(int number) const {
     } else {
       // This is probably a DynamicMessage.
       GOOGLE_LOG(FATAL) << ": No extension is registered for \""
-                 << extendee_->full_name() << "\" with number "
+                 << (*extendee_)->full_name() << "\" with number "
                  << number << ".  If you were using a DynamicMessage, "
                     "remember that you are only allowed to access extensions "
                     "which are defined in the DescriptorPool which you passed "
@@ -105,7 +73,7 @@ ExtensionSet::GetPrototype(const Descriptor* message_type) const {
 // ===================================================================
 // Constructors and basic methods.
 
-ExtensionSet::ExtensionSet(const Descriptor* extendee,
+ExtensionSet::ExtensionSet(const Descriptor* const* extendee,
                            const DescriptorPool* pool,
                            MessageFactory* factory)
   : extendee_(extendee),
@@ -461,7 +429,7 @@ void MergeRepeatedFields(const RepeatedPtrField<Message>& source,
 }  // namespace
 
 void ExtensionSet::MergeFrom(const ExtensionSet& other) {
-  GOOGLE_DCHECK_EQ(extendee_, other.extendee_);
+  GOOGLE_DCHECK_EQ(*extendee_, *other.extendee_);
 
   for (map<int, Extension>::const_iterator iter = other.extensions_.begin();
        iter != other.extensions_.end(); ++iter) {
@@ -558,22 +526,23 @@ bool ExtensionSet::IsInitialized() const {
 }
 
 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
-                              Message::Reflection* reflection) {
+                              Message* message) {
   const FieldDescriptor* field =
-    FindKnownExtensionByNumber(WireFormat::GetTagFieldNumber(tag));
+    message->GetReflection()
+           ->FindKnownExtensionByNumber(WireFormat::GetTagFieldNumber(tag));
 
-  return WireFormat::ParseAndMergeField(tag, field, reflection, input);
+  return WireFormat::ParseAndMergeField(tag, field, message, input);
 }
 
 bool ExtensionSet::SerializeWithCachedSizes(
     int start_field_number, int end_field_number,
-    const Message::Reflection* reflection,
+    const Message& message,
     io::CodedOutputStream* output) const {
   map<int, Extension>::const_iterator iter;
   for (iter = extensions_.lower_bound(start_field_number);
        iter != extensions_.end() && iter->first < end_field_number;
        ++iter) {
-    if (!iter->second.SerializeFieldWithCachedSizes(reflection, output)) {
+    if (!iter->second.SerializeFieldWithCachedSizes(message, output)) {
       return false;
     }
   }
@@ -581,12 +550,12 @@ bool ExtensionSet::SerializeWithCachedSizes(
   return true;
 }
 
-int ExtensionSet::ByteSize(const Message::Reflection* reflection) const {
+int ExtensionSet::ByteSize(const Message& message) const {
   int total_size = 0;
 
   for (map<int, Extension>::const_iterator iter = extensions_.begin();
        iter != extensions_.end(); ++iter) {
-    total_size += iter->second.ByteSize(reflection);
+    total_size += iter->second.ByteSize(message);
   }
 
   return total_size;
@@ -652,20 +621,19 @@ void ExtensionSet::Extension::Clear() {
 }
 
 bool ExtensionSet::Extension::SerializeFieldWithCachedSizes(
-    const Message::Reflection* reflection,
+    const Message& message,
     io::CodedOutputStream* output) const {
   if (descriptor->is_repeated() || !is_cleared) {
     return WireFormat::SerializeFieldWithCachedSizes(
-        descriptor, reflection, output);
+      descriptor, message, output);
   } else {
     return true;
   }
 }
 
-int64 ExtensionSet::Extension::ByteSize(
-    const Message::Reflection* reflection) const {
+int64 ExtensionSet::Extension::ByteSize(const Message& message) const {
   if (descriptor->is_repeated() || !is_cleared) {
-    return WireFormat::FieldByteSize(descriptor, reflection);
+    return WireFormat::FieldByteSize(descriptor, message);
   } else {
     // Cleared, non-repeated field.
     return 0;
diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h
index 902ec7364f11fcc5c8865f6b41fec4edc4091b62..c8e124f8c38d51b347ff9220d2f7ef37c54150a6 100644
--- a/src/google/protobuf/extension_set.h
+++ b/src/google/protobuf/extension_set.h
@@ -64,26 +64,28 @@ namespace internal {
 class LIBPROTOBUF_EXPORT ExtensionSet {
  public:
   // Construct an ExtensionSet.
-  //   extendee:  Descriptor for the type being extended.
+  //   extendee:  Descriptor for the type being extended. We pass in a pointer
+  //              to a pointer to the extendee to get around an initialization
+  //              problem: when we create the ExtensionSet for a message type,
+  //              its descriptor may not exist yet. But we know where that
+  //              descriptor pointer will be placed, and by the time it's used
+  //              by this ExtensionSet it will be fully initialized, so passing
+  //              a pointer to that location works. Note that this problem
+  //              will only occur for messages defined in descriptor.proto.
   //   pool:      DescriptorPool to search for extension definitions.
   //   factory:   MessageFactory used to construct implementations of messages
   //              for extensions with message type.  This factory must be able
   //              to construct any message type found in "pool".
   // All three objects remain property of the caller and must outlive the
   // ExtensionSet.
-  ExtensionSet(const Descriptor* extendee,
+  ExtensionSet(const Descriptor* const* extendee,
                const DescriptorPool* pool,
                MessageFactory* factory);
 
   ~ExtensionSet();
 
-  // Search for a known (compiled-in) extension of this type by name or number.
-  // Returns NULL if no extension is known.
-  const FieldDescriptor* FindKnownExtensionByName(const string& name) const;
-  const FieldDescriptor* FindKnownExtensionByNumber(int number) const;
-
   // Add all fields which are currently present to the given vector.  This
-  // is useful to implement Message::Reflection::ListFields().
+  // is useful to implement Reflection::ListFields().
   void AppendToList(vector<const FieldDescriptor*>* output) const;
 
   // =================================================================
@@ -110,7 +112,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
   // die on an assert failure.  The message objects returned by the message
   // accessors are guaranteed to be of the correct linked-in type.
   //
-  // These methods pretty much match Message::Reflection except that:
+  // These methods pretty much match Reflection except that:
   // - They're not virtual.
   // - They identify fields by number rather than FieldDescriptors.
   // - They identify enum values using integers rather than descriptors.
@@ -196,7 +198,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
   bool IsInitialized() const;
 
   // These parsing and serialization functions all want a pointer to the
-  // reflection interface because they hand off the actual work to WireFormat,
+  // message object because they hand off the actual work to WireFormat,
   // which works in terms of a reflection interface.  Yes, this means there
   // are some redundant virtual function calls that end up being made, but
   // it probably doesn't matter much in practice, and the alternative would
@@ -204,8 +206,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
 
   // Parses a single extension from the input.  The input should start out
   // positioned immediately after the tag.
-  bool ParseField(uint32 tag, io::CodedInputStream* input,
-                  Message::Reflection* reflection);
+  bool ParseField(uint32 tag, io::CodedInputStream* input, Message* message);
 
   // Write all extension fields with field numbers in the range
   //   [start_field_number, end_field_number)
@@ -213,11 +214,11 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
   // last called.  Note that the range bounds are inclusive-exclusive.
   bool SerializeWithCachedSizes(int start_field_number,
                                 int end_field_number,
-                                const Message::Reflection* reflection,
+                                const Message& message,
                                 io::CodedOutputStream* output) const;
 
   // Returns the total serialized size of all the extensions.
-  int ByteSize(const Message::Reflection* reflection) const;
+  int ByteSize(const Message& message) const;
 
  private:
   // Like FindKnownExtension(), but GOOGLE_CHECK-fail if not found.
@@ -265,9 +266,9 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
 
     // Some helper methods for operations on a single Extension.
     bool SerializeFieldWithCachedSizes(
-        const Message::Reflection* reflection,
+        const Message& message,
         io::CodedOutputStream* output) const;
-    int64 ByteSize(const Message::Reflection* reflection) const;
+    int64 ByteSize(const Message& message) const;
     void Clear();
     int GetSize() const;
     void Free();
@@ -280,7 +281,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
   // for 100 elements or more.  Also, we want AppendToList() to order fields
   // by field number.
   map<int, Extension> extensions_;
-  const Descriptor* extendee_;
+  const Descriptor* const* extendee_;
   const DescriptorPool* descriptor_pool_;
   MessageFactory* message_factory_;
 
diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc
index ec17572bbb199df96f970f3a99e0365eef1f6f30..65530c7ebf1477ad788f3352006939f50909c498 100644
--- a/src/google/protobuf/generated_message_reflection.cc
+++ b/src/google/protobuf/generated_message_reflection.cc
@@ -43,7 +43,7 @@ void ReportReflectionUsageError(
     const char* method, const char* description) {
   GOOGLE_LOG(FATAL)
     << "Protocol Buffer reflection usage error:\n"
-       "  Method      : google::protobuf::Message::Reflection::" << method << "\n"
+       "  Method      : google::protobuf::Reflection::" << method << "\n"
        "  Message type: " << descriptor->full_name() << "\n"
        "  Field       : " << field->full_name() << "\n"
        "  Problem     : " << description;
@@ -69,7 +69,7 @@ static void ReportReflectionUsageTypeError(
     FieldDescriptor::CppType expected_type) {
   GOOGLE_LOG(FATAL)
     << "Protocol Buffer reflection usage error:\n"
-       "  Method      : google::protobuf::Message::Reflection::" << method << "\n"
+       "  Method      : google::protobuf::Reflection::" << method << "\n"
        "  Message type: " << descriptor->full_name() << "\n"
        "  Field       : " << field->full_name() << "\n"
        "  Problem     : Field is not the right type for this message:\n"
@@ -82,7 +82,7 @@ static void ReportReflectionUsageEnumTypeError(
     const char* method, const EnumValueDescriptor* value) {
   GOOGLE_LOG(FATAL)
     << "Protocol Buffer reflection usage error:\n"
-       "  Method      : google::protobuf::Message::Reflection::" << method << "\n"
+       "  Method      : google::protobuf::Reflection::" << method << "\n"
        "  Message type: " << descriptor->full_name() << "\n"
        "  Field       : " << field->full_name() << "\n"
        "  Problem     : Enum value did not match field type:\n"
@@ -128,64 +128,79 @@ static void ReportReflectionUsageEnumTypeError(
 
 GeneratedMessageReflection::GeneratedMessageReflection(
     const Descriptor* descriptor,
-    void* base, const void* default_base,
-    const int offsets[], uint32 has_bits[],
-    ExtensionSet* extensions)
-  : descriptor_  (descriptor),
-    base_        (base),
-    default_base_(default_base),
-    offsets_     (offsets),
-    has_bits_    (has_bits),
-    extensions_  (extensions) {
+    const Message* default_instance,
+    const int offsets[],
+    int has_bits_offset,
+    int unknown_fields_offset,
+    int extensions_offset,
+    const DescriptorPool* descriptor_pool)
+  : descriptor_       (descriptor),
+    default_instance_ (default_instance),
+    offsets_          (offsets),
+    has_bits_offset_  (has_bits_offset),
+    unknown_fields_offset_(unknown_fields_offset),
+    extensions_offset_(extensions_offset),
+    descriptor_pool_  ((descriptor_pool == NULL) ?
+                         DescriptorPool::generated_pool() :
+                         descriptor_pool) {
 }
 
 GeneratedMessageReflection::~GeneratedMessageReflection() {}
 
-const UnknownFieldSet& GeneratedMessageReflection::GetUnknownFields() const {
-  return unknown_fields_;
+const UnknownFieldSet& GeneratedMessageReflection::GetUnknownFields(
+    const Message& message) const {
+  const void* ptr = reinterpret_cast<const uint8*>(&message) +
+                    unknown_fields_offset_;
+  return *reinterpret_cast<const UnknownFieldSet*>(ptr);
 }
-UnknownFieldSet* GeneratedMessageReflection::MutableUnknownFields() {
-  return &unknown_fields_;
+UnknownFieldSet* GeneratedMessageReflection::MutableUnknownFields(
+    Message* message) const {
+  void* ptr = reinterpret_cast<uint8*>(message) + unknown_fields_offset_;
+  return reinterpret_cast<UnknownFieldSet*>(ptr);
 }
 
 // -------------------------------------------------------------------
 
-bool GeneratedMessageReflection::HasField(const FieldDescriptor* field) const {
+bool GeneratedMessageReflection::HasField(const Message& message,
+                                          const FieldDescriptor* field) const {
   USAGE_CHECK_MESSAGE_TYPE(HasField);
   USAGE_CHECK_SINGULAR(HasField);
 
   if (field->is_extension()) {
-    return extensions_->Has(field->number());
+    return GetExtensionSet(message).Has(field->number());
   } else {
-    return HasBit(field);
+    return HasBit(message, field);
   }
 }
 
-int GeneratedMessageReflection::FieldSize(const FieldDescriptor* field) const {
+int GeneratedMessageReflection::FieldSize(const Message& message,
+                                          const FieldDescriptor* field) const {
   USAGE_CHECK_MESSAGE_TYPE(HasField);
   USAGE_CHECK_REPEATED(HasField);
 
   if (field->is_extension()) {
-    return extensions_->ExtensionSize(field->number());
+    return GetExtensionSet(message).ExtensionSize(field->number());
   } else {
-    return GetRaw<GenericRepeatedField>(field).GenericSize();
+    return GetRaw<GenericRepeatedField>(message, field).GenericSize();
   }
 }
 
-void GeneratedMessageReflection::ClearField(const FieldDescriptor* field) {
+void GeneratedMessageReflection::ClearField(
+    Message* message, const FieldDescriptor* field) const {
   USAGE_CHECK_MESSAGE_TYPE(ClearField);
 
   if (field->is_extension()) {
-    extensions_->ClearExtension(field->number());
+    MutableExtensionSet(message)->ClearExtension(field->number());
   } else if (!field->is_repeated()) {
-    if (HasBit(field)) {
-      ClearBit(field);
+    if (HasBit(*message, field)) {
+      ClearBit(message, field);
 
       // We need to set the field back to its default value.
       switch (field->cpp_type()) {
 #define CLEAR_TYPE(CPPTYPE, TYPE)                                            \
         case FieldDescriptor::CPPTYPE_##CPPTYPE:                             \
-          *MutableRaw<TYPE>(field) = field->default_value_##TYPE();          \
+          *MutableRaw<TYPE>(message, field) =                                \
+            field->default_value_##TYPE();                                   \
           break;
 
         CLEAR_TYPE(INT32 , int32 );
@@ -198,12 +213,13 @@ void GeneratedMessageReflection::ClearField(const FieldDescriptor* field) {
 #undef CLEAR_TYPE
 
         case FieldDescriptor::CPPTYPE_ENUM:
-          *MutableRaw<int>(field) = field->default_value_enum()->number();
+          *MutableRaw<int>(message, field) =
+            field->default_value_enum()->number();
           break;
 
         case FieldDescriptor::CPPTYPE_STRING: {
             const string* default_ptr = DefaultRaw<const string*>(field);
-            string** value = MutableRaw<string*>(field);
+            string** value = MutableRaw<string*>(message, field);
             if (*value != default_ptr) {
               if (field->has_default_value()) {
                 (*value)->assign(field->default_value_string());
@@ -215,12 +231,12 @@ void GeneratedMessageReflection::ClearField(const FieldDescriptor* field) {
         }
 
         case FieldDescriptor::CPPTYPE_MESSAGE:
-          (*MutableRaw<Message*>(field))->Clear();
+          (*MutableRaw<Message*>(message, field))->Clear();
           break;
       }
     }
   } else {
-    MutableRaw<GenericRepeatedField>(field)->GenericClear();
+    MutableRaw<GenericRepeatedField>(message, field)->GenericClear();
   }
 }
 
@@ -235,27 +251,28 @@ struct FieldNumberSorter {
 }  // namespace
 
 void GeneratedMessageReflection::ListFields(
+    const Message& message,
     vector<const FieldDescriptor*>* output) const {
   output->clear();
 
   // Optimization:  The default instance never has any fields set.
-  if (base_ == default_base_) return;
+  if (&message == default_instance_) return;
 
   for (int i = 0; i < descriptor_->field_count(); i++) {
     const FieldDescriptor* field = descriptor_->field(i);
     if (field->is_repeated()) {
-      if (GetRaw<GenericRepeatedField>(field).GenericSize() > 0) {
+      if (GetRaw<GenericRepeatedField>(message, field).GenericSize() > 0) {
         output->push_back(field);
       }
     } else {
-      if (HasBit(field)) {
+      if (HasBit(message, field)) {
         output->push_back(field);
       }
     }
   }
 
-  if (extensions_ != NULL) {
-    extensions_->AppendToList(output);
+  if (extensions_offset_ != -1) {
+    GetExtensionSet(message).AppendToList(output);
   }
 
   // ListFields() must sort output by field number.
@@ -267,52 +284,59 @@ void GeneratedMessageReflection::ListFields(
 #undef DEFINE_PRIMITIVE_ACCESSORS
 #define DEFINE_PRIMITIVE_ACCESSORS(TYPENAME, TYPE, PASSTYPE, CPPTYPE)        \
   PASSTYPE GeneratedMessageReflection::Get##TYPENAME(                        \
-                                       const FieldDescriptor* field) const { \
+      const Message& message, const FieldDescriptor* field) const {          \
     USAGE_CHECK_ALL(Get##TYPENAME, SINGULAR, CPPTYPE);                       \
     if (field->is_extension()) {                                             \
-      return extensions_->Get##TYPENAME(field->number());                    \
+      return GetExtensionSet(message).Get##TYPENAME(field->number());        \
     } else {                                                                 \
-      return GetField<TYPE>(field);                                          \
+      return GetField<TYPE>(message, field);                                 \
     }                                                                        \
   }                                                                          \
                                                                              \
   void GeneratedMessageReflection::Set##TYPENAME(                            \
-      const FieldDescriptor* field, PASSTYPE value) {                        \
+      Message* message, const FieldDescriptor* field,                        \
+      PASSTYPE value) const {                                                \
     USAGE_CHECK_ALL(Set##TYPENAME, SINGULAR, CPPTYPE);                       \
     if (field->is_extension()) {                                             \
-      return extensions_->Set##TYPENAME(field->number(), value);             \
+      return MutableExtensionSet(message)->Set##TYPENAME(                    \
+        field->number(), value);                                             \
     } else {                                                                 \
-      SetField<TYPE>(field, value);                                          \
+      SetField<TYPE>(message, field, value);                                 \
     }                                                                        \
   }                                                                          \
                                                                              \
   PASSTYPE GeneratedMessageReflection::GetRepeated##TYPENAME(                \
+      const Message& message,                                                \
       const FieldDescriptor* field, int index) const {                       \
     USAGE_CHECK_ALL(GetRepeated##TYPENAME, REPEATED, CPPTYPE);               \
     if (field->is_extension()) {                                             \
-      return extensions_->GetRepeated##TYPENAME(field->number(), index);     \
+      return GetExtensionSet(message).GetRepeated##TYPENAME(                 \
+        field->number(), index);                                             \
     } else {                                                                 \
-      return GetRepeatedField<TYPE>(field, index);                           \
+      return GetRepeatedField<TYPE>(message, field, index);                  \
     }                                                                        \
   }                                                                          \
                                                                              \
   void GeneratedMessageReflection::SetRepeated##TYPENAME(                    \
-      const FieldDescriptor* field, int index, PASSTYPE value) {             \
+      Message* message, const FieldDescriptor* field,                        \
+      int index, PASSTYPE value) const {                                     \
     USAGE_CHECK_ALL(SetRepeated##TYPENAME, REPEATED, CPPTYPE);               \
     if (field->is_extension()) {                                             \
-      extensions_->SetRepeated##TYPENAME(field->number(), index, value);     \
+      MutableExtensionSet(message)->SetRepeated##TYPENAME(                   \
+        field->number(), index, value);                                      \
     } else {                                                                 \
-      SetRepeatedField<TYPE>(field, index, value);                           \
+      SetRepeatedField<TYPE>(message, field, index, value);                  \
     }                                                                        \
   }                                                                          \
                                                                              \
   void GeneratedMessageReflection::Add##TYPENAME(                            \
-      const FieldDescriptor* field, PASSTYPE value) {                        \
+      Message* message, const FieldDescriptor* field,                        \
+      PASSTYPE value) const {                                                \
     USAGE_CHECK_ALL(Add##TYPENAME, REPEATED, CPPTYPE);                       \
     if (field->is_extension()) {                                             \
-      extensions_->Add##TYPENAME(field->number(), value);                    \
+      MutableExtensionSet(message)->Add##TYPENAME(field->number(), value);   \
     } else {                                                                 \
-      AddField<TYPE>(field, value);                                          \
+      AddField<TYPE>(message, field, value);                                 \
     }                                                                        \
   }
 
@@ -328,33 +352,35 @@ DEFINE_PRIMITIVE_ACCESSORS(Bool  , bool  , bool  , BOOL  )
 // -------------------------------------------------------------------
 
 string GeneratedMessageReflection::GetString(
-    const FieldDescriptor* field) const {
+    const Message& message, const FieldDescriptor* field) const {
   USAGE_CHECK_ALL(GetString, SINGULAR, STRING);
   if (field->is_extension()) {
-    return extensions_->GetString(field->number());
+    return GetExtensionSet(message).GetString(field->number());
   } else {
-    return *GetField<const string*>(field);
+    return *GetField<const string*>(message, field);
   }
 }
 
 const string& GeneratedMessageReflection::GetStringReference(
+    const Message& message,
     const FieldDescriptor* field, string* scratch) const {
   USAGE_CHECK_ALL(GetStringReference, SINGULAR, STRING);
   if (field->is_extension()) {
-    return extensions_->GetString(field->number());
+    return GetExtensionSet(message).GetString(field->number());
   } else {
-    return *GetField<const string*>(field);
+    return *GetField<const string*>(message, field);
   }
 }
 
 
 void GeneratedMessageReflection::SetString(
-    const FieldDescriptor* field, const string& value) {
+    Message* message, const FieldDescriptor* field,
+    const string& value) const {
   USAGE_CHECK_ALL(SetString, SINGULAR, STRING);
   if (field->is_extension()) {
-    return extensions_->SetString(field->number(), value);
+    return MutableExtensionSet(message)->SetString(field->number(), value);
   } else {
-    string** ptr = MutableField<string*>(field);
+    string** ptr = MutableField<string*>(message, field);
     if (*ptr == DefaultRaw<const string*>(field)) {
       *ptr = new string(value);
     } else {
@@ -365,44 +391,48 @@ void GeneratedMessageReflection::SetString(
 
 
 string GeneratedMessageReflection::GetRepeatedString(
-    const FieldDescriptor* field, int index) const {
+    const Message& message, const FieldDescriptor* field, int index) const {
   USAGE_CHECK_ALL(GetRepeatedString, REPEATED, STRING);
   if (field->is_extension()) {
-    return extensions_->GetRepeatedString(field->number(), index);
+    return GetExtensionSet(message).GetRepeatedString(field->number(), index);
   } else {
-    return GetRepeatedField<string>(field, index);
+    return GetRepeatedField<string>(message, field, index);
   }
 }
 
 const string& GeneratedMessageReflection::GetRepeatedStringReference(
-    const FieldDescriptor* field, int index, string* scratch) const {
+    const Message& message, const FieldDescriptor* field,
+    int index, string* scratch) const {
   USAGE_CHECK_ALL(GetRepeatedStringReference, REPEATED, STRING);
   if (field->is_extension()) {
-    return extensions_->GetRepeatedString(field->number(), index);
+    return GetExtensionSet(message).GetRepeatedString(field->number(), index);
   } else {
-    return GetRepeatedField<string>(field, index);
+    return GetRepeatedField<string>(message, field, index);
   }
 }
 
 
 void GeneratedMessageReflection::SetRepeatedString(
-    const FieldDescriptor* field, int index, const string& value) {
+    Message* message, const FieldDescriptor* field,
+    int index, const string& value) const {
   USAGE_CHECK_ALL(SetRepeatedString, REPEATED, STRING);
   if (field->is_extension()) {
-    extensions_->SetRepeatedString(field->number(), index, value);
+    MutableExtensionSet(message)->SetRepeatedString(
+      field->number(), index, value);
   } else {
-    SetRepeatedField<string>(field, index, value);
+    SetRepeatedField<string>(message, field, index, value);
   }
 }
 
 
 void GeneratedMessageReflection::AddString(
-    const FieldDescriptor* field, const string& value) {
+    Message* message, const FieldDescriptor* field,
+    const string& value) const {
   USAGE_CHECK_ALL(AddString, REPEATED, STRING);
   if (field->is_extension()) {
-    extensions_->AddString(field->number(), value);
+    MutableExtensionSet(message)->AddString(field->number(), value);
   } else {
-    AddField<string>(field, value);
+    AddField<string>(message, field, value);
   }
 }
 
@@ -410,14 +440,14 @@ void GeneratedMessageReflection::AddString(
 // -------------------------------------------------------------------
 
 const EnumValueDescriptor* GeneratedMessageReflection::GetEnum(
-    const FieldDescriptor* field) const {
+    const Message& message, const FieldDescriptor* field) const {
   USAGE_CHECK_ALL(GetEnum, SINGULAR, ENUM);
 
   int value;
   if (field->is_extension()) {
-    value = extensions_->GetEnum(field->number());
+    value = GetExtensionSet(message).GetEnum(field->number());
   } else {
-    value = GetField<int>(field);
+    value = GetField<int>(message, field);
   }
   const EnumValueDescriptor* result =
     field->enum_type()->FindValueByNumber(value);
@@ -425,27 +455,28 @@ const EnumValueDescriptor* GeneratedMessageReflection::GetEnum(
   return result;
 }
 
-void GeneratedMessageReflection::SetEnum(const FieldDescriptor* field,
-                                         const EnumValueDescriptor* value) {
+void GeneratedMessageReflection::SetEnum(
+    Message* message, const FieldDescriptor* field,
+    const EnumValueDescriptor* value) const {
   USAGE_CHECK_ALL(SetEnum, SINGULAR, ENUM);
   USAGE_CHECK_ENUM_VALUE(SetEnum);
 
   if (field->is_extension()) {
-    extensions_->SetEnum(field->number(), value->number());
+    MutableExtensionSet(message)->SetEnum(field->number(), value->number());
   } else {
-    SetField<int>(field, value->number());
+    SetField<int>(message, field, value->number());
   }
 }
 
 const EnumValueDescriptor* GeneratedMessageReflection::GetRepeatedEnum(
-    const FieldDescriptor* field, int index) const {
+    const Message& message, const FieldDescriptor* field, int index) const {
   USAGE_CHECK_ALL(GetRepeatedEnum, REPEATED, ENUM);
 
   int value;
   if (field->is_extension()) {
-    value = extensions_->GetRepeatedEnum(field->number(), index);
+    value = GetExtensionSet(message).GetRepeatedEnum(field->number(), index);
   } else {
-    value = GetRepeatedField<int>(field, index);
+    value = GetRepeatedField<int>(message, field, index);
   }
   const EnumValueDescriptor* result =
     field->enum_type()->FindValueByNumber(value);
@@ -454,40 +485,43 @@ const EnumValueDescriptor* GeneratedMessageReflection::GetRepeatedEnum(
 }
 
 void GeneratedMessageReflection::SetRepeatedEnum(
+    Message* message,
     const FieldDescriptor* field, int index,
-    const EnumValueDescriptor* value) {
+    const EnumValueDescriptor* value) const {
   USAGE_CHECK_ALL(SetRepeatedEnum, REPEATED, ENUM);
   USAGE_CHECK_ENUM_VALUE(SetRepeatedEnum);
 
   if (field->is_extension()) {
-    extensions_->SetRepeatedEnum(field->number(), index, value->number());
+    MutableExtensionSet(message)->SetRepeatedEnum(
+      field->number(), index, value->number());
   } else {
-    SetRepeatedField<int>(field, index, value->number());
+    SetRepeatedField<int>(message, field, index, value->number());
   }
 }
 
-void GeneratedMessageReflection::AddEnum(const FieldDescriptor* field,
-                                         const EnumValueDescriptor* value) {
+void GeneratedMessageReflection::AddEnum(
+    Message* message, const FieldDescriptor* field,
+    const EnumValueDescriptor* value) const {
   USAGE_CHECK_ALL(AddEnum, REPEATED, ENUM);
   USAGE_CHECK_ENUM_VALUE(AddEnum);
 
   if (field->is_extension()) {
-    extensions_->AddEnum(field->number(), value->number());
+    MutableExtensionSet(message)->AddEnum(field->number(), value->number());
   } else {
-    AddField<int>(field, value->number());
+    AddField<int>(message, field, value->number());
   }
 }
 
 // -------------------------------------------------------------------
 
 const Message& GeneratedMessageReflection::GetMessage(
-    const FieldDescriptor* field) const {
+    const Message& message, const FieldDescriptor* field) const {
   USAGE_CHECK_ALL(GetMessage, SINGULAR, MESSAGE);
 
   if (field->is_extension()) {
-    return extensions_->GetMessage(field->number());
+    return GetExtensionSet(message).GetMessage(field->number());
   } else {
-    const Message* result = GetRaw<const Message*>(field);
+    const Message* result = GetRaw<const Message*>(message, field);
     if (result == NULL) {
       result = DefaultRaw<const Message*>(field);
     }
@@ -496,13 +530,13 @@ const Message& GeneratedMessageReflection::GetMessage(
 }
 
 Message* GeneratedMessageReflection::MutableMessage(
-    const FieldDescriptor* field) {
+    Message* message, const FieldDescriptor* field) const {
   USAGE_CHECK_ALL(MutableMessage, SINGULAR, MESSAGE);
 
   if (field->is_extension()) {
-    return extensions_->MutableMessage(field->number());
+    return MutableExtensionSet(message)->MutableMessage(field->number());
   } else {
-    Message** result = MutableField<Message*>(field);
+    Message** result = MutableField<Message*>(message, field);
     if (*result == NULL) {
       const Message* default_message = DefaultRaw<const Message*>(field);
       *result = default_message->New();
@@ -513,34 +547,36 @@ Message* GeneratedMessageReflection::MutableMessage(
 }
 
 const Message& GeneratedMessageReflection::GetRepeatedMessage(
-    const FieldDescriptor* field, int index) const {
+    const Message& message, const FieldDescriptor* field, int index) const {
   USAGE_CHECK_ALL(GetRepeatedMessage, REPEATED, MESSAGE);
 
   if (field->is_extension()) {
-    return extensions_->GetRepeatedMessage(field->number(), index);
+    return GetExtensionSet(message).GetRepeatedMessage(field->number(), index);
   } else {
-    return GetRepeatedField<Message>(field, index);
+    return GetRepeatedField<Message>(message, field, index);
   }
 }
 
 Message* GeneratedMessageReflection::MutableRepeatedMessage(
-    const FieldDescriptor* field, int index) {
+    Message* message, const FieldDescriptor* field, int index) const {
   USAGE_CHECK_ALL(MutableRepeatedMessage, REPEATED, MESSAGE);
 
   if (field->is_extension()) {
-    return extensions_->MutableRepeatedMessage(field->number(), index);
+    return MutableExtensionSet(message)->MutableRepeatedMessage(
+      field->number(), index);
   } else {
-    return MutableRepeatedField<Message>(field, index);
+    return MutableRepeatedField<Message>(message, field, index);
   }
 }
 
-Message* GeneratedMessageReflection::AddMessage(const FieldDescriptor* field) {
+Message* GeneratedMessageReflection::AddMessage(
+    Message* message, const FieldDescriptor* field) const {
   USAGE_CHECK_ALL(AddMessage, REPEATED, MESSAGE);
 
   if (field->is_extension()) {
-    return extensions_->AddMessage(field->number());
+    return MutableExtensionSet(message)->AddMessage(field->number());
   } else {
-    return AddField<Message>(field);
+    return AddField<Message>(message, field);
   }
 }
 
@@ -548,14 +584,38 @@ Message* GeneratedMessageReflection::AddMessage(const FieldDescriptor* field) {
 
 const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByName(
     const string& name) const {
-  if (extensions_ == NULL) return NULL;
-  return extensions_->FindKnownExtensionByName(name);
+  if (extensions_offset_ == -1) return NULL;
+
+  const FieldDescriptor* result = descriptor_pool_->FindExtensionByName(name);
+  if (result != NULL && result->containing_type() == descriptor_) {
+    return result;
+  }
+
+  if (descriptor_->options().message_set_wire_format()) {
+    // MessageSet extensions may be identified by type name.
+    const Descriptor* type = descriptor_pool_->FindMessageTypeByName(name);
+    if (type != NULL) {
+      // Look for a matching extension in the foreign type's scope.
+      for (int i = 0; i < type->extension_count(); i++) {
+        const FieldDescriptor* extension = type->extension(i);
+        if (extension->containing_type() == descriptor_ &&
+            extension->type() == FieldDescriptor::TYPE_MESSAGE &&
+            extension->is_optional() &&
+            extension->message_type() == type) {
+          // Found it.
+          return extension;
+        }
+      }
+    }
+  }
+
+  return NULL;
 }
 
 const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByNumber(
     int number) const {
-  if (extensions_ == NULL) return NULL;
-  return extensions_->FindKnownExtensionByNumber(number);
+  if (extensions_offset_ == -1) return NULL;
+  return descriptor_pool_->FindExtensionByNumber(descriptor_, number);
 }
 
 // ===================================================================
@@ -565,41 +625,67 @@ const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByNumber(
 // the given field.
 template <typename Type>
 inline const Type& GeneratedMessageReflection::GetRaw(
-    const FieldDescriptor* field) const {
-  const void* ptr = reinterpret_cast<const uint8*>(base_) +
+    const Message& message, const FieldDescriptor* field) const {
+  const void* ptr = reinterpret_cast<const uint8*>(&message) +
                     offsets_[field->index()];
   return *reinterpret_cast<const Type*>(ptr);
 }
 
 template <typename Type>
 inline Type* GeneratedMessageReflection::MutableRaw(
-    const FieldDescriptor* field) {
-  void* ptr = reinterpret_cast<uint8*>(base_) + offsets_[field->index()];
+    Message* message, const FieldDescriptor* field) const {
+  void* ptr = reinterpret_cast<uint8*>(message) + offsets_[field->index()];
   return reinterpret_cast<Type*>(ptr);
 }
 
 template <typename Type>
 inline const Type& GeneratedMessageReflection::DefaultRaw(
     const FieldDescriptor* field) const {
-  const void* ptr = reinterpret_cast<const uint8*>(default_base_) +
+  const void* ptr = reinterpret_cast<const uint8*>(default_instance_) +
                     offsets_[field->index()];
   return *reinterpret_cast<const Type*>(ptr);
 }
 
+inline const uint32* GeneratedMessageReflection::GetHasBits(
+    const Message& message) const {
+  const void* ptr = reinterpret_cast<const uint8*>(&message) + has_bits_offset_;
+  return reinterpret_cast<const uint32*>(ptr);
+}
+inline uint32* GeneratedMessageReflection::MutableHasBits(
+    Message* message) const {
+  void* ptr = reinterpret_cast<uint8*>(message) + has_bits_offset_;
+  return reinterpret_cast<uint32*>(ptr);
+}
+
+inline const ExtensionSet& GeneratedMessageReflection::GetExtensionSet(
+    const Message& message) const {
+  GOOGLE_DCHECK_NE(extensions_offset_, -1);
+  const void* ptr = reinterpret_cast<const uint8*>(&message) +
+                    extensions_offset_;
+  return *reinterpret_cast<const ExtensionSet*>(ptr);
+}
+inline ExtensionSet* GeneratedMessageReflection::MutableExtensionSet(
+    Message* message) const {
+  GOOGLE_DCHECK_NE(extensions_offset_, -1);
+  void* ptr = reinterpret_cast<uint8*>(message) + extensions_offset_;
+  return reinterpret_cast<ExtensionSet*>(ptr);
+}
+
 // Simple accessors for manipulating has_bits_.
 inline bool GeneratedMessageReflection::HasBit(
-    const FieldDescriptor* field) const {
-  return has_bits_[field->index() / 32] & (1 << (field->index() % 32));
+    const Message& message, const FieldDescriptor* field) const {
+  return GetHasBits(message)[field->index() / 32] &
+    (1 << (field->index() % 32));
 }
 
 inline void GeneratedMessageReflection::SetBit(
-    const FieldDescriptor* field) {
-  has_bits_[field->index() / 32] |= (1 << (field->index() % 32));
+    Message* message, const FieldDescriptor* field) const {
+  MutableHasBits(message)[field->index() / 32] |= (1 << (field->index() % 32));
 }
 
 inline void GeneratedMessageReflection::ClearBit(
-    const FieldDescriptor* field) {
-  has_bits_[field->index() / 32] &= ~(1 << (field->index() % 32));
+    Message* message, const FieldDescriptor* field) const {
+  MutableHasBits(message)[field->index() / 32] &= ~(1 << (field->index() % 32));
 }
 
 // Template implementations of basic accessors.  Inline because each
@@ -607,56 +693,61 @@ inline void GeneratedMessageReflection::ClearBit(
 // used for all types except messages.
 template <typename Type>
 inline const Type& GeneratedMessageReflection::GetField(
-    const FieldDescriptor* field) const {
-  return GetRaw<Type>(field);
+    const Message& message, const FieldDescriptor* field) const {
+  return GetRaw<Type>(message, field);
 }
 
 template <typename Type>
 inline void GeneratedMessageReflection::SetField(
-    const FieldDescriptor* field, const Type& value) {
-  *MutableRaw<Type>(field) = value;
-  SetBit(field);
+    Message* message, const FieldDescriptor* field, const Type& value) const {
+  *MutableRaw<Type>(message, field) = value;
+  SetBit(message, field);
 }
 
 template <typename Type>
 inline Type* GeneratedMessageReflection::MutableField(
-    const FieldDescriptor* field) {
-  SetBit(field);
-  return MutableRaw<Type>(field);
+    Message* message, const FieldDescriptor* field) const {
+  SetBit(message, field);
+  return MutableRaw<Type>(message, field);
 }
 
 template <typename Type>
 inline const Type& GeneratedMessageReflection::GetRepeatedField(
-    const FieldDescriptor* field, int index) const {
+    const Message& message, const FieldDescriptor* field, int index) const {
   return *reinterpret_cast<const Type*>(
-    GetRaw<GenericRepeatedField>(field).GenericGet(index));
+    GetRaw<GenericRepeatedField>(message, field).GenericGet(index));
 }
 
 template <typename Type>
 inline void GeneratedMessageReflection::SetRepeatedField(
-    const FieldDescriptor* field, int index, const Type& value) {
-  GenericRepeatedField* repeated = MutableRaw<GenericRepeatedField>(field);
+    Message* message, const FieldDescriptor* field,
+    int index, const Type& value) const {
+  GenericRepeatedField* repeated =
+    MutableRaw<GenericRepeatedField>(message, field);
   *reinterpret_cast<Type*>(repeated->GenericMutable(index)) = value;
 }
 
 template <typename Type>
 inline Type* GeneratedMessageReflection::MutableRepeatedField(
-    const FieldDescriptor* field, int index) {
-  GenericRepeatedField* repeated = MutableRaw<GenericRepeatedField>(field);
+    Message* message, const FieldDescriptor* field, int index) const {
+  GenericRepeatedField* repeated =
+    MutableRaw<GenericRepeatedField>(message, field);
   return reinterpret_cast<Type*>(repeated->GenericMutable(index));
 }
 
 template <typename Type>
 inline void GeneratedMessageReflection::AddField(
-    const FieldDescriptor* field, const Type& value) {
-  GenericRepeatedField* repeated = MutableRaw<GenericRepeatedField>(field);
+    Message* message, const FieldDescriptor* field, const Type& value) const {
+  GenericRepeatedField* repeated =
+    MutableRaw<GenericRepeatedField>(message, field);
   *reinterpret_cast<Type*>(repeated->GenericAdd()) = value;
 }
 
 template <typename Type>
 inline Type* GeneratedMessageReflection::AddField(
-    const FieldDescriptor* field) {
-  GenericRepeatedField* repeated = MutableRaw<GenericRepeatedField>(field);
+    Message* message, const FieldDescriptor* field) const {
+  GenericRepeatedField* repeated =
+    MutableRaw<GenericRepeatedField>(message, field);
   return reinterpret_cast<Type*>(repeated->GenericAdd());
 }
 
diff --git a/src/google/protobuf/generated_message_reflection.h b/src/google/protobuf/generated_message_reflection.h
index 579d6abe1ae5a789cf576836e0988645a341e42e..48df8dc1776fcdaa72ade43835b1026646f934bd 100644
--- a/src/google/protobuf/generated_message_reflection.h
+++ b/src/google/protobuf/generated_message_reflection.h
@@ -30,10 +30,13 @@
 #include <google/protobuf/unknown_field_set.h>
 
 
-// Generated code needs this to have been forward-declared.  Easier to do it
-// here than to print it inside every .pb.h file.
 namespace google {
-namespace protobuf { class EnumDescriptor; }
+namespace protobuf {
+  class DescriptorPool;
+  // Generated code needs this to have been forward-declared.  Easier to do it
+  // here than to print it inside every .pb.h file.
+  class EnumDescriptor;
+}
 
 namespace protobuf {
 namespace internal {
@@ -48,7 +51,7 @@ class ExtensionSet;             // extension_set.h
 // by generated code.  This class is just a big hack that reduces code
 // size.
 //
-// A GeneratedMessageReflection is an implementation of Message::Reflection
+// A GeneratedMessageReflection is an implementation of Reflection
 // which expects all fields to be backed by simple variables located in
 // memory.  The locations are given using a base pointer and a set of
 // offsets.
@@ -68,122 +71,172 @@ class ExtensionSet;             // extension_set.h
 //    of whatever type the individual field would be.  Strings and
 //    Messages use RepeatedPtrFields while everything else uses
 //    RepeatedFields.
-class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Message::Reflection {
+class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
  public:
   // Constructs a GeneratedMessageReflection.
   // Parameters:
   //   descriptor:    The descriptor for the message type being implemented.
-  //   base:          Pointer to the location where the message object is
-  //                  stored.
-  //   default_base:  Pointer to the location where the message's default
-  //                  instance is stored.  This is only used to obtain
-  //                  pointers to default instances of embedded messages,
-  //                  which GetMessage() will return if the particular sub-
-  //                  message has not been initialized yet.  (Thus, all
+  //   default_instance:  The default instance of the message.  This is only
+  //                  used to obtain pointers to default instances of embedded
+  //                  messages, which GetMessage() will return if the particular
+  //                  sub-message has not been initialized yet.  (Thus, all
   //                  embedded message fields *must* have non-NULL pointers
   //                  in the default instance.)
-  //   offsets:       An array of bits giving the byte offsets, relative to
-  //                  "base" and "default_base", of each field.  These can
+  //   offsets:       An array of ints giving the byte offsets, relative to
+  //                  the start of the message object, of each field.  These can
   //                  be computed at compile time using the
   //                  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET() macro, defined
   //                  below.
-  //   has_bits:      An array of uint32s of size descriptor->field_count()/32,
-  //                  rounded up.  This is a bitfield where each bit indicates
-  //                  whether or not the corresponding field of the message
-  //                  has been initialized.  The bit for field index i is
-  //                  obtained by the expression:
+  //   has_bits_offset:  Offset in the message of an array of uint32s of size
+  //                  descriptor->field_count()/32, rounded up.  This is a
+  //                  bitfield where each bit indicates whether or not the
+  //                  corresponding field of the message has been initialized.
+  //                  The bit for field index i is obtained by the expression:
   //                    has_bits[i / 32] & (1 << (i % 32))
-  //   extensions:    The ExtensionSet for this message, or NULL if the
-  //                  message type has no extension ranges.
+  //   unknown_fields_offset:  Offset in the message of the UnknownFieldSet for
+  //                  the message.
+  //   extensions_offset:  Offset in the message of the ExtensionSet for the
+  //                  message, or -1 if the message type has no extension
+  //                  ranges.
+  //   pool:          DescriptorPool to search for extension definitions.  Only
+  //                  used by FindKnownExtensionByName() and
+  //                  FindKnownExtensionByNumber().
   GeneratedMessageReflection(const Descriptor* descriptor,
-                             void* base, const void* default_base,
-                             const int offsets[], uint32 has_bits[],
-                             ExtensionSet* extensions);
+                             const Message* default_instance,
+                             const int offsets[],
+                             int has_bits_offset,
+                             int unknown_fields_offset,
+                             int extensions_offset,
+                             const DescriptorPool* pool);
   ~GeneratedMessageReflection();
 
-  inline const UnknownFieldSet& unknown_fields() const {
-    return unknown_fields_;
-  }
-  inline UnknownFieldSet* mutable_unknown_fields() {
-    return &unknown_fields_;
-  }
-
-  // implements Message::Reflection ----------------------------------
-
-  const UnknownFieldSet& GetUnknownFields() const;
-  UnknownFieldSet* MutableUnknownFields();
-
-  bool HasField(const FieldDescriptor* field) const;
-  int FieldSize(const FieldDescriptor* field) const;
-  void ClearField(const FieldDescriptor* field);
-  void ListFields(vector<const FieldDescriptor*>* output) const;
-
-  int32  GetInt32 (const FieldDescriptor* field) const;
-  int64  GetInt64 (const FieldDescriptor* field) const;
-  uint32 GetUInt32(const FieldDescriptor* field) const;
-  uint64 GetUInt64(const FieldDescriptor* field) const;
-  float  GetFloat (const FieldDescriptor* field) const;
-  double GetDouble(const FieldDescriptor* field) const;
-  bool   GetBool  (const FieldDescriptor* field) const;
-  string GetString(const FieldDescriptor* field) const;
-  const string& GetStringReference(const FieldDescriptor* field,
+  // implements Reflection -------------------------------------------
+
+  const UnknownFieldSet& GetUnknownFields(const Message& message) const;
+  UnknownFieldSet* MutableUnknownFields(Message* message) const;
+
+  bool HasField(const Message& message, const FieldDescriptor* field) const;
+  int FieldSize(const Message& message, const FieldDescriptor* field) const;
+  void ClearField(Message* message, const FieldDescriptor* field) const;
+  void ListFields(const Message& message,
+                  vector<const FieldDescriptor*>* output) const;
+
+  int32  GetInt32 (const Message& message,
+                   const FieldDescriptor* field) const;
+  int64  GetInt64 (const Message& message,
+                   const FieldDescriptor* field) const;
+  uint32 GetUInt32(const Message& message,
+                   const FieldDescriptor* field) const;
+  uint64 GetUInt64(const Message& message,
+                   const FieldDescriptor* field) const;
+  float  GetFloat (const Message& message,
+                   const FieldDescriptor* field) const;
+  double GetDouble(const Message& message,
+                   const FieldDescriptor* field) const;
+  bool   GetBool  (const Message& message,
+                   const FieldDescriptor* field) const;
+  string GetString(const Message& message,
+                   const FieldDescriptor* field) const;
+  const string& GetStringReference(const Message& message,
+                                   const FieldDescriptor* field,
                                    string* scratch) const;
-  const EnumValueDescriptor* GetEnum(const FieldDescriptor* field) const;
-  const Message& GetMessage(const FieldDescriptor* field) const;
-
-  void SetInt32 (const FieldDescriptor* field, int32  value);
-  void SetInt64 (const FieldDescriptor* field, int64  value);
-  void SetUInt32(const FieldDescriptor* field, uint32 value);
-  void SetUInt64(const FieldDescriptor* field, uint64 value);
-  void SetFloat (const FieldDescriptor* field, float  value);
-  void SetDouble(const FieldDescriptor* field, double value);
-  void SetBool  (const FieldDescriptor* field, bool   value);
-  void SetString(const FieldDescriptor* field,
-                 const string& value);
-  void SetEnum  (const FieldDescriptor* field,
-                 const EnumValueDescriptor* value);
-  Message* MutableMessage(const FieldDescriptor* field);
-
-  int32  GetRepeatedInt32 (const FieldDescriptor* field, int index) const;
-  int64  GetRepeatedInt64 (const FieldDescriptor* field, int index) const;
-  uint32 GetRepeatedUInt32(const FieldDescriptor* field, int index) const;
-  uint64 GetRepeatedUInt64(const FieldDescriptor* field, int index) const;
-  float  GetRepeatedFloat (const FieldDescriptor* field, int index) const;
-  double GetRepeatedDouble(const FieldDescriptor* field, int index) const;
-  bool   GetRepeatedBool  (const FieldDescriptor* field, int index) const;
-  string GetRepeatedString(const FieldDescriptor* field, int index) const;
-  const string& GetRepeatedStringReference(const FieldDescriptor* field,
+  const EnumValueDescriptor* GetEnum(const Message& message,
+                                     const FieldDescriptor* field) const;
+  const Message& GetMessage(const Message& message,
+                            const FieldDescriptor* field) const;
+
+  void SetInt32 (Message* message,
+                 const FieldDescriptor* field, int32  value) const;
+  void SetInt64 (Message* message,
+                 const FieldDescriptor* field, int64  value) const;
+  void SetUInt32(Message* message,
+                 const FieldDescriptor* field, uint32 value) const;
+  void SetUInt64(Message* message,
+                 const FieldDescriptor* field, uint64 value) const;
+  void SetFloat (Message* message,
+                 const FieldDescriptor* field, float  value) const;
+  void SetDouble(Message* message,
+                 const FieldDescriptor* field, double value) const;
+  void SetBool  (Message* message,
+                 const FieldDescriptor* field, bool   value) const;
+  void SetString(Message* message,
+                 const FieldDescriptor* field,
+                 const string& value) const;
+  void SetEnum  (Message* message, const FieldDescriptor* field,
+                 const EnumValueDescriptor* value) const;
+  Message* MutableMessage(Message* message, const FieldDescriptor* field) const;
+
+  int32  GetRepeatedInt32 (const Message& message,
+                           const FieldDescriptor* field, int index) const;
+  int64  GetRepeatedInt64 (const Message& message,
+                           const FieldDescriptor* field, int index) const;
+  uint32 GetRepeatedUInt32(const Message& message,
+                           const FieldDescriptor* field, int index) const;
+  uint64 GetRepeatedUInt64(const Message& message,
+                           const FieldDescriptor* field, int index) const;
+  float  GetRepeatedFloat (const Message& message,
+                           const FieldDescriptor* field, int index) const;
+  double GetRepeatedDouble(const Message& message,
+                           const FieldDescriptor* field, int index) const;
+  bool   GetRepeatedBool  (const Message& message,
+                           const FieldDescriptor* field, int index) const;
+  string GetRepeatedString(const Message& message,
+                           const FieldDescriptor* field, int index) const;
+  const string& GetRepeatedStringReference(const Message& message,
+                                           const FieldDescriptor* field,
                                            int index, string* scratch) const;
-  const EnumValueDescriptor* GetRepeatedEnum(const FieldDescriptor* field,
+  const EnumValueDescriptor* GetRepeatedEnum(const Message& message,
+                                             const FieldDescriptor* field,
                                              int index) const;
-  const Message& GetRepeatedMessage(const FieldDescriptor* field,
+  const Message& GetRepeatedMessage(const Message& message,
+                                    const FieldDescriptor* field,
                                     int index) const;
 
   // Set the value of a field.
-  void SetRepeatedInt32 (const FieldDescriptor* field, int index, int32  value);
-  void SetRepeatedInt64 (const FieldDescriptor* field, int index, int64  value);
-  void SetRepeatedUInt32(const FieldDescriptor* field, int index, uint32 value);
-  void SetRepeatedUInt64(const FieldDescriptor* field, int index, uint64 value);
-  void SetRepeatedFloat (const FieldDescriptor* field, int index, float  value);
-  void SetRepeatedDouble(const FieldDescriptor* field, int index, double value);
-  void SetRepeatedBool  (const FieldDescriptor* field, int index, bool   value);
-  void SetRepeatedString(const FieldDescriptor* field, int index,
-                         const string& value);
-  void SetRepeatedEnum  (const FieldDescriptor* field, int index,
-                         const EnumValueDescriptor* value);
+  void SetRepeatedInt32 (Message* message,
+                         const FieldDescriptor* field, int index, int32  value) const;
+  void SetRepeatedInt64 (Message* message,
+                         const FieldDescriptor* field, int index, int64  value) const;
+  void SetRepeatedUInt32(Message* message,
+                         const FieldDescriptor* field, int index, uint32 value) const;
+  void SetRepeatedUInt64(Message* message,
+                         const FieldDescriptor* field, int index, uint64 value) const;
+  void SetRepeatedFloat (Message* message,
+                         const FieldDescriptor* field, int index, float  value) const;
+  void SetRepeatedDouble(Message* message,
+                         const FieldDescriptor* field, int index, double value) const;
+  void SetRepeatedBool  (Message* message,
+                         const FieldDescriptor* field, int index, bool   value) const;
+  void SetRepeatedString(Message* message,
+                         const FieldDescriptor* field, int index,
+                         const string& value) const;
+  void SetRepeatedEnum(Message* message, const FieldDescriptor* field,
+                       int index, const EnumValueDescriptor* value) const;
   // Get a mutable pointer to a field with a message type.
-  Message* MutableRepeatedMessage(const FieldDescriptor* field, int index);
-
-  void AddInt32 (const FieldDescriptor* field, int32  value);
-  void AddInt64 (const FieldDescriptor* field, int64  value);
-  void AddUInt32(const FieldDescriptor* field, uint32 value);
-  void AddUInt64(const FieldDescriptor* field, uint64 value);
-  void AddFloat (const FieldDescriptor* field, float  value);
-  void AddDouble(const FieldDescriptor* field, double value);
-  void AddBool  (const FieldDescriptor* field, bool   value);
-  void AddString(const FieldDescriptor* field, const string& value);
-  void AddEnum(const FieldDescriptor* field, const EnumValueDescriptor* value);
-  Message* AddMessage(const FieldDescriptor* field);
+  Message* MutableRepeatedMessage(Message* message,
+                                  const FieldDescriptor* field,
+                                  int index) const;
+
+  void AddInt32 (Message* message,
+                 const FieldDescriptor* field, int32  value) const;
+  void AddInt64 (Message* message,
+                 const FieldDescriptor* field, int64  value) const;
+  void AddUInt32(Message* message,
+                 const FieldDescriptor* field, uint32 value) const;
+  void AddUInt64(Message* message,
+                 const FieldDescriptor* field, uint64 value) const;
+  void AddFloat (Message* message,
+                 const FieldDescriptor* field, float  value) const;
+  void AddDouble(Message* message,
+                 const FieldDescriptor* field, double value) const;
+  void AddBool  (Message* message,
+                 const FieldDescriptor* field, bool   value) const;
+  void AddString(Message* message,
+                 const FieldDescriptor* field, const string& value) const;
+  void AddEnum(Message* message,
+               const FieldDescriptor* field,
+               const EnumValueDescriptor* value) const;
+  Message* AddMessage(Message* message, const FieldDescriptor* field) const;
 
   const FieldDescriptor* FindKnownExtensionByName(const string& name) const;
   const FieldDescriptor* FindKnownExtensionByNumber(int number) const;
@@ -192,50 +245,64 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Message::Reflection
   friend class GeneratedMessage;
 
   const Descriptor* descriptor_;
-  void* base_;
-  const void* default_base_;
+  const Message* default_instance_;
   const int* offsets_;
 
-  // TODO(kenton):  These two pointers just point back into the message object.
-  //   We could save space by removing them and using offsets instead.
-  uint32* has_bits_;
-  ExtensionSet* extensions_;
+  int has_bits_offset_;
+  int unknown_fields_offset_;
+  int extensions_offset_;
 
-  // We put this directly in the GeneratedMessageReflection because every
-  // message class needs it, and if we don't find any unknown fields, it
-  // takes up only one pointer of space.
-  UnknownFieldSet unknown_fields_;
+  const DescriptorPool* descriptor_pool_;
 
   template <typename Type>
-  inline const Type& GetRaw(const FieldDescriptor* field) const;
+  inline const Type& GetRaw(const Message& message,
+                            const FieldDescriptor* field) const;
   template <typename Type>
-  inline Type* MutableRaw(const FieldDescriptor* field);
+  inline Type* MutableRaw(Message* message,
+                          const FieldDescriptor* field) const;
   template <typename Type>
   inline const Type& DefaultRaw(const FieldDescriptor* field) const;
   inline const Message* GetMessagePrototype(const FieldDescriptor* field) const;
 
-  inline bool HasBit(const FieldDescriptor* field) const;
-  inline void SetBit(const FieldDescriptor* field);
-  inline void ClearBit(const FieldDescriptor* field);
+  inline const uint32* GetHasBits(const Message& message) const;
+  inline uint32* MutableHasBits(Message* message) const;
+  inline const ExtensionSet& GetExtensionSet(const Message& message) const;
+  inline ExtensionSet* MutableExtensionSet(Message* message) const;
+
+  inline bool HasBit(const Message& message,
+                     const FieldDescriptor* field) const;
+  inline void SetBit(Message* message,
+                     const FieldDescriptor* field) const;
+  inline void ClearBit(Message* message,
+                       const FieldDescriptor* field) const;
 
   template <typename Type>
-  inline const Type& GetField(const FieldDescriptor* field) const;
+  inline const Type& GetField(const Message& message,
+                              const FieldDescriptor* field) const;
   template <typename Type>
-  inline void SetField(const FieldDescriptor* field, const Type& value);
+  inline void SetField(Message* message,
+                       const FieldDescriptor* field, const Type& value) const;
   template <typename Type>
-  inline Type* MutableField(const FieldDescriptor* field);
+  inline Type* MutableField(Message* message,
+                            const FieldDescriptor* field) const;
   template <typename Type>
-  inline const Type& GetRepeatedField(const FieldDescriptor* field,
+  inline const Type& GetRepeatedField(const Message& message,
+                                      const FieldDescriptor* field,
                                       int index) const;
   template <typename Type>
-  inline void SetRepeatedField(const FieldDescriptor* field, int index,
-                               const Type& value);
+  inline void SetRepeatedField(Message* message,
+                               const FieldDescriptor* field, int index,
+                               const Type& value) const;
   template <typename Type>
-  inline Type* MutableRepeatedField(const FieldDescriptor* field, int index);
+  inline Type* MutableRepeatedField(Message* message,
+                                    const FieldDescriptor* field,
+                                    int index) const;
   template <typename Type>
-  inline void AddField(const FieldDescriptor* field, const Type& value);
+  inline void AddField(Message* message,
+                       const FieldDescriptor* field, const Type& value) const;
   template <typename Type>
-  inline Type* AddField(const FieldDescriptor* field);
+  inline Type* AddField(Message* message,
+                        const FieldDescriptor* field) const;
 
   int GetExtensionNumberOrDie(const Descriptor* type) const;
 
diff --git a/src/google/protobuf/generated_message_reflection_unittest.cc b/src/google/protobuf/generated_message_reflection_unittest.cc
index bde7fac7b08fc849386e12c09e7302c9e0453a82..d0e96bd8f6409ddc8f5c44c52c9200e281b51095 100644
--- a/src/google/protobuf/generated_message_reflection_unittest.cc
+++ b/src/google/protobuf/generated_message_reflection_unittest.cc
@@ -56,21 +56,21 @@ TEST(GeneratedMessageReflectionTest, Defaults) {
   TestUtil::ReflectionTester reflection_tester(
     unittest::TestAllTypes::descriptor());
 
-  reflection_tester.ExpectClearViaReflection(*message.GetReflection());
+  reflection_tester.ExpectClearViaReflection(message);
 
-  const Message::Reflection& reflection = *message.GetReflection();
+  const Reflection* reflection = message.GetReflection();
 
   // Messages should return pointers to default instances until first use.
   // (This is not checked by ExpectClear() since it is not actually true after
   // the fields have been set and then cleared.)
   EXPECT_EQ(&unittest::TestAllTypes::OptionalGroup::default_instance(),
-            &reflection.GetMessage(F("optionalgroup")));
+            &reflection->GetMessage(message, F("optionalgroup")));
   EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(),
-            &reflection.GetMessage(F("optional_nested_message")));
+            &reflection->GetMessage(message, F("optional_nested_message")));
   EXPECT_EQ(&unittest::ForeignMessage::default_instance(),
-            &reflection.GetMessage(F("optional_foreign_message")));
+            &reflection->GetMessage(message, F("optional_foreign_message")));
   EXPECT_EQ(&unittest_import::ImportMessage::default_instance(),
-            &reflection.GetMessage(F("optional_import_message")));
+            &reflection->GetMessage(message, F("optional_import_message")));
 }
 
 TEST(GeneratedMessageReflectionTest, Accessors) {
@@ -80,11 +80,11 @@ TEST(GeneratedMessageReflectionTest, Accessors) {
   TestUtil::ReflectionTester reflection_tester(
     unittest::TestAllTypes::descriptor());
 
-  reflection_tester.SetAllFieldsViaReflection(message.GetReflection());
+  reflection_tester.SetAllFieldsViaReflection(&message);
   TestUtil::ExpectAllFieldsSet(message);
-  reflection_tester.ExpectAllFieldsSetViaReflection(*message.GetReflection());
+  reflection_tester.ExpectAllFieldsSetViaReflection(message);
 
-  reflection_tester.ModifyRepeatedFieldsViaReflection(message.GetReflection());
+  reflection_tester.ModifyRepeatedFieldsViaReflection(&message);
   TestUtil::ExpectRepeatedFieldsModified(message);
 }
 
@@ -95,15 +95,16 @@ TEST(GeneratedMessageReflectionTest, GetStringReference) {
   message.set_optional_string("foo");
   message.add_repeated_string("foo");
 
-  const Message::Reflection& reflection = *message.GetReflection();
+  const Reflection* reflection = message.GetReflection();
   string scratch;
 
   EXPECT_EQ(&message.optional_string(),
-      &reflection.GetStringReference(F("optional_string"), &scratch))
+      &reflection->GetStringReference(message, F("optional_string"), &scratch))
     << "For simple string fields, GetStringReference() should return a "
        "reference to the underlying string.";
   EXPECT_EQ(&message.repeated_string(0),
-      &reflection.GetRepeatedStringReference(F("repeated_string"), 0, &scratch))
+      &reflection->GetRepeatedStringReference(message, F("repeated_string"),
+                                              0, &scratch))
     << "For simple string fields, GetRepeatedStringReference() should return "
        "a reference to the underlying string.";
 }
@@ -119,16 +120,16 @@ TEST(GeneratedMessageReflectionTest, DefaultsAfterClear) {
   TestUtil::SetAllFields(&message);
   message.Clear();
 
-  const Message::Reflection& reflection = *message.GetReflection();
+  const Reflection* reflection = message.GetReflection();
 
   EXPECT_NE(&unittest::TestAllTypes::OptionalGroup::default_instance(),
-            &reflection.GetMessage(F("optionalgroup")));
+            &reflection->GetMessage(message, F("optionalgroup")));
   EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(),
-            &reflection.GetMessage(F("optional_nested_message")));
+            &reflection->GetMessage(message, F("optional_nested_message")));
   EXPECT_NE(&unittest::ForeignMessage::default_instance(),
-            &reflection.GetMessage(F("optional_foreign_message")));
+            &reflection->GetMessage(message, F("optional_foreign_message")));
   EXPECT_NE(&unittest_import::ImportMessage::default_instance(),
-            &reflection.GetMessage(F("optional_import_message")));
+            &reflection->GetMessage(message, F("optional_import_message")));
 }
 
 TEST(GeneratedMessageReflectionTest, Extensions) {
@@ -138,17 +139,17 @@ TEST(GeneratedMessageReflectionTest, Extensions) {
   TestUtil::ReflectionTester reflection_tester(
     unittest::TestAllExtensions::descriptor());
 
-  reflection_tester.SetAllFieldsViaReflection(message.GetReflection());
+  reflection_tester.SetAllFieldsViaReflection(&message);
   TestUtil::ExpectAllExtensionsSet(message);
-  reflection_tester.ExpectAllFieldsSetViaReflection(*message.GetReflection());
+  reflection_tester.ExpectAllFieldsSetViaReflection(message);
 
-  reflection_tester.ModifyRepeatedFieldsViaReflection(message.GetReflection());
+  reflection_tester.ModifyRepeatedFieldsViaReflection(&message);
   TestUtil::ExpectRepeatedExtensionsModified(message);
 }
 
 TEST(GeneratedMessageReflectionTest, FindExtensionTypeByNumber) {
-  const Message::Reflection& reflection =
-    *unittest::TestAllExtensions::default_instance().GetReflection();
+  const Reflection* reflection =
+    unittest::TestAllExtensions::default_instance().GetReflection();
 
   const FieldDescriptor* extension1 =
     unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName(
@@ -158,12 +159,12 @@ TEST(GeneratedMessageReflectionTest, FindExtensionTypeByNumber) {
       "repeated_string_extension");
 
   EXPECT_EQ(extension1,
-            reflection.FindKnownExtensionByNumber(extension1->number()));
+            reflection->FindKnownExtensionByNumber(extension1->number()));
   EXPECT_EQ(extension2,
-            reflection.FindKnownExtensionByNumber(extension2->number()));
+            reflection->FindKnownExtensionByNumber(extension2->number()));
 
   // Non-existent extension.
-  EXPECT_TRUE(reflection.FindKnownExtensionByNumber(62341) == NULL);
+  EXPECT_TRUE(reflection->FindKnownExtensionByNumber(62341) == NULL);
 
   // Extensions of TestAllExtensions should not show up as extensions of
   // other types.
@@ -172,8 +173,8 @@ TEST(GeneratedMessageReflectionTest, FindExtensionTypeByNumber) {
 }
 
 TEST(GeneratedMessageReflectionTest, FindKnownExtensionByName) {
-  const Message::Reflection& reflection =
-    *unittest::TestAllExtensions::default_instance().GetReflection();
+  const Reflection* reflection =
+    unittest::TestAllExtensions::default_instance().GetReflection();
 
   const FieldDescriptor* extension1 =
     unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName(
@@ -183,12 +184,12 @@ TEST(GeneratedMessageReflectionTest, FindKnownExtensionByName) {
       "repeated_string_extension");
 
   EXPECT_EQ(extension1,
-            reflection.FindKnownExtensionByName(extension1->full_name()));
+            reflection->FindKnownExtensionByName(extension1->full_name()));
   EXPECT_EQ(extension2,
-            reflection.FindKnownExtensionByName(extension2->full_name()));
+            reflection->FindKnownExtensionByName(extension2->full_name()));
 
   // Non-existent extension.
-  EXPECT_TRUE(reflection.FindKnownExtensionByName("no_such_ext") == NULL);
+  EXPECT_TRUE(reflection->FindKnownExtensionByName("no_such_ext") == NULL);
 
   // Extensions of TestAllExtensions should not show up as extensions of
   // other types.
@@ -200,7 +201,7 @@ TEST(GeneratedMessageReflectionTest, FindKnownExtensionByName) {
 
 TEST(GeneratedMessageReflectionTest, UsageErrors) {
   unittest::TestAllTypes message;
-  Message::Reflection* reflection = message.GetReflection();
+  const Reflection* reflection = message.GetReflection();
   const Descriptor* descriptor = message.GetDescriptor();
 
 #define f(NAME) descriptor->FindFieldByName(NAME)
@@ -208,34 +209,36 @@ TEST(GeneratedMessageReflectionTest, UsageErrors) {
   // Testing every single failure mode would be too much work.  Let's just
   // check a few.
   EXPECT_DEATH(
-    reflection->GetInt32(descriptor->FindFieldByName("optional_int64")),
+    reflection->GetInt32(
+      message, descriptor->FindFieldByName("optional_int64")),
     "Protocol Buffer reflection usage error:\n"
-    "  Method      : google::protobuf::Message::Reflection::GetInt32\n"
+    "  Method      : google::protobuf::Reflection::GetInt32\n"
     "  Message type: protobuf_unittest\\.TestAllTypes\n"
     "  Field       : protobuf_unittest\\.TestAllTypes\\.optional_int64\n"
     "  Problem     : Field is not the right type for this message:\n"
     "    Expected  : CPPTYPE_INT32\n"
     "    Field type: CPPTYPE_INT64");
   EXPECT_DEATH(
-    reflection->GetInt32(descriptor->FindFieldByName("repeated_int32")),
+    reflection->GetInt32(
+      message, descriptor->FindFieldByName("repeated_int32")),
     "Protocol Buffer reflection usage error:\n"
-    "  Method      : google::protobuf::Message::Reflection::GetInt32\n"
+    "  Method      : google::protobuf::Reflection::GetInt32\n"
     "  Message type: protobuf_unittest.TestAllTypes\n"
     "  Field       : protobuf_unittest.TestAllTypes.repeated_int32\n"
     "  Problem     : Field is repeated; the method requires a singular field.");
   EXPECT_DEATH(
     reflection->GetInt32(
-      unittest::ForeignMessage::descriptor()->FindFieldByName("c")),
+      message, unittest::ForeignMessage::descriptor()->FindFieldByName("c")),
     "Protocol Buffer reflection usage error:\n"
-    "  Method      : google::protobuf::Message::Reflection::GetInt32\n"
+    "  Method      : google::protobuf::Reflection::GetInt32\n"
     "  Message type: protobuf_unittest.TestAllTypes\n"
     "  Field       : protobuf_unittest.ForeignMessage.c\n"
     "  Problem     : Field does not match message type.");
   EXPECT_DEATH(
     reflection->HasField(
-      unittest::ForeignMessage::descriptor()->FindFieldByName("c")),
+      message, unittest::ForeignMessage::descriptor()->FindFieldByName("c")),
     "Protocol Buffer reflection usage error:\n"
-    "  Method      : google::protobuf::Message::Reflection::HasField\n"
+    "  Method      : google::protobuf::Reflection::HasField\n"
     "  Message type: protobuf_unittest.TestAllTypes\n"
     "  Field       : protobuf_unittest.ForeignMessage.c\n"
     "  Problem     : Field does not match message type.");
diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc
index f740ef184aafa69562800bba5a7603213bd46792..b9b1ac6c374af8d68ef63591470d75134053bb36 100644
--- a/src/google/protobuf/message.cc
+++ b/src/google/protobuf/message.cc
@@ -50,7 +50,6 @@ static string InitializationErrorMessage(const char* action,
 }
 
 Message::~Message() {}
-Message::Reflection::~Reflection() {}
 
 void Message::MergeFrom(const Message& from) {
   const Descriptor* descriptor = GetDescriptor();
@@ -58,7 +57,7 @@ void Message::MergeFrom(const Message& from) {
     << ": Tried to merge from a message with a different type.  "
        "to: " << descriptor->full_name() << ", "
        "from:" << from.GetDescriptor()->full_name();
-  ReflectionOps::Merge(descriptor, *from.GetReflection(), GetReflection());
+  ReflectionOps::Merge(from, this);
 }
 
 void Message::CopyFrom(const Message& from) {
@@ -67,20 +66,19 @@ void Message::CopyFrom(const Message& from) {
     << ": Tried to copy from a message with a different type."
        "to: " << descriptor->full_name() << ", "
        "from:" << from.GetDescriptor()->full_name();
-  ReflectionOps::Copy(descriptor, *from.GetReflection(), GetReflection());
+  ReflectionOps::Copy(from, this);
 }
 
 void Message::Clear() {
-  ReflectionOps::Clear(GetDescriptor(), GetReflection());
+  ReflectionOps::Clear(this);
 }
 
 bool Message::IsInitialized() const {
-  return ReflectionOps::IsInitialized(GetDescriptor(), *GetReflection());
+  return ReflectionOps::IsInitialized(*this);
 }
 
 void Message::FindInitializationErrors(vector<string>* errors) const {
-  return ReflectionOps::FindInitializationErrors(
-    GetDescriptor(), *GetReflection(), "", errors);
+  return ReflectionOps::FindInitializationErrors(*this, "", errors);
 }
 
 string Message::InitializationErrorString() const {
@@ -96,12 +94,11 @@ void Message::CheckInitialized() const {
 }
 
 void Message::DiscardUnknownFields() {
-  return ReflectionOps::DiscardUnknownFields(GetDescriptor(), GetReflection());
+  return ReflectionOps::DiscardUnknownFields(this);
 }
 
 bool Message::MergePartialFromCodedStream(io::CodedInputStream* input) {
-  return WireFormat::ParseAndMergePartial(
-    GetDescriptor(), input, GetReflection());
+  return WireFormat::ParseAndMergePartial(input, this);
 }
 
 bool Message::MergeFromCodedStream(io::CodedInputStream* input) {
@@ -178,12 +175,11 @@ bool Message::ParsePartialFromIstream(istream* input) {
 
 bool Message::SerializeWithCachedSizes(
     io::CodedOutputStream* output) const {
-  return WireFormat::SerializeWithCachedSizes(
-    GetDescriptor(), GetReflection(), GetCachedSize(), output);
+  return WireFormat::SerializeWithCachedSizes(*this, GetCachedSize(), output);
 }
 
 int Message::ByteSize() const {
-  int size = WireFormat::ByteSize(GetDescriptor(), GetReflection());
+  int size = WireFormat::ByteSize(*this);
   SetCachedSize(size);
   return size;
 }
@@ -281,6 +277,8 @@ bool Message::SerializePartialToOstream(ostream* output) const {
 }
 
 
+Reflection::~Reflection() {}
+
 // ===================================================================
 // MessageFactory
 
diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h
index 2c2cf5bd53128e282c590dfabbdb96ac00247263..1a297b125ef1248278693277ffe77e47e1799fe2 100644
--- a/src/google/protobuf/message.h
+++ b/src/google/protobuf/message.h
@@ -81,12 +81,12 @@
 //     foo->ParseFromString(data);
 //
 //     // Use the reflection interface to examine the contents.
-//     Message::Reflection* reflection = foo->GetReflection();
-//     assert(reflection->GetString(text_field) == "Hello World!");
-//     assert(reflection->CountField(numbers_field) == 3);
-//     assert(reflection->GetInt32(numbers_field, 0) == 1);
-//     assert(reflection->GetInt32(numbers_field, 1) == 5);
-//     assert(reflection->GetInt32(numbers_field, 2) == 42);
+//     Reflection* reflection = foo->GetReflection();
+//     assert(reflection->GetString(foo, text_field) == "Hello World!");
+//     assert(reflection->CountField(foo, numbers_field) == 3);
+//     assert(reflection->GetInt32(foo, numbers_field, 0) == 1);
+//     assert(reflection->GetInt32(foo, numbers_field, 1) == 5);
+//     assert(reflection->GetInt32(foo, numbers_field, 2) == 42);
 //
 //     delete foo;
 //   }
@@ -105,6 +105,7 @@ namespace protobuf {
 
 // Defined in this file.
 class Message;
+class Reflection;
 
 // Defined in other files.
 class Descriptor;            // descriptor.h
@@ -336,7 +337,8 @@ class LIBPROTOBUF_EXPORT Message {
 
   // Introspection ---------------------------------------------------
 
-  class Reflection;  // Defined below.
+  // Typedef for backwards-compatibility.
+  typedef google::protobuf::Reflection Reflection;
 
   // Get a Descriptor for this message's type.  This describes what
   // fields the message contains, the types of those fields, etc.
@@ -348,12 +350,6 @@ class LIBPROTOBUF_EXPORT Message {
   // property of the Message.
   virtual const Reflection* GetReflection() const = 0;
 
-  // Get the Reflection interface for this Message, which can be used to
-  // read and modify the fields of the Message dynamically (in other words,
-  // without knowing the message type at compile time).  This object remains
-  // property of the Message.
-  virtual Reflection* GetReflection() = 0;
-
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Message);
 };
@@ -367,7 +363,9 @@ class LIBPROTOBUF_EXPORT Message {
 // This interface is separate from Message only for efficiency reasons;
 // the vast majority of implementations of Message will share the same
 // implementation of Reflection (GeneratedMessageReflection,
-// defined in generated_message.h).
+// defined in generated_message.h), and all Messages of a particular class
+// should share the same Reflection object (though you should not rely on
+// the latter fact).
 //
 // There are several ways that these methods can be used incorrectly.  For
 // example, any of the following conditions will lead to undefined
@@ -382,6 +380,8 @@ class LIBPROTOBUF_EXPORT Message {
 //   field.
 // - GetRepeated*(), SetRepeated*(), or Add*() is called on a non-repeated
 //   field.
+// - The Message object passed to any method is not of the right type for
+//   this Reflection object (i.e. message.GetReflection() != reflection).
 //
 // You might wonder why there is not any abstract representation for a field
 // of arbitrary type.  E.g., why isn't there just a "GetField()" method that
@@ -393,54 +393,75 @@ class LIBPROTOBUF_EXPORT Message {
 // objects on-demand, on the other hand, would be expensive and prone to
 // memory leaks.  So, instead we ended up with this flat interface.
 //
+// WARNING:  This class is currently in the process of being converted from
+//   a per-instance object to a per-class object.  You'll notice that there
+//   are two sets of methods below:  ones that take a Message pointer or
+//   reference as a parameter, and ones that don't.  The former ones are the
+//   new interface; the latter ones will go away soon.
+//
 // TODO(kenton):  Create a utility class which callers can use to read and
 //   write fields from a Reflection without paying attention to the type.
-class LIBPROTOBUF_EXPORT Message::Reflection {
+class LIBPROTOBUF_EXPORT Reflection {
  public:
+  // TODO(kenton):  Remove parameter.
   inline Reflection() {}
   virtual ~Reflection();
 
   // Get the UnknownFieldSet for the message.  This contains fields which
   // were seen when the Message was parsed but were not recognized according
   // to the Message's definition.
-  virtual const UnknownFieldSet& GetUnknownFields() const = 0;
+  virtual const UnknownFieldSet& GetUnknownFields(
+      const Message& message) const = 0;
   // Get a mutable pointer to the UnknownFieldSet for the message.  This
   // contains fields which were seen when the Message was parsed but were not
   // recognized according to the Message's definition.
-  virtual UnknownFieldSet* MutableUnknownFields() = 0;
+  virtual UnknownFieldSet* MutableUnknownFields(Message* message) const = 0;
 
   // Check if the given non-repeated field is set.
-  virtual bool HasField(const FieldDescriptor* field) const = 0;
+  virtual bool HasField(const Message& message,
+                        const FieldDescriptor* field) const = 0;
 
   // Get the number of elements of a repeated field.
-  virtual int FieldSize(const FieldDescriptor* field) const = 0;
+  virtual int FieldSize(const Message& message,
+                        const FieldDescriptor* field) const = 0;
 
   // Clear the value of a field, so that HasField() returns false or
   // FieldSize() returns zero.
-  virtual void ClearField(const FieldDescriptor* field) = 0;
+  virtual void ClearField(Message* message,
+                          const FieldDescriptor* field) const = 0;
 
   // List all fields of the message which are currently set.  This includes
   // extensions.  Singular fields will only be listed if HasField(field) would
   // return true and repeated fields will only be listed if FieldSize(field)
   // would return non-zero.  Fields (both normal fields and extension fields)
   // will be listed ordered by field number.
-  virtual void ListFields(vector<const FieldDescriptor*>* output) const = 0;
+  virtual void ListFields(const Message& message,
+                          vector<const FieldDescriptor*>* output) const = 0;
 
   // Singular field getters ------------------------------------------
   // These get the value of a non-repeated field.  They return the default
   // value for fields that aren't set.
 
-  virtual int32  GetInt32 (const FieldDescriptor* field) const = 0;
-  virtual int64  GetInt64 (const FieldDescriptor* field) const = 0;
-  virtual uint32 GetUInt32(const FieldDescriptor* field) const = 0;
-  virtual uint64 GetUInt64(const FieldDescriptor* field) const = 0;
-  virtual float  GetFloat (const FieldDescriptor* field) const = 0;
-  virtual double GetDouble(const FieldDescriptor* field) const = 0;
-  virtual bool   GetBool  (const FieldDescriptor* field) const = 0;
-  virtual string GetString(const FieldDescriptor* field) const = 0;
+  virtual int32  GetInt32 (const Message& message,
+                           const FieldDescriptor* field) const = 0;
+  virtual int64  GetInt64 (const Message& message,
+                           const FieldDescriptor* field) const = 0;
+  virtual uint32 GetUInt32(const Message& message,
+                           const FieldDescriptor* field) const = 0;
+  virtual uint64 GetUInt64(const Message& message,
+                           const FieldDescriptor* field) const = 0;
+  virtual float  GetFloat (const Message& message,
+                           const FieldDescriptor* field) const = 0;
+  virtual double GetDouble(const Message& message,
+                           const FieldDescriptor* field) const = 0;
+  virtual bool   GetBool  (const Message& message,
+                           const FieldDescriptor* field) const = 0;
+  virtual string GetString(const Message& message,
+                           const FieldDescriptor* field) const = 0;
   virtual const EnumValueDescriptor* GetEnum(
-      const FieldDescriptor* field) const = 0;
-  virtual const Message& GetMessage(const FieldDescriptor* field) const = 0;
+      const Message& message, const FieldDescriptor* field) const = 0;
+  virtual const Message& GetMessage(const Message& message,
+                                    const FieldDescriptor* field) const = 0;
 
   // Get a string value without copying, if possible.
   //
@@ -457,98 +478,140 @@ class LIBPROTOBUF_EXPORT Message::Reflection {
   //   a newly-constructed string, though, it's just as fast and more readable
   //   to use code like:
   //     string str = reflection->GetString(field);
-  virtual const string& GetStringReference(const FieldDescriptor* field,
+  virtual const string& GetStringReference(const Message& message,
+                                           const FieldDescriptor* field,
                                            string* scratch) const = 0;
 
 
   // Singular field mutators -----------------------------------------
   // These mutate the value of a non-repeated field.
 
-  virtual void SetInt32 (const FieldDescriptor* field, int32  value) = 0;
-  virtual void SetInt64 (const FieldDescriptor* field, int64  value) = 0;
-  virtual void SetUInt32(const FieldDescriptor* field, uint32 value) = 0;
-  virtual void SetUInt64(const FieldDescriptor* field, uint64 value) = 0;
-  virtual void SetFloat (const FieldDescriptor* field, float  value) = 0;
-  virtual void SetDouble(const FieldDescriptor* field, double value) = 0;
-  virtual void SetBool  (const FieldDescriptor* field, bool   value) = 0;
-  virtual void SetString(const FieldDescriptor* field, const string& value) = 0;
-  virtual void SetEnum  (const FieldDescriptor* field,
-                         const EnumValueDescriptor* value) = 0;
+  virtual void SetInt32 (Message* message,
+                         const FieldDescriptor* field, int32  value) const = 0;
+  virtual void SetInt64 (Message* message,
+                         const FieldDescriptor* field, int64  value) const = 0;
+  virtual void SetUInt32(Message* message,
+                         const FieldDescriptor* field, uint32 value) const = 0;
+  virtual void SetUInt64(Message* message,
+                         const FieldDescriptor* field, uint64 value) const = 0;
+  virtual void SetFloat (Message* message,
+                         const FieldDescriptor* field, float  value) const = 0;
+  virtual void SetDouble(Message* message,
+                         const FieldDescriptor* field, double value) const = 0;
+  virtual void SetBool  (Message* message,
+                         const FieldDescriptor* field, bool   value) const = 0;
+  virtual void SetString(Message* message,
+                         const FieldDescriptor* field,
+                         const string& value) const = 0;
+  virtual void SetEnum  (Message* message,
+                         const FieldDescriptor* field,
+                         const EnumValueDescriptor* value) const = 0;
   // Get a mutable pointer to a field with a message type.
-  virtual Message* MutableMessage(const FieldDescriptor* field) = 0;
+  virtual Message* MutableMessage(Message* message,
+                                  const FieldDescriptor* field) const = 0;
 
 
   // Repeated field getters ------------------------------------------
   // These get the value of one element of a repeated field.
 
-  virtual int32  GetRepeatedInt32 (const FieldDescriptor* field,
+  virtual int32  GetRepeatedInt32 (const Message& message,
+                                   const FieldDescriptor* field,
                                    int index) const = 0;
-  virtual int64  GetRepeatedInt64 (const FieldDescriptor* field,
+  virtual int64  GetRepeatedInt64 (const Message& message,
+                                   const FieldDescriptor* field,
                                    int index) const = 0;
-  virtual uint32 GetRepeatedUInt32(const FieldDescriptor* field,
+  virtual uint32 GetRepeatedUInt32(const Message& message,
+                                   const FieldDescriptor* field,
                                    int index) const = 0;
-  virtual uint64 GetRepeatedUInt64(const FieldDescriptor* field,
+  virtual uint64 GetRepeatedUInt64(const Message& message,
+                                   const FieldDescriptor* field,
                                    int index) const = 0;
-  virtual float  GetRepeatedFloat (const FieldDescriptor* field,
+  virtual float  GetRepeatedFloat (const Message& message,
+                                   const FieldDescriptor* field,
                                    int index) const = 0;
-  virtual double GetRepeatedDouble(const FieldDescriptor* field,
+  virtual double GetRepeatedDouble(const Message& message,
+                                   const FieldDescriptor* field,
                                    int index) const = 0;
-  virtual bool   GetRepeatedBool  (const FieldDescriptor* field,
+  virtual bool   GetRepeatedBool  (const Message& message,
+                                   const FieldDescriptor* field,
                                    int index) const = 0;
-  virtual string GetRepeatedString(const FieldDescriptor* field,
+  virtual string GetRepeatedString(const Message& message,
+                                   const FieldDescriptor* field,
                                    int index) const = 0;
   virtual const EnumValueDescriptor* GetRepeatedEnum(
+      const Message& message,
       const FieldDescriptor* field, int index) const = 0;
   virtual const Message& GetRepeatedMessage(
+      const Message& message,
       const FieldDescriptor* field, int index) const = 0;
 
   // See GetStringReference(), above.
   virtual const string& GetRepeatedStringReference(
-      const FieldDescriptor* field, int index,
-      string* scratch) const = 0;
+      const Message& message, const FieldDescriptor* field,
+      int index, string* scratch) const = 0;
 
 
   // Repeated field mutators -----------------------------------------
   // These mutate the value of one element of a repeated field.
 
-  virtual void SetRepeatedInt32 (const FieldDescriptor* field,
-                                 int index, int32  value) = 0;
-  virtual void SetRepeatedInt64 (const FieldDescriptor* field,
-                                 int index, int64  value) = 0;
-  virtual void SetRepeatedUInt32(const FieldDescriptor* field,
-                                 int index, uint32 value) = 0;
-  virtual void SetRepeatedUInt64(const FieldDescriptor* field,
-                                 int index, uint64 value) = 0;
-  virtual void SetRepeatedFloat (const FieldDescriptor* field,
-                                 int index, float  value) = 0;
-  virtual void SetRepeatedDouble(const FieldDescriptor* field,
-                                 int index, double value) = 0;
-  virtual void SetRepeatedBool  (const FieldDescriptor* field,
-                                 int index, bool   value) = 0;
-  virtual void SetRepeatedString(const FieldDescriptor* field,
-                                 int index, const string& value) = 0;
-  virtual void SetRepeatedEnum(const FieldDescriptor* field,
-                               int index, const EnumValueDescriptor* value) = 0;
+  virtual void SetRepeatedInt32 (Message* message,
+                                 const FieldDescriptor* field,
+                                 int index, int32  value) const = 0;
+  virtual void SetRepeatedInt64 (Message* message,
+                                 const FieldDescriptor* field,
+                                 int index, int64  value) const = 0;
+  virtual void SetRepeatedUInt32(Message* message,
+                                 const FieldDescriptor* field,
+                                 int index, uint32 value) const = 0;
+  virtual void SetRepeatedUInt64(Message* message,
+                                 const FieldDescriptor* field,
+                                 int index, uint64 value) const = 0;
+  virtual void SetRepeatedFloat (Message* message,
+                                 const FieldDescriptor* field,
+                                 int index, float  value) const = 0;
+  virtual void SetRepeatedDouble(Message* message,
+                                 const FieldDescriptor* field,
+                                 int index, double value) const = 0;
+  virtual void SetRepeatedBool  (Message* message,
+                                 const FieldDescriptor* field,
+                                 int index, bool   value) const = 0;
+  virtual void SetRepeatedString(Message* message,
+                                 const FieldDescriptor* field,
+                                 int index, const string& value) const = 0;
+  virtual void SetRepeatedEnum(Message* message,
+                               const FieldDescriptor* field, int index,
+                               const EnumValueDescriptor* value) const = 0;
   // Get a mutable pointer to an element of a repeated field with a message
   // type.
   virtual Message* MutableRepeatedMessage(
-      const FieldDescriptor* field, int index) = 0;
+      Message* message, const FieldDescriptor* field, int index) const = 0;
 
 
   // Repeated field adders -------------------------------------------
   // These add an element to a repeated field.
 
-  virtual void AddInt32 (const FieldDescriptor* field, int32  value) = 0;
-  virtual void AddInt64 (const FieldDescriptor* field, int64  value) = 0;
-  virtual void AddUInt32(const FieldDescriptor* field, uint32 value) = 0;
-  virtual void AddUInt64(const FieldDescriptor* field, uint64 value) = 0;
-  virtual void AddFloat (const FieldDescriptor* field, float  value) = 0;
-  virtual void AddDouble(const FieldDescriptor* field, double value) = 0;
-  virtual void AddBool  (const FieldDescriptor* field, bool   value) = 0;
-  virtual void AddString(const FieldDescriptor* field, const string& value) = 0;
-  virtual void AddEnum  (const FieldDescriptor* field,
-                         const EnumValueDescriptor* value) = 0;
-  virtual Message* AddMessage(const FieldDescriptor* field) = 0;
+  virtual void AddInt32 (Message* message,
+                         const FieldDescriptor* field, int32  value) const = 0;
+  virtual void AddInt64 (Message* message,
+                         const FieldDescriptor* field, int64  value) const = 0;
+  virtual void AddUInt32(Message* message,
+                         const FieldDescriptor* field, uint32 value) const = 0;
+  virtual void AddUInt64(Message* message,
+                         const FieldDescriptor* field, uint64 value) const = 0;
+  virtual void AddFloat (Message* message,
+                         const FieldDescriptor* field, float  value) const = 0;
+  virtual void AddDouble(Message* message,
+                         const FieldDescriptor* field, double value) const = 0;
+  virtual void AddBool  (Message* message,
+                         const FieldDescriptor* field, bool   value) const = 0;
+  virtual void AddString(Message* message,
+                         const FieldDescriptor* field,
+                         const string& value) const = 0;
+  virtual void AddEnum  (Message* message,
+                         const FieldDescriptor* field,
+                         const EnumValueDescriptor* value) const = 0;
+  virtual Message* AddMessage(Message* message,
+                              const FieldDescriptor* field) const = 0;
 
 
   // Extensions ------------------------------------------------------
diff --git a/src/google/protobuf/reflection_ops.cc b/src/google/protobuf/reflection_ops.cc
index 2b263298c7675ff6927184cb547ed55bd62699b9..9e12658da3d0c4473cd22f51767f61617615cb04 100644
--- a/src/google/protobuf/reflection_ops.cc
+++ b/src/google/protobuf/reflection_ops.cc
@@ -27,31 +27,35 @@ namespace google {
 namespace protobuf {
 namespace internal {
 
-void ReflectionOps::Copy(const Descriptor* descriptor,
-                         const Message::Reflection& from,
-                         Message::Reflection* to) {
+void ReflectionOps::Copy(const Message& from, Message* to) {
   if (&from == to) return;
-  Clear(descriptor, to);
-  Merge(descriptor, from, to);
+  Clear(to);
+  Merge(from, to);
 }
 
-void ReflectionOps::Merge(const Descriptor* descriptor,
-                          const Message::Reflection& from,
-                          Message::Reflection* to) {
+void ReflectionOps::Merge(const Message& from, Message* to) {
   GOOGLE_CHECK_NE(&from, to);
+
+  const Descriptor* descriptor = from.GetDescriptor();
+  GOOGLE_CHECK_EQ(to->GetDescriptor(), descriptor)
+    << "Tried to merge messages of different types.";
+
+  const Reflection* from_reflection = from.GetReflection();
+  const Reflection* to_reflection = to->GetReflection();
+
   vector<const FieldDescriptor*> fields;
-  from.ListFields(&fields);
+  from_reflection->ListFields(from, &fields);
   for (int i = 0; i < fields.size(); i++) {
     const FieldDescriptor* field = fields[i];
 
     if (field->is_repeated()) {
-      int count = from.FieldSize(field);
+      int count = from_reflection->FieldSize(from, field);
       for (int j = 0; j < count; j++) {
         switch (field->cpp_type()) {
 #define HANDLE_TYPE(CPPTYPE, METHOD)                                     \
           case FieldDescriptor::CPPTYPE_##CPPTYPE:                       \
-            to->Add##METHOD(field,                                       \
-              from.GetRepeated##METHOD(field, j));                       \
+            to_reflection->Add##METHOD(to, field,                        \
+              from_reflection->GetRepeated##METHOD(from, field, j));     \
             break;
 
           HANDLE_TYPE(INT32 , Int32 );
@@ -66,16 +70,17 @@ void ReflectionOps::Merge(const Descriptor* descriptor,
 #undef HANDLE_TYPE
 
           case FieldDescriptor::CPPTYPE_MESSAGE:
-            to->AddMessage(field)->MergeFrom(
-              from.GetRepeatedMessage(field, j));
+            to_reflection->AddMessage(to, field)->MergeFrom(
+              from_reflection->GetRepeatedMessage(from, field, j));
             break;
         }
       }
-    } else if (from.HasField(field)) {
+    } else {
       switch (field->cpp_type()) {
 #define HANDLE_TYPE(CPPTYPE, METHOD)                                        \
         case FieldDescriptor::CPPTYPE_##CPPTYPE:                            \
-          to->Set##METHOD(field, from.Get##METHOD(field));                  \
+          to_reflection->Set##METHOD(to, field,                             \
+            from_reflection->Get##METHOD(from, field));                     \
           break;
 
         HANDLE_TYPE(INT32 , Int32 );
@@ -90,33 +95,37 @@ void ReflectionOps::Merge(const Descriptor* descriptor,
 #undef HANDLE_TYPE
 
         case FieldDescriptor::CPPTYPE_MESSAGE:
-          to->MutableMessage(field)->MergeFrom(
-            from.GetMessage(field));
+          to_reflection->MutableMessage(to, field)->MergeFrom(
+            from_reflection->GetMessage(from, field));
           break;
       }
     }
   }
 
-  to->MutableUnknownFields()->MergeFrom(from.GetUnknownFields());
+  to_reflection->MutableUnknownFields(to)->MergeFrom(
+    from_reflection->GetUnknownFields(from));
 }
 
-void ReflectionOps::Clear(const Descriptor* descriptor,
-                          Message::Reflection* reflection) {
+void ReflectionOps::Clear(Message* message) {
+  const Reflection* reflection = message->GetReflection();
+
   vector<const FieldDescriptor*> fields;
-  reflection->ListFields(&fields);
+  reflection->ListFields(*message, &fields);
   for (int i = 0; i < fields.size(); i++) {
-    reflection->ClearField(fields[i]);
+    reflection->ClearField(message, fields[i]);
   }
 
-  reflection->MutableUnknownFields()->Clear();
+  reflection->MutableUnknownFields(message)->Clear();
 }
 
-bool ReflectionOps::IsInitialized(const Descriptor* descriptor,
-                                  const Message::Reflection& reflection) {
+bool ReflectionOps::IsInitialized(const Message& message) {
+  const Descriptor* descriptor = message.GetDescriptor();
+  const Reflection* reflection = message.GetReflection();
+
   // Check required fields of this message.
   for (int i = 0; i < descriptor->field_count(); i++) {
     if (descriptor->field(i)->is_required()) {
-      if (!reflection.HasField(descriptor->field(i))) {
+      if (!reflection->HasField(message, descriptor->field(i))) {
         return false;
       }
     }
@@ -124,21 +133,21 @@ bool ReflectionOps::IsInitialized(const Descriptor* descriptor,
 
   // Check that sub-messages are initialized.
   vector<const FieldDescriptor*> fields;
-  reflection.ListFields(&fields);
+  reflection->ListFields(message, &fields);
   for (int i = 0; i < fields.size(); i++) {
     const FieldDescriptor* field = fields[i];
     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
       if (field->is_repeated()) {
-        int size = reflection.FieldSize(field);
+        int size = reflection->FieldSize(message, field);
 
         for (int i = 0; i < size; i++) {
-          if (!reflection.GetRepeatedMessage(field, i).IsInitialized()) {
+          if (!reflection->GetRepeatedMessage(message, field, i)
+                          .IsInitialized()) {
             return false;
           }
         }
       } else {
-        if (reflection.HasField(field) &&
-            !reflection.GetMessage(field).IsInitialized()) {
+        if (!reflection->GetMessage(message, field).IsInitialized()) {
           return false;
         }
       }
@@ -148,25 +157,24 @@ bool ReflectionOps::IsInitialized(const Descriptor* descriptor,
   return true;
 }
 
-void ReflectionOps::DiscardUnknownFields(
-    const Descriptor* descriptor,
-    Message::Reflection* reflection) {
-  reflection->MutableUnknownFields()->Clear();
+void ReflectionOps::DiscardUnknownFields(Message* message) {
+  const Reflection* reflection = message->GetReflection();
+
+  reflection->MutableUnknownFields(message)->Clear();
 
   vector<const FieldDescriptor*> fields;
-  reflection->ListFields(&fields);
+  reflection->ListFields(*message, &fields);
   for (int i = 0; i < fields.size(); i++) {
     const FieldDescriptor* field = fields[i];
     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
       if (field->is_repeated()) {
-        int size = reflection->FieldSize(field);
+        int size = reflection->FieldSize(*message, field);
         for (int i = 0; i < size; i++) {
-          reflection->MutableRepeatedMessage(field, i)->DiscardUnknownFields();
+          reflection->MutableRepeatedMessage(message, field, i)
+                    ->DiscardUnknownFields();
         }
       } else {
-        if (reflection->HasField(field)) {
-          reflection->MutableMessage(field)->DiscardUnknownFields();
-        }
+        reflection->MutableMessage(message, field)->DiscardUnknownFields();
       }
     }
   }
@@ -193,14 +201,16 @@ static string SubMessagePrefix(const string& prefix,
 }
 
 void ReflectionOps::FindInitializationErrors(
-    const Descriptor* descriptor,
-    const Message::Reflection& reflection,
+    const Message& message,
     const string& prefix,
     vector<string>* errors) {
+  const Descriptor* descriptor = message.GetDescriptor();
+  const Reflection* reflection = message.GetReflection();
+
   // Check required fields of this message.
   for (int i = 0; i < descriptor->field_count(); i++) {
     if (descriptor->field(i)->is_required()) {
-      if (!reflection.HasField(descriptor->field(i))) {
+      if (!reflection->HasField(message, descriptor->field(i))) {
         errors->push_back(prefix + descriptor->field(i)->name());
       }
     }
@@ -208,29 +218,26 @@ void ReflectionOps::FindInitializationErrors(
 
   // Check sub-messages.
   vector<const FieldDescriptor*> fields;
-  reflection.ListFields(&fields);
+  reflection->ListFields(message, &fields);
   for (int i = 0; i < fields.size(); i++) {
     const FieldDescriptor* field = fields[i];
     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
 
       if (field->is_repeated()) {
-        int size = reflection.FieldSize(field);
+        int size = reflection->FieldSize(message, field);
 
         for (int i = 0; i < size; i++) {
-          const Message& sub_message = reflection.GetRepeatedMessage(field, i);
-          FindInitializationErrors(field->message_type(),
-                                   *sub_message.GetReflection(),
+          const Message& sub_message =
+            reflection->GetRepeatedMessage(message, field, i);
+          FindInitializationErrors(sub_message,
                                    SubMessagePrefix(prefix, field, i),
                                    errors);
         }
       } else {
-        if (reflection.HasField(field)) {
-          const Message& sub_message = reflection.GetMessage(field);
-          FindInitializationErrors(field->message_type(),
-                                   *sub_message.GetReflection(),
-                                   SubMessagePrefix(prefix, field, -1),
-                                   errors);
-        }
+        const Message& sub_message = reflection->GetMessage(message, field);
+        FindInitializationErrors(sub_message,
+                                 SubMessagePrefix(prefix, field, -1),
+                                 errors);
       }
     }
   }
diff --git a/src/google/protobuf/reflection_ops.h b/src/google/protobuf/reflection_ops.h
index 4a7f76bbe9cfa3d52410130d59cafcb95d0d7c26..b6922a6333489c8ef6da5974d8fb65d6c85b8b26 100644
--- a/src/google/protobuf/reflection_ops.h
+++ b/src/google/protobuf/reflection_ops.h
@@ -30,7 +30,7 @@ namespace google {
 namespace protobuf {
 namespace internal {
 
-// Basic operations that can be performed using Message::Reflection.
+// Basic operations that can be performed using reflection.
 // These can be used as a cheap way to implement the corresponding
 // methods of the Message interface, though they are likely to be
 // slower than implementations tailored for the specific message type.
@@ -41,24 +41,16 @@ namespace internal {
 // This class is really a namespace that contains only static methods.
 class LIBPROTOBUF_EXPORT ReflectionOps {
  public:
-  static void Copy(const Descriptor* descriptor,
-                   const Message::Reflection& from,
-                   Message::Reflection* to);
-  static void Merge(const Descriptor* descriptor,
-                    const Message::Reflection& from,
-                    Message::Reflection* to);
-  static void Clear(const Descriptor* descriptor,
-                    Message::Reflection* reflection);
-  static bool IsInitialized(const Descriptor* descriptor,
-                            const Message::Reflection& reflection);
-  static void DiscardUnknownFields(const Descriptor* descriptor,
-                                   Message::Reflection* reflection);
+  static void Copy(const Message& from, Message* to);
+  static void Merge(const Message& from, Message* to);
+  static void Clear(Message* message);
+  static bool IsInitialized(const Message& message);
+  static void DiscardUnknownFields(Message* message);
 
   // Finds all unset required fields in the message and adds their full
   // paths (e.g. "foo.bar[5].baz") to *names.  "prefix" will be attached to
   // the front of each name.
-  static void FindInitializationErrors(const Descriptor* descriptor,
-                                       const Message::Reflection& reflection,
+  static void FindInitializationErrors(const Message& message,
                                        const string& prefix,
                                        vector<string>* errors);
 
diff --git a/src/google/protobuf/reflection_ops_unittest.cc b/src/google/protobuf/reflection_ops_unittest.cc
index e1af2fcab3dd02ea7fe5b72bcced96eddba1a22a..ab587331cf7e4354db36e4eadf9da6b7b4f10cd7 100644
--- a/src/google/protobuf/reflection_ops_unittest.cc
+++ b/src/google/protobuf/reflection_ops_unittest.cc
@@ -45,14 +45,12 @@ TEST(ReflectionOpsTest, Copy) {
 
   TestUtil::SetAllFields(&message);
 
-  ReflectionOps::Copy(message.descriptor(), *message.GetReflection(),
-                      message2.GetReflection());
+  ReflectionOps::Copy(message, &message2);
 
   TestUtil::ExpectAllFieldsSet(message2);
 
   // Copying from self should be a no-op.
-  ReflectionOps::Copy(message2.descriptor(), *message2.GetReflection(),
-                      message2.GetReflection());
+  ReflectionOps::Copy(message2, &message2);
   TestUtil::ExpectAllFieldsSet(message2);
 }
 
@@ -61,8 +59,7 @@ TEST(ReflectionOpsTest, CopyExtensions) {
 
   TestUtil::SetAllExtensions(&message);
 
-  ReflectionOps::Copy(message.descriptor(), *message.GetReflection(),
-                      message2.GetReflection());
+  ReflectionOps::Copy(message, &message2);
 
   TestUtil::ExpectAllExtensionsSet(message2);
 }
@@ -89,8 +86,7 @@ TEST(ReflectionOpsTest, Merge) {
   message.clear_repeated_int32();
   message.add_repeated_int32(i);
 
-  ReflectionOps::Merge(message2.descriptor(), *message2.GetReflection(),
-                       message.GetReflection());
+  ReflectionOps::Merge(message2, &message);
 
   TestUtil::ExpectAllFieldsSet(message);
 }
@@ -120,8 +116,7 @@ TEST(ReflectionOpsTest, MergeExtensions) {
   message.ClearExtension(unittest::repeated_int32_extension);
   message.AddExtension(unittest::repeated_int32_extension, i);
 
-  ReflectionOps::Merge(message2.descriptor(), *message2.GetReflection(),
-                       message.GetReflection());
+  ReflectionOps::Merge(message2, &message);
 
   TestUtil::ExpectAllExtensionsSet(message);
 }
@@ -132,9 +127,7 @@ TEST(ReflectionOpsTest, MergeUnknown) {
   message1.mutable_unknown_fields()->AddField(1234)->add_varint(1);
   message2.mutable_unknown_fields()->AddField(1234)->add_varint(2);
 
-  ReflectionOps::Merge(unittest::TestEmptyMessage::descriptor(),
-                       *message2.GetReflection(),
-                       message1.GetReflection());
+  ReflectionOps::Merge(message2, &message1);
 
   ASSERT_EQ(1, message1.unknown_fields().field_count());
   const UnknownField& field = message1.unknown_fields().field(0);
@@ -152,8 +145,7 @@ TEST(ReflectionOpsTest, MergeFromSelf) {
   unittest::TestAllTypes message;
 
   EXPECT_DEATH(
-    ReflectionOps::Merge(message.descriptor(), *message.GetReflection(),
-                         message.GetReflection()),
+    ReflectionOps::Merge(message, &message),
     "&from");
 }
 
@@ -164,7 +156,7 @@ TEST(ReflectionOpsTest, Clear) {
 
   TestUtil::SetAllFields(&message);
 
-  ReflectionOps::Clear(message.descriptor(), message.GetReflection());
+  ReflectionOps::Clear(&message);
 
   TestUtil::ExpectClear(message);
 
@@ -185,7 +177,7 @@ TEST(ReflectionOpsTest, ClearExtensions) {
 
   TestUtil::SetAllExtensions(&message);
 
-  ReflectionOps::Clear(message.descriptor(), message.GetReflection());
+  ReflectionOps::Clear(&message);
 
   TestUtil::ExpectExtensionsClear(message);
 
@@ -207,7 +199,7 @@ TEST(ReflectionOpsTest, ClearUnknown) {
   unittest::TestEmptyMessage message;
   message.mutable_unknown_fields()->AddField(1234)->add_varint(1);
 
-  ReflectionOps::Clear(message.descriptor(), message.GetReflection());
+  ReflectionOps::Clear(&message);
 
   EXPECT_EQ(0, message.unknown_fields().field_count());
 }
@@ -236,8 +228,7 @@ TEST(ReflectionOpsTest, DiscardUnknownFields) {
                       .unknown_fields().field_count());
 
   // Discard them.
-  ReflectionOps::DiscardUnknownFields(message.GetDescriptor(),
-                                      message.GetReflection());
+  ReflectionOps::DiscardUnknownFields(&message);
   TestUtil::ExpectAllFieldsSet(message);
 
   EXPECT_EQ(0, message.unknown_fields().field_count());
@@ -273,8 +264,7 @@ TEST(ReflectionOpsTest, DiscardUnknownExtensions) {
            .unknown_fields().field_count());
 
   // Discard them.
-  ReflectionOps::DiscardUnknownFields(message.GetDescriptor(),
-                                      message.GetReflection());
+  ReflectionOps::DiscardUnknownFields(&message);
   TestUtil::ExpectAllExtensionsSet(message);
 
   EXPECT_EQ(0, message.unknown_fields().field_count());
@@ -289,17 +279,13 @@ TEST(ReflectionOpsTest, DiscardUnknownExtensions) {
 TEST(ReflectionOpsTest, IsInitialized) {
   unittest::TestRequired message;
 
-  EXPECT_FALSE(ReflectionOps::IsInitialized(message.descriptor(),
-                                            *message.GetReflection()));
+  EXPECT_FALSE(ReflectionOps::IsInitialized(message));
   message.set_a(1);
-  EXPECT_FALSE(ReflectionOps::IsInitialized(message.descriptor(),
-                                            *message.GetReflection()));
+  EXPECT_FALSE(ReflectionOps::IsInitialized(message));
   message.set_b(2);
-  EXPECT_FALSE(ReflectionOps::IsInitialized(message.descriptor(),
-                                            *message.GetReflection()));
+  EXPECT_FALSE(ReflectionOps::IsInitialized(message));
   message.set_c(3);
-  EXPECT_TRUE(ReflectionOps::IsInitialized(message.descriptor(),
-                                           *message.GetReflection()));
+  EXPECT_TRUE(ReflectionOps::IsInitialized(message));
 }
 
 TEST(ReflectionOpsTest, ForeignIsInitialized) {
@@ -307,32 +293,27 @@ TEST(ReflectionOpsTest, ForeignIsInitialized) {
 
   // Starts out initialized because the foreign message is itself an optional
   // field.
-  EXPECT_TRUE(ReflectionOps::IsInitialized(message.descriptor(),
-                                           *message.GetReflection()));
+  EXPECT_TRUE(ReflectionOps::IsInitialized(message));
 
   // Once we create that field, the message is no longer initialized.
   message.mutable_optional_message();
-  EXPECT_FALSE(ReflectionOps::IsInitialized(message.descriptor(),
-                                            *message.GetReflection()));
+  EXPECT_FALSE(ReflectionOps::IsInitialized(message));
 
   // Initialize it.  Now we're initialized.
   message.mutable_optional_message()->set_a(1);
   message.mutable_optional_message()->set_b(2);
   message.mutable_optional_message()->set_c(3);
-  EXPECT_TRUE(ReflectionOps::IsInitialized(message.descriptor(),
-                                           *message.GetReflection()));
+  EXPECT_TRUE(ReflectionOps::IsInitialized(message));
 
   // Add a repeated version of the message.  No longer initialized.
   unittest::TestRequired* sub_message = message.add_repeated_message();
-  EXPECT_FALSE(ReflectionOps::IsInitialized(message.descriptor(),
-                                            *message.GetReflection()));
+  EXPECT_FALSE(ReflectionOps::IsInitialized(message));
 
   // Initialize that repeated version.
   sub_message->set_a(1);
   sub_message->set_b(2);
   sub_message->set_c(3);
-  EXPECT_TRUE(ReflectionOps::IsInitialized(message.descriptor(),
-                                           *message.GetReflection()));
+  EXPECT_TRUE(ReflectionOps::IsInitialized(message));
 }
 
 TEST(ReflectionOpsTest, ExtensionIsInitialized) {
@@ -340,39 +321,32 @@ TEST(ReflectionOpsTest, ExtensionIsInitialized) {
 
   // Starts out initialized because the foreign message is itself an optional
   // field.
-  EXPECT_TRUE(ReflectionOps::IsInitialized(message.descriptor(),
-                                           *message.GetReflection()));
+  EXPECT_TRUE(ReflectionOps::IsInitialized(message));
 
   // Once we create that field, the message is no longer initialized.
   message.MutableExtension(unittest::TestRequired::single);
-  EXPECT_FALSE(ReflectionOps::IsInitialized(message.descriptor(),
-                                            *message.GetReflection()));
+  EXPECT_FALSE(ReflectionOps::IsInitialized(message));
 
   // Initialize it.  Now we're initialized.
   message.MutableExtension(unittest::TestRequired::single)->set_a(1);
   message.MutableExtension(unittest::TestRequired::single)->set_b(2);
   message.MutableExtension(unittest::TestRequired::single)->set_c(3);
-  EXPECT_TRUE(ReflectionOps::IsInitialized(message.descriptor(),
-                                           *message.GetReflection()));
+  EXPECT_TRUE(ReflectionOps::IsInitialized(message));
 
   // Add a repeated version of the message.  No longer initialized.
   message.AddExtension(unittest::TestRequired::multi);
-  EXPECT_FALSE(ReflectionOps::IsInitialized(message.descriptor(),
-                                            *message.GetReflection()));
+  EXPECT_FALSE(ReflectionOps::IsInitialized(message));
 
   // Initialize that repeated version.
   message.MutableExtension(unittest::TestRequired::multi, 0)->set_a(1);
   message.MutableExtension(unittest::TestRequired::multi, 0)->set_b(2);
   message.MutableExtension(unittest::TestRequired::multi, 0)->set_c(3);
-  EXPECT_TRUE(ReflectionOps::IsInitialized(message.descriptor(),
-                                           *message.GetReflection()));
+  EXPECT_TRUE(ReflectionOps::IsInitialized(message));
 }
 
 static string FindInitializationErrors(const Message& message) {
   vector<string> errors;
-  ReflectionOps::FindInitializationErrors(message.GetDescriptor(),
-                                          *message.GetReflection(),
-                                          "", &errors);
+  ReflectionOps::FindInitializationErrors(message, "", &errors);
   return JoinStrings(errors, ",");
 }
 
diff --git a/src/google/protobuf/service.h b/src/google/protobuf/service.h
index f3e78e7b476d80f12245d68bbfd1bb0ff5b816d1..22edf69400c28b70edb5d04eadddbb9b8e43f986 100644
--- a/src/google/protobuf/service.h
+++ b/src/google/protobuf/service.h
@@ -103,7 +103,7 @@ class Message;               // message.h
 // themselves are abstract interfaces (implemented either by servers or as
 // stubs), but they subclass this base interface.  The methods of this
 // interface can be used to call the methods of the Service without knowing
-// its exact type at compile time (analogous to Message::Reflection).
+// its exact type at compile time (analogous to Reflection).
 class LIBPROTOBUF_EXPORT Service {
  public:
   inline Service() {}
diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h
index f0d55b534f07a5a639d63e8e5a34d824a0441631..89070d638b520c14cfa35c746e742663ff045614 100644
--- a/src/google/protobuf/stubs/common.h
+++ b/src/google/protobuf/stubs/common.h
@@ -69,20 +69,20 @@ namespace internal {
 
 // The minimum library version which works with the current version of the
 // headers.
-#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 2000000
+#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 2000001
 
 // The minimum header version which works with the current version of
 // the library.  This constant should only be used by protoc's C++ code
 // generator.
-static const int kMinHeaderVersionForLibrary = 2000000;
+static const int kMinHeaderVersionForLibrary = 2000001;
 
 // The minimum protoc version which works with the current version of the
 // headers.
-#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 2000000
+#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 2000001
 
 // The minimum header version which works with the current version of
 // protoc.  This constant should only be used in VerifyVersion().
-static const int kMinHeaderVersionForProtoc = 2000000;
+static const int kMinHeaderVersionForProtoc = 2000001;
 
 // Verifies that the headers and libraries are compatible.  Use the macro
 // below to call this.
diff --git a/src/google/protobuf/test_util.cc b/src/google/protobuf/test_util.cc
index 1525e94f1ef5abe7a4103fec7a5f967a90fa9286..59d98736c1e53a6726214486aaa17dd48dcef47c 100644
--- a/src/google/protobuf/test_util.cc
+++ b/src/google/protobuf/test_util.cc
@@ -58,9 +58,11 @@ void TestUtil::SetAllFields(unittest::TestAllTypes* message) {
   // StringPiece and Cord fields are only accessible via reflection in the
   // open source release; see comments in compiler/cpp/string_field.cc.
   message->GetReflection()->SetString(
+    message,
     message->GetDescriptor()->FindFieldByName("optional_string_piece"),
     "124");
   message->GetReflection()->SetString(
+    message,
     message->GetDescriptor()->FindFieldByName("optional_cord"),
     "125");
 
@@ -92,9 +94,11 @@ void TestUtil::SetAllFields(unittest::TestAllTypes* message) {
   message->add_repeated_import_enum (unittest_import::IMPORT_BAR);
 
   message->GetReflection()->AddString(
+    message,
     message->GetDescriptor()->FindFieldByName("repeated_string_piece"),
     "224");
   message->GetReflection()->AddString(
+    message,
     message->GetDescriptor()->FindFieldByName("repeated_cord"),
     "225");
 
@@ -125,9 +129,11 @@ void TestUtil::SetAllFields(unittest::TestAllTypes* message) {
   message->add_repeated_import_enum (unittest_import::IMPORT_BAZ);
 
   message->GetReflection()->AddString(
+    message,
     message->GetDescriptor()->FindFieldByName("repeated_string_piece"),
     "324");
   message->GetReflection()->AddString(
+    message,
     message->GetDescriptor()->FindFieldByName("repeated_cord"),
     "325");
 
@@ -154,9 +160,11 @@ void TestUtil::SetAllFields(unittest::TestAllTypes* message) {
   message->set_default_import_enum (unittest_import::IMPORT_FOO);
 
   message->GetReflection()->SetString(
+    message,
     message->GetDescriptor()->FindFieldByName("default_string_piece"),
     "424");
   message->GetReflection()->SetString(
+    message,
     message->GetDescriptor()->FindFieldByName("default_cord"),
     "425");
 }
@@ -190,9 +198,11 @@ void TestUtil::ModifyRepeatedFields(unittest::TestAllTypes* message) {
   message->set_repeated_import_enum (1, unittest_import::IMPORT_FOO);
 
   message->GetReflection()->SetRepeatedString(
+    message,
     message->GetDescriptor()->FindFieldByName("repeated_string_piece"),
     1, "424");
   message->GetReflection()->SetRepeatedString(
+    message,
     message->GetDescriptor()->FindFieldByName("repeated_cord"),
     1, "425");
 }
@@ -1322,590 +1332,588 @@ const FieldDescriptor* TestUtil::ReflectionTester::F(const string& name) {
 
 // -------------------------------------------------------------------
 
-void TestUtil::ReflectionTester::SetAllFieldsViaReflection(
-    Message::Reflection* message) {
-  message->SetInt32 (F("optional_int32"   ), 101);
-  message->SetInt64 (F("optional_int64"   ), 102);
-  message->SetUInt32(F("optional_uint32"  ), 103);
-  message->SetUInt64(F("optional_uint64"  ), 104);
-  message->SetInt32 (F("optional_sint32"  ), 105);
-  message->SetInt64 (F("optional_sint64"  ), 106);
-  message->SetUInt32(F("optional_fixed32" ), 107);
-  message->SetUInt64(F("optional_fixed64" ), 108);
-  message->SetInt32 (F("optional_sfixed32"), 109);
-  message->SetInt64 (F("optional_sfixed64"), 110);
-  message->SetFloat (F("optional_float"   ), 111);
-  message->SetDouble(F("optional_double"  ), 112);
-  message->SetBool  (F("optional_bool"    ), true);
-  message->SetString(F("optional_string"  ), "115");
-  message->SetString(F("optional_bytes"   ), "116");
-
-  message->MutableMessage(F("optionalgroup"))
-         ->GetReflection()->SetInt32(group_a_, 117);
-  message->MutableMessage(F("optional_nested_message"))
-         ->GetReflection()->SetInt32(nested_b_, 118);
-  message->MutableMessage(F("optional_foreign_message"))
-         ->GetReflection()->SetInt32(foreign_c_, 119);
-  message->MutableMessage(F("optional_import_message"))
-         ->GetReflection()->SetInt32(import_d_, 120);
-
-  message->SetEnum(F("optional_nested_enum" ),  nested_baz_);
-  message->SetEnum(F("optional_foreign_enum"), foreign_baz_);
-  message->SetEnum(F("optional_import_enum" ),  import_baz_);
-
-  message->SetString(F("optional_string_piece"), "124");
-  message->SetString(F("optional_cord"), "125");
+void TestUtil::ReflectionTester::SetAllFieldsViaReflection(Message* message) {
+  const Reflection* reflection = message->GetReflection();
+  Message* sub_message;
+
+  reflection->SetInt32 (message, F("optional_int32"   ), 101);
+  reflection->SetInt64 (message, F("optional_int64"   ), 102);
+  reflection->SetUInt32(message, F("optional_uint32"  ), 103);
+  reflection->SetUInt64(message, F("optional_uint64"  ), 104);
+  reflection->SetInt32 (message, F("optional_sint32"  ), 105);
+  reflection->SetInt64 (message, F("optional_sint64"  ), 106);
+  reflection->SetUInt32(message, F("optional_fixed32" ), 107);
+  reflection->SetUInt64(message, F("optional_fixed64" ), 108);
+  reflection->SetInt32 (message, F("optional_sfixed32"), 109);
+  reflection->SetInt64 (message, F("optional_sfixed64"), 110);
+  reflection->SetFloat (message, F("optional_float"   ), 111);
+  reflection->SetDouble(message, F("optional_double"  ), 112);
+  reflection->SetBool  (message, F("optional_bool"    ), true);
+  reflection->SetString(message, F("optional_string"  ), "115");
+  reflection->SetString(message, F("optional_bytes"   ), "116");
+
+  sub_message = reflection->MutableMessage(message, F("optionalgroup"));
+  sub_message->GetReflection()->SetInt32(sub_message, group_a_, 117);
+  sub_message = reflection->MutableMessage(message, F("optional_nested_message"));
+  sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 118);
+  sub_message = reflection->MutableMessage(message, F("optional_foreign_message"));
+  sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 119);
+  sub_message = reflection->MutableMessage(message, F("optional_import_message"));
+  sub_message->GetReflection()->SetInt32(sub_message, import_d_, 120);
+
+  reflection->SetEnum(message, F("optional_nested_enum" ),  nested_baz_);
+  reflection->SetEnum(message, F("optional_foreign_enum"), foreign_baz_);
+  reflection->SetEnum(message, F("optional_import_enum" ),  import_baz_);
+
+  reflection->SetString(message, F("optional_string_piece"), "124");
+  reflection->SetString(message, F("optional_cord"), "125");
 
   // -----------------------------------------------------------------
 
-  message->AddInt32 (F("repeated_int32"   ), 201);
-  message->AddInt64 (F("repeated_int64"   ), 202);
-  message->AddUInt32(F("repeated_uint32"  ), 203);
-  message->AddUInt64(F("repeated_uint64"  ), 204);
-  message->AddInt32 (F("repeated_sint32"  ), 205);
-  message->AddInt64 (F("repeated_sint64"  ), 206);
-  message->AddUInt32(F("repeated_fixed32" ), 207);
-  message->AddUInt64(F("repeated_fixed64" ), 208);
-  message->AddInt32 (F("repeated_sfixed32"), 209);
-  message->AddInt64 (F("repeated_sfixed64"), 210);
-  message->AddFloat (F("repeated_float"   ), 211);
-  message->AddDouble(F("repeated_double"  ), 212);
-  message->AddBool  (F("repeated_bool"    ), true);
-  message->AddString(F("repeated_string"  ), "215");
-  message->AddString(F("repeated_bytes"   ), "216");
-
-  message->AddMessage(F("repeatedgroup"))
-         ->GetReflection()->SetInt32(repeated_group_a_, 217);
-  message->AddMessage(F("repeated_nested_message"))
-         ->GetReflection()->SetInt32(nested_b_, 218);
-  message->AddMessage(F("repeated_foreign_message"))
-         ->GetReflection()->SetInt32(foreign_c_, 219);
-  message->AddMessage(F("repeated_import_message"))
-         ->GetReflection()->SetInt32(import_d_, 220);
-
-  message->AddEnum(F("repeated_nested_enum" ),  nested_bar_);
-  message->AddEnum(F("repeated_foreign_enum"), foreign_bar_);
-  message->AddEnum(F("repeated_import_enum" ),  import_bar_);
-
-  message->AddString(F("repeated_string_piece"), "224");
-  message->AddString(F("repeated_cord"), "225");
+  reflection->AddInt32 (message, F("repeated_int32"   ), 201);
+  reflection->AddInt64 (message, F("repeated_int64"   ), 202);
+  reflection->AddUInt32(message, F("repeated_uint32"  ), 203);
+  reflection->AddUInt64(message, F("repeated_uint64"  ), 204);
+  reflection->AddInt32 (message, F("repeated_sint32"  ), 205);
+  reflection->AddInt64 (message, F("repeated_sint64"  ), 206);
+  reflection->AddUInt32(message, F("repeated_fixed32" ), 207);
+  reflection->AddUInt64(message, F("repeated_fixed64" ), 208);
+  reflection->AddInt32 (message, F("repeated_sfixed32"), 209);
+  reflection->AddInt64 (message, F("repeated_sfixed64"), 210);
+  reflection->AddFloat (message, F("repeated_float"   ), 211);
+  reflection->AddDouble(message, F("repeated_double"  ), 212);
+  reflection->AddBool  (message, F("repeated_bool"    ), true);
+  reflection->AddString(message, F("repeated_string"  ), "215");
+  reflection->AddString(message, F("repeated_bytes"   ), "216");
+
+  sub_message = reflection->AddMessage(message, F("repeatedgroup"));
+  sub_message->GetReflection()->SetInt32(sub_message, repeated_group_a_, 217);
+  sub_message = reflection->AddMessage(message, F("repeated_nested_message"));
+  sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 218);
+  sub_message = reflection->AddMessage(message, F("repeated_foreign_message"));
+  sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 219);
+  sub_message = reflection->AddMessage(message, F("repeated_import_message"));
+  sub_message->GetReflection()->SetInt32(sub_message, import_d_, 220);
+
+  reflection->AddEnum(message, F("repeated_nested_enum" ),  nested_bar_);
+  reflection->AddEnum(message, F("repeated_foreign_enum"), foreign_bar_);
+  reflection->AddEnum(message, F("repeated_import_enum" ),  import_bar_);
+
+  reflection->AddString(message, F("repeated_string_piece"), "224");
+  reflection->AddString(message, F("repeated_cord"), "225");
 
   // Add a second one of each field.
-  message->AddInt32 (F("repeated_int32"   ), 301);
-  message->AddInt64 (F("repeated_int64"   ), 302);
-  message->AddUInt32(F("repeated_uint32"  ), 303);
-  message->AddUInt64(F("repeated_uint64"  ), 304);
-  message->AddInt32 (F("repeated_sint32"  ), 305);
-  message->AddInt64 (F("repeated_sint64"  ), 306);
-  message->AddUInt32(F("repeated_fixed32" ), 307);
-  message->AddUInt64(F("repeated_fixed64" ), 308);
-  message->AddInt32 (F("repeated_sfixed32"), 309);
-  message->AddInt64 (F("repeated_sfixed64"), 310);
-  message->AddFloat (F("repeated_float"   ), 311);
-  message->AddDouble(F("repeated_double"  ), 312);
-  message->AddBool  (F("repeated_bool"    ), false);
-  message->AddString(F("repeated_string"  ), "315");
-  message->AddString(F("repeated_bytes"   ), "316");
-
-  message->AddMessage(F("repeatedgroup"))
-         ->GetReflection()->SetInt32(repeated_group_a_, 317);
-  message->AddMessage(F("repeated_nested_message"))
-         ->GetReflection()->SetInt32(nested_b_, 318);
-  message->AddMessage(F("repeated_foreign_message"))
-         ->GetReflection()->SetInt32(foreign_c_, 319);
-  message->AddMessage(F("repeated_import_message"))
-         ->GetReflection()->SetInt32(import_d_, 320);
-
-  message->AddEnum(F("repeated_nested_enum" ),  nested_baz_);
-  message->AddEnum(F("repeated_foreign_enum"), foreign_baz_);
-  message->AddEnum(F("repeated_import_enum" ),  import_baz_);
-
-  message->AddString(F("repeated_string_piece"), "324");
-  message->AddString(F("repeated_cord"), "325");
+  reflection->AddInt32 (message, F("repeated_int32"   ), 301);
+  reflection->AddInt64 (message, F("repeated_int64"   ), 302);
+  reflection->AddUInt32(message, F("repeated_uint32"  ), 303);
+  reflection->AddUInt64(message, F("repeated_uint64"  ), 304);
+  reflection->AddInt32 (message, F("repeated_sint32"  ), 305);
+  reflection->AddInt64 (message, F("repeated_sint64"  ), 306);
+  reflection->AddUInt32(message, F("repeated_fixed32" ), 307);
+  reflection->AddUInt64(message, F("repeated_fixed64" ), 308);
+  reflection->AddInt32 (message, F("repeated_sfixed32"), 309);
+  reflection->AddInt64 (message, F("repeated_sfixed64"), 310);
+  reflection->AddFloat (message, F("repeated_float"   ), 311);
+  reflection->AddDouble(message, F("repeated_double"  ), 312);
+  reflection->AddBool  (message, F("repeated_bool"    ), false);
+  reflection->AddString(message, F("repeated_string"  ), "315");
+  reflection->AddString(message, F("repeated_bytes"   ), "316");
+
+  sub_message = reflection->AddMessage(message, F("repeatedgroup"));
+  sub_message->GetReflection()->SetInt32(sub_message, repeated_group_a_, 317);
+  sub_message = reflection->AddMessage(message, F("repeated_nested_message"));
+  sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 318);
+  sub_message = reflection->AddMessage(message, F("repeated_foreign_message"));
+  sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 319);
+  sub_message = reflection->AddMessage(message, F("repeated_import_message"));
+  sub_message->GetReflection()->SetInt32(sub_message, import_d_, 320);
+
+  reflection->AddEnum(message, F("repeated_nested_enum" ),  nested_baz_);
+  reflection->AddEnum(message, F("repeated_foreign_enum"), foreign_baz_);
+  reflection->AddEnum(message, F("repeated_import_enum" ),  import_baz_);
+
+  reflection->AddString(message, F("repeated_string_piece"), "324");
+  reflection->AddString(message, F("repeated_cord"), "325");
 
   // -----------------------------------------------------------------
 
-  message->SetInt32 (F("default_int32"   ), 401);
-  message->SetInt64 (F("default_int64"   ), 402);
-  message->SetUInt32(F("default_uint32"  ), 403);
-  message->SetUInt64(F("default_uint64"  ), 404);
-  message->SetInt32 (F("default_sint32"  ), 405);
-  message->SetInt64 (F("default_sint64"  ), 406);
-  message->SetUInt32(F("default_fixed32" ), 407);
-  message->SetUInt64(F("default_fixed64" ), 408);
-  message->SetInt32 (F("default_sfixed32"), 409);
-  message->SetInt64 (F("default_sfixed64"), 410);
-  message->SetFloat (F("default_float"   ), 411);
-  message->SetDouble(F("default_double"  ), 412);
-  message->SetBool  (F("default_bool"    ), false);
-  message->SetString(F("default_string"  ), "415");
-  message->SetString(F("default_bytes"   ), "416");
-
-  message->SetEnum(F("default_nested_enum" ),  nested_foo_);
-  message->SetEnum(F("default_foreign_enum"), foreign_foo_);
-  message->SetEnum(F("default_import_enum" ),  import_foo_);
-
-  message->SetString(F("default_string_piece"), "424");
-  message->SetString(F("default_cord"), "425");
+  reflection->SetInt32 (message, F("default_int32"   ), 401);
+  reflection->SetInt64 (message, F("default_int64"   ), 402);
+  reflection->SetUInt32(message, F("default_uint32"  ), 403);
+  reflection->SetUInt64(message, F("default_uint64"  ), 404);
+  reflection->SetInt32 (message, F("default_sint32"  ), 405);
+  reflection->SetInt64 (message, F("default_sint64"  ), 406);
+  reflection->SetUInt32(message, F("default_fixed32" ), 407);
+  reflection->SetUInt64(message, F("default_fixed64" ), 408);
+  reflection->SetInt32 (message, F("default_sfixed32"), 409);
+  reflection->SetInt64 (message, F("default_sfixed64"), 410);
+  reflection->SetFloat (message, F("default_float"   ), 411);
+  reflection->SetDouble(message, F("default_double"  ), 412);
+  reflection->SetBool  (message, F("default_bool"    ), false);
+  reflection->SetString(message, F("default_string"  ), "415");
+  reflection->SetString(message, F("default_bytes"   ), "416");
+
+  reflection->SetEnum(message, F("default_nested_enum" ),  nested_foo_);
+  reflection->SetEnum(message, F("default_foreign_enum"), foreign_foo_);
+  reflection->SetEnum(message, F("default_import_enum" ),  import_foo_);
+
+  reflection->SetString(message, F("default_string_piece"), "424");
+  reflection->SetString(message, F("default_cord"), "425");
 }
 
 // -------------------------------------------------------------------
 
 void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection(
-    const Message::Reflection& message) {
+    const Message& message) {
+  const Reflection* reflection = message.GetReflection();
   string scratch;
-
-  EXPECT_TRUE(message.HasField(F("optional_int32"   )));
-  EXPECT_TRUE(message.HasField(F("optional_int64"   )));
-  EXPECT_TRUE(message.HasField(F("optional_uint32"  )));
-  EXPECT_TRUE(message.HasField(F("optional_uint64"  )));
-  EXPECT_TRUE(message.HasField(F("optional_sint32"  )));
-  EXPECT_TRUE(message.HasField(F("optional_sint64"  )));
-  EXPECT_TRUE(message.HasField(F("optional_fixed32" )));
-  EXPECT_TRUE(message.HasField(F("optional_fixed64" )));
-  EXPECT_TRUE(message.HasField(F("optional_sfixed32")));
-  EXPECT_TRUE(message.HasField(F("optional_sfixed64")));
-  EXPECT_TRUE(message.HasField(F("optional_float"   )));
-  EXPECT_TRUE(message.HasField(F("optional_double"  )));
-  EXPECT_TRUE(message.HasField(F("optional_bool"    )));
-  EXPECT_TRUE(message.HasField(F("optional_string"  )));
-  EXPECT_TRUE(message.HasField(F("optional_bytes"   )));
-
-  EXPECT_TRUE(message.HasField(F("optionalgroup"           )));
-  EXPECT_TRUE(message.HasField(F("optional_nested_message" )));
-  EXPECT_TRUE(message.HasField(F("optional_foreign_message")));
-  EXPECT_TRUE(message.HasField(F("optional_import_message" )));
-
-  EXPECT_TRUE(message.GetMessage(F("optionalgroup"))
-                     .GetReflection()->HasField(group_a_));
-  EXPECT_TRUE(message.GetMessage(F("optional_nested_message"))
-                     .GetReflection()->HasField(nested_b_));
-  EXPECT_TRUE(message.GetMessage(F("optional_foreign_message"))
-                     .GetReflection()->HasField(foreign_c_));
-  EXPECT_TRUE(message.GetMessage(F("optional_import_message"))
-                     .GetReflection()->HasField(import_d_));
-
-  EXPECT_TRUE(message.HasField(F("optional_nested_enum" )));
-  EXPECT_TRUE(message.HasField(F("optional_foreign_enum")));
-  EXPECT_TRUE(message.HasField(F("optional_import_enum" )));
-
-  EXPECT_TRUE(message.HasField(F("optional_string_piece")));
-  EXPECT_TRUE(message.HasField(F("optional_cord")));
-
-  EXPECT_EQ(101  , message.GetInt32 (F("optional_int32"   )));
-  EXPECT_EQ(102  , message.GetInt64 (F("optional_int64"   )));
-  EXPECT_EQ(103  , message.GetUInt32(F("optional_uint32"  )));
-  EXPECT_EQ(104  , message.GetUInt64(F("optional_uint64"  )));
-  EXPECT_EQ(105  , message.GetInt32 (F("optional_sint32"  )));
-  EXPECT_EQ(106  , message.GetInt64 (F("optional_sint64"  )));
-  EXPECT_EQ(107  , message.GetUInt32(F("optional_fixed32" )));
-  EXPECT_EQ(108  , message.GetUInt64(F("optional_fixed64" )));
-  EXPECT_EQ(109  , message.GetInt32 (F("optional_sfixed32")));
-  EXPECT_EQ(110  , message.GetInt64 (F("optional_sfixed64")));
-  EXPECT_EQ(111  , message.GetFloat (F("optional_float"   )));
-  EXPECT_EQ(112  , message.GetDouble(F("optional_double"  )));
-  EXPECT_EQ(true , message.GetBool  (F("optional_bool"    )));
-  EXPECT_EQ("115", message.GetString(F("optional_string"  )));
-  EXPECT_EQ("116", message.GetString(F("optional_bytes"   )));
-
-  EXPECT_EQ("115", message.GetStringReference(F("optional_string"), &scratch));
-  EXPECT_EQ("116", message.GetStringReference(F("optional_bytes" ), &scratch));
-
-  EXPECT_EQ(117, message.GetMessage(F("optionalgroup"))
-                        .GetReflection()->GetInt32(group_a_));
-  EXPECT_EQ(118, message.GetMessage(F("optional_nested_message"))
-                        .GetReflection()->GetInt32(nested_b_));
-  EXPECT_EQ(119, message.GetMessage(F("optional_foreign_message"))
-                        .GetReflection()->GetInt32(foreign_c_));
-  EXPECT_EQ(120, message.GetMessage(F("optional_import_message"))
-                        .GetReflection()->GetInt32(import_d_));
-
-  EXPECT_EQ( nested_baz_, message.GetEnum(F("optional_nested_enum" )));
-  EXPECT_EQ(foreign_baz_, message.GetEnum(F("optional_foreign_enum")));
-  EXPECT_EQ( import_baz_, message.GetEnum(F("optional_import_enum" )));
-
-  EXPECT_EQ("124", message.GetString(F("optional_string_piece")));
-  EXPECT_EQ("124", message.GetStringReference(F("optional_string_piece"),
-                                              &scratch));
-
-  EXPECT_EQ("125", message.GetString(F("optional_cord")));
-  EXPECT_EQ("125", message.GetStringReference(F("optional_cord"),
-                                              &scratch));
+  const Message* sub_message;
+
+  EXPECT_TRUE(reflection->HasField(message, F("optional_int32"   )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_int64"   )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_uint32"  )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_uint64"  )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_sint32"  )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_sint64"  )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_fixed32" )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_fixed64" )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_sfixed32")));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_sfixed64")));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_float"   )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_double"  )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_bool"    )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_string"  )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_bytes"   )));
+
+  EXPECT_TRUE(reflection->HasField(message, F("optionalgroup"           )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_nested_message" )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_foreign_message")));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_import_message" )));
+
+  sub_message = &reflection->GetMessage(message, F("optionalgroup"));
+  EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, group_a_));
+  sub_message = &reflection->GetMessage(message, F("optional_nested_message"));
+  EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, nested_b_));
+  sub_message = &reflection->GetMessage(message, F("optional_foreign_message"));
+  EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, foreign_c_));
+  sub_message = &reflection->GetMessage(message, F("optional_import_message"));
+  EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, import_d_));
+
+  EXPECT_TRUE(reflection->HasField(message, F("optional_nested_enum" )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_foreign_enum")));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_import_enum" )));
+
+  EXPECT_TRUE(reflection->HasField(message, F("optional_string_piece")));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_cord")));
+
+  EXPECT_EQ(101  , reflection->GetInt32 (message, F("optional_int32"   )));
+  EXPECT_EQ(102  , reflection->GetInt64 (message, F("optional_int64"   )));
+  EXPECT_EQ(103  , reflection->GetUInt32(message, F("optional_uint32"  )));
+  EXPECT_EQ(104  , reflection->GetUInt64(message, F("optional_uint64"  )));
+  EXPECT_EQ(105  , reflection->GetInt32 (message, F("optional_sint32"  )));
+  EXPECT_EQ(106  , reflection->GetInt64 (message, F("optional_sint64"  )));
+  EXPECT_EQ(107  , reflection->GetUInt32(message, F("optional_fixed32" )));
+  EXPECT_EQ(108  , reflection->GetUInt64(message, F("optional_fixed64" )));
+  EXPECT_EQ(109  , reflection->GetInt32 (message, F("optional_sfixed32")));
+  EXPECT_EQ(110  , reflection->GetInt64 (message, F("optional_sfixed64")));
+  EXPECT_EQ(111  , reflection->GetFloat (message, F("optional_float"   )));
+  EXPECT_EQ(112  , reflection->GetDouble(message, F("optional_double"  )));
+  EXPECT_EQ(true , reflection->GetBool  (message, F("optional_bool"    )));
+  EXPECT_EQ("115", reflection->GetString(message, F("optional_string"  )));
+  EXPECT_EQ("116", reflection->GetString(message, F("optional_bytes"   )));
+
+  EXPECT_EQ("115", reflection->GetStringReference(message, F("optional_string"), &scratch));
+  EXPECT_EQ("116", reflection->GetStringReference(message, F("optional_bytes" ), &scratch));
+
+  sub_message = &reflection->GetMessage(message, F("optionalgroup"));
+  EXPECT_EQ(117, sub_message->GetReflection()->GetInt32(*sub_message, group_a_));
+  sub_message = &reflection->GetMessage(message, F("optional_nested_message"));
+  EXPECT_EQ(118, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
+  sub_message = &reflection->GetMessage(message, F("optional_foreign_message"));
+  EXPECT_EQ(119, sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_));
+  sub_message = &reflection->GetMessage(message, F("optional_import_message"));
+  EXPECT_EQ(120, sub_message->GetReflection()->GetInt32(*sub_message, import_d_));
+
+  EXPECT_EQ( nested_baz_, reflection->GetEnum(message, F("optional_nested_enum" )));
+  EXPECT_EQ(foreign_baz_, reflection->GetEnum(message, F("optional_foreign_enum")));
+  EXPECT_EQ( import_baz_, reflection->GetEnum(message, F("optional_import_enum" )));
+
+  EXPECT_EQ("124", reflection->GetString(message, F("optional_string_piece")));
+  EXPECT_EQ("124", reflection->GetStringReference(message, F("optional_string_piece"), &scratch));
+
+  EXPECT_EQ("125", reflection->GetString(message, F("optional_cord")));
+  EXPECT_EQ("125", reflection->GetStringReference(message, F("optional_cord"), &scratch));
 
   // -----------------------------------------------------------------
 
-  ASSERT_EQ(2, message.FieldSize(F("repeated_int32"   )));
-  ASSERT_EQ(2, message.FieldSize(F("repeated_int64"   )));
-  ASSERT_EQ(2, message.FieldSize(F("repeated_uint32"  )));
-  ASSERT_EQ(2, message.FieldSize(F("repeated_uint64"  )));
-  ASSERT_EQ(2, message.FieldSize(F("repeated_sint32"  )));
-  ASSERT_EQ(2, message.FieldSize(F("repeated_sint64"  )));
-  ASSERT_EQ(2, message.FieldSize(F("repeated_fixed32" )));
-  ASSERT_EQ(2, message.FieldSize(F("repeated_fixed64" )));
-  ASSERT_EQ(2, message.FieldSize(F("repeated_sfixed32")));
-  ASSERT_EQ(2, message.FieldSize(F("repeated_sfixed64")));
-  ASSERT_EQ(2, message.FieldSize(F("repeated_float"   )));
-  ASSERT_EQ(2, message.FieldSize(F("repeated_double"  )));
-  ASSERT_EQ(2, message.FieldSize(F("repeated_bool"    )));
-  ASSERT_EQ(2, message.FieldSize(F("repeated_string"  )));
-  ASSERT_EQ(2, message.FieldSize(F("repeated_bytes"   )));
-
-  ASSERT_EQ(2, message.FieldSize(F("repeatedgroup"           )));
-  ASSERT_EQ(2, message.FieldSize(F("repeated_nested_message" )));
-  ASSERT_EQ(2, message.FieldSize(F("repeated_foreign_message")));
-  ASSERT_EQ(2, message.FieldSize(F("repeated_import_message" )));
-  ASSERT_EQ(2, message.FieldSize(F("repeated_nested_enum"    )));
-  ASSERT_EQ(2, message.FieldSize(F("repeated_foreign_enum"   )));
-  ASSERT_EQ(2, message.FieldSize(F("repeated_import_enum"    )));
-
-  ASSERT_EQ(2, message.FieldSize(F("repeated_string_piece")));
-  ASSERT_EQ(2, message.FieldSize(F("repeated_cord")));
-
-  EXPECT_EQ(201  , message.GetRepeatedInt32 (F("repeated_int32"   ), 0));
-  EXPECT_EQ(202  , message.GetRepeatedInt64 (F("repeated_int64"   ), 0));
-  EXPECT_EQ(203  , message.GetRepeatedUInt32(F("repeated_uint32"  ), 0));
-  EXPECT_EQ(204  , message.GetRepeatedUInt64(F("repeated_uint64"  ), 0));
-  EXPECT_EQ(205  , message.GetRepeatedInt32 (F("repeated_sint32"  ), 0));
-  EXPECT_EQ(206  , message.GetRepeatedInt64 (F("repeated_sint64"  ), 0));
-  EXPECT_EQ(207  , message.GetRepeatedUInt32(F("repeated_fixed32" ), 0));
-  EXPECT_EQ(208  , message.GetRepeatedUInt64(F("repeated_fixed64" ), 0));
-  EXPECT_EQ(209  , message.GetRepeatedInt32 (F("repeated_sfixed32"), 0));
-  EXPECT_EQ(210  , message.GetRepeatedInt64 (F("repeated_sfixed64"), 0));
-  EXPECT_EQ(211  , message.GetRepeatedFloat (F("repeated_float"   ), 0));
-  EXPECT_EQ(212  , message.GetRepeatedDouble(F("repeated_double"  ), 0));
-  EXPECT_EQ(true , message.GetRepeatedBool  (F("repeated_bool"    ), 0));
-  EXPECT_EQ("215", message.GetRepeatedString(F("repeated_string"  ), 0));
-  EXPECT_EQ("216", message.GetRepeatedString(F("repeated_bytes"   ), 0));
-
-  EXPECT_EQ("215", message.GetRepeatedStringReference(F("repeated_string"),
-                                                      0, &scratch));
-  EXPECT_EQ("216", message.GetRepeatedStringReference(F("repeated_bytes"),
-                                                      0, &scratch));
-
-  EXPECT_EQ(217, message.GetRepeatedMessage(F("repeatedgroup"), 0)
-                        .GetReflection()->GetInt32(repeated_group_a_));
-  EXPECT_EQ(218, message.GetRepeatedMessage(F("repeated_nested_message"), 0)
-                        .GetReflection()->GetInt32(nested_b_));
-  EXPECT_EQ(219, message.GetRepeatedMessage(F("repeated_foreign_message"), 0)
-                        .GetReflection()->GetInt32(foreign_c_));
-  EXPECT_EQ(220, message.GetRepeatedMessage(F("repeated_import_message"), 0)
-                        .GetReflection()->GetInt32(import_d_));
-
-  EXPECT_EQ( nested_bar_, message.GetRepeatedEnum(F("repeated_nested_enum" ),0));
-  EXPECT_EQ(foreign_bar_, message.GetRepeatedEnum(F("repeated_foreign_enum"),0));
-  EXPECT_EQ( import_bar_, message.GetRepeatedEnum(F("repeated_import_enum" ),0));
-
-  EXPECT_EQ("224", message.GetRepeatedString(F("repeated_string_piece"), 0));
-  EXPECT_EQ("224", message.GetRepeatedStringReference(
-                        F("repeated_string_piece"), 0, &scratch));
-
-  EXPECT_EQ("225", message.GetRepeatedString(F("repeated_cord"), 0));
-  EXPECT_EQ("225", message.GetRepeatedStringReference(
-                        F("repeated_cord"), 0, &scratch));
-
-  EXPECT_EQ(301  , message.GetRepeatedInt32 (F("repeated_int32"   ), 1));
-  EXPECT_EQ(302  , message.GetRepeatedInt64 (F("repeated_int64"   ), 1));
-  EXPECT_EQ(303  , message.GetRepeatedUInt32(F("repeated_uint32"  ), 1));
-  EXPECT_EQ(304  , message.GetRepeatedUInt64(F("repeated_uint64"  ), 1));
-  EXPECT_EQ(305  , message.GetRepeatedInt32 (F("repeated_sint32"  ), 1));
-  EXPECT_EQ(306  , message.GetRepeatedInt64 (F("repeated_sint64"  ), 1));
-  EXPECT_EQ(307  , message.GetRepeatedUInt32(F("repeated_fixed32" ), 1));
-  EXPECT_EQ(308  , message.GetRepeatedUInt64(F("repeated_fixed64" ), 1));
-  EXPECT_EQ(309  , message.GetRepeatedInt32 (F("repeated_sfixed32"), 1));
-  EXPECT_EQ(310  , message.GetRepeatedInt64 (F("repeated_sfixed64"), 1));
-  EXPECT_EQ(311  , message.GetRepeatedFloat (F("repeated_float"   ), 1));
-  EXPECT_EQ(312  , message.GetRepeatedDouble(F("repeated_double"  ), 1));
-  EXPECT_EQ(false, message.GetRepeatedBool  (F("repeated_bool"    ), 1));
-  EXPECT_EQ("315", message.GetRepeatedString(F("repeated_string"  ), 1));
-  EXPECT_EQ("316", message.GetRepeatedString(F("repeated_bytes"   ), 1));
-
-  EXPECT_EQ("315", message.GetRepeatedStringReference(F("repeated_string"),
-                                                      1, &scratch));
-  EXPECT_EQ("316", message.GetRepeatedStringReference(F("repeated_bytes"),
-                                                      1, &scratch));
-
-  EXPECT_EQ(317, message.GetRepeatedMessage(F("repeatedgroup"), 1)
-                        .GetReflection()->GetInt32(repeated_group_a_));
-  EXPECT_EQ(318, message.GetRepeatedMessage(F("repeated_nested_message"), 1)
-                        .GetReflection()->GetInt32(nested_b_));
-  EXPECT_EQ(319, message.GetRepeatedMessage(F("repeated_foreign_message"), 1)
-                        .GetReflection()->GetInt32(foreign_c_));
-  EXPECT_EQ(320, message.GetRepeatedMessage(F("repeated_import_message"), 1)
-                        .GetReflection()->GetInt32(import_d_));
-
-  EXPECT_EQ( nested_baz_, message.GetRepeatedEnum(F("repeated_nested_enum" ),1));
-  EXPECT_EQ(foreign_baz_, message.GetRepeatedEnum(F("repeated_foreign_enum"),1));
-  EXPECT_EQ( import_baz_, message.GetRepeatedEnum(F("repeated_import_enum" ),1));
-
-  EXPECT_EQ("324", message.GetRepeatedString(F("repeated_string_piece"), 1));
-  EXPECT_EQ("324", message.GetRepeatedStringReference(
-                        F("repeated_string_piece"), 1, &scratch));
-
-  EXPECT_EQ("325", message.GetRepeatedString(F("repeated_cord"), 1));
-  EXPECT_EQ("325", message.GetRepeatedStringReference(
-                        F("repeated_cord"), 1, &scratch));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_int32"   )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_int64"   )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_uint32"  )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_uint64"  )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_sint32"  )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_sint64"  )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_fixed32" )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_fixed64" )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_sfixed32")));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_sfixed64")));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_float"   )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_double"  )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_bool"    )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_string"  )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_bytes"   )));
+
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeatedgroup"           )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_nested_message" )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_foreign_message")));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_import_message" )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_nested_enum"    )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_foreign_enum"   )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_import_enum"    )));
+
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_string_piece")));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_cord")));
+
+  EXPECT_EQ(201  , reflection->GetRepeatedInt32 (message, F("repeated_int32"   ), 0));
+  EXPECT_EQ(202  , reflection->GetRepeatedInt64 (message, F("repeated_int64"   ), 0));
+  EXPECT_EQ(203  , reflection->GetRepeatedUInt32(message, F("repeated_uint32"  ), 0));
+  EXPECT_EQ(204  , reflection->GetRepeatedUInt64(message, F("repeated_uint64"  ), 0));
+  EXPECT_EQ(205  , reflection->GetRepeatedInt32 (message, F("repeated_sint32"  ), 0));
+  EXPECT_EQ(206  , reflection->GetRepeatedInt64 (message, F("repeated_sint64"  ), 0));
+  EXPECT_EQ(207  , reflection->GetRepeatedUInt32(message, F("repeated_fixed32" ), 0));
+  EXPECT_EQ(208  , reflection->GetRepeatedUInt64(message, F("repeated_fixed64" ), 0));
+  EXPECT_EQ(209  , reflection->GetRepeatedInt32 (message, F("repeated_sfixed32"), 0));
+  EXPECT_EQ(210  , reflection->GetRepeatedInt64 (message, F("repeated_sfixed64"), 0));
+  EXPECT_EQ(211  , reflection->GetRepeatedFloat (message, F("repeated_float"   ), 0));
+  EXPECT_EQ(212  , reflection->GetRepeatedDouble(message, F("repeated_double"  ), 0));
+  EXPECT_EQ(true , reflection->GetRepeatedBool  (message, F("repeated_bool"    ), 0));
+  EXPECT_EQ("215", reflection->GetRepeatedString(message, F("repeated_string"  ), 0));
+  EXPECT_EQ("216", reflection->GetRepeatedString(message, F("repeated_bytes"   ), 0));
+
+  EXPECT_EQ("215", reflection->GetRepeatedStringReference(message, F("repeated_string"), 0, &scratch));
+  EXPECT_EQ("216", reflection->GetRepeatedStringReference(message, F("repeated_bytes"), 0, &scratch));
+
+  sub_message = &reflection->GetRepeatedMessage(message, F("repeatedgroup"), 0);
+  EXPECT_EQ(217, sub_message->GetReflection()->GetInt32(*sub_message, repeated_group_a_));
+  sub_message = &reflection->GetRepeatedMessage(message, F("repeated_nested_message"), 0);
+  EXPECT_EQ(218, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
+  sub_message = &reflection->GetRepeatedMessage(message, F("repeated_foreign_message"), 0);
+  EXPECT_EQ(219, sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_));
+  sub_message = &reflection->GetRepeatedMessage(message, F("repeated_import_message"), 0);
+  EXPECT_EQ(220, sub_message->GetReflection()->GetInt32(*sub_message, import_d_));
+
+  EXPECT_EQ( nested_bar_, reflection->GetRepeatedEnum(message, F("repeated_nested_enum" ),0));
+  EXPECT_EQ(foreign_bar_, reflection->GetRepeatedEnum(message, F("repeated_foreign_enum"),0));
+  EXPECT_EQ( import_bar_, reflection->GetRepeatedEnum(message, F("repeated_import_enum" ),0));
+
+  EXPECT_EQ("224", reflection->GetRepeatedString(message, F("repeated_string_piece"), 0));
+  EXPECT_EQ("224", reflection->GetRepeatedStringReference(
+                        message, F("repeated_string_piece"), 0, &scratch));
+
+  EXPECT_EQ("225", reflection->GetRepeatedString(message, F("repeated_cord"), 0));
+  EXPECT_EQ("225", reflection->GetRepeatedStringReference(
+                        message, F("repeated_cord"), 0, &scratch));
+
+  EXPECT_EQ(301  , reflection->GetRepeatedInt32 (message, F("repeated_int32"   ), 1));
+  EXPECT_EQ(302  , reflection->GetRepeatedInt64 (message, F("repeated_int64"   ), 1));
+  EXPECT_EQ(303  , reflection->GetRepeatedUInt32(message, F("repeated_uint32"  ), 1));
+  EXPECT_EQ(304  , reflection->GetRepeatedUInt64(message, F("repeated_uint64"  ), 1));
+  EXPECT_EQ(305  , reflection->GetRepeatedInt32 (message, F("repeated_sint32"  ), 1));
+  EXPECT_EQ(306  , reflection->GetRepeatedInt64 (message, F("repeated_sint64"  ), 1));
+  EXPECT_EQ(307  , reflection->GetRepeatedUInt32(message, F("repeated_fixed32" ), 1));
+  EXPECT_EQ(308  , reflection->GetRepeatedUInt64(message, F("repeated_fixed64" ), 1));
+  EXPECT_EQ(309  , reflection->GetRepeatedInt32 (message, F("repeated_sfixed32"), 1));
+  EXPECT_EQ(310  , reflection->GetRepeatedInt64 (message, F("repeated_sfixed64"), 1));
+  EXPECT_EQ(311  , reflection->GetRepeatedFloat (message, F("repeated_float"   ), 1));
+  EXPECT_EQ(312  , reflection->GetRepeatedDouble(message, F("repeated_double"  ), 1));
+  EXPECT_EQ(false, reflection->GetRepeatedBool  (message, F("repeated_bool"    ), 1));
+  EXPECT_EQ("315", reflection->GetRepeatedString(message, F("repeated_string"  ), 1));
+  EXPECT_EQ("316", reflection->GetRepeatedString(message, F("repeated_bytes"   ), 1));
+
+  EXPECT_EQ("315", reflection->GetRepeatedStringReference(message, F("repeated_string"),
+                                                          1, &scratch));
+  EXPECT_EQ("316", reflection->GetRepeatedStringReference(message, F("repeated_bytes"),
+                                                          1, &scratch));
+
+  sub_message = &reflection->GetRepeatedMessage(message, F("repeatedgroup"), 1);
+  EXPECT_EQ(317, sub_message->GetReflection()->GetInt32(*sub_message, repeated_group_a_));
+  sub_message = &reflection->GetRepeatedMessage(message, F("repeated_nested_message"), 1);
+  EXPECT_EQ(318, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
+  sub_message = &reflection->GetRepeatedMessage(message, F("repeated_foreign_message"), 1);
+  EXPECT_EQ(319, sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_));
+  sub_message = &reflection->GetRepeatedMessage(message, F("repeated_import_message"), 1);
+  EXPECT_EQ(320, sub_message->GetReflection()->GetInt32(*sub_message, import_d_));
+
+  EXPECT_EQ( nested_baz_, reflection->GetRepeatedEnum(message, F("repeated_nested_enum" ),1));
+  EXPECT_EQ(foreign_baz_, reflection->GetRepeatedEnum(message, F("repeated_foreign_enum"),1));
+  EXPECT_EQ( import_baz_, reflection->GetRepeatedEnum(message, F("repeated_import_enum" ),1));
+
+  EXPECT_EQ("324", reflection->GetRepeatedString(message, F("repeated_string_piece"), 1));
+  EXPECT_EQ("324", reflection->GetRepeatedStringReference(
+                        message, F("repeated_string_piece"), 1, &scratch));
+
+  EXPECT_EQ("325", reflection->GetRepeatedString(message, F("repeated_cord"), 1));
+  EXPECT_EQ("325", reflection->GetRepeatedStringReference(
+                        message, F("repeated_cord"), 1, &scratch));
 
   // -----------------------------------------------------------------
 
-  EXPECT_TRUE(message.HasField(F("default_int32"   )));
-  EXPECT_TRUE(message.HasField(F("default_int64"   )));
-  EXPECT_TRUE(message.HasField(F("default_uint32"  )));
-  EXPECT_TRUE(message.HasField(F("default_uint64"  )));
-  EXPECT_TRUE(message.HasField(F("default_sint32"  )));
-  EXPECT_TRUE(message.HasField(F("default_sint64"  )));
-  EXPECT_TRUE(message.HasField(F("default_fixed32" )));
-  EXPECT_TRUE(message.HasField(F("default_fixed64" )));
-  EXPECT_TRUE(message.HasField(F("default_sfixed32")));
-  EXPECT_TRUE(message.HasField(F("default_sfixed64")));
-  EXPECT_TRUE(message.HasField(F("default_float"   )));
-  EXPECT_TRUE(message.HasField(F("default_double"  )));
-  EXPECT_TRUE(message.HasField(F("default_bool"    )));
-  EXPECT_TRUE(message.HasField(F("default_string"  )));
-  EXPECT_TRUE(message.HasField(F("default_bytes"   )));
-
-  EXPECT_TRUE(message.HasField(F("default_nested_enum" )));
-  EXPECT_TRUE(message.HasField(F("default_foreign_enum")));
-  EXPECT_TRUE(message.HasField(F("default_import_enum" )));
-
-  EXPECT_TRUE(message.HasField(F("default_string_piece")));
-  EXPECT_TRUE(message.HasField(F("default_cord")));
-
-  EXPECT_EQ(401  , message.GetInt32 (F("default_int32"   )));
-  EXPECT_EQ(402  , message.GetInt64 (F("default_int64"   )));
-  EXPECT_EQ(403  , message.GetUInt32(F("default_uint32"  )));
-  EXPECT_EQ(404  , message.GetUInt64(F("default_uint64"  )));
-  EXPECT_EQ(405  , message.GetInt32 (F("default_sint32"  )));
-  EXPECT_EQ(406  , message.GetInt64 (F("default_sint64"  )));
-  EXPECT_EQ(407  , message.GetUInt32(F("default_fixed32" )));
-  EXPECT_EQ(408  , message.GetUInt64(F("default_fixed64" )));
-  EXPECT_EQ(409  , message.GetInt32 (F("default_sfixed32")));
-  EXPECT_EQ(410  , message.GetInt64 (F("default_sfixed64")));
-  EXPECT_EQ(411  , message.GetFloat (F("default_float"   )));
-  EXPECT_EQ(412  , message.GetDouble(F("default_double"  )));
-  EXPECT_EQ(false, message.GetBool  (F("default_bool"    )));
-  EXPECT_EQ("415", message.GetString(F("default_string"  )));
-  EXPECT_EQ("416", message.GetString(F("default_bytes"   )));
-
-  EXPECT_EQ("415", message.GetStringReference(F("default_string"), &scratch));
-  EXPECT_EQ("416", message.GetStringReference(F("default_bytes" ), &scratch));
-
-  EXPECT_EQ( nested_foo_, message.GetEnum(F("default_nested_enum" )));
-  EXPECT_EQ(foreign_foo_, message.GetEnum(F("default_foreign_enum")));
-  EXPECT_EQ( import_foo_, message.GetEnum(F("default_import_enum" )));
-
-  EXPECT_EQ("424", message.GetString(F("default_string_piece")));
-  EXPECT_EQ("424", message.GetStringReference(F("default_string_piece"),
-                                              &scratch));
-
-  EXPECT_EQ("425", message.GetString(F("default_cord")));
-  EXPECT_EQ("425", message.GetStringReference(F("default_cord"), &scratch));
+  EXPECT_TRUE(reflection->HasField(message, F("default_int32"   )));
+  EXPECT_TRUE(reflection->HasField(message, F("default_int64"   )));
+  EXPECT_TRUE(reflection->HasField(message, F("default_uint32"  )));
+  EXPECT_TRUE(reflection->HasField(message, F("default_uint64"  )));
+  EXPECT_TRUE(reflection->HasField(message, F("default_sint32"  )));
+  EXPECT_TRUE(reflection->HasField(message, F("default_sint64"  )));
+  EXPECT_TRUE(reflection->HasField(message, F("default_fixed32" )));
+  EXPECT_TRUE(reflection->HasField(message, F("default_fixed64" )));
+  EXPECT_TRUE(reflection->HasField(message, F("default_sfixed32")));
+  EXPECT_TRUE(reflection->HasField(message, F("default_sfixed64")));
+  EXPECT_TRUE(reflection->HasField(message, F("default_float"   )));
+  EXPECT_TRUE(reflection->HasField(message, F("default_double"  )));
+  EXPECT_TRUE(reflection->HasField(message, F("default_bool"    )));
+  EXPECT_TRUE(reflection->HasField(message, F("default_string"  )));
+  EXPECT_TRUE(reflection->HasField(message, F("default_bytes"   )));
+
+  EXPECT_TRUE(reflection->HasField(message, F("default_nested_enum" )));
+  EXPECT_TRUE(reflection->HasField(message, F("default_foreign_enum")));
+  EXPECT_TRUE(reflection->HasField(message, F("default_import_enum" )));
+
+  EXPECT_TRUE(reflection->HasField(message, F("default_string_piece")));
+  EXPECT_TRUE(reflection->HasField(message, F("default_cord")));
+
+  EXPECT_EQ(401  , reflection->GetInt32 (message, F("default_int32"   )));
+  EXPECT_EQ(402  , reflection->GetInt64 (message, F("default_int64"   )));
+  EXPECT_EQ(403  , reflection->GetUInt32(message, F("default_uint32"  )));
+  EXPECT_EQ(404  , reflection->GetUInt64(message, F("default_uint64"  )));
+  EXPECT_EQ(405  , reflection->GetInt32 (message, F("default_sint32"  )));
+  EXPECT_EQ(406  , reflection->GetInt64 (message, F("default_sint64"  )));
+  EXPECT_EQ(407  , reflection->GetUInt32(message, F("default_fixed32" )));
+  EXPECT_EQ(408  , reflection->GetUInt64(message, F("default_fixed64" )));
+  EXPECT_EQ(409  , reflection->GetInt32 (message, F("default_sfixed32")));
+  EXPECT_EQ(410  , reflection->GetInt64 (message, F("default_sfixed64")));
+  EXPECT_EQ(411  , reflection->GetFloat (message, F("default_float"   )));
+  EXPECT_EQ(412  , reflection->GetDouble(message, F("default_double"  )));
+  EXPECT_EQ(false, reflection->GetBool  (message, F("default_bool"    )));
+  EXPECT_EQ("415", reflection->GetString(message, F("default_string"  )));
+  EXPECT_EQ("416", reflection->GetString(message, F("default_bytes"   )));
+
+  EXPECT_EQ("415", reflection->GetStringReference(message, F("default_string"), &scratch));
+  EXPECT_EQ("416", reflection->GetStringReference(message, F("default_bytes" ), &scratch));
+
+  EXPECT_EQ( nested_foo_, reflection->GetEnum(message, F("default_nested_enum" )));
+  EXPECT_EQ(foreign_foo_, reflection->GetEnum(message, F("default_foreign_enum")));
+  EXPECT_EQ( import_foo_, reflection->GetEnum(message, F("default_import_enum" )));
+
+  EXPECT_EQ("424", reflection->GetString(message, F("default_string_piece")));
+  EXPECT_EQ("424", reflection->GetStringReference(message, F("default_string_piece"),
+                                                  &scratch));
+
+  EXPECT_EQ("425", reflection->GetString(message, F("default_cord")));
+  EXPECT_EQ("425", reflection->GetStringReference(message, F("default_cord"), &scratch));
 }
 
 // -------------------------------------------------------------------
 
 void TestUtil::ReflectionTester::ExpectClearViaReflection(
-    const Message::Reflection& message) {
+    const Message& message) {
+  const Reflection* reflection = message.GetReflection();
   string scratch;
+  const Message* sub_message;
 
   // has_blah() should initially be false for all optional fields.
-  EXPECT_FALSE(message.HasField(F("optional_int32"   )));
-  EXPECT_FALSE(message.HasField(F("optional_int64"   )));
-  EXPECT_FALSE(message.HasField(F("optional_uint32"  )));
-  EXPECT_FALSE(message.HasField(F("optional_uint64"  )));
-  EXPECT_FALSE(message.HasField(F("optional_sint32"  )));
-  EXPECT_FALSE(message.HasField(F("optional_sint64"  )));
-  EXPECT_FALSE(message.HasField(F("optional_fixed32" )));
-  EXPECT_FALSE(message.HasField(F("optional_fixed64" )));
-  EXPECT_FALSE(message.HasField(F("optional_sfixed32")));
-  EXPECT_FALSE(message.HasField(F("optional_sfixed64")));
-  EXPECT_FALSE(message.HasField(F("optional_float"   )));
-  EXPECT_FALSE(message.HasField(F("optional_double"  )));
-  EXPECT_FALSE(message.HasField(F("optional_bool"    )));
-  EXPECT_FALSE(message.HasField(F("optional_string"  )));
-  EXPECT_FALSE(message.HasField(F("optional_bytes"   )));
-
-  EXPECT_FALSE(message.HasField(F("optionalgroup"           )));
-  EXPECT_FALSE(message.HasField(F("optional_nested_message" )));
-  EXPECT_FALSE(message.HasField(F("optional_foreign_message")));
-  EXPECT_FALSE(message.HasField(F("optional_import_message" )));
-
-  EXPECT_FALSE(message.HasField(F("optional_nested_enum" )));
-  EXPECT_FALSE(message.HasField(F("optional_foreign_enum")));
-  EXPECT_FALSE(message.HasField(F("optional_import_enum" )));
-
-  EXPECT_FALSE(message.HasField(F("optional_string_piece")));
-  EXPECT_FALSE(message.HasField(F("optional_cord")));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_int32"   )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_int64"   )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_uint32"  )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_uint64"  )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_sint32"  )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_sint64"  )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_fixed32" )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_fixed64" )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_sfixed32")));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_sfixed64")));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_float"   )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_double"  )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_bool"    )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_string"  )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_bytes"   )));
+
+  EXPECT_FALSE(reflection->HasField(message, F("optionalgroup"           )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_nested_message" )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_foreign_message")));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_import_message" )));
+
+  EXPECT_FALSE(reflection->HasField(message, F("optional_nested_enum" )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_foreign_enum")));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_import_enum" )));
+
+  EXPECT_FALSE(reflection->HasField(message, F("optional_string_piece")));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_cord")));
 
   // Optional fields without defaults are set to zero or something like it.
-  EXPECT_EQ(0    , message.GetInt32 (F("optional_int32"   )));
-  EXPECT_EQ(0    , message.GetInt64 (F("optional_int64"   )));
-  EXPECT_EQ(0    , message.GetUInt32(F("optional_uint32"  )));
-  EXPECT_EQ(0    , message.GetUInt64(F("optional_uint64"  )));
-  EXPECT_EQ(0    , message.GetInt32 (F("optional_sint32"  )));
-  EXPECT_EQ(0    , message.GetInt64 (F("optional_sint64"  )));
-  EXPECT_EQ(0    , message.GetUInt32(F("optional_fixed32" )));
-  EXPECT_EQ(0    , message.GetUInt64(F("optional_fixed64" )));
-  EXPECT_EQ(0    , message.GetInt32 (F("optional_sfixed32")));
-  EXPECT_EQ(0    , message.GetInt64 (F("optional_sfixed64")));
-  EXPECT_EQ(0    , message.GetFloat (F("optional_float"   )));
-  EXPECT_EQ(0    , message.GetDouble(F("optional_double"  )));
-  EXPECT_EQ(false, message.GetBool  (F("optional_bool"    )));
-  EXPECT_EQ(""   , message.GetString(F("optional_string"  )));
-  EXPECT_EQ(""   , message.GetString(F("optional_bytes"   )));
-
-  EXPECT_EQ("", message.GetStringReference(F("optional_string"), &scratch));
-  EXPECT_EQ("", message.GetStringReference(F("optional_bytes" ), &scratch));
+  EXPECT_EQ(0    , reflection->GetInt32 (message, F("optional_int32"   )));
+  EXPECT_EQ(0    , reflection->GetInt64 (message, F("optional_int64"   )));
+  EXPECT_EQ(0    , reflection->GetUInt32(message, F("optional_uint32"  )));
+  EXPECT_EQ(0    , reflection->GetUInt64(message, F("optional_uint64"  )));
+  EXPECT_EQ(0    , reflection->GetInt32 (message, F("optional_sint32"  )));
+  EXPECT_EQ(0    , reflection->GetInt64 (message, F("optional_sint64"  )));
+  EXPECT_EQ(0    , reflection->GetUInt32(message, F("optional_fixed32" )));
+  EXPECT_EQ(0    , reflection->GetUInt64(message, F("optional_fixed64" )));
+  EXPECT_EQ(0    , reflection->GetInt32 (message, F("optional_sfixed32")));
+  EXPECT_EQ(0    , reflection->GetInt64 (message, F("optional_sfixed64")));
+  EXPECT_EQ(0    , reflection->GetFloat (message, F("optional_float"   )));
+  EXPECT_EQ(0    , reflection->GetDouble(message, F("optional_double"  )));
+  EXPECT_EQ(false, reflection->GetBool  (message, F("optional_bool"    )));
+  EXPECT_EQ(""   , reflection->GetString(message, F("optional_string"  )));
+  EXPECT_EQ(""   , reflection->GetString(message, F("optional_bytes"   )));
+
+  EXPECT_EQ("", reflection->GetStringReference(message, F("optional_string"), &scratch));
+  EXPECT_EQ("", reflection->GetStringReference(message, F("optional_bytes" ), &scratch));
 
   // Embedded messages should also be clear.
-  EXPECT_FALSE(message.GetMessage(F("optionalgroup"))
-                      .GetReflection()->HasField(group_a_));
-  EXPECT_FALSE(message.GetMessage(F("optional_nested_message"))
-                      .GetReflection()->HasField(nested_b_));
-  EXPECT_FALSE(message.GetMessage(F("optional_foreign_message"))
-                      .GetReflection()->HasField(foreign_c_));
-  EXPECT_FALSE(message.GetMessage(F("optional_import_message"))
-                      .GetReflection()->HasField(import_d_));
-
-  EXPECT_EQ(0, message.GetMessage(F("optionalgroup"))
-                      .GetReflection()->GetInt32(group_a_));
-  EXPECT_EQ(0, message.GetMessage(F("optional_nested_message"))
-                      .GetReflection()->GetInt32(nested_b_));
-  EXPECT_EQ(0, message.GetMessage(F("optional_foreign_message"))
-                      .GetReflection()->GetInt32(foreign_c_));
-  EXPECT_EQ(0, message.GetMessage(F("optional_import_message"))
-                      .GetReflection()->GetInt32(import_d_));
+  sub_message = &reflection->GetMessage(message, F("optionalgroup"));
+  EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, group_a_));
+  EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, group_a_));
+  sub_message = &reflection->GetMessage(message, F("optional_nested_message"));
+  EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, nested_b_));
+  EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
+  sub_message = &reflection->GetMessage(message, F("optional_foreign_message"));
+  EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, foreign_c_));
+  EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_));
+  sub_message = &reflection->GetMessage(message, F("optional_import_message"));
+  EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, import_d_));
+  EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, import_d_));
 
   // Enums without defaults are set to the first value in the enum.
-  EXPECT_EQ( nested_foo_, message.GetEnum(F("optional_nested_enum" )));
-  EXPECT_EQ(foreign_foo_, message.GetEnum(F("optional_foreign_enum")));
-  EXPECT_EQ( import_foo_, message.GetEnum(F("optional_import_enum" )));
+  EXPECT_EQ( nested_foo_, reflection->GetEnum(message, F("optional_nested_enum" )));
+  EXPECT_EQ(foreign_foo_, reflection->GetEnum(message, F("optional_foreign_enum")));
+  EXPECT_EQ( import_foo_, reflection->GetEnum(message, F("optional_import_enum" )));
 
-  EXPECT_EQ("", message.GetString(F("optional_string_piece")));
-  EXPECT_EQ("", message.GetStringReference(F("optional_string_piece"),
-                                           &scratch));
+  EXPECT_EQ("", reflection->GetString(message, F("optional_string_piece")));
+  EXPECT_EQ("", reflection->GetStringReference(message, F("optional_string_piece"), &scratch));
 
-  EXPECT_EQ("", message.GetString(F("optional_cord")));
-  EXPECT_EQ("", message.GetStringReference(F("optional_cord"), &scratch));
+  EXPECT_EQ("", reflection->GetString(message, F("optional_cord")));
+  EXPECT_EQ("", reflection->GetStringReference(message, F("optional_cord"), &scratch));
 
   // Repeated fields are empty.
-  EXPECT_EQ(0, message.FieldSize(F("repeated_int32"   )));
-  EXPECT_EQ(0, message.FieldSize(F("repeated_int64"   )));
-  EXPECT_EQ(0, message.FieldSize(F("repeated_uint32"  )));
-  EXPECT_EQ(0, message.FieldSize(F("repeated_uint64"  )));
-  EXPECT_EQ(0, message.FieldSize(F("repeated_sint32"  )));
-  EXPECT_EQ(0, message.FieldSize(F("repeated_sint64"  )));
-  EXPECT_EQ(0, message.FieldSize(F("repeated_fixed32" )));
-  EXPECT_EQ(0, message.FieldSize(F("repeated_fixed64" )));
-  EXPECT_EQ(0, message.FieldSize(F("repeated_sfixed32")));
-  EXPECT_EQ(0, message.FieldSize(F("repeated_sfixed64")));
-  EXPECT_EQ(0, message.FieldSize(F("repeated_float"   )));
-  EXPECT_EQ(0, message.FieldSize(F("repeated_double"  )));
-  EXPECT_EQ(0, message.FieldSize(F("repeated_bool"    )));
-  EXPECT_EQ(0, message.FieldSize(F("repeated_string"  )));
-  EXPECT_EQ(0, message.FieldSize(F("repeated_bytes"   )));
-
-  EXPECT_EQ(0, message.FieldSize(F("repeatedgroup"           )));
-  EXPECT_EQ(0, message.FieldSize(F("repeated_nested_message" )));
-  EXPECT_EQ(0, message.FieldSize(F("repeated_foreign_message")));
-  EXPECT_EQ(0, message.FieldSize(F("repeated_import_message" )));
-  EXPECT_EQ(0, message.FieldSize(F("repeated_nested_enum"    )));
-  EXPECT_EQ(0, message.FieldSize(F("repeated_foreign_enum"   )));
-  EXPECT_EQ(0, message.FieldSize(F("repeated_import_enum"    )));
-
-  EXPECT_EQ(0, message.FieldSize(F("repeated_string_piece")));
-  EXPECT_EQ(0, message.FieldSize(F("repeated_cord")));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_int32"   )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_int64"   )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_uint32"  )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_uint64"  )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_sint32"  )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_sint64"  )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_fixed32" )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_fixed64" )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_sfixed32")));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_sfixed64")));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_float"   )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_double"  )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_bool"    )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_string"  )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_bytes"   )));
+
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeatedgroup"           )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_nested_message" )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_foreign_message")));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_import_message" )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_nested_enum"    )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_foreign_enum"   )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_import_enum"    )));
+
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_string_piece")));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_cord")));
 
   // has_blah() should also be false for all default fields.
-  EXPECT_FALSE(message.HasField(F("default_int32"   )));
-  EXPECT_FALSE(message.HasField(F("default_int64"   )));
-  EXPECT_FALSE(message.HasField(F("default_uint32"  )));
-  EXPECT_FALSE(message.HasField(F("default_uint64"  )));
-  EXPECT_FALSE(message.HasField(F("default_sint32"  )));
-  EXPECT_FALSE(message.HasField(F("default_sint64"  )));
-  EXPECT_FALSE(message.HasField(F("default_fixed32" )));
-  EXPECT_FALSE(message.HasField(F("default_fixed64" )));
-  EXPECT_FALSE(message.HasField(F("default_sfixed32")));
-  EXPECT_FALSE(message.HasField(F("default_sfixed64")));
-  EXPECT_FALSE(message.HasField(F("default_float"   )));
-  EXPECT_FALSE(message.HasField(F("default_double"  )));
-  EXPECT_FALSE(message.HasField(F("default_bool"    )));
-  EXPECT_FALSE(message.HasField(F("default_string"  )));
-  EXPECT_FALSE(message.HasField(F("default_bytes"   )));
-
-  EXPECT_FALSE(message.HasField(F("default_nested_enum" )));
-  EXPECT_FALSE(message.HasField(F("default_foreign_enum")));
-  EXPECT_FALSE(message.HasField(F("default_import_enum" )));
-
-  EXPECT_FALSE(message.HasField(F("default_string_piece")));
-  EXPECT_FALSE(message.HasField(F("default_cord")));
+  EXPECT_FALSE(reflection->HasField(message, F("default_int32"   )));
+  EXPECT_FALSE(reflection->HasField(message, F("default_int64"   )));
+  EXPECT_FALSE(reflection->HasField(message, F("default_uint32"  )));
+  EXPECT_FALSE(reflection->HasField(message, F("default_uint64"  )));
+  EXPECT_FALSE(reflection->HasField(message, F("default_sint32"  )));
+  EXPECT_FALSE(reflection->HasField(message, F("default_sint64"  )));
+  EXPECT_FALSE(reflection->HasField(message, F("default_fixed32" )));
+  EXPECT_FALSE(reflection->HasField(message, F("default_fixed64" )));
+  EXPECT_FALSE(reflection->HasField(message, F("default_sfixed32")));
+  EXPECT_FALSE(reflection->HasField(message, F("default_sfixed64")));
+  EXPECT_FALSE(reflection->HasField(message, F("default_float"   )));
+  EXPECT_FALSE(reflection->HasField(message, F("default_double"  )));
+  EXPECT_FALSE(reflection->HasField(message, F("default_bool"    )));
+  EXPECT_FALSE(reflection->HasField(message, F("default_string"  )));
+  EXPECT_FALSE(reflection->HasField(message, F("default_bytes"   )));
+
+  EXPECT_FALSE(reflection->HasField(message, F("default_nested_enum" )));
+  EXPECT_FALSE(reflection->HasField(message, F("default_foreign_enum")));
+  EXPECT_FALSE(reflection->HasField(message, F("default_import_enum" )));
+
+  EXPECT_FALSE(reflection->HasField(message, F("default_string_piece")));
+  EXPECT_FALSE(reflection->HasField(message, F("default_cord")));
 
   // Fields with defaults have their default values (duh).
-  EXPECT_EQ( 41    , message.GetInt32 (F("default_int32"   )));
-  EXPECT_EQ( 42    , message.GetInt64 (F("default_int64"   )));
-  EXPECT_EQ( 43    , message.GetUInt32(F("default_uint32"  )));
-  EXPECT_EQ( 44    , message.GetUInt64(F("default_uint64"  )));
-  EXPECT_EQ(-45    , message.GetInt32 (F("default_sint32"  )));
-  EXPECT_EQ( 46    , message.GetInt64 (F("default_sint64"  )));
-  EXPECT_EQ( 47    , message.GetUInt32(F("default_fixed32" )));
-  EXPECT_EQ( 48    , message.GetUInt64(F("default_fixed64" )));
-  EXPECT_EQ( 49    , message.GetInt32 (F("default_sfixed32")));
-  EXPECT_EQ(-50    , message.GetInt64 (F("default_sfixed64")));
-  EXPECT_EQ( 51.5  , message.GetFloat (F("default_float"   )));
-  EXPECT_EQ( 52e3  , message.GetDouble(F("default_double"  )));
-  EXPECT_EQ(true   , message.GetBool  (F("default_bool"    )));
-  EXPECT_EQ("hello", message.GetString(F("default_string"  )));
-  EXPECT_EQ("world", message.GetString(F("default_bytes"   )));
-
-  EXPECT_EQ("hello", message.GetStringReference(F("default_string"), &scratch));
-  EXPECT_EQ("world", message.GetStringReference(F("default_bytes" ), &scratch));
-
-  EXPECT_EQ( nested_bar_, message.GetEnum(F("default_nested_enum" )));
-  EXPECT_EQ(foreign_bar_, message.GetEnum(F("default_foreign_enum")));
-  EXPECT_EQ( import_bar_, message.GetEnum(F("default_import_enum" )));
-
-  EXPECT_EQ("abc", message.GetString(F("default_string_piece")));
-  EXPECT_EQ("abc", message.GetStringReference(F("default_string_piece"),
-                                              &scratch));
-
-  EXPECT_EQ("123", message.GetString(F("default_cord")));
-  EXPECT_EQ("123", message.GetStringReference(F("default_cord"), &scratch));
+  EXPECT_EQ( 41    , reflection->GetInt32 (message, F("default_int32"   )));
+  EXPECT_EQ( 42    , reflection->GetInt64 (message, F("default_int64"   )));
+  EXPECT_EQ( 43    , reflection->GetUInt32(message, F("default_uint32"  )));
+  EXPECT_EQ( 44    , reflection->GetUInt64(message, F("default_uint64"  )));
+  EXPECT_EQ(-45    , reflection->GetInt32 (message, F("default_sint32"  )));
+  EXPECT_EQ( 46    , reflection->GetInt64 (message, F("default_sint64"  )));
+  EXPECT_EQ( 47    , reflection->GetUInt32(message, F("default_fixed32" )));
+  EXPECT_EQ( 48    , reflection->GetUInt64(message, F("default_fixed64" )));
+  EXPECT_EQ( 49    , reflection->GetInt32 (message, F("default_sfixed32")));
+  EXPECT_EQ(-50    , reflection->GetInt64 (message, F("default_sfixed64")));
+  EXPECT_EQ( 51.5  , reflection->GetFloat (message, F("default_float"   )));
+  EXPECT_EQ( 52e3  , reflection->GetDouble(message, F("default_double"  )));
+  EXPECT_EQ(true   , reflection->GetBool  (message, F("default_bool"    )));
+  EXPECT_EQ("hello", reflection->GetString(message, F("default_string"  )));
+  EXPECT_EQ("world", reflection->GetString(message, F("default_bytes"   )));
+
+  EXPECT_EQ("hello", reflection->GetStringReference(message, F("default_string"), &scratch));
+  EXPECT_EQ("world", reflection->GetStringReference(message, F("default_bytes" ), &scratch));
+
+  EXPECT_EQ( nested_bar_, reflection->GetEnum(message, F("default_nested_enum" )));
+  EXPECT_EQ(foreign_bar_, reflection->GetEnum(message, F("default_foreign_enum")));
+  EXPECT_EQ( import_bar_, reflection->GetEnum(message, F("default_import_enum" )));
+
+  EXPECT_EQ("abc", reflection->GetString(message, F("default_string_piece")));
+  EXPECT_EQ("abc", reflection->GetStringReference(message, F("default_string_piece"), &scratch));
+
+  EXPECT_EQ("123", reflection->GetString(message, F("default_cord")));
+  EXPECT_EQ("123", reflection->GetStringReference(message, F("default_cord"), &scratch));
 }
 
 // -------------------------------------------------------------------
 
 void TestUtil::ReflectionTester::ModifyRepeatedFieldsViaReflection(
-    Message::Reflection* message) {
-  message->SetRepeatedInt32 (F("repeated_int32"   ), 1, 501);
-  message->SetRepeatedInt64 (F("repeated_int64"   ), 1, 502);
-  message->SetRepeatedUInt32(F("repeated_uint32"  ), 1, 503);
-  message->SetRepeatedUInt64(F("repeated_uint64"  ), 1, 504);
-  message->SetRepeatedInt32 (F("repeated_sint32"  ), 1, 505);
-  message->SetRepeatedInt64 (F("repeated_sint64"  ), 1, 506);
-  message->SetRepeatedUInt32(F("repeated_fixed32" ), 1, 507);
-  message->SetRepeatedUInt64(F("repeated_fixed64" ), 1, 508);
-  message->SetRepeatedInt32 (F("repeated_sfixed32"), 1, 509);
-  message->SetRepeatedInt64 (F("repeated_sfixed64"), 1, 510);
-  message->SetRepeatedFloat (F("repeated_float"   ), 1, 511);
-  message->SetRepeatedDouble(F("repeated_double"  ), 1, 512);
-  message->SetRepeatedBool  (F("repeated_bool"    ), 1, true);
-  message->SetRepeatedString(F("repeated_string"  ), 1, "515");
-  message->SetRepeatedString(F("repeated_bytes"   ), 1, "516");
-
-  message->MutableRepeatedMessage(F("repeatedgroup"), 1)
-         ->GetReflection()->SetInt32(repeated_group_a_, 517);
-  message->MutableRepeatedMessage(F("repeated_nested_message"), 1)
-         ->GetReflection()->SetInt32(nested_b_, 518);
-  message->MutableRepeatedMessage(F("repeated_foreign_message"), 1)
-         ->GetReflection()->SetInt32(foreign_c_, 519);
-  message->MutableRepeatedMessage(F("repeated_import_message"), 1)
-         ->GetReflection()->SetInt32(import_d_, 520);
-
-  message->SetRepeatedEnum(F("repeated_nested_enum" ), 1,  nested_foo_);
-  message->SetRepeatedEnum(F("repeated_foreign_enum"), 1, foreign_foo_);
-  message->SetRepeatedEnum(F("repeated_import_enum" ), 1,  import_foo_);
-
-  message->SetRepeatedString(F("repeated_string_piece"), 1, "524");
-  message->SetRepeatedString(F("repeated_cord"), 1, "525");
+    Message* message) {
+  const Reflection* reflection = message->GetReflection();
+  Message* sub_message;
+
+  reflection->SetRepeatedInt32 (message, F("repeated_int32"   ), 1, 501);
+  reflection->SetRepeatedInt64 (message, F("repeated_int64"   ), 1, 502);
+  reflection->SetRepeatedUInt32(message, F("repeated_uint32"  ), 1, 503);
+  reflection->SetRepeatedUInt64(message, F("repeated_uint64"  ), 1, 504);
+  reflection->SetRepeatedInt32 (message, F("repeated_sint32"  ), 1, 505);
+  reflection->SetRepeatedInt64 (message, F("repeated_sint64"  ), 1, 506);
+  reflection->SetRepeatedUInt32(message, F("repeated_fixed32" ), 1, 507);
+  reflection->SetRepeatedUInt64(message, F("repeated_fixed64" ), 1, 508);
+  reflection->SetRepeatedInt32 (message, F("repeated_sfixed32"), 1, 509);
+  reflection->SetRepeatedInt64 (message, F("repeated_sfixed64"), 1, 510);
+  reflection->SetRepeatedFloat (message, F("repeated_float"   ), 1, 511);
+  reflection->SetRepeatedDouble(message, F("repeated_double"  ), 1, 512);
+  reflection->SetRepeatedBool  (message, F("repeated_bool"    ), 1, true);
+  reflection->SetRepeatedString(message, F("repeated_string"  ), 1, "515");
+  reflection->SetRepeatedString(message, F("repeated_bytes"   ), 1, "516");
+
+  sub_message = reflection->MutableRepeatedMessage(message, F("repeatedgroup"), 1);
+  sub_message->GetReflection()->SetInt32(sub_message, repeated_group_a_, 517);
+  sub_message = reflection->MutableRepeatedMessage(message, F("repeated_nested_message"), 1);
+  sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 518);
+  sub_message = reflection->MutableRepeatedMessage(message, F("repeated_foreign_message"), 1);
+  sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 519);
+  sub_message = reflection->MutableRepeatedMessage(message, F("repeated_import_message"), 1);
+  sub_message->GetReflection()->SetInt32(sub_message, import_d_, 520);
+
+  reflection->SetRepeatedEnum(message, F("repeated_nested_enum" ), 1,  nested_foo_);
+  reflection->SetRepeatedEnum(message, F("repeated_foreign_enum"), 1, foreign_foo_);
+  reflection->SetRepeatedEnum(message, F("repeated_import_enum" ), 1,  import_foo_);
+
+  reflection->SetRepeatedString(message, F("repeated_string_piece"), 1, "524");
+  reflection->SetRepeatedString(message, F("repeated_cord"), 1, "525");
 }
 
 }  // namespace protobuf
diff --git a/src/google/protobuf/test_util.h b/src/google/protobuf/test_util.h
index 4157d095f4c62a5ef2955843fa99c566e42f81ee..4c578bcd2abd06043a313531deee4ee4e129a617 100644
--- a/src/google/protobuf/test_util.h
+++ b/src/google/protobuf/test_util.h
@@ -78,11 +78,10 @@ class TestUtil {
     // its file.
     explicit ReflectionTester(const Descriptor* base_descriptor);
 
-    void SetAllFieldsViaReflection(Message::Reflection* message);
-    void ModifyRepeatedFieldsViaReflection(Message::Reflection* message);
-    void ExpectAllFieldsSetViaReflection(
-        const Message::Reflection& message);
-    void ExpectClearViaReflection(const Message::Reflection& message);
+    void SetAllFieldsViaReflection(Message* message);
+    void ModifyRepeatedFieldsViaReflection(Message* message);
+    void ExpectAllFieldsSetViaReflection(const Message& message);
+    void ExpectClearViaReflection(const Message& message);
 
    private:
     const FieldDescriptor* F(const string& name);
diff --git a/src/google/protobuf/testing/googletest.cc b/src/google/protobuf/testing/googletest.cc
index aabc657fb789e1512315a65285fd8b73aadea2d1..65c1154f58243d4867006b9d9a5b20ce23808397 100644
--- a/src/google/protobuf/testing/googletest.cc
+++ b/src/google/protobuf/testing/googletest.cc
@@ -126,9 +126,28 @@ string TestTempDir() {
   return temp_dir_deleter_.GetTempDir();
 }
 
+// TODO(kenton):  Share duplicated code below.  Too busy/lazy for now.
+
+static string stdout_capture_filename_;
 static string stderr_capture_filename_;
+static int original_stdout_ = -1;
 static int original_stderr_ = -1;
 
+void CaptureTestStdout() {
+  GOOGLE_CHECK_EQ(original_stdout_, -1) << "Already capturing.";
+
+  stdout_capture_filename_ = TestTempDir() + "/captured_stdout";
+
+  int fd = open(stdout_capture_filename_.c_str(),
+                O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0777);
+  GOOGLE_CHECK(fd >= 0) << "open: " << strerror(errno);
+
+  original_stdout_ = dup(1);
+  close(1);
+  dup2(fd, 1);
+  close(fd);
+}
+
 void CaptureTestStderr() {
   GOOGLE_CHECK_EQ(original_stderr_, -1) << "Already capturing.";
 
@@ -144,6 +163,21 @@ void CaptureTestStderr() {
   close(fd);
 }
 
+string GetCapturedTestStdout() {
+  GOOGLE_CHECK_NE(original_stdout_, -1) << "Not capturing.";
+
+  close(1);
+  dup2(original_stdout_, 1);
+  original_stdout_ = -1;
+
+  string result;
+  File::ReadFileToStringOrDie(stdout_capture_filename_, &result);
+
+  remove(stdout_capture_filename_.c_str());
+
+  return result;
+}
+
 string GetCapturedTestStderr() {
   GOOGLE_CHECK_NE(original_stderr_, -1) << "Not capturing.";
 
diff --git a/src/google/protobuf/testing/googletest.h b/src/google/protobuf/testing/googletest.h
index 9420641a10e837267a07e0fd73e44f02c736e0bc..bb4aafab82561f7999d70757786bef2b63483c02 100644
--- a/src/google/protobuf/testing/googletest.h
+++ b/src/google/protobuf/testing/googletest.h
@@ -33,10 +33,12 @@ string TestSourceDir();
 // placed.
 string TestTempDir();
 
-// Capture all text written to stderr.
+// Capture all text written to stdout or stderr.
+void CaptureTestStdout();
 void CaptureTestStderr();
 
-// Stop capturing stderr and return the text captured.
+// Stop capturing stdout or stderr and return the text captured.
+string GetCapturedTestStdout();
 string GetCapturedTestStderr();
 
 // For use with ScopedMemoryLog::GetMessages().  Inside Google the LogLevel
diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc
index d698681c23cdd770754a0c5a4f25f6290d371f2b..a23186780748693d283c354df0e85ccd06175a2c 100644
--- a/src/google/protobuf/text_format.cc
+++ b/src/google/protobuf/text_format.cc
@@ -103,9 +103,7 @@ class TextFormat::ParserImpl {
   // false if an error occurs (an error will also be logged to
   // GOOGLE_LOG(ERROR)).
   bool Parse(Message* output) {
-    Message::Reflection* reflection = output->GetReflection();
-    const Descriptor* descriptor = output->GetDescriptor();
-    root_message_type_ = descriptor;
+    root_message_type_ = output->GetDescriptor();
 
     // Consume fields until we cannot do so anymore.
     while(true) {
@@ -113,7 +111,7 @@ class TextFormat::ParserImpl {
         return true;
       }
 
-      DO(ConsumeField(reflection, descriptor));
+      DO(ConsumeField(output));
     }
   }
 
@@ -148,11 +146,8 @@ class TextFormat::ParserImpl {
   // This method checks to see that the end delimeter at the conclusion of
   // the consumption matches the starting delimeter passed in here.
   bool ConsumeMessage(Message* message, const string delimeter) {
-    Message::Reflection* reflection = message->GetReflection();
-    const Descriptor* descriptor = message->GetDescriptor();
-
     while (!LookingAt(">") &&  !LookingAt("}")) {
-      DO(ConsumeField(reflection, descriptor));
+      DO(ConsumeField(message));
     }
 
     // Confirm that we have a valid ending delimeter.
@@ -163,8 +158,10 @@ class TextFormat::ParserImpl {
 
   // Consumes the current field (as returned by the tokenizer) on the
   // passed in message.
-  bool ConsumeField(Message::Reflection* reflection,
-                    const Descriptor* descriptor) {
+  bool ConsumeField(Message* message) {
+    const Reflection* reflection = message->GetReflection();
+    const Descriptor* descriptor = message->GetDescriptor();
+
     string field_name;
 
     const FieldDescriptor* field = NULL;
@@ -232,19 +229,21 @@ class TextFormat::ParserImpl {
       }
 
       if (field->is_repeated()) {
-        DO(ConsumeMessage(reflection->AddMessage(field), delimeter));
+        DO(ConsumeMessage(reflection->AddMessage(message, field), delimeter));
       } else {
-        DO(ConsumeMessage(reflection->MutableMessage(field), delimeter));
+        DO(ConsumeMessage(reflection->MutableMessage(message, field),
+                          delimeter));
       }
     } else {
       DO(Consume(":"));
-      DO(ConsumeFieldValue(reflection, field));
+      DO(ConsumeFieldValue(message, reflection, field));
     }
 
     return true;
   }
 
-  bool ConsumeFieldValue(Message::Reflection* reflection,
+  bool ConsumeFieldValue(Message* message,
+                         const Reflection* reflection,
                          const FieldDescriptor* field) {
 
 // Define an easy to use macro for setting fields. This macro checks
@@ -252,9 +251,9 @@ class TextFormat::ParserImpl {
 // methods or not (in which case we need to use the Set methods).
 #define SET_FIELD(CPPTYPE, VALUE)                                  \
         if (field->is_repeated()) {                                \
-          reflection->Add##CPPTYPE(field, VALUE);                  \
+          reflection->Add##CPPTYPE(message, field, VALUE);         \
         } else {                                                   \
-          reflection->Set##CPPTYPE(field, VALUE);                  \
+          reflection->Set##CPPTYPE(message, field, VALUE);         \
         }                                                          \
 
     switch(field->cpp_type()) {
@@ -742,7 +741,7 @@ bool TextFormat::Parser::MergeFromString(const string& input,
                                     io::ZeroCopyOutputStream* output) {
   TextGenerator generator(output);
 
-  Print(message.GetDescriptor(), message.GetReflection(), generator);
+  Print(message, generator);
 
   // Output false if the generator failed internally.
   return !generator.failed();
@@ -759,15 +758,15 @@ bool TextFormat::Parser::MergeFromString(const string& input,
   return !generator.failed();
 }
 
-/* static */ void TextFormat::Print(const Descriptor* descriptor,
-                                    const Message::Reflection* message,
+/* static */ void TextFormat::Print(const Message& message,
                                     TextGenerator& generator) {
+  const Reflection* reflection = message.GetReflection();
   vector<const FieldDescriptor*> fields;
-  message->ListFields(&fields);
+  reflection->ListFields(message, &fields);
   for (int i = 0; i < fields.size(); i++) {
-    PrintField(fields[i], message, generator);
+    PrintField(message, reflection, fields[i], generator);
   }
-  PrintUnknownFields(message->GetUnknownFields(), generator);
+  PrintUnknownFields(reflection->GetUnknownFields(message), generator);
 }
 
 /* static */ void TextFormat::PrintFieldValueToString(
@@ -782,17 +781,18 @@ bool TextFormat::Parser::MergeFromString(const string& input,
   io::StringOutputStream output_stream(output);
   TextGenerator generator(&output_stream);
 
-  PrintFieldValue(message.GetReflection(), field, index, generator);
+  PrintFieldValue(message, message.GetReflection(), field, index, generator);
 }
 
-/* static */ void TextFormat::PrintField(const FieldDescriptor* field,
-                                         const Message::Reflection* message,
+/* static */ void TextFormat::PrintField(const Message& message,
+                                         const Reflection* reflection,
+                                         const FieldDescriptor* field,
                                          TextGenerator& generator) {
   int count = 0;
 
   if (field->is_repeated()) {
-    count = message->FieldSize(field);
-  } else if (message->HasField(field)) {
+    count = reflection->FieldSize(message, field);
+  } else if (reflection->HasField(message, field)) {
     count = 1;
   }
 
@@ -831,7 +831,7 @@ bool TextFormat::Parser::MergeFromString(const string& input,
       field_index = -1;
     }
 
-    PrintFieldValue(message, field, field_index, generator);
+    PrintFieldValue(message, reflection, field, field_index, generator);
 
     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
         generator.Outdent();
@@ -843,7 +843,8 @@ bool TextFormat::Parser::MergeFromString(const string& input,
 }
 
 /* static */ void TextFormat::PrintFieldValue(
-    const Message::Reflection* reflection,
+    const Message& message,
+    const Reflection* reflection,
     const FieldDescriptor* field,
     int index,
     TextGenerator& generator) {
@@ -854,8 +855,8 @@ bool TextFormat::Parser::MergeFromString(const string& input,
 #define OUTPUT_FIELD(CPPTYPE, METHOD, TO_STRING)                             \
       case FieldDescriptor::CPPTYPE_##CPPTYPE:                               \
         generator.Print(TO_STRING(field->is_repeated() ?                     \
-                         reflection->GetRepeated##METHOD(field, index) :     \
-                         reflection->Get##METHOD(field)));                   \
+          reflection->GetRepeated##METHOD(message, field, index) :           \
+          reflection->Get##METHOD(message, field)));                         \
         break;                                                               \
 
       OUTPUT_FIELD( INT32,  Int32, SimpleItoa);
@@ -869,8 +870,9 @@ bool TextFormat::Parser::MergeFromString(const string& input,
       case FieldDescriptor::CPPTYPE_STRING: {
         string scratch;
         const string& value = field->is_repeated() ?
-            reflection->GetRepeatedStringReference(field, index, &scratch) :
-            reflection->GetStringReference(field, &scratch);
+            reflection->GetRepeatedStringReference(
+              message, field, index, &scratch) :
+            reflection->GetStringReference(message, field, &scratch);
 
         generator.Print("\"");
         generator.Print(CEscape(value));
@@ -881,24 +883,25 @@ bool TextFormat::Parser::MergeFromString(const string& input,
 
       case FieldDescriptor::CPPTYPE_BOOL:
         if (field->is_repeated()) {
-          generator.Print(reflection->GetRepeatedBool(field, index)
+          generator.Print(reflection->GetRepeatedBool(message, field, index)
                           ? "true" : "false");
         } else {
-          generator.Print(reflection->GetBool(field) ? "true" : "false");
+          generator.Print(reflection->GetBool(message, field)
+                          ? "true" : "false");
         }
         break;
 
       case FieldDescriptor::CPPTYPE_ENUM:
         generator.Print(field->is_repeated() ?
-                        reflection->GetRepeatedEnum(field, index)->name()
-                        : reflection->GetEnum(field)->name());
+          reflection->GetRepeatedEnum(message, field, index)->name() :
+          reflection->GetEnum(message, field)->name());
         break;
 
       case FieldDescriptor::CPPTYPE_MESSAGE:
-        Print(field->message_type(),
-              field->is_repeated() ?
-              reflection->GetRepeatedMessage(field, index).GetReflection()
-              : reflection->GetMessage(field).GetReflection(), generator);
+        Print(field->is_repeated() ?
+                reflection->GetRepeatedMessage(message, field, index) :
+                reflection->GetMessage(message, field),
+              generator);
         break;
   }
 }
diff --git a/src/google/protobuf/text_format.h b/src/google/protobuf/text_format.h
index 00d50ad156247f255e231ca03b55c49c11d52437..cd93c14a00c7f7f475dfc6991378b57359f9a875 100644
--- a/src/google/protobuf/text_format.h
+++ b/src/google/protobuf/text_format.h
@@ -25,7 +25,7 @@
 #define GOOGLE_PROTOBUF_TEXT_FORMAT_H__
 
 #include <string>
-#include <google/protobuf/message.h>  // Message, Message::Reflection
+#include <google/protobuf/message.h>
 #include <google/protobuf/descriptor.h>
 
 namespace google {
@@ -124,18 +124,19 @@ class LIBPROTOBUF_EXPORT TextFormat {
 
   // Internal Print method, used for writing to the OutputStream via
   // the TextGenerator class.
-  static void Print(const Descriptor* descriptor,
-                    const Message::Reflection* message,
+  static void Print(const Message& message,
                     TextGenerator& generator);
 
   // Print a single field.
-  static void PrintField(const FieldDescriptor* field,
-                         const Message::Reflection* message,
+  static void PrintField(const Message& message,
+                         const Reflection* reflection,
+                         const FieldDescriptor* field,
                          TextGenerator& generator);
 
   // Outputs a textual representation of the value of the field supplied on
   // the message supplied or the default value if not set.
-  static void PrintFieldValue(const Message::Reflection* reflection,
+  static void PrintFieldValue(const Message& message,
+                              const Reflection* reflection,
                               const FieldDescriptor* field,
                               int index,
                               TextGenerator& generator);
diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc
index ac4efc941a4c933f3aa66e8fc80929ea2c7817a7..63a0c33134e2fc0c61e3a6f143ce34fe0c3988b7 100644
--- a/src/google/protobuf/text_format_unittest.cc
+++ b/src/google/protobuf/text_format_unittest.cc
@@ -731,7 +731,8 @@ TEST_F(TextFormatMessageSetTest, Deserialize) {
 
   // Ensure that these are the only entries present.
   vector<const FieldDescriptor*> descriptors;
-  proto.message_set().GetReflection()->ListFields(&descriptors);
+  proto.message_set().GetReflection()->ListFields(
+    proto.message_set(), &descriptors);
   EXPECT_EQ(2, descriptors.size());
 }
 
diff --git a/src/google/protobuf/unknown_field_set.h b/src/google/protobuf/unknown_field_set.h
index 2e908c3369d4c675da017bcea967cab4f28edf6d..a3dce33d6a1dea90b03437d3f68673cceb451d9a 100644
--- a/src/google/protobuf/unknown_field_set.h
+++ b/src/google/protobuf/unknown_field_set.h
@@ -43,7 +43,7 @@ class UnknownField;                 // below
 // to be updated every time a new field is added to the message definition.
 //
 // To get the UnknownFieldSet attached to any message, call
-// Message::Reflection::GetUnknownFields().
+// Reflection::GetUnknownFields().
 //
 // This class is necessarily tied to the protocol buffer wire format, unlike
 // the Reflection interface which is independent of any serialization scheme.
diff --git a/src/google/protobuf/unknown_field_set_unittest.cc b/src/google/protobuf/unknown_field_set_unittest.cc
index 39b005f40f5e70fdd7ed477802c5dad8a8a3d5b1..63f1dffde1ebc72f5fd6752fd3873d35cc05a534 100644
--- a/src/google/protobuf/unknown_field_set_unittest.cc
+++ b/src/google/protobuf/unknown_field_set_unittest.cc
@@ -176,8 +176,7 @@ TEST_F(UnknownFieldSetTest, ParseViaReflection) {
   io::ArrayInputStream raw_input(all_fields_data_.data(),
                                  all_fields_data_.size());
   io::CodedInputStream input(&raw_input);
-  ASSERT_TRUE(WireFormat::ParseAndMergePartial(message.GetDescriptor(), &input,
-                                               message.GetReflection()));
+  ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &message));
 
   EXPECT_EQ(message.DebugString(), empty_message_.DebugString());
 }
@@ -191,12 +190,9 @@ TEST_F(UnknownFieldSetTest, SerializeViaReflection) {
   {
     io::StringOutputStream raw_output(&data);
     io::CodedOutputStream output(&raw_output);
-    int size = WireFormat::ByteSize(empty_message_.GetDescriptor(),
-                                    empty_message_.GetReflection());
+    int size = WireFormat::ByteSize(empty_message_);
     ASSERT_TRUE(
-      WireFormat::SerializeWithCachedSizes(empty_message_.GetDescriptor(),
-                                           empty_message_.GetReflection(),
-                                           size, &output));
+      WireFormat::SerializeWithCachedSizes(empty_message_, size, &output));
   }
 
   // Don't use EXPECT_EQ because we don't want to dump raw binary data to
@@ -290,9 +286,7 @@ TEST_F(UnknownFieldSetTest, WrongTypeTreatedAsUnknownViaReflection) {
   string bizarro_data = GetBizarroData();
   io::ArrayInputStream raw_input(bizarro_data.data(), bizarro_data.size());
   io::CodedInputStream input(&raw_input);
-  ASSERT_TRUE(WireFormat::ParseAndMergePartial(
-    all_types_message.GetDescriptor(), &input,
-    all_types_message.GetReflection()));
+  ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &all_types_message));
   ASSERT_TRUE(empty_message.ParseFromString(bizarro_data));
 
   EXPECT_EQ(empty_message.DebugString(), all_types_message.DebugString());
@@ -315,8 +309,7 @@ TEST_F(UnknownFieldSetTest, UnknownExtensionsReflection) {
   io::ArrayInputStream raw_input(all_fields_data_.data(),
                                  all_fields_data_.size());
   io::CodedInputStream input(&raw_input);
-  ASSERT_TRUE(WireFormat::ParseAndMergePartial(message.GetDescriptor(), &input,
-                                               message.GetReflection()));
+  ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &message));
 
   EXPECT_EQ(message.DebugString(), empty_message_.DebugString());
 }
diff --git a/src/google/protobuf/wire_format.cc b/src/google/protobuf/wire_format.cc
index 77e9c74b45a85f940e12219e75d2014bc7577f99..5f87c10369dbbc16bd33922d904be8cc9034e3c7 100644
--- a/src/google/protobuf/wire_format.cc
+++ b/src/google/protobuf/wire_format.cc
@@ -117,7 +117,9 @@ bool WireFormat::SkipField(io::CodedInputStream* input, uint32 tag,
       if (field == NULL) {
         if (!input->Skip(length)) return false;
       } else {
-        input->ReadString(field->add_length_delimited(), length);
+        if (!input->ReadString(field->add_length_delimited(), length)) {
+          return false;
+        }
       }
       return true;
     }
@@ -299,9 +301,11 @@ int WireFormat::ComputeUnknownMessageSetItemsSize(
 
 // ===================================================================
 
-bool WireFormat::ParseAndMergePartial(const Descriptor* descriptor,
-                                      io::CodedInputStream* input,
-                                      Message::Reflection* message_reflection) {
+bool WireFormat::ParseAndMergePartial(io::CodedInputStream* input,
+                                      Message* message) {
+  const Descriptor* descriptor = message->GetDescriptor();
+  const Reflection* message_reflection = message->GetReflection();
+
   while(true) {
     uint32 tag = input->ReadTag();
     if (tag == 0) {
@@ -330,14 +334,14 @@ bool WireFormat::ParseAndMergePartial(const Descriptor* descriptor,
       if (field == NULL &&
           descriptor->options().message_set_wire_format() &&
           tag == kMessageSetItemStartTag) {
-        if (!ParseAndMergeMessageSetItem(input, message_reflection)) {
+        if (!ParseAndMergeMessageSetItem(input, message)) {
           return false;
         }
         continue;  // Skip ParseAndMergeField(); already taken care of.
       }
     }
 
-    if (!ParseAndMergeField(tag, field, message_reflection, input)) {
+    if (!ParseAndMergeField(tag, field, message, input)) {
       return false;
     }
   }
@@ -346,13 +350,16 @@ bool WireFormat::ParseAndMergePartial(const Descriptor* descriptor,
 bool WireFormat::ParseAndMergeField(
     uint32 tag,
     const FieldDescriptor* field,        // May be NULL for unknown
-    Message::Reflection* message_reflection,
+    Message* message,
     io::CodedInputStream* input) {
+  const Reflection* message_reflection = message->GetReflection();
+
   if (field == NULL ||
       GetTagWireType(tag) != WireTypeForFieldType(field->type())) {
     // We don't recognize this field.  Either the field number is unknown
     // or the wire type doesn't match.  Put it in our unknown field set.
-    return SkipField(input, tag, message_reflection->MutableUnknownFields());
+    return SkipField(input, tag,
+                     message_reflection->MutableUnknownFields(message));
   }
 
   switch (field->type()) {
@@ -361,9 +368,9 @@ bool WireFormat::ParseAndMergeField(
       CPPTYPE value;                                                    \
       if (!Read##TYPE_METHOD(input, &value)) return false;              \
       if (field->is_repeated()) {                                       \
-        message_reflection->Add##CPPTYPE_METHOD(field, value);          \
+        message_reflection->Add##CPPTYPE_METHOD(message, field, value); \
       } else {                                                          \
-        message_reflection->Set##CPPTYPE_METHOD(field, value);          \
+        message_reflection->Set##CPPTYPE_METHOD(message, field, value); \
       }                                                                 \
       break;                                                            \
     }
@@ -397,15 +404,15 @@ bool WireFormat::ParseAndMergeField(
         field->enum_type()->FindValueByNumber(value);
       if (enum_value != NULL) {
         if (field->is_repeated()) {
-          message_reflection->AddEnum(field, enum_value);
+          message_reflection->AddEnum(message, field, enum_value);
         } else {
-          message_reflection->SetEnum(field, enum_value);
+          message_reflection->SetEnum(message, field, enum_value);
         }
       } else {
         // The enum value is not one of the known values.  Add it to the
         // UnknownFieldSet.
         int64 sign_extended_value = static_cast<int64>(value);
-        message_reflection->MutableUnknownFields()
+        message_reflection->MutableUnknownFields(message)
                           ->AddField(GetTagFieldNumber(tag))
                           ->add_varint(sign_extended_value);
       }
@@ -416,9 +423,9 @@ bool WireFormat::ParseAndMergeField(
     case FieldDescriptor::TYPE_GROUP: {
       Message* sub_message;
       if (field->is_repeated()) {
-        sub_message = message_reflection->AddMessage(field);
+        sub_message = message_reflection->AddMessage(message, field);
       } else {
-        sub_message = message_reflection->MutableMessage(field);
+        sub_message = message_reflection->MutableMessage(message, field);
       }
 
       if (!ReadGroup(GetTagFieldNumber(tag), input, sub_message)) return false;
@@ -428,9 +435,9 @@ bool WireFormat::ParseAndMergeField(
     case FieldDescriptor::TYPE_MESSAGE: {
       Message* sub_message;
       if (field->is_repeated()) {
-        sub_message = message_reflection->AddMessage(field);
+        sub_message = message_reflection->AddMessage(message, field);
       } else {
-        sub_message = message_reflection->MutableMessage(field);
+        sub_message = message_reflection->MutableMessage(message, field);
       }
 
       if (!ReadMessage(input, sub_message)) return false;
@@ -443,7 +450,9 @@ bool WireFormat::ParseAndMergeField(
 
 bool WireFormat::ParseAndMergeMessageSetItem(
     io::CodedInputStream* input,
-    Message::Reflection* message_reflection) {
+    Message* message) {
+  const Reflection* message_reflection = message->GetReflection();
+
   // This method parses a group which should contain two fields:
   //   required int32 type_id = 2;
   //   required data message = 3;
@@ -481,7 +490,7 @@ bool WireFormat::ParseAndMergeMessageSetItem(
           io::ArrayInputStream raw_input(message_data.data(),
                                          message_data.size());
           io::CodedInputStream sub_input(&raw_input);
-          if (!ParseAndMergeField(fake_tag, field, message_reflection,
+          if (!ParseAndMergeField(fake_tag, field, message,
                                   &sub_input)) {
             return false;
           }
@@ -501,7 +510,7 @@ bool WireFormat::ParseAndMergeMessageSetItem(
           message_data.append(temp);
         } else {
           // Already saw type_id, so we can parse this directly.
-          if (!ParseAndMergeField(fake_tag, field, message_reflection, input)) {
+          if (!ParseAndMergeField(fake_tag, field, message, input)) {
             return false;
           }
         }
@@ -523,27 +532,28 @@ bool WireFormat::ParseAndMergeMessageSetItem(
 // ===================================================================
 
 bool WireFormat::SerializeWithCachedSizes(
-    const Descriptor* descriptor,
-    const Message::Reflection* message_reflection,
+    const Message& message,
     int size, io::CodedOutputStream* output) {
+  const Descriptor* descriptor = message.GetDescriptor();
+  const Reflection* message_reflection = message.GetReflection();
   int expected_endpoint = output->ByteCount() + size;
 
   vector<const FieldDescriptor*> fields;
-  message_reflection->ListFields(&fields);
+  message_reflection->ListFields(message, &fields);
   for (int i = 0; i < fields.size(); i++) {
-    if (!SerializeFieldWithCachedSizes(fields[i], message_reflection, output)) {
+    if (!SerializeFieldWithCachedSizes(fields[i], message, output)) {
       return false;
     }
   }
 
   if (descriptor->options().message_set_wire_format()) {
     if (!SerializeUnknownMessageSetItems(
-           message_reflection->GetUnknownFields(), output)) {
+           message_reflection->GetUnknownFields(message), output)) {
       return false;
     }
   } else {
     if (!SerializeUnknownFields(
-           message_reflection->GetUnknownFields(), output)) {
+           message_reflection->GetUnknownFields(message), output)) {
       return false;
     }
   }
@@ -558,21 +568,23 @@ bool WireFormat::SerializeWithCachedSizes(
 
 bool WireFormat::SerializeFieldWithCachedSizes(
     const FieldDescriptor* field,
-    const Message::Reflection* message_reflection,
+    const Message& message,
     io::CodedOutputStream* output) {
+  const Reflection* message_reflection = message.GetReflection();
+
   if (field->is_extension() &&
       field->containing_type()->options().message_set_wire_format() &&
       field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
       !field->is_repeated()) {
     return SerializeMessageSetItemWithCachedSizes(
-      field, message_reflection, output);
+      field, message, output);
   }
 
   int count = 0;
 
   if (field->is_repeated()) {
-    count = message_reflection->FieldSize(field);
-  } else if (message_reflection->HasField(field)) {
+    count = message_reflection->FieldSize(message, field);
+  } else if (message_reflection->HasField(message, field)) {
     count = 1;
   }
 
@@ -583,8 +595,9 @@ bool WireFormat::SerializeFieldWithCachedSizes(
         if (!Write##TYPE_METHOD(                                             \
               field->number(),                                               \
               field->is_repeated() ?                                         \
-                message_reflection->GetRepeated##CPPTYPE_METHOD(field, j) :  \
-                message_reflection->Get##CPPTYPE_METHOD(field),              \
+                message_reflection->GetRepeated##CPPTYPE_METHOD(             \
+                  message, field, j) :                                       \
+                message_reflection->Get##CPPTYPE_METHOD(message, field),     \
               output)) {                                                     \
           return false;                                                      \
         }                                                                    \
@@ -613,8 +626,8 @@ bool WireFormat::SerializeFieldWithCachedSizes(
 
       case FieldDescriptor::TYPE_ENUM: {
         const EnumValueDescriptor* value = field->is_repeated() ?
-          message_reflection->GetRepeatedEnum(field, j) :
-          message_reflection->GetEnum(field);
+          message_reflection->GetRepeatedEnum(message, field, j) :
+          message_reflection->GetEnum(message, field);
         if (!WriteEnum(field->number(), value->number(), output)) return false;
         break;
       }
@@ -625,8 +638,9 @@ bool WireFormat::SerializeFieldWithCachedSizes(
       case FieldDescriptor::TYPE_BYTES: {
           string scratch;
           const string& value = field->is_repeated() ?
-            message_reflection->GetRepeatedStringReference(field, j, &scratch) :
-            message_reflection->GetStringReference(field, &scratch);
+            message_reflection->GetRepeatedStringReference(
+              message, field, j, &scratch) :
+            message_reflection->GetStringReference(message, field, &scratch);
           if (!WriteString(field->number(), value, output)) return false;
         break;
       }
@@ -638,8 +652,10 @@ bool WireFormat::SerializeFieldWithCachedSizes(
 
 bool WireFormat::SerializeMessageSetItemWithCachedSizes(
     const FieldDescriptor* field,
-    const Message::Reflection* message_reflection,
+    const Message& message,
     io::CodedOutputStream* output) {
+  const Reflection* message_reflection = message.GetReflection();
+
   // Start group.
   if (!output->WriteVarint32(kMessageSetItemStartTag)) return false;
 
@@ -650,7 +666,7 @@ bool WireFormat::SerializeMessageSetItemWithCachedSizes(
   // Write message.
   if (!output->WriteVarint32(kMessageSetMessageTag)) return false;
 
-  const Message& sub_message = message_reflection->GetMessage(field);
+  const Message& sub_message = message_reflection->GetMessage(message, field);
   if (!output->WriteVarint32(sub_message.GetCachedSize())) return false;
   if (!sub_message.SerializeWithCachedSizes(output)) return false;
 
@@ -662,23 +678,24 @@ bool WireFormat::SerializeMessageSetItemWithCachedSizes(
 
 // ===================================================================
 
-int WireFormat::ByteSize(
-    const Descriptor* descriptor,
-    const Message::Reflection* message_reflection) {
+int WireFormat::ByteSize(const Message& message) {
+  const Descriptor* descriptor = message.GetDescriptor();
+  const Reflection* message_reflection = message.GetReflection();
+
   int our_size = 0;
 
   vector<const FieldDescriptor*> fields;
-  message_reflection->ListFields(&fields);
+  message_reflection->ListFields(message, &fields);
   for (int i = 0; i < fields.size(); i++) {
-    our_size += FieldByteSize(fields[i], message_reflection);
+    our_size += FieldByteSize(fields[i], message);
   }
 
   if (descriptor->options().message_set_wire_format()) {
     our_size += ComputeUnknownMessageSetItemsSize(
-      message_reflection->GetUnknownFields());
+      message_reflection->GetUnknownFields(message));
   } else {
     our_size += ComputeUnknownFieldsSize(
-      message_reflection->GetUnknownFields());
+      message_reflection->GetUnknownFields(message));
   }
 
   return our_size;
@@ -686,12 +703,14 @@ int WireFormat::ByteSize(
 
 int WireFormat::FieldByteSize(
     const FieldDescriptor* field,
-    const Message::Reflection* message_reflection) {
+    const Message& message) {
+  const Reflection* message_reflection = message.GetReflection();
+
   if (field->is_extension() &&
       field->containing_type()->options().message_set_wire_format() &&
       field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
       !field->is_repeated()) {
-    return MessageSetItemByteSize(field, message_reflection);
+    return MessageSetItemByteSize(field, message);
   }
 
   int our_size = 0;
@@ -699,8 +718,8 @@ int WireFormat::FieldByteSize(
   int count = 0;
 
   if (field->is_repeated()) {
-    count = message_reflection->FieldSize(field);
-  } else if (message_reflection->HasField(field)) {
+    count = message_reflection->FieldSize(message, field);
+  } else if (message_reflection->HasField(message, field)) {
     count = 1;
   }
 
@@ -712,11 +731,12 @@ int WireFormat::FieldByteSize(
       if (field->is_repeated()) {                                          \
         for (int j = 0; j < count; j++) {                                  \
           our_size += TYPE_METHOD##Size(                                   \
-            message_reflection->GetRepeated##CPPTYPE_METHOD(field, j));    \
+            message_reflection->GetRepeated##CPPTYPE_METHOD(               \
+              message, field, j));                                         \
         }                                                                  \
       } else {                                                             \
         our_size += TYPE_METHOD##Size(                                     \
-          message_reflection->Get##CPPTYPE_METHOD(field));                 \
+          message_reflection->Get##CPPTYPE_METHOD(message, field));        \
       }                                                                    \
       break;
 
@@ -751,11 +771,11 @@ int WireFormat::FieldByteSize(
       if (field->is_repeated()) {
         for (int j = 0; j < count; j++) {
           our_size += EnumSize(
-            message_reflection->GetRepeatedEnum(field, j)->number());
+            message_reflection->GetRepeatedEnum(message, field, j)->number());
         }
       } else {
         our_size += EnumSize(
-          message_reflection->GetEnum(field)->number());
+          message_reflection->GetEnum(message, field)->number());
       }
       break;
     }
@@ -767,8 +787,9 @@ int WireFormat::FieldByteSize(
         for (int j = 0; j < count; j++) {
           string scratch;
           const string& value = field->is_repeated() ?
-            message_reflection->GetRepeatedStringReference(field, j, &scratch) :
-            message_reflection->GetStringReference(field, &scratch);
+            message_reflection->GetRepeatedStringReference(
+              message, field, j, &scratch) :
+            message_reflection->GetStringReference(message, field, &scratch);
           our_size += StringSize(value);
         }
       break;
@@ -780,14 +801,16 @@ int WireFormat::FieldByteSize(
 
 int WireFormat::MessageSetItemByteSize(
     const FieldDescriptor* field,
-    const Message::Reflection* message_reflection) {
+    const Message& message) {
+  const Reflection* message_reflection = message.GetReflection();
+
   int our_size = kMessageSetItemTagsSize;
 
   // type_id
   our_size += io::CodedOutputStream::VarintSize32(field->number());
 
   // message
-  const Message& sub_message = message_reflection->GetMessage(field);
+  const Message& sub_message = message_reflection->GetMessage(message, field);
   int message_size = sub_message.ByteSize();
 
   our_size += io::CodedOutputStream::VarintSize32(message_size);
diff --git a/src/google/protobuf/wire_format.h b/src/google/protobuf/wire_format.h
index d59f3fc13bc8a510d32cd9722ad404cd46c0a8f7..7e8ab5db055f0c3c7cebcad6209ac9193828ec8e 100644
--- a/src/google/protobuf/wire_format.h
+++ b/src/google/protobuf/wire_format.h
@@ -26,7 +26,7 @@
 #define GOOGLE_PROTOBUF_WIRE_FORMAT_H__
 
 #include <string>
-#include <google/protobuf/message.h>  // Message::Reflection
+#include <google/protobuf/message.h>
 #include <google/protobuf/descriptor.h>
 
 namespace google {
@@ -55,7 +55,7 @@ class LIBPROTOBUF_EXPORT WireFormat {
  public:
   // These procedures can be used to implement the methods of Message which
   // handle parsing and serialization of the protocol buffer wire format
-  // using only the Message::Reflection interface.  When you ask the protocol
+  // using only the Reflection interface.  When you ask the protocol
   // compiler to optimize for code size rather than speed, it will implement
   // those methods in terms of these procedures.  Of course, these are much
   // slower than the specialized implementations which the protocol compiler
@@ -69,9 +69,8 @@ class LIBPROTOBUF_EXPORT WireFormat {
   //
   // Required fields are NOT checked by this method.  You must call
   // IsInitialized() on the resulting message yourself.
-  static bool ParseAndMergePartial(const Descriptor* descriptor,
-                                   io::CodedInputStream* input,
-                                   Message::Reflection* message_reflection);
+  static bool ParseAndMergePartial(io::CodedInputStream* input,
+                                   Message* message);
 
   // Serialize a message in protocol buffer wire format.
   //
@@ -81,8 +80,7 @@ class LIBPROTOBUF_EXPORT WireFormat {
   //
   // These return false iff the underlying stream returns a write error.
   static bool SerializeWithCachedSizes(
-      const Descriptor* descriptor,
-      const Message::Reflection* message_reflection,
+      const Message& message,
       int size, io::CodedOutputStream* output);
 
   // Implements Message::ByteSize() via reflection.  WARNING:  The result
@@ -90,8 +88,7 @@ class LIBPROTOBUF_EXPORT WireFormat {
   // will have their ByteSize() methods called, so their sizes will be cached.
   // Therefore, calling this method is sufficient to allow you to call
   // WireFormat::SerializeWithCachedSizes() on the same object.
-  static int ByteSize(const Descriptor* descriptor,
-                      const Message::Reflection* message_reflection);
+  static int ByteSize(const Message& message);
 
   // -----------------------------------------------------------------
   // Helpers for dealing with unknown fields
@@ -188,13 +185,13 @@ class LIBPROTOBUF_EXPORT WireFormat {
   static bool ParseAndMergeField(
       uint32 tag,
       const FieldDescriptor* field,        // May be NULL for unknown
-      Message::Reflection* message_reflection,
+      Message* message,
       io::CodedInputStream* input);
 
   // Serialize a single field.
   static bool SerializeFieldWithCachedSizes(
       const FieldDescriptor* field,        // Cannot be NULL
-      const Message::Reflection* message_reflection,
+      const Message& message,
       io::CodedOutputStream* output);
 
   // Compute size of a single field.  If the field is a message type, this
@@ -202,7 +199,7 @@ class LIBPROTOBUF_EXPORT WireFormat {
   // its size.
   static int FieldByteSize(
       const FieldDescriptor* field,        // Cannot be NULL
-      const Message::Reflection* message_reflection);
+      const Message& message);
 
   // =================================================================
   // Methods for reading/writing individual field.  The implementations
@@ -335,14 +332,14 @@ class LIBPROTOBUF_EXPORT WireFormat {
   // opion message_set_wire_format = true.
   static bool ParseAndMergeMessageSetItem(
       io::CodedInputStream* input,
-      Message::Reflection* message_reflection);
+      Message* message);
   static bool SerializeMessageSetItemWithCachedSizes(
       const FieldDescriptor* field,
-      const Message::Reflection* message_reflection,
+      const Message& message,
       io::CodedOutputStream* output);
   static int MessageSetItemByteSize(
       const FieldDescriptor* field,
-      const Message::Reflection* message_reflection);
+      const Message& message);
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(WireFormat);
 };
diff --git a/src/google/protobuf/wire_format_unittest.cc b/src/google/protobuf/wire_format_unittest.cc
index 7430786c7e637cea4b905657ac294011ddc80fce..f5953beac410b1352d5932cd46bf23548edf1f7f 100644
--- a/src/google/protobuf/wire_format_unittest.cc
+++ b/src/google/protobuf/wire_format_unittest.cc
@@ -53,8 +53,7 @@ TEST(WireFormatTest, Parse) {
   // Parse using WireFormat.
   io::ArrayInputStream raw_input(data.data(), data.size());
   io::CodedInputStream input(&raw_input);
-  WireFormat::ParseAndMergePartial(unittest::TestAllTypes::descriptor(),
-                                   &input, dest.GetReflection());
+  WireFormat::ParseAndMergePartial(&input, &dest);
 
   // Check.
   TestUtil::ExpectAllFieldsSet(dest);
@@ -71,8 +70,7 @@ TEST(WireFormatTest, ParseExtensions) {
   // Parse using WireFormat.
   io::ArrayInputStream raw_input(data.data(), data.size());
   io::CodedInputStream input(&raw_input);
-  WireFormat::ParseAndMergePartial(unittest::TestAllExtensions::descriptor(),
-                                   &input, dest.GetReflection());
+  WireFormat::ParseAndMergePartial(&input, &dest);
 
   // Check.
   TestUtil::ExpectAllExtensionsSet(dest);
@@ -82,13 +80,10 @@ TEST(WireFormatTest, ByteSize) {
   unittest::TestAllTypes message;
   TestUtil::SetAllFields(&message);
 
-  EXPECT_EQ(message.ByteSize(),
-            WireFormat::ByteSize(unittest::TestAllTypes::descriptor(),
-                                 message.GetReflection()));
+  EXPECT_EQ(message.ByteSize(), WireFormat::ByteSize(message));
   message.Clear();
   EXPECT_EQ(0, message.ByteSize());
-  EXPECT_EQ(0, WireFormat::ByteSize(unittest::TestAllTypes::descriptor(),
-                                    message.GetReflection()));
+  EXPECT_EQ(0, WireFormat::ByteSize(message));
 }
 
 TEST(WireFormatTest, ByteSizeExtensions) {
@@ -96,12 +91,10 @@ TEST(WireFormatTest, ByteSizeExtensions) {
   TestUtil::SetAllExtensions(&message);
 
   EXPECT_EQ(message.ByteSize(),
-            WireFormat::ByteSize(unittest::TestAllExtensions::descriptor(),
-                                 message.GetReflection()));
+            WireFormat::ByteSize(message));
   message.Clear();
   EXPECT_EQ(0, message.ByteSize());
-  EXPECT_EQ(0, WireFormat::ByteSize(unittest::TestAllExtensions::descriptor(),
-                                    message.GetReflection()));
+  EXPECT_EQ(0, WireFormat::ByteSize(message));
 }
 
 TEST(WireFormatTest, Serialize) {
@@ -123,9 +116,7 @@ TEST(WireFormatTest, Serialize) {
   {
     io::StringOutputStream raw_output(&dynamic_data);
     io::CodedOutputStream output(&raw_output);
-    WireFormat::SerializeWithCachedSizes(
-      unittest::TestAllTypes::descriptor(),
-      message.GetReflection(), size, &output);
+    WireFormat::SerializeWithCachedSizes(message, size, &output);
   }
 
   // Should be the same.
@@ -153,9 +144,7 @@ TEST(WireFormatTest, SerializeExtensions) {
   {
     io::StringOutputStream raw_output(&dynamic_data);
     io::CodedOutputStream output(&raw_output);
-    WireFormat::SerializeWithCachedSizes(
-      unittest::TestAllExtensions::descriptor(),
-      message.GetReflection(), size, &output);
+    WireFormat::SerializeWithCachedSizes(message, size, &output);
   }
 
   // Should be the same.
@@ -183,9 +172,7 @@ TEST(WireFormatTest, SerializeFieldsAndExtensions) {
   {
     io::StringOutputStream raw_output(&dynamic_data);
     io::CodedOutputStream output(&raw_output);
-    WireFormat::SerializeWithCachedSizes(
-      unittest::TestFieldOrderings::descriptor(),
-      message.GetReflection(), size, &output);
+    WireFormat::SerializeWithCachedSizes(message, size, &output);
   }
 
   // Should be the same.
@@ -497,9 +484,9 @@ TEST_F(WireFormatInvalidInputTest, InvalidGroup) {
 }
 
 TEST_F(WireFormatInvalidInputTest, InvalidUnknownGroup) {
-  // Use ForeignMessage so that the group made by MakeInvalidGroup will not
+  // Use TestEmptyMessage so that the group made by MakeInvalidGroup will not
   // be a known tag number.
-  unittest::ForeignMessage message;
+  unittest::TestEmptyMessage message;
 
   // Control case.
   EXPECT_TRUE(message.ParseFromString(MakeInvalidGroup("", 0, true)));
@@ -520,6 +507,26 @@ TEST_F(WireFormatInvalidInputTest, InvalidUnknownGroup) {
   EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\017", 1, true)));
 }
 
+TEST_F(WireFormatInvalidInputTest, InvalidStringInUnknownGroup) {
+  // Test a bug fix:  SkipMessage should fail if the message contains a string
+  // whose length would extend beyond the message end.
+
+  unittest::TestAllTypes message;
+  message.set_optional_string("foo foo foo foo");
+  string data;
+  message.SerializeToString(&data);
+
+  // Chop some bytes off the end.
+  data.resize(data.size() - 4);
+
+  // Try to skip it.  Note that the bug was only present when parsing to an
+  // UnknownFieldSet.
+  io::ArrayInputStream raw_input(data.data(), data.size());
+  io::CodedInputStream coded_input(&raw_input);
+  UnknownFieldSet unknown_fields;
+  EXPECT_FALSE(WireFormat::SkipMessage(&coded_input, &unknown_fields));
+}
+
 }  // namespace
 }  // namespace internal
 }  // namespace protobuf